1 /** 2 * @fileOverview 3 * Copyright (c) 2013 Regione Autonoma della Sardegna 4 * Published under the GPL license.<br> 5 * See <a href="https://sardegnageoportale.it/webgis/license.txt">https://sardegnageoportale.it/webgis/license.txt</a> 6 * for the full text of the license. 7 * @version 0.1 8 */ 9 10 /** 11 * @require OpenLayers/Control.js 12 */ 13 14 /** 15 * @namespace framework.widgets.control 16 */ 17 Ext.namespace("framework.widgets.control"); 18 19 /** 20 * Provides control for getting Latitude and Longitude of a click point. 21 * @name_ InfoObliquePosition 22 * @class Provides control for getting Latitude and Longitude of a click point. 23 * @constructor 24 * @extends <a target="_blank" href="http://dev.openlayers.org/docs/files/OpenLayers/Control-js.html">OpenLayers.Control</a> 25 */ 26 framework.widgets.control.InfoObliquePosition = OpenLayers.Class(OpenLayers.Control, 27 /** 28 * @lends framework.widgets.control.InfoObliquePosition.prototype 29 */ 30 { 31 /** 32 * If provided, a marker will be drawn on this 33 * layer with the location returned by click point. 34 * @public 35 * @type OpenLayers.Layer.Vector 36 */ 37 layer: null, 38 39 /** 40 * paht for images marker, 41 * default value is "theme/app/img/". 42 * @public 43 * @type String 44 */ 45 markersImgPath: 'theme/app/img/', 46 47 /** 48 * Default options object 49 * @private 50 * @type object 51 */ 52 defaultHandlerOptions: { 53 'single': true, 54 'double': false, 55 'pixelTolerance': 0, 56 'stopSingle': false, 57 'stopDouble': false 58 }, 59 60 /** 61 * Control with Altitude 62 * @private 63 * @type OpenLayers.Control.WMSGetFeatureInfo 64 */ 65 controlPoint: null, 66 67 /** 68 * Unit of measurement for Altitude 69 * @private 70 * @type String 71 */ 72 textUnit: "metri", 73 74 /** 75 * Type of service for calculate oblique Photos. If is null: dinamic url generated 76 * 77 * @public 78 * @type string 79 */ 80 urlServOPDedicated: false, 81 82 /** 83 * Foto Oblique visualizzata in mappa' 84 * 85 * @public 86 * @type {Object} JSON 87 */ 88 obliquePhoto: { 89 /** 90 * Property: extent 91 * {OpenLayers.Bounds} extent of the tile map 92 */ 93 extent: null, 94 /** 95 * Property: extent 96 * {OpenLayers.Bounds} Maximum extent of the tile map 97 */ 98 maxExtent: null, 99 /** 100 * Property: tileOrigin 101 * {OpenLayers.LonLat} origin of the tile map 102 */ 103 tileOrigin: null, 104 /** 105 * Property: maxResolution 106 * {float} max resolution of the zero level 107 */ 108 maxResolution: null, 109 /** 110 * Property: zoom 111 * {int} zooom of the tilemap 112 */ 113 typeImg: null, 114 /** 115 * Property: numLevels 116 * {int} num levels of the tile map 117 */ 118 numLevels: 0, 119 /** 120 * Property: resolutions 121 * {int} resolution of the tile map 122 */ 123 resolutions: null, 124 /** 125 * Property: area 126 * {int} area of the tile map 127 */ 128 projection: 'EPSG:32632', 129 /** 130 * Property: area 131 * {int} area of the tile map 132 */ 133 area: null, 134 /** 135 * Property: initcoordRect 136 * {OpenLayers.LonLat} coordinata "fittizzia" del centro della mappa (rettangolo) 137 */ 138 initcoordRect: null, 139 /** 140 * Property: initcoordTrap 141 * {OpenLayers.LonLat} coordinata "reale" del centro della mappa (trapezio) 142 */ 143 initcoordTrap: null, 144 /** 145 * Property: scale 146 * {string} actual scale of the tile map 147 */ 148 scale: null, 149 /** 150 * Flag to remember if obliquephoto is opened or not 151 * {boolean} flag for opened status 152 */ 153 opened: false 154 155 }, 156 /** 157 * Classe della mappa doppia' 158 * 159 * @public 160 * @type String 161 */ 162 idDoubleMapComp: null, 163 /** 164 * Configured doublemap 165 * 166 * @public 167 * @type {Object} OpenLayers.Map 168 */ 169 map2: null, 170 /** 171 * Marker calcolo altezza 172 * 173 * @private 174 * @type {Object} OpenLayers.Layer.Markers 175 */ 176 markers: null, 177 178 179 /** 180 * Create a handler for the click event 181 * @private 182 */ 183 initialize: function(options) { 184 185 this.handlerOptions = OpenLayers.Util.extend({}, this.defaultHandlerOptions); 186 OpenLayers.Control.prototype.initialize.apply(this, arguments); 187 this.handler = new OpenLayers.Handler.Click(this, 188 { 189 'click': this.onClick 190 }, 191 this.handlerOptions 192 ); 193 194 if(!this.layer){ 195 this.layer = new OpenLayers.Layer.Vector('InfoObliquePosition', { 196 displayInLayerSwitcher: false, 197 visibility: true, 198 styleMap: new OpenLayers.StyleMap({ 199 'default': new OpenLayers.Style({ 200 graphicZIndex: 100, 201 externalGraphic: this.markersImgPath + "fa_marker.png", 202 graphicWidth: 68, 203 graphicHeight: 32, 204 graphicOpacity: 1 205 })}) 206 }); 207 } 208 }, 209 210 211 /** 212 * APIMethod: activate 213 * Extend method OpenLayers.Control. 214 * Explicitly activates a control and it's associated 215 * handler if one has been set. Controls can be 216 * deactivated by calling the deactivate() method. 217 * 218 * Returns: 219 * {Boolean} True if the control was successfully activated or 220 * false if the control was already active. 221 * @private 222 */ 223 activate: function () { 224 225 226 if (this.active) { 227 return false; 228 } 229 230 if (this.handler) { 231 this.handler.activate(); 232 } 233 this.active = true; 234 if(this.map) { 235 OpenLayers.Element.addClass( 236 this.map.viewPortDiv, 237 this.displayClass.replace(/ /g, "") + "Active" 238 ); 239 } 240 241 if (this.idDoubleMapComp) { 242 this.map2 = Ext.getCmp(this.idDoubleMapComp).app2.mapPanel.map; 243 this.markers = new OpenLayers.Layer.Markers( "Markers" ); 244 this.map2.addLayer(this.markers); 245 246 } 247 248 this.events.triggerEvent("activate"); 249 return true; 250 251 252 253 }, 254 255 256 /** 257 * APIMethod: deactivate 258 * Deactivates a control and it's associated handler if any. The exact 259 * effect of this depends on the control itself. 260 * 261 * Returns: 262 * {Boolean} True if the control was effectively deactivated or false 263 * if the control was already inactive. 264 */ 265 deactivate: function () { 266 if (this.active) { 267 if (this.handler) { 268 this.handler.deactivate(); 269 } 270 this.active = false; 271 if(this.map) { 272 OpenLayers.Element.removeClass( 273 this.map.viewPortDiv, 274 this.displayClass.replace(/ /g, "") + "Active" 275 ); 276 } 277 278 if (this.idDoubleMapComp) { 279 if (this.map2.getLayersByName(this.layer2.name).length !== 0) { 280 this.map2.removeLayer(this.layer2); 281 }; 282 283 } 284 this.events.triggerEvent("deactivate"); 285 return true; 286 } 287 return false; 288 }, 289 290 291 /** 292 * Perform the click event getting longitude and latidude information from the selected point 293 * @private 294 * @param {Object} evt event object. 295 */ 296 onClick: function(evt) { 297 var layerVector = null; 298 var layerVector2 = null; 299 300 var position = this.map.getLonLatFromPixel(evt.xy); 301 302 Ext.Ajax.request({ 303 url: this.getObliqueServletUrl(), 304 method: 'POST', 305 params: { 306 method: 'testConvert', 307 area: this.obliquePhoto.area, 308 coordinate: Ext.util.JSON.encode(position), 309 photoId: this.obliquePhoto.id 310 }, 311 success: function(data) { 312 if (data.responseText) { 313 var record = Ext.util.JSON.decode(data.responseText); 314 //la coordinata si trova in record.coordinate 315 //l'altezza in record.altitude 316 317 // INSERIMENTO MARKER MAPPA SIGOLA 318 layerVector = this.layer; 319 320 if (this.map.getLayersByName(this.layer.name).length !== 0) { 321 this.map.removeLayer(this.layer); 322 }; 323 this.map.addLayer(this.layer); 324 325 //create popup on "featureselected" 326 layerVector.events.on({ 327 featureselected: function(e) { 328 createPopup(e.feature); 329 } 330 }); 331 332 this.deactivate(); 333 334 //remove marker 335 var f = this.layer.features; 336 for(i=f.length-1;i>-1;i--){ 337 if(f[i].selfRemove) 338 this.layer.removeFeatures(f[i]); 339 } 340 341 //create new feature with marker 342 var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(position.lon, position.lat) 343 , null, {externalGraphic: this.markersImgPath + "fa_marker.png", 344 graphicWidth: 60, graphicHeight: 38, graphicYOffset: -38, fillOpacity: 1}); 345 var coordinateText = '<h1>Coordinate</h1>'+ '<p>nord: ' + (Math.round(record.coordinate.y*100)/100) + '<br />est: ' + Math.round(record.coordinate.x*100)/100 + '</p>'; 346 347 feature.selfRemove = true; 348 349 var altitudeText = ""; 350 var heightText = ""; 351 352 if (record.height > 0.001) { 353 var hei = (Math.round(record.height*100)/100); 354 heightText = '<h1>Altezza da terra</h1>'+'<p> '+ ((hei>=0)?hei+' m':"n.d") +'</p>'; 355 } 356 357 if (record.altitude > 0.001) { 358 var alt = (Math.round(record.altitude*100)/100); 359 altitudeText = '<h1>Quota sul livello del mare</h1>'+'<p> '+ alt +' m</p>'; 360 } 361 else 362 altitudeText = "<h1>Altezza non disponibile</h1>"; 363 364 feature.text = 365 heightText+ 366 altitudeText+ 367 coordinateText; 368 369 370 this.layer.addFeatures(feature); 371 372 var selectCtrl = new OpenLayers.Control.SelectFeature([this.layer], {toggle: true, clickout: true}); 373 374 this.map.addControl(selectCtrl); 375 selectCtrl.activate(); 376 377 // remove popup 378 removePopup(); 379 createPopup(feature); 380 381 this.map.zoomOut(); 382 this.map.zoomIn(); 383 this.map.setCenter(position); 384 385 386 if (this.idDoubleMapComp) { 387 388 // INSERIMENTO MARKER MAPPA DOPPIA 389 layerVector2 = this.layer2; 390 391 if (this.map2.getLayersByName(this.layer2.name).length !== 0) { 392 this.map2.removeLayer(this.layer2); 393 }; 394 this.map2.addLayer(this.layer2); 395 396 this.deactivate(); 397 398 //remove marker 399 var f = this.layer2.features; 400 for(i=f.length-1;i>-1;i--){ 401 if(f[i].selfRemove) 402 this.layer2.removeFeatures(f[i]); 403 } 404 405 //create new feature with marker 406 var feature2 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(record.coordinate.x,record.coordinate.y) 407 , null, {externalGraphic: this.markersImgPath + "fa_marker.png", 408 graphicWidth: 60, graphicHeight: 38, graphicYOffset: -38, fillOpacity: 1}); 409 var coordinateText2 = '<p>lon: ' + (Math.round(record.coordinate.x*100)/100) + '<br />lat: ' + Math.round(record.coordinate.y*100)/100 + '</p>'; 410 feature2.selfRemove = true; 411 412 var altitudeText2 = ""; 413 414 if (record.altitude) { 415 altitudeText = '<h1>Altezza da terra</h1>'+ 416 '<p> '+ (Math.round(record.altitude*100)/100) +' m</p>'; 417 } 418 419 feature2.text = '<h1>Coordinate</h1>'+ coordinateText2 +' '+ altitudeText2; 420 421 422 this.layer2.addFeatures(feature2); 423 424 var position_real = new OpenLayers.LonLat(record.coordinate.x,record.coordinate.y); 425 this.map2.zoomToScale(this.map.getScale()); 426 this.map2.setCenter(position_real); 427 428 429 } 430 431 432 } else { 433 Ext.MessageBox.alert('Errore', record.error); 434 } 435 }, 436 failure: function() { 437 Ext.MessageBox.alert('Errore', 'Errore in chiamata servizio.'); 438 }, 439 scope: this 440 }); 441 442 443 function removePopup() { 444 if (this.popupAddr) { 445 this.popupAddr.close(); 446 this.popupAddr.destroy(); 447 } 448 449 } 450 451 452 function createPopup(feature) { 453 454 removePopup(); 455 456 this.popupAddr = new framework.plugins.PopUp({ 457 location: feature, 458 width: 200, 459 border: false, 460 html: '<div class="popupAddr">'+feature.text+'</div>', 461 maximizable: false, 462 collapsible: false 463 }); 464 465 // unselect feature when the popup 466 // is closed 467 this.popupAddr.on({ 468 close: function() { 469 if (OpenLayers.Util.indexOf(layerVector.selectedFeatures, this.feature) > -1) { 470 selectCtrl.unselect(this.feature); 471 } 472 } 473 }); 474 this.popupAddr.show(); 475 476 } 477 478 479 }, 480 481 /** 482 * Returns oblique servlet url 483 * @private 484 * @return url servelt obliquephotos 485 */ 486 getObliqueServletUrl: function() { 487 if (this.urlServOPDedicated) { 488 return this.urlServOPDedicated 489 } 490 else { 491 var current = String(window.location); 492 current = current.replace("print.jsp", ""); //removes print modality 493 current = current.replace(/\?.*/g, ""); //removes possible querystring 494 if (!current.match(/.*\/$/)) { 495 current += '/'; 496 } 497 return current + 'ObliquePhotos'; 498 } 499 } 500 501 502 503 }); 504