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