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 widgets/Viewer.js
 12  */
 13 
 14 /**
 15  * @namespace framework
 16  */
 17 
 18 Ext.ns("framework");
 19 
 20 /** api: constructor
 21  *  .. class:: RASViewer(config)
 22  *
 23  *  Estensione del visualizzatore cartografico per il frameword Sardegna.
 24  */
 25 
 26 
 27 /**Visual container 
 28  * @name_ RASViewer
 29  * @class Visual container 
 30  * @constructor
 31  * @extends gxp.Viewer - See <a href="http://gxp.opengeo.org/master/doc/lib/widgets/Viewer.html">gxp.Viewer</a>
 32  */
 33 framework.RASViewer = Ext.extend(gxp.Viewer,
 34     /** 
 35      * @lends framework.RASViewer.prototype 
 36      */
 37         {
 38           /** Construct the viewer
 39            * @private
 40            * @param {Object} config is a object configuration
 41            */
 42           constructor: function (config) {
 43             // Ripristino layer attivi
 44             Ext.each(config.map.layersInfo, function (item, i) {
 45               var layer = this.getConfigLayersByName(config, item.name);
 46               if (layer) {
 47                 layer.visibility = item.visibility;
 48                 layer.selected = item.selected;
 49               }
 50             }, this);
 51 
 52             framework.RASViewer.superclass.constructor.apply(this, arguments);
 53             if (Ext.isDefined(config.customData)) {
 54               this.addListener('ready', function (e) {
 55                 this.loadCustomData();
 56               }, this);
 57             }
 58           },
 59           /** serialize a json object
 60            * @public
 61            * @returns {Object} map definition in json
 62            */
 63           serialize: function () {
 64             return Ext.util.JSON.encode(this.serializableState());
 65          },
 66           serializableState: function () {
 67             var state = this.getState();
 68             delete state.proxy;
 69             delete state.tools;
 70             delete state.defaultSourceType;
 71             delete state.mapPlugins;
 72             delete state.portalConfig;
 73             delete state.map.controls;
 74             delete state.map.items;
 75             delete state.map.tbar;
 76             // Layers information is moved into layersInfo property to allow 
 77             // layers overriding at construction time
 78             state.map.layersInfo = state.map.layers;
 79             //sometime this.getState lost some metadataURLs
 80             this.recoveryMetadataUrl(state);
 81             state.customData = this.serializeCustomData();
 82             return state;
 83           },
 84           /** recovery MatadataUrl for layers object
 85            * @private
 86            */
 87           recoveryMetadataUrl: function (state) {
 88             try {
 89               var layers = state.map.layers;
 90               for (var i = 0; i < layers.length; i++) {
 91                 if (layers[i].capability && layers[i].capability.metadataURLs && layers[i].capability.metadataURLs.length === 0) {
 92                   var records = this.mapPanel.layers.data.items;
 93                   for (var j = 0; j < records.length; j++) {
 94                     if (records[j].data.name === layers[i].name) {
 95                       layers[i].capability.metadataURLs = records[j].data.metadataURLs;
 96                     }
 97                   }
 98                 }
 99               }
100             } catch (ex) {
101             }
102           },
103           /** load custom data from this object configuration an retrieves it
104            * @public
105            */
106           loadCustomData: function (config) {
107             if (Ext.isDefined(this.customData)) {
108               if (Ext.isDefined(this.customData.backgroundColor)) {
109                 var container = Ext.get(this.mapPanel.map.getViewport());
110                 container.setStyle('background-color', this.customData.backgroundColor);
111               }
112               if (Ext.isDefined(this.customData.layers)) {
113                 var geojson_format = new OpenLayers.Format.GeoJSON();
114                 Ext.each(this.customData.layers, function (item, i) {
115                   var layers = this.mapPanel.map.getLayersByName(item.name);
116                   if (layers.length > 0) {
117                     var features = new Array();
118                     Ext.each(item.features, function (feature, j) {
119                       var vector = geojson_format.read(feature.data)[0];
120                       vector.style = Ext.util.JSON.decode(feature.style);
121                       vector.text = feature.text;
122                       vector.selfRemove = feature.selfRemove;
123                       features.push(vector);
124                     }, this);
125                     layers[0].addFeatures(features);
126                     this.mapPanel.map.raiseLayer(layers[0], 10);
127 
128                     //inserimento popUp
129                     selectCtrl = new OpenLayers.Control.SelectFeature([layers[0]], {
130                       toggle: true,
131                       clickout: true
132                     });
133                     this.mapPanel.map.addControl(selectCtrl);
134                     selectCtrl.activate();
135 
136                     function removePopup() {
137                       if (this.popupAddr) {
138                         this.popupAddr.close();
139                         this.popupAddr.destroy();
140                       }
141 
142                     };
143 
144                     function createPopup(feature) {
145                       removePopup();
146                       this.popupAddr = new framework.plugins.PopUp({
147                         //title: 'Ricerca indirizzo',
148                         //map: this.map,
149                         location: feature,
150                         width: 200,
151                         border: false,
152                         html: '<div class="popupAddr">' + feature.text + '</div>',
153                         maximizable: false,
154                         collapsible: false
155                       });
156                       this.popupAddr.show();
157                     };
158 
159                     layers[0].events.on({
160                       featureselected: function (e) {
161                         createPopup(e.feature);
162                       }
163                     });
164                   }
165                 }, this);
166               }
167             }
168 
169             //CONTROLLO LAYER TMS "NON DISPONIBILE
170             Ext.each(this.mapPanel.map.layers, function (l) {
171               if (l.layerNT && l.visibility == true) {
172                 //l.layerNT.display(false);
173                 l.layerNT.setZIndex(-9);
174                 l.setZIndex(-10);
175               }
176             });
177 
178           },
179           /** get base url for current application
180            * @public
181            * @returns {String} base url for current application
182            */
183           getBaseUrl: function () {
184             var url = location.href;  //url intera compresi querystring
185             //elimino l'eventuale querystring
186             var indexQuestion = url.lastIndexOf("?");
187             if (indexQuestion > -1) {
188               url = url.substr(0, indexQuestion);
189             }
190             //arrivo fino all'ultima /
191             url = url.substr(0, url.lastIndexOf("/"));
192             return url + '/';
193           },
194           /** FeatureLayer serialization
195            * @public
196            * @param {OpenLayers.Layer} layer
197            * @returns {objet} inside an Array with serialized feature plus layer information
198            */
199           serializeFeatureLayer: function (layer) {
200             var geojson_format = new OpenLayers.Format.GeoJSON();
201             var features = new Array();
202             Ext.each(layer.features, function (feature, index) {
203               var record = new Object();
204               record.data = geojson_format.write(feature);
205               record.style = Ext.util.JSON.encode(feature.style);
206               record.text = feature.text;
207               record.selfRemove = feature.selfRemove;
208               features.push(record);
209             }, this);
210             return {
211               name: layer.name,
212               type: layer.type,
213               features: features
214             };
215           },
216           /** Serialization of custom data
217            * @private
218            * @returns {objet} serialized object
219            */
220           serializeCustomData: function () {
221             var ris = new Object();
222             for (var key in this.customData) {
223               if (key === 'layers') {
224                 ris['layers'] = [];
225               } else {
226                 ris[key] = this.customData[key];
227               }
228             }
229             Ext.each(this.customData.layers, function (element, i) {
230               if (Ext.isDefined(element.type) && element.type === 'featureLayer') {
231                 ris.layers.push(this.serializeFeatureLayer(element));
232               }
233             }, this);
234             return ris;
235           },
236           /** private: method[getState]
237            *  :returns: ``Object`` Representation of the app's current state.
238            */
239           getState: function () {
240 
241             // start with what was originally given
242             var state = Ext.apply({}, this.initialConfig);
243 
244             // update anything that can change
245             var center = this.mapPanel.map.getCenter();
246             if (center) {
247               Ext.apply(state.map, {
248                 center: [center.lon, center.lat],
249                 zoom: this.mapPanel.map.zoom,
250                 layers: []
251               });
252             }
253 
254             // include all layer config
255             var sources = {};
256             this.mapPanel.layers.each(function (record) {
257               var layer = record.getLayer();
258               if (layer.displayInLayerSwitcher) {
259                 var id = record.get("source");
260                 var source = this.layerSources[id];
261                 if (!source) {
262                   console.error("Could not find source for layer '" + record.get("name") + "'");
263                 } else {
264                   // add layer
265                   state.map.layers.push(source.getConfigForRecord(record));
266                   if (!sources[id]) {
267                     sources[id] = source.getState();
268                   }
269                 }
270               }
271             }, this);
272             // update sources, adding new ones
273             // HACK per URL 
274             for (var key in sources) {
275               var obj = sources[key];
276               for (var prop in obj) {
277                 // important check that this is objects own property 
278                 // not from prototype prop inherited
279                 if (obj.hasOwnProperty(prop)) {
280                   if (prop == "url") {
281                     var urlString = obj[prop];
282                     var pos = urlString.indexOf("?");
283                     if (pos > -1 && !urlString.indexOf("Proxy?") == 0)
284                       obj[prop] = urlString.substring(0, pos);
285                   }
286                 }
287               }
288             }
289 
290             Ext.apply(this.sources, sources);
291 
292             //get tool states, for most tools this will be the same as its initial config
293             state.tools = [];
294             Ext.iterate(this.tools, function (key, val, obj) {
295               //only get and persist the state if there a tool specific getState method
296               if (val.getState != gxp.plugins.Tool.prototype.getState) {
297                 state.tools.push(val.getState());
298               }
299             });
300             return state;
301           },
302           getConfigLayersByName: function (config, layerName) {
303             var layer = null;
304             Ext.each(config.map.layers, function (el, index) {
305               if (el.name === layerName) {
306                 layer = el;
307                 return false;  // Stops iteration
308               }
309             });
310             return layer;
311           }
312         });
313 
314     Ext.preg(framework.RASViewer.prototype.ptype, framework.RASViewer);
315