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  * @namespace framework.plugins
 12  */
 13 Ext.namespace("framework.form");
 14 
 15 /**
 16  * Creates a combo box that handles results from a directory service OpenLS. By
 17  *  default it uses OpenPOI service by Regione Autonoma della Sardegna, but it can be configured with a custom store
 18  *  to use other services standard OpenPOI. If the user enters a valid address in the search
 19  *  box, the combo's store will be populated with records that match the
 20  *  address.
 21  *  @name_ OpenPOISearchCombo
 22  * @class Creates a combo box that handles results from a OpenPOI service.
 23  * @constructor
 24  @extends <a target="_blank" href="http://docs.sencha.com/extjs/3.4.0/#!/api/Ext.form.ComboBox">Ext.form.ComboBox</a>
 25  */
 26 
 27 framework.form.OpenPOISearchCombo = Ext.extend(Ext.form.ComboBox,
 28         /** 
 29          * @lends framework.form.OpenPOISearchCombo.prototype 
 30          */
 31                 {
 32                     /**
 33                      * A configured map or a configuration object
 34                      *  for the map constructor, required only if :attr:`zoom` is set to
 35                      *  value greater than or equal to 0.
 36                      * @public
 37                      * @type OpenLayers.Map or Object
 38                      */
 39                     map: null,
 40                     /** 
 41                      * If provided, a marker will be drawn on this
 42                      * layer with the location returned by the geocoder. The location will be
 43                      * cleared when the map panned. 
 44                      * @public
 45                      * @type OpenLayers.Layer.Vector
 46                      */
 47                     layer: null,
 48                     /**
 49                      * See http://www.dev.sencha.com/deploy/dev/docs/source/BoxComponent.html#cfg-Ext.BoxComponent-width,
 50                      * default value is 240.
 51                      * @public
 52                      * @type Number
 53                      */
 54                     width: 350,
 55                     /**
 56                      * See http://www.dev.sencha.com/deploy/dev/docs/source/Combo.html#cfg-Ext.form.ComboBox-listWidth,
 57                      * default value is 350.
 58                      * @public
 59                      * @type Number
 60                      */
 61                     listWidth: 350,
 62                     /**
 63                      * See http://www.dev.sencha.com/deploy/dev/docs/source/Combo.html#cfg-Ext.form.ComboBox-loadingText,
 64                      * default value is "Search in Geonames...".
 65                      * @public
 66                      * @type String
 67                      */
 68                     loadingText: 'Ricerca in corso...',
 69                     /**
 70                      * Text to display for an empty field
 71                      * default value is "Ricerca posizione".
 72                      * @public
 73                      * @type String
 74                      */
 75                     emptyText: 'Ricerca posizione',
 76                     /** 
 77                      * The minimum zoom level to use when zooming to a location.
 78                      * Not used when zooming to a bounding box. 
 79                      * Default is 12.
 80                      * @public
 81                      * @type number
 82                      */
 83                     zoom: 8,
 84                     /** 
 85                      * Minimum number of characters to be typed before search occurs
 86                      * Defaults to 1
 87                      * @public
 88                      * @type number
 89                      */
 90                     minChars: 3,
 91                     /** 
 92                      * Delay before the search occurs.
 93                      * Default is 50ms.
 94                      * @public
 95                      * @type number
 96                      */
 97                     queryDelay: 50,
 98                     /** 
 99                      * See: http://www.geonames.org/export/geonames-search.html
100                      * The maximum number of rows in the responses, defaults to 20,
101                      * maximum allowed value is 1000
102                      * @public
103                      * @type String
104                      */
105                     maxfeatures: '20',
106                     /**
107                      * paht for images marker,
108                      * default value is "theme/app/img/".
109                      * @public
110                      * @type String
111                      */
112                     markersImgPath: 'theme/app/img/',
113                     /**
114                      * see http://www.extjs.com/deploy/dev/docs/output/Ext.XTemplate.html 
115                      * Template for presenting the result in the list, 
116                      * if not set a default value is provided
117                      * @private
118                      * @type Ext.XTemplate
119                      */
120                     tpl: '<tpl for="."><div class="x-combo-list-item"><h1>{labels}<br></h1>{terms}</div></tpl>',
121                     /** 
122                      * See: http://www.geonames.org/export/geonames-search.html
123                      * Place name and country name will be returned in the specified language
124                      * Default is Italian (it). 
125                      * @private
126                      * @type String
127                      */
128                     lang: 'it',
129                     /** 
130                      * Country in which to make a GeoNames search, default is all countries.
131                      * Providing several countries can be done like: countryString: country=FR&country=GP
132                      * @private
133                      * @type String
134                      */
135                     term: '',
136                     /** 
137                      * Restricts the search for toponym of the given continent
138                      * Default is all continents.
139                      * @private
140                      * @type String
141                      */
142                     category: '',
143                      /** 
144                      * Search filter: bounding box
145                      * @private
146                      * @type String
147                      */
148                     bbox: '',
149                      /** 
150                      * Search filter: codice ISTAT dei comuni 
151                      * @private
152                      * @type String
153                      */
154                     istat: '',
155                      /** 
156                      * Search filter: address
157                      * @private
158                      * @type String
159                      */
160                     address: '',
161                      /** 
162                      * Search filter: longitudine del punto per la ricerca per raggio
163                      * @private
164                      * @type String
165                      */
166                     lon: '',
167                      /** 
168                      * Search filter: latitudine del punto per la ricerca per raggio
169                      * @private
170                      * @type String
171                      */
172                     lat: '',
173                      /** 
174                      * Search filter: raggio in metri
175                      * @private
176                      * @type String
177                      */
178                     radius: '',
179                     /** 
180                      * See: http://www.geonames.org/export/geonames-search.html
181                      * Search for toponyms tagged with the specified tag, default is all tags.
182                      * @private
183                      * @type String
184                      */
185                     tag: '',
186                     /** 
187                      * See: http://www.geonames.org/export/geonames-search.html
188                      * Defines the encoding used for the document returned by the web service, defaults to 'UTF8'.
189                      * @private
190                      * @type String
191                      */
192                     charset: 'UTF8',
193                     /** 
194                      * Hide trigger of the combo.
195                      * @private
196                      * @type boolean
197                      */
198                     hideTrigger: true,
199                     /** 
200                      * Display field name.
201                      * @private
202                      * @type String
203                      */
204                     displayField: 'name',
205                     /** 
206                      * Force selection.
207                      * @private
208                      * @type boolean
209                      */
210                     forceSelection: true,
211                     /** 
212                      * Query parameter.
213                      * @private
214                      * @type String
215                      */
216                     queryParam: 'name',
217                     /** 
218                      * Url of the GeoNames service: http://www.GeoNames.org/export/GeoNames-search.html
219                      * @private
220                      * @type String
221                      */
222                     url: 'PoiQuery?',
223                     /** 
224                      * Url of the external service to retrieve POIs. Default is MapQuest Nominatim
225                      * @private
226                      * @type String
227                      */
228                     baseUrlExternalPois: 'http://open.mapquestapi.com/nominatim/v1/search.php?format=json&addressdetails=1&limit=1000',
229                     /** 
230                      * Attribution URL of the external service to retrieve POIs. Default refers to MapQuest Nominatim
231                      * @private
232                      * @type String
233                      */
234                     attributionExternalPoisServiceUrl: 'http://open.mapquestapi.com/nominatim/',
235                     /** 
236                      * Attribution description string of the external service to retrieve POIs. Default refers to MapQuest Nominatim
237                      * @private
238                      * @type String
239                      */
240                     attributionExternalPoisServiceName: 'MapQuest',
241                     /** 
242                      * Maximum area extent to pass to external service to filter the POIs. 
243                      * It must be defined with a object like defauult value using map SRS EPSG:3003
244                      * @private
245                      * @type String
246                      */
247                     maxSearchExternalExtent: {left: 1209895, bottom: 4294504, right: 1786972, top: 4580410},
248                     /**
249                      * The srs used by the geocoder service.
250                      * Default is "EPSG:3003".
251                      * @public
252                      * @type String
253                      */
254                     srs: "EPSG:3003",
255                      /** 
256                      * Variabile per memorizzare il testo libero dell'ultima ricerca
257                      * @private
258                      * @type String
259                      */
260                     textSearch: '',
261                      /** 
262                      * Nome della servlet per la ricerca
263                      * @private
264                      * @type String
265                      */
266                     serveltName: 'POIManagingServlet',
267                      /** 
268                      * url di base per la chiamata al servizio
269                      * @private
270                      * @type String
271                      */
272                     baseUrl: '',
273                      /** 
274                      * id (Codice Fiscale) dell'utente con privilegi
275                      * @private
276                      * @type String
277                      */
278                     authenticatedUser: null,
279                     /** 
280                      * Enable POI search on external services
281                      * @public
282                      * @type Boolean
283                      */
284                     searchExternalPoi: true,
285                      /** 
286                      * Enable search by extent (default true)
287                      * @private
288                      * @type Boolean
289                      */
290                     applySearchByExtent: true,
291                     /** 
292                      * Enable the destroying of the previously rendered features before render new features that represent search results
293                      * @public
294                      * @type Boolean
295                      */
296                     destroyPreviousFeatures: true,
297                     /** 
298                      * the authenticate user
299                      * @public
300                     * @type Ext.data.Store
301                      */
302                     userAuthDS: null,
303                     /** 
304                      * Window for create and editing POI
305                      * @private
306                      * @type framework.widgets.PoiDataPanel
307                      */
308                     winEditPOI: null,
309                     /** 
310                      * Vector layer for editing POI
311                      * @private
312                      * @type OpenLayers.Layer.Vector
313                      */
314                     layerEdit: null,
315                     /** 
316                      * Feature for Editing Vector Layer 
317                      * @private
318                      * @type OpenLayers.Feature.Vector
319                      */
320                     featureEdit: null,
321                     /** 
322                      * Add a drag feature control to move features around.
323                      * @private
324                      * @type OpenLayers.Control.DragFeature
325                      */
326                     dragFeature: null,
327                     /** 
328                      * ID obj framework.widgets.POIManagmentBox
329                      * @private
330                      * @type String
331                      */
332                     idnewPoiManage: 'newPOIManage',
333                     /** 
334                      * ID obj framework.widgets.PoiVerifyManagementBox
335                      * @private
336                      * @type String
337                      */
338                     idPoiVerifyManagement: 'idPoiVerifyManagement',
339                     /** 
340                      * Bounding box for extent to zoom
341                      * @private
342                      * @type OpenLayers.Bounds
343                      */
344                     extentToZoom: null,
345                     /**
346                     * number current page
347                     * default is 1.
348                     * @private
349                     * @type boolean
350                     */
351                    numpage: 1,
352 
353                    /**
354                     * number page size
355                     * default is 10.
356                     * @private
357                     * @type boolean
358                     */
359                    pageSize: 40,
360                    /** api: config[urlService]
361                     *  
362                     *  url to proxy for authenticate http calls
363                     *  @public
364                     *  @type String
365                     */
366                    urlProxy: '',
367                    /** api: config[urlCatasto]
368                     *  
369                     *  url for wfs catasto service
370                     *  @public
371                     *  @type String
372                     */
373                    urlWFS: '/geoserver/ows?',
374                    /** api: config[serviceType]
375                     *  
376                     *  Service type for catasto service (query string parameter)
377                     *  Default WFS
378                     *  @public
379                     *  @type String
380                     */
381                    serviceType: 'WFS',
382                    /** api: config[version]
383                     *  
384                     *  Version for WFS service (query string parameter)
385                     *  Default 1.0.0
386                     *  @public
387                     *  @type String
388                     */
389                    version: '1.0.0',
390                    /** api: config[GetFeature]
391                     *  
392                     *  Request type for WFS service (query string parameter)
393                     *  Default GetFeature
394                     *  @public
395                     *  @type String
396                     */
397                    requestType: 'GetFeature',
398                    /** api: config[typeName]
399                     * 
400                     *  typeName for WFS service (query string parameter)
401                     *  @public
402                     *  @type String
403                     */
404                     typeName: 'dbu:limitiamministrcomunali', // dbu:LIMITIAMMINISTRCOMUNALI
405                     /** 
406                      * ricerca comune WFS: nome del campo geometrico del layer
407                      * @private
408                      * @type String
409                      */
410                     nameGeometry: 'geom', // POLIGONO
411                     /** 
412                      * ricerca comune WFS: nome del campo con il nome del comune
413                      * @private
414                      * @type String
415                      */
416                     properties_nome: 'nome', // NOME
417                     /** 
418                      * ricerca comune WFS: nome del campo con l'ISTAT del comune
419                      * @private
420                      * @type String
421                      */
422                     properties_istat: 'codiceist1', //CODICEISTATCOMUNALE
423                    /** api: config[infoFormat]
424                     *  
425                     *  maxFeatures for WFS service (query string parameter)
426                     *  Default 50
427                     *  @public
428                     *  @type Number
429                     */
430                    maxFeatures: 5,
431                     /** api: config[path_img]
432                     *  
433                     *  
434                     *  @public
435                     *  @type String
436                     */                
437                    path_img: 'theme/app/img/poi/',
438                    
439                    /** api: config[geometryFields]
440                     *  
441                     *  fields from service answer to be transformed on OpenLayers.Bounds
442                     *  @public
443                     *  @type Array of String
444                     */
445                     mapSearchExtent: null,
446                     /** Init the component creating a store and object'events.
447                      * @private
448                      */
449                     initComponent: function() {
450                         framework.form.OpenPOISearchCombo.superclass.initComponent.apply(this, arguments);
451                         var _self = this;
452                         
453                         this.searchExternalPoiDefault = this.searchExternalPoi;
454                         if (Ext.isString(this.srs)) {
455                             this.srs = new OpenLayers.Projection(this.srs);
456                         }
457 
458                         if (!this.map) {
459                             var mapPanel = this.findParentBy(function(cmp) {
460                                 return cmp instanceof GeoExt.MapPanel;
461                             });
462                             this.map = mapPanel.map;
463                         }
464                         
465                         this.layer.events.register('featuresremoved', this, this.onFeaturesremoved);
466 
467 
468                         this.lastInternalSearchParams = {};
469 
470                         /**
471                          *  Store CATEGORIES
472                          */
473                         this.categoriesDS = new Ext.data.Store({
474                             url: this.baseUrl + this.serveltName,
475                             path_img: this.path_img,
476                             reader: new Ext.data.JsonReader(
477                                     {
478                                         id: 'id',
479                                         root: 'categories',
480                                         totalProperty: 'totalCount'
481                                     }, [
482                                 {name: 'term', mapping: 'term'},
483                                 {name: 'termIt', mapping: 'termIt'},
484                                 {name: 'category', mapping: 'category'},
485                                 {name: 'categoryIt', mapping: 'categoryIt'}
486                             ])
487                         });
488                         this.categoriesDS.load({params: {method: 'getCategories'}});
489 
490                         var urlAppendString = '';
491 
492                         if (this.term.length > 0) {
493                             urlAppendString = urlAppendString + this.term;
494                         }
495                         if (this.category.length > 0) {
496                             urlAppendString = urlAppendString + this.category;
497                         }
498                         
499                         
500                         this.store = new Ext.data.Store({
501                             /* proxy: new Ext.data.ScriptTagProxy({
502                              url: this.url + urlAppendString,
503                              method: 'GET'
504                              }),*/
505                             proxy: new Ext.data.HttpProxy({
506                                 method: 'GET',
507                                 prettyUrls: false,
508                                 url: this.url
509                             }),
510                             baseParams: {
511                                 start: 0,
512                                 limit: this.pageSize,
513                                 cache: false,
514                                 maxFeatures: this.maxFeatures,
515                                 term: this.term,
516                                 category: this.category,
517                                 bbox: this.bbox,
518                                 istat: this.istat,
519                                 address: this.address,
520                                 codfisc: this.authenticatedUser,
521                                 lon: this.lon,
522                                 lat: this.lat,
523                                 radius: this.radius
524                             },
525                             isPoisExternal: false,
526                             reader: new Ext.data.JsonReader({
527                                 idProperty: 'myid',
528                                 root: "pois",
529                                 totalProperty: "totalCount",
530                                 id: 'myid',
531                                 fields: [
532                                     {
533                                         name: 'authorid'
534                                     },
535                                     {
536                                         name: 'base'
537                                     },
538                                     {
539                                         name: 'categories', type: 'auto', mapping: 'categories[0].value'
540                                     },
541                                     {
542                                         name: 'terms', type: 'auto', mapping: 'categories[0].term'
543                                     },
544                                     {
545                                         name: 'created'
546                                     },
547                                     {
548                                         name: 'descriptions'
549                                     },
550                                     {
551                                         name: 'href'
552                                     },
553                                     {
554                                         name: 'id'
555                                     },
556                                     {
557                                         name: 'labels', type: 'auto', mapping: 'labels[0].value'
558                                     },
559                                     {
560                                         name: 'links'
561                                     },
562                                     {
563                                         name: 'location', type: 'auto', mapping: 'location.points[0].coordinates'
564                                     },
565                                     {
566                                         name: 'myid'
567                                     },
568                                     {
569                                         name: 'times'
570                                     },
571                                     {
572                                         name: 'updated'
573                                     },
574                                     {
575                                         name: 'enabled'
576                                     }
577                                 ]
578                             }),
579                             listeners: {
580                                 load: function() {
581                                     //  this.combo.fireEvent('viewReady');
582                                     if (this.data.items.length === 0) {                                    
583                                         Ext.Msg.alert('Avviso', 'La ricerca non ha prodotto risultati. Controllare i filtri di ricerca e riprovare.');
584                                     } /*else {
585                                         var btnExportPoi = Ext.getCmp(this.combo.idBtnExportPoi);
586                                         if (btnExportPoi) {
587                                             btnExportPoi.setDisabled(false);
588                                         }
589                                     }*/
590                                     
591                                     this.combo.store.baseParams['cache'] = true;
592                                 },
593                                 loadexception: function( misc ) {
594                                     Ext.Msg.alert('Avviso', 'La ricerca non ha prodotto risultati. Inserire almeno un filtro di ricerca o riprovare.');
595                                 },
596                                 datachanged: this.insertPoiToMap
597                             }
598                         });
599 
600                         /*
601                          this.pagingBar = new Ext.PagingToolbar({
602                             store: this.store,
603                             emptyMsg: "Nessun POI da visualizzare",
604                             items: ['-']
605                           });*/
606 
607                         this.storeExternalPois = new Ext.data.Store({
608                             proxy: new Ext.data.HttpProxy({
609                                 method: 'GET',
610                                 prettyUrls: false,
611                                 url: this.baseUrlExternalPois
612                             }),
613                             baseParams: {
614                             },
615                             isPoisExternal: true,
616                             reader: new Ext.data.JsonReader({
617                                 idProperty: 'myid',
618 //                                root: "pois",
619                                 //totalProperty: "totalResultsCount",
620                                 fields: [
621                                     {
622                                         name: 'authorid'
623                                     },
624                                     {
625                                         name: 'base'
626                                     },
627                                     {
628                                         name: 'categories', type: 'auto', mapping: 'type'
629                                     },
630                                     {
631                                         name: 'terms', type: 'auto', mapping: 'class'
632                                     },
633                                     {
634                                         name: 'created'
635                                     },
636                                     {
637                                         name: 'descriptions'
638                                     },
639                                     {
640                                         name: 'href'
641                                     },
642                                     {
643                                         name: 'id'
644                                     },
645                                     {
646                                         name: 'labels', type: 'auto', mapping: 'display_name'
647                                     },
648                                     {
649                                         name: 'links', type: 'auto', mapping: 'licence'
650                                     },
651                                     {
652                                         name: 'location'
653                                     },
654                                     {
655                                         name: 'lon', type: 'auto', mapping: 'lon'
656                                     },
657                                     {
658                                         name: 'lat', type: 'auto', mapping: 'lat'
659                                     },
660                                     {
661                                         name: 'myid'
662                                     },
663                                     {
664                                         name: 'times'
665                                     },
666                                     {
667                                         name: 'updated'
668                                     },
669                                     {
670                                         name: 'enabled'
671                                     }
672                                 ]
673                             }),
674                             listeners: {
675                                 load: function() {
676                                     //  this.combo.fireEvent('viewReady');
677                                 },
678                                 datachanged: this.insertPoiToMap
679                             }
680                         });
681 
682                         this.store.combo = this;
683                         this.storeExternalPois.combo = this;
684 
685                         this.on({
686                             added: this.handleAdded,
687                             select: this.handleSelect,
688                             focus: function() {
689                                 this.clearResult();
690                                 if (this.store.data.items.length > 0)
691                                     this.expand();
692                                 this.setValue(this.textSearch);
693                                 //  this.removeLocationFeature();
694                             },
695                             blur: function(textfield) {
696                               //  textfield.setValue("");
697                                 textfield.setValue(this.textSearch);
698                             },
699                             keyup: function(textfield, eventObject) {
700                                 //  this.textSearch = textfield.getValue();
701                                 this.textSearch = this.el.dom.value;
702                                 if (eventObject.getCharCode() === Ext.EventObject.ENTER) {
703                                     this.focus();
704                                       this.setValue(this.textSearch);
705                                       this.doQuery(this.el.dom.value,true);
706                                 } else {
707                                     if (this.isExpanded()) {
708                                         this.list.hide();
709                                     }
710                                 }
711                             },
712                             //Gestione onMouseOver 
713                             //TODO  non funzionante
714                             viewReady: function() {
715                                 this.view.trackOver = true;
716                                 this.view.on({
717                                     mouseenter: function(obj, index, node, e) {
718                                         var x = 1;
719                                         alert(index);
720                                     }
721                                 });
722                                 var x = 1;
723                             },
724                             scope: this
725                         });
726 
727                         this.tpl = new Ext.XTemplate(
728                                 '<tpl for=".">',
729                                 '<div class="x-combo-list-item"><h1>{labels}<br></h1>',
730                                 '{[this.getTermIt(values.terms, values.categories)]}</div>',
731                                 '</tpl>',
732                                 {
733                                     getTermIt: function(term, value) {
734 
735                                         var filterValue = null;
736                                         this.categoriesDS.each(function(record) {
737                                             if ((record.get('category') == value || record.get('categoryIt') == value) &&
738                                                     (record.get('term') == term || record.get('term') == term)) {
739                                                 filterValue = record;
740                                             }
741                                         });
742                                        
743                                         var img = '<img style="float:left;padding: 4px;" width="15" height="15" src="'+this.categoriesDS.path_img+'icon_poi_' + filterValue.data.term + '.png" alt="' + filterValue.data.termIt + '">';
744                                         var label = filterValue.data.termIt + ' - ' + filterValue.data.categoryIt;
745                                         return img + ' ' + label;
746                                     },
747                                     categoriesDS: this.categoriesDS
748                                 }
749                         );
750                     },
751                     onFeaturesremoved: function() {
752                         var btnExportPoi = Ext.getCmp(this.idBtnExportPoi);
753                         if (btnExportPoi) {
754                             btnExportPoi.setDisabled(true);
755                             btnExportPoi.hide();
756                         }
757 
758                         if (this.map && this.layer.features.length == 0) {
759                             var ctrlFeature = this.map.getControlsByClass("OpenLayers.Control.SelectFeature");
760                             for (i = 0; i < ctrlFeature.length; i++) {
761                                 this.map.controls.remove(ctrlFeature[i]);
762                             } 
763                           //  console.log('OpenLayers.Control.SelectFeature ---> ' + ctrlFeature.length);
764                         }
765                     },
766                     insertPoiToMap: function(store) {
767                         
768                       //  console.log('>>> external ' + store.isPoisExternal + ' - ')
769                         //  alert(store);
770                         if (this.combo.map.getLayersByName(this.combo.layer.name).length == 0) {
771                             this.combo.map.addLayer(this.combo.layer);
772                         }
773 
774                         //this.combo.map.zoom = 12;
775 
776                         //remove marker and popup
777                         if (store.isPoisExternal) {
778                             this.combo.layer.destroyFeatures();
779                         } else if (this.combo.searchExternalPoi) {
780                             this.combo.localPoiReady = true;
781                         }
782                         
783                         if (!store.isPoisExternal && this.combo.store.baseParams['cache']) {
784                             //this.combo.layer.destroyFeatures();                        
785                             for (var i = 0; i < this.combo.layer.features.length; i++) {
786                                 if (!this.combo.layer.features[i].isPoisExternal)
787                                     this.combo.layer.features[i].destroy();
788                             }
789                             
790                         }
791                         
792                         
793                         //check export marker
794                         if (!store.isPoisExternal && store.data.items.length > 0) {
795                             var btnExportPoi = Ext.getCmp(this.combo.idBtnExportPoi);
796                             if (btnExportPoi) {
797                                 btnExportPoi.setDisabled(false);
798                                 btnExportPoi.show();
799                             }
800                          }
801                                     
802 //                        if (store.isPoisExternal) {
803 //                            if (this.combo.syncronizePoiOnMap) {
804 //                                this.combo.externalPoiReady = true;
805 //                            }
806 //                        } else {
807 //                            this.combo.layer.destroyFeatures();
808 //                        }
809                         removePopup();
810 
811                         function removePopup() {
812                             if (this.popupAddr) {
813                                 this.popupAddr.close();
814                                 this.popupAddr.destroy();
815                                 if (this.winEditPOI) {
816                                     this.winEditPOI.close();
817                                     this.winEditPOI.destroy();
818                                 }
819                             }
820 
821                         }
822                         ;
823 
824                         function createPopup(combo, feature) {
825 
826                             removePopup();
827 
828                             this.popupAddr = new framework.plugins.PopUp({
829                                 location: feature,
830                                 obj: feature,
831                                 width: 200,
832                                 border: false,
833                                 userAuth: combo.userAuthDS,
834                                 isPoisExternal: feature.isPoisExternal,
835                                 html: '<div class="popupAddr">' + feature.text + '</div>',
836                                 maximizable: false,
837                                 collapsible: false,
838                                 listeners: {
839                                     modPOI: function(e) {
840                                         this.modFeaturePOI(e);
841                                     },
842                                     insPOI: function(e) {
843                                         this.insFeaturePOI(e);
844                                     },
845                                     scope: combo
846                                 }
847                             });
848                             this.popupAddr.show();
849                             
850                             var coord = new OpenLayers.LonLat(feature.geometry.x, feature.geometry.y);
851                             combo.updateISTAT(coord);
852                                     
853                         };                       
854                         
855                                                             
856 
857                       
858                         //insert marker	
859                         for (var i = 0; i < store.data.items.length; i++) {
860                             var idCat = store.combo.categoriesDS.find("category", store.data.items[i].data.categories);
861                             if (idCat === -1) {
862                                 idCat = store.combo.categoriesDS.find("categoryIt", store.data.items[i].data.categories);
863                             }
864 
865                             if (idCat > -1 || !store.isPoisExternal) {
866                                 var position;
867                                 if (store.isPoisExternal) {
868                                     position = new OpenLayers.LonLat(store.data.items[i].data.lon, store.data.items[i].data.lat);
869                                     // Reproject (if required)
870                                     position.transform(
871                                             new OpenLayers.Projection("EPSG:4326"),
872                                             this.combo.map.getProjectionObject()
873                                             );
874                                     store.data.items[i].data.location = [store.data.items[i].data.lon, store.data.items[i].data.lat];
875                                 } else {
876                                     position = new OpenLayers.LonLat(store.data.items[i].data.location[0], store.data.items[i].data.location[1]);
877                                     // Reproject (if required)
878                                     position.transform(
879                                             new OpenLayers.Projection("EPSG:3003"),
880                                             this.combo.map.getProjectionObject()
881                                             );
882                                 }
883                                 if (!store.isPoisExternal || (this.combo.isPointContainedInSearchExtent(position.lon, position.lat))) {
884 
885                                     var icon = "nopublic.png";
886                                     var basePath = "";
887                                     if (store.isPoisExternal) {
888                                         basePath = "poi/icon_external_poi_";
889                                         icon = store.data.items[i].data.terms + ".png";
890                                     } else {
891                                         basePath = "poi/icon_poi_";
892                                         if (store.data.items[i].data.enabled) {
893                                             icon = store.data.items[i].data.terms + ".png";
894                                         }
895                                     }
896                                     icon = basePath + icon;
897 
898                                     //                                var external = '';
899                                     //                                var icon = "poi/icon_poi_nopublic.png";
900                                     //                                if (store.isPoisExternal)
901                                     //                                    icon = "poi/icon_external_poi.png";
902                                     //                                else if (store.data.items[i].data.enabled)
903                                     //                                    icon = "poi/icon_poi_" + store.data.items[i].data.terms + external + ".png";
904 
905                                     var feature = new OpenLayers.Feature.Vector(
906                                             new OpenLayers.Geometry.Point(position.lon, position.lat),
907                                             null,
908                                             {
909                                                 externalGraphic: this.combo.markersImgPath + icon,
910                                                 graphicWidth: 25,
911                                                 graphicHeight: 25,
912                                                 fillOpacity: 1,
913                                                 cursor: "pointer"
914                                             });
915                                    // console.log(store.data.items[i]);
916                                     feature.poiUUID = store.data.items[i].id;
917                                     feature.text = this.combo.msgPopup(store.data.items[i].data, store.isPoisExternal);
918                                     feature.name = store.data.items[i].data.labels;
919                                     feature.category = store.data.items[i].data.categories;
920                                     feature.terms = store.data.items[i].data.terms;
921                                     feature.isPoisExternal = store.isPoisExternal;
922                                     
923                                     this.combo.layer.addFeatures(feature);
924                                     
925                                     if (!store.isPoisExternal)
926                                         this.combo.extentToZoom.extend(new OpenLayers.LonLat(position.lon, position.lat));
927                                     //store.data.items[i].data.img = this.combo.markersImgPath + "carattere_red_" + i + ".gif";
928                                 }
929                             }
930                         }
931 
932                         this.combo.selectCtrl = new OpenLayers.Control.SelectFeature([this.combo.layer], {
933                             toggle: true,
934                             clickout: true
935                         });
936 
937                         this.combo.map.addControl(this.combo.selectCtrl);
938                         this.combo.selectCtrl.activate();
939 
940                         this.combo.map.searchName = this.combo.id;
941 
942                         //set map extent solo per ricerche in locale
943 //                        if (store.data.items.length && !store.isPoisExternal && !this.combo.searchExternalPoi)
944 //                            this.combo.map.zoomToExtent(bounds);
945                         if (!store.isPoisExternal && this.combo.isValidExtent(this.combo.extentToZoom)) {
946                             this.combo.map.zoomToExtent(this.combo.extentToZoom);
947                         }
948 
949                         // create popup on "featureselected"
950                         if (!this.combo.isActiveFeatureselected) {
951                             this.combo.layer.events.on({
952                                 featureselected: function(e) {
953                                     createPopup(this.combo, e.feature);
954                                 },
955                                 scope: this
956                             });
957                             this.combo.isActiveFeatureselected = true;
958                         }
959 
960 //                        this.combo.clearBaseParams(store);
961 
962                         if (store.isPoisExternal && this.combo.localPoiReady) {
963                             //ricarico i poi interni che devono stare sopra gli esterni
964                             this.combo.localPoiReady = false;
965                             this.combo.store.fireEvent('datachanged', this.combo.store);
966                         }
967 
968 //                        if (!store.isPoisExternal && this.combo.externalPoiReady) {
969 ////                        if (this.searchExternalPoi && !store.isPoisExternal && this.combo.externalPoiReady) {
970 //                            //ricarico i poi interni che devono stare sopra gli esterni
971 //                            this.combo.externalPoiReady = false;
972 //                            this.combo.storeExternalPois.fireEvent('datachanged', this.combo.storeExternalPois);
973 //                        }
974 
975 
976                           var searchadvpoi = Ext.getCmp("searchadvpoiID");
977                             
978                           if (searchadvpoi && !store.isPoisExternal) {
979                                 var activesearchadvpoiID = Ext.getCmp("activesearchadvpoiID");
980                                 if (activesearchadvpoiID) {
981                                     if (searchadvpoi.checkBaseParams()) {
982                                        activesearchadvpoiID.body.update('<p id="active">ricerca avanzata (filtri attivi)</p>');
983                                     }
984                                     else {
985                                        activesearchadvpoiID.body.update("<p>ricerca avanzata</p>");
986                                     }
987                                     searchadvpoi.hide();
988                                 }
989                                 
990                           }
991                     },
992                     updateuserAuth: function(userAuthDS) {
993 
994                         this.userAuthDS = userAuthDS;
995 
996                         if (userAuthDS) {
997                             this.store.baseParams.codfisc = this.userAuthDS.codfiscale;
998                             this.authenticatedUser = this.userAuthDS.codfiscale;
999 
1000                             if (!this.layerEdit) {
1001                                 var renderer = OpenLayers.Util.getParameters(window.location.href).renderer;
1002                                 renderer = (renderer) ? [renderer] : OpenLayers.Layer.Vector.prototype.renderers;
1003 
1004                                 this.layerEdit = new OpenLayers.Layer.Vector('editPOI', {
1005                                     displayInLayerSwitcher: false,
1006                                     visibility: true,
1007                                     rendererOptions: {yOrdering: true},
1008                                     renderers: renderer,
1009                                     styleMap: new OpenLayers.StyleMap({
1010                                         'default': new OpenLayers.Style({
1011                                             graphicZIndex: 100,
1012                                             externalGraphic: "theme/app/img/poi/icon_poi_sel.png",
1013                                             graphicWidth: 25,
1014                                             graphicHeight: 34,
1015                                             graphicYOffset: -34,
1016                                             graphicOpacity: 1,
1017                                             cursor: "pointer"
1018                                         })
1019                                     })
1020                                 });
1021 
1022                                 function moveFeaturePOI(feature) {
1023                                     if (this.combo.winEditPOI) {
1024                                         this.combo.winEditPOI.updateCoord(feature.geometry.bounds.getCenterLonLat());
1025                                         this.combo.winEditPOI.updateISTAT(feature.geometry.bounds.getCenterLonLat());
1026                                     }
1027                                     else if (this.combo.winNewPOI) {
1028                                         this.combo.winNewPOI.updateCoord(feature.geometry.bounds.getCenterLonLat());
1029                                         this.combo.winNewPOI.updateISTAT(feature.geometry.bounds.getCenterLonLat());
1030                                     }
1031                                 }
1032                                 // Add a drag feature control to move features around.
1033                                 this.dragFeature = new OpenLayers.Control.DragFeature(this.layerEdit, {
1034                                     autoActivate: true,
1035                                     onComplete: moveFeaturePOI,
1036                                     combo: this
1037                                 });
1038 
1039                                 this.map.addLayer(this.layerEdit);
1040 
1041                                 this.map.addControl(this.dragFeature);
1042                             }
1043                             this.dragFeature.activate();
1044                         }
1045                         else if (this.dragFeature) {
1046                             this.dragFeature.deactivate();
1047                             this.store.baseParams.codfisc = '';
1048                         }
1049                         else
1050                             this.store.baseParams.codfisc = '';
1051 
1052 
1053                     },
1054                     modFeaturePOI: function(evt) {
1055 
1056                         var position = evt.location;
1057                         // Reproject (if required)
1058                         position.transform(
1059                                 new OpenLayers.Projection("EPSG:3003"),
1060                                 this.map.getProjectionObject()
1061                                 );
1062 
1063                         this.featureEdit = new OpenLayers.Feature.Vector(
1064                                 new OpenLayers.Geometry.Point(position.lon, position.lat),
1065                                 null, {
1066                                     externalGraphic: "theme/app/img/poi/icon_poi_sel.png",
1067                                     graphicWidth: 25,
1068                                     graphicHeight: 34,
1069                                     graphicYOffset: -34,
1070                                     graphicOpacity: 1,
1071                                     graphicZIndex: 1000,
1072                                     cursor: "hand"
1073                                 });
1074                         this.layerEdit.addFeatures(this.featureEdit);
1075                         this.layerEdit.drawFeature(this.featureEdit);
1076 
1077                         this.selectCtrlEdit = new OpenLayers.Control.SelectFeature([this.layerEdit], {
1078                             toggle: true,
1079                             clickout: true
1080                         });
1081 
1082                         this.map.addControl(this.selectCtrlEdit);
1083                         this.selectCtrlEdit.activate();
1084 
1085                         evt.obj.style.display = 'none'; // hide
1086                         evt.obj.layer.redraw();
1087 
1088                         if (Ext.getCmp('IDPoiDataPanel') && !this.winEditPOI)
1089                             this.winEditPOI = Ext.getCmp('IDPoiDataPanel');
1090 
1091                         if (!this.winEditPOI) {
1092                             this.winEditPOI = new framework.widgets.PoiDataPanel({
1093                                 userAuthDS: this.userAuthDS,
1094                                 typeName: this.typeName, 
1095                                 nameGeometry: this.nameGeometry,
1096                                 properties_nome: this.properties_nome,
1097                                 properties_istat: this.properties_istat,
1098                                 listeners: {
1099                                     modPositionPOI: function(e) {
1100                                         var lonlat = e.object.getLonLatFromPixel(e.xy);
1101 
1102                                         if (Ext.getCmp(this.idnewPoiManage)) {
1103                                             if (Ext.getCmp(this.idnewPoiManage).featureEdit) {
1104                                                 Ext.getCmp(this.idnewPoiManage).featureEdit.move(lonlat);
1105                                                 Ext.getCmp(this.idnewPoiManage).layerEdit.redraw();
1106                                             }
1107                                         }
1108                                         if (Ext.getCmp(this.idPoiVerifyManagement)) {
1109                                             if (Ext.getCmp(this.idPoiVerifyManagement).featureEdit) {
1110                                                 Ext.getCmp(this.idPoiVerifyManagement).featureEdit.move(lonlat);
1111                                                 Ext.getCmp(this.idPoiVerifyManagement).layerEdit.redraw();
1112                                             }
1113                                         }
1114                                         this.featureEdit.move(lonlat);
1115                                         this.layerEdit.redraw();
1116 
1117                                     },
1118                                     hide: function(win) {
1119                                         if (Ext.getCmp(this.idnewPoiManage)) {
1120                                             if (Ext.getCmp(this.idnewPoiManage).featureEdit) {
1121                                                 Ext.getCmp(this.idnewPoiManage).closeWinEdit();
1122                                             }
1123                                         }
1124                                         if (Ext.getCmp(this.idPoiVerifyManagement)) {
1125                                             if (Ext.getCmp(this.idPoiVerifyManagement).featureEdit) {
1126                                                 Ext.getCmp(this.idPoiVerifyManagement).closeWinEdit();
1127                                             }
1128                                             Ext.getCmp(this.idPoiVerifyManagement).poiDS.load();
1129                                         }
1130                                         this.closeWinEdit();
1131 
1132                                     },
1133                                     close: function(win) {
1134                                         if (Ext.getCmp(this.idPoiManage)) {
1135                                             if (Ext.getCmp(this.idPoiManage).featureEdit) {
1136                                                 Ext.getCmp(this.idPoiManage).closeWinEdit();
1137                                             }
1138                                         }
1139                                         if (Ext.getCmp(this.idPoiVerifyManagement)) {
1140                                             if (Ext.getCmp(this.idPoiVerifyManagement).featureEdit) {
1141                                                 Ext.getCmp(this.idPoiVerifyManagement).closeWinEdit();
1142                                             }
1143                                             Ext.getCmp(this.idPoiVerifyManagement).poiDS.load();
1144                                         }
1145                                         this.closeWinEdit();
1146 
1147                                     },
1148                                     scope: this
1149                                 }
1150                             });
1151                         }
1152                         this.winEditPOI.updateUserAuth(this.userAuthDS);
1153                         this.winEditPOI.openEditPoiForm(evt.obj);
1154                         this.winEditPOI.show();
1155                         this.dragFeature.activate();
1156                         if (Ext.getCmp('idBtnInsPOI'))
1157                             Ext.getCmp('idBtnInsPOI').disable();
1158                         if (Ext.getCmp('idGridPanelVerifyPoi'))
1159                             Ext.getCmp('idGridPanelVerifyPoi').disable();
1160 
1161                         evt.hide();
1162 
1163                         this.map.moveTo(evt.location, 12);
1164 
1165 
1166                     },
1167                     closeWinEdit: function() {
1168                         this.layerEdit.removeAllFeatures();
1169                         this.selectCtrlEdit.deactivate();
1170                         this.selectCtrl.activate();
1171                         this.dragFeature.deactivate();
1172                         if (Ext.getCmp('idBtnInsPOI'))
1173                             Ext.getCmp('idBtnInsPOI').enable();
1174                         if (Ext.getCmp('idGridPanelVerifyPoi'))
1175                             Ext.getCmp('idGridPanelVerifyPoi').enable();
1176                         //hack per visualizzare il marker
1177                         this.map.zoomOut();
1178                         this.map.zoomIn();
1179                     },
1180                     insFeaturePOI: function(evt) {
1181 
1182                         var position = evt.location;
1183                         // Reproject (if required)
1184                         position.transform(
1185                                 new OpenLayers.Projection("EPSG:3003"),
1186                                 this.map.getProjectionObject()
1187                                 );
1188 
1189                         this.featureEdit = new OpenLayers.Feature.Vector(
1190                                 new OpenLayers.Geometry.Point(position.lon, position.lat),
1191                                 null, {
1192                                     externalGraphic: "theme/app/img/poi/icon_poi_sel.png",
1193                                     graphicWidth: 25,
1194                                     graphicHeight: 34,
1195                                     graphicYOffset: -34,
1196                                     graphicOpacity: 1,
1197                                     graphicZIndex: 1000,
1198                                     cursor: "hand"
1199                                 });
1200                         this.layerEdit.addFeatures(this.featureEdit);
1201                         this.layerEdit.drawFeature(this.featureEdit);
1202 
1203                         this.selectCtrlEdit = new OpenLayers.Control.SelectFeature([this.layerEdit], {
1204                             toggle: true,
1205                             clickout: true
1206                         });
1207 
1208                         this.map.addControl(this.selectCtrlEdit);
1209                         this.selectCtrlEdit.activate();
1210 
1211                         evt.obj.style.display = 'none'; // hide
1212                         evt.obj.layer.redraw();
1213 
1214                         if (Ext.getCmp('IDPoiDataPanel') && !this.winNewPOI)
1215                             this.winNewPOI = Ext.getCmp('IDPoiDataPanel');
1216                         if (!this.winNewPOI) {
1217                             this.winNewPOI = new framework.widgets.PoiDataPanel({
1218 //                                termsDefaultValue: evt.obj.terms,
1219 //                                categoryDefaultValue: evt.obj.category,
1220                                 userAuthDS: this.userAuthDS,
1221                                 typeName: this.typeName, 
1222                                 nameGeometry: this.nameGeometry,
1223                                 properties_nome: this.properties_nome,
1224                                 properties_istat: this.properties_istat,
1225                                 listeners: {
1226                                     modPositionPOI: function(e) {
1227                                         var lonlat = e.object.getLonLatFromPixel(e.xy);
1228 
1229                                         if (Ext.getCmp(this.idnewPoiManage)) {
1230                                             if (Ext.getCmp(this.idnewPoiManage).featureEdit) {
1231                                                 Ext.getCmp(this.idnewPoiManage).featureEdit.move(lonlat);
1232                                                 Ext.getCmp(this.idnewPoiManage).layerEdit.redraw();
1233                                             }
1234                                         }
1235                                         if (Ext.getCmp(this.idPoiVerifyManagement)) {
1236                                             if (Ext.getCmp(this.idPoiVerifyManagement).featureEdit) {
1237                                                 Ext.getCmp(this.idPoiVerifyManagement).featureEdit.move(lonlat);
1238                                                 Ext.getCmp(this.idPoiVerifyManagement).layerEdit.redraw();
1239                                             }
1240                                         }
1241                                         this.featureEdit.move(lonlat);
1242                                         this.layerEdit.redraw();
1243 
1244                                     },
1245                                     hide: function(win) {
1246                                         if (Ext.getCmp(this.idComboPoi)) {
1247                                             if (Ext.getCmp(this.idComboPoi).featureEdit) {
1248                                                 Ext.getCmp(this.idComboPoi).closeWinEdit();
1249                                             }
1250                                         }
1251                                         if (Ext.getCmp(this.idPoiVerifyManagement)) {
1252                                             if (Ext.getCmp(this.idPoiVerifyManagement).featureEdit) {
1253                                                 Ext.getCmp(this.idPoiVerifyManagement).closeWinEdit();
1254                                             }
1255                                             Ext.getCmp(this.idPoiVerifyManagement).poiDS.load();
1256                                         }
1257                                         this.closeWinEdit();
1258                                     },
1259                                     close: function(win) {
1260                                         if (Ext.getCmp(this.idComboPoi)) {
1261                                             if (Ext.getCmp(this.idComboPoi).featureEdit) {
1262                                                 Ext.getCmp(this.idComboPoi).closeWinEdit();
1263                                             }
1264                                         }
1265                                         if (Ext.getCmp(this.idPoiVerifyManagement)) {
1266                                             if (Ext.getCmp(this.idPoiVerifyManagement).featureEdit) {
1267                                                 Ext.getCmp(this.idPoiVerifyManagement).closeWinEdit();
1268                                             }
1269                                             Ext.getCmp(this.idPoiVerifyManagement).poiDS.load();
1270                                         }
1271                                         this.closeWinEdit();
1272                                     },
1273                                     scope: this
1274                                 }
1275                             });
1276                         }
1277                         this.winNewPOI.termsDefaultValue = evt.obj.terms;
1278                         this.winNewPOI.categoryDefaultValue = evt.obj.category;
1279 
1280                         this.winNewPOI.updateUserAuth(this.userAuthDS);
1281 
1282                         this.winNewPOI.openEditNewPoiForm(evt.obj, position);
1283                         this.winNewPOI.click.deactivate();//non deve cambiare il punto con i click sulla mappa
1284                         var name = '';
1285                         var address = '';
1286                         var index = evt.obj.name.indexOf(',');
1287                         if (index > -1) {
1288                             name = evt.obj.name.substr(0, index);
1289                             if (evt.obj.name.substr(index + 1, index + 2) === ' ')
1290                                 index++;
1291                             address = evt.obj.name.substr(index + 1);
1292                         }
1293                         var values = {label: name, address: address};
1294                         var idCat = this.winNewPOI.categoryByTermDs.find("category", evt.obj.category);
1295                         if (idCat > -1) {
1296                             values.category = this.winNewPOI.categoryByTermDs.getAt(idCat).data.category;
1297                             values.terms = this.winNewPOI.categoryByTermDs.getAt(idCat).data.terms;
1298                         }
1299 
1300 
1301                         this.winNewPOI._categoryform.getForm().setValues(values);
1302                         this.winNewPOI.show();
1303 
1304 
1305                         this.dragFeature.activate();
1306                         if (Ext.getCmp('idBtnInsPOI'))
1307                             Ext.getCmp('idBtnInsPOI').disable();
1308                         if (Ext.getCmp('idGridPanelVerifyPoi'))
1309                             Ext.getCmp('idGridPanelVerifyPoi').disable();
1310 
1311                         evt.hide();
1312                         this.map.moveTo(evt.location, 12);
1313                     },
1314                     /** Create comboBox object, the main object of the class.
1315                      * @private
1316                      * @param {String} data is a record store
1317                      * @returns {String} html text to load on marker'popUp
1318                      */
1319                     msgPopup: function(data, isExternal) {
1320                         
1321                         var idCat = this.categoriesDS.find("category", data.categories);
1322                         var cat = null;
1323                         if (idCat == -1) {
1324                             if (isExternal) {
1325                                 cat = data.categories;
1326                             }
1327                             else {
1328                                 idCat = this.categoriesDS.find("categoryIt", data.categories);
1329                                 if(idCat > -1)
1330                                     idCat = 0;
1331                                 cat = this.categoriesDS.getAt(idCat).data.categoryIt;
1332                             }
1333                         }
1334                         else
1335                             cat = this.categoriesDS.getAt(idCat).data.categoryIt;
1336 
1337                         var text = '<b>' + data.labels + '</b><br />'
1338                         
1339                         text = text + '<span id="IdComune"></span>';
1340                         text = text + '<br/><br />';
1341                         
1342                         if (data.descriptions.length > 0) {
1343                             text = text +  '<i>'+data.descriptions[0].value + '</i><br /><br />'      
1344                         }
1345                         
1346                         text = text + 'tipo: ' + cat + '<br />';
1347                         var link = data.href;
1348                         if (isExternal) {
1349                             var attributionService = '<br /><b>Fonte: <a target="_blank" href="' + this.attributionExternalPoisServiceUrl + '">' + this.attributionExternalPoisServiceName + '</a></b>';
1350                             text = text + '<span class="att_service">';
1351                             text = text + attributionService;
1352                             text = text + this.findAttribution(data.links);
1353                             text = text + "</span>";
1354                         }
1355                         else {
1356                             if (data.links.length > 0) {
1357                                 text = text + this.checkUrl(data.links[0].href);
1358                             }
1359                         }
1360                         return text;
1361                     },
1362                     /**
1363                      * A utility function to find all URLs - FTP, HTTP(S) and Email - in a text string
1364                      * and return them in an array.  Note, the URLs returned are exactly as found in the text.
1365                      * 
1366                      * @param text
1367                      *            the text to be searched.
1368                      * @return an array of URLs.
1369                      */
1370                     findAttribution: function(text) {
1371                         var attribution = "";
1372                         if (text) {
1373                             var indexIni = text.toLowerCase().indexOf("http");
1374                             if (indexIni >= 0) {
1375                                 var desc = "";
1376                                 var link = "";
1377                                 desc = '<br>' + text.substring(0, indexIni);
1378                                 var indexFin = text.toLowerCase().indexOf(" ", indexIni);
1379                                 if (indexFin < 0) {
1380                                     indexFin = text.length;
1381                                 }
1382                                 link = text.substring(indexIni, indexFin);
1383                                 attribution = desc + '<br><a target="_blank" href="' + link + '">vai al sito</a>';
1384                             } else {
1385                                 attribution = '<br>' + text;
1386                             }
1387                         }
1388                         return attribution;
1389                     },
1390                     /**
1391                      * 
1392                      * @returns {url}
1393                      */
1394                     checkUrl: function(url) {
1395                         var urlHTML;
1396                         if (url) {
1397                             var indexIni = url.toLowerCase().indexOf("http");
1398                             if (indexIni >= 0) {
1399                                 urlHTML = '<br><a target="_blank" href="' + url + '">vai al sito</a>';
1400                             } else {
1401                                 urlHTML = '<br><a target="_blank" href="http://' + url + '">vai al sito</a>';
1402                             }
1403                         }
1404                         return urlHTML;
1405                     },
1406                     /** 
1407                      *  When this component is added to a container, see if it has a parent
1408                      *  MapPanel somewhere and set the map
1409                      *  @private
1410                      */
1411                     handleAdded: function() {
1412                         var mapPanel = this.findParentBy(function(cmp) {
1413                             return cmp instanceof GeoExt.MapPanel;
1414                         });
1415                         if (mapPanel) {
1416                             this.setMap(mapPanel);
1417                         }
1418 
1419                     },
1420                     /**
1421                      *  Hides the dropdown list if it is currently expanded. Fires the {@link #collapse} event on completion.
1422                      *  @private
1423                      */
1424                     collapse: function() {
1425                         if (!this.isExpanded()) {
1426                             return;
1427                         }
1428                         this.list.hide();
1429                         this.el.blur();
1430                         Ext.getDoc().un('mousewheel', this.collapseIf, this);
1431                         Ext.getDoc().un('mousedown', this.collapseIf, this);
1432                         this.fireEvent('collapse', this);
1433                     },
1434                     /** 
1435                      * Zoom to the selected location, and also set a location marker if this
1436                      * component was configured with an :obj:`layer`.
1437                      * @private
1438                      * @param {Object} combo comnoBox object.
1439                      * @param {Object} record selected record.
1440                      * @param {Object} index index of selected record.
1441                      */
1442                     handleSelect: function(combo, record, index) {
1443                         //  var position = new OpenLayers.LonLat(record.data.lon, record.data.lat);
1444                         // var position = new OpenLayers.LonLat(record.data.location.points[0].coordinates[0],record.data.location.points[0].coordinates[1]);
1445                         var position = new OpenLayers.LonLat(record.data.location[0], record.data.location[1]);
1446 
1447 
1448                         // Reproject (if required)
1449                         position.transform(
1450                                 new OpenLayers.Projection("EPSG:3003"),
1451                                 this.map.getProjectionObject()
1452                                 );
1453 
1454                         // zoom in on the location
1455                         zoomResult = this.zoom;
1456 
1457                         this.map.setCenter(position, zoomResult);
1458 
1459                         //strip HTML tags from string 
1460                         var div = document.createElement("div");
1461                         div.innerHTML = record.data.labels;
1462                         var text = div.textContent || div.innerText || "";
1463  //                       this.textSearch = text;
1464                      //   this.setValue(text); // put the selected name in the box
1465 
1466                         // blur the combo box
1467                         //TODO Investigate if there is a more elegant way to do this.
1468                         (function() {
1469                             this.triggerBlur();
1470                             this.el.blur();
1471                         }).defer(100, this);
1472                     },
1473                     /** 
1474                      *  Handler for the map's moveend event. Clears the selected location
1475                      *  when the map center has changed.
1476                      *  @private
1477                      */
1478                     clearResult: function() {
1479                         this.clearValue();
1480                     },
1481                     /** 
1482                      *  Set the :obj:`map` for this instance.
1483                      *  @private
1484                      *  @param {GeoExt.MapPanel||OpenLayers.Map} map object
1485                      */
1486                     setMap: function(map) {
1487                         if (map instanceof GeoExt.MapPanel) {
1488                             map = map.map;
1489                         }
1490                         this.map = map;
1491                         map.events.on({
1492                             // "moveend": this.clearResult,
1493                             //  "click": this.removeFocus,
1494                             scope: this
1495                         });
1496                     },
1497                     /** 
1498                      *  Called by a MapPanel if this component is one of the items in the panel.
1499                      *  @private
1500                      */
1501                     addToMapPanel: Ext.emptyFn,
1502                     /**
1503                      * Execute a query to filter the dropdown list.  Fires the {@link #beforequery} event prior to performing the
1504                      * query allowing the query action to be canceled if needed.
1505                      * @param {String} q query The SQL query to execute
1506                      * @param {Boolean} forceAll <tt>true</tt> to force the query to execute even if there are currently fewer
1507                      * characters in the field than the minimum specified by the <tt>{@link #minChars}</tt> config option.  It
1508                      * also clears any filter previously saved in the current store (defaults to <tt>false</tt>)
1509                      */
1510                     doQuery: function(q, forceAll) {
1511                         var qb = q.replace(' ', '+');
1512                         q = Ext.isEmpty(q) ? '' : '%' + q + '%';
1513                         var qe = {
1514                             query: q,
1515                             forceAll: forceAll,
1516                             combo: this,
1517                             cancel: false
1518                         };
1519 
1520                         if (this.fireEvent('beforequery', qe) === false || qe.cancel) {
1521                             return false;
1522                         }
1523                         q = qe.query;
1524                         forceAll = qe.forceAll;
1525                         if (forceAll === true || (q.length >= this.minChars)) {
1526                             if (this.lastQuery !== q || true) {
1527                                 
1528                                 this.lastQuery = q;
1529                                 if (this.destroyPreviousFeatures) {
1530                                     this.store.combo.layer.destroyFeatures();
1531                                 } else {
1532                                     this.destroyPreviousFeatures = true;
1533                                 }
1534                                 if (this.mode == 'local') {
1535                                     this.selectedIndex = -1;
1536                                     if (forceAll) {
1537                                         this.store.clearFilter();
1538                                     } else {
1539                                         this.store.filter(this.displayField, q);
1540                                     }
1541                                     this.onLoad();
1542                                 } else {
1543                                     this.extentToZoom = new OpenLayers.Bounds();
1544                                     this.localPoiReady = false;
1545 
1546                                     this.store.baseParams[this.queryParam] = q;
1547                                     this.storeExternalPois.baseParams['q'] = qb;
1548                                     if (this.applySearchByExtent) {
1549                                         this.mapSearchExtent = this.getBoundedExtent(this.map.getExtent(), this.maxSearchExternalExtent);
1550 
1551                                         var mapSearchExtent = this.mapSearchExtent;
1552                                         var mapExtent = mapSearchExtent.transform(
1553                                                 this.map.getProjectionObject(),
1554                                                 new OpenLayers.Projection("EPSG:4326")
1555                                                 );
1556                                         this.storeExternalPois.baseParams['viewbox'] = mapExtent.left + ',' + mapExtent.top + ',' + mapExtent.right + ',' + mapExtent.bottom;
1557                                         this.storeExternalPois.baseParams['countrycodes'] = '';
1558                                         this.store.baseParams.bbox = mapExtent.left + "," + mapExtent.bottom + "," + mapExtent.right + "," + mapExtent.top;
1559                                     } else {
1560                                         this.mapSearchExtent = this.map.getExtent();
1561                                         this.mapSearchExtent.left = this.maxSearchExternalExtent.left;
1562                                         this.mapSearchExtent.bottom = this.maxSearchExternalExtent.bottom;
1563                                         this.mapSearchExtent.right = this.maxSearchExternalExtent.right;
1564                                         this.mapSearchExtent.top = this.maxSearchExternalExtent.top;
1565                                         var mapSearchExtent = this.mapSearchExtent;
1566                                         var mapExtent = mapSearchExtent.transform(
1567                                                 this.map.getProjectionObject(),
1568                                                 new OpenLayers.Projection("EPSG:4326")
1569                                                 );
1570                                         this.storeExternalPois.baseParams['viewbox'] = mapExtent.left + ',' + mapExtent.top + ',' + mapExtent.right + ',' + mapExtent.bottom;
1571                                         this.storeExternalPois.baseParams['countrycodes'] = 'IT';
1572                                         this.store.baseParams.bbox = '';
1573                                     }
1574                                     this.storeExternalPois.baseParams['bounded'] = 1;
1575                                     //salva ricerca
1576                                     this.lastInternalSearchParams.term = this.store.baseParams.term;
1577                                     this.lastInternalSearchParams.category = this.store.baseParams.category;
1578                                     this.lastInternalSearchParams.extent = mapExtent.toGeometry();
1579                                     this.lastInternalSearchParams.istat = this.store.baseParams.istat;
1580                                     this.lastInternalSearchParams.address = this.store.baseParams.address;
1581                                     this.lastInternalSearchParams.lon = this.store.baseParams.lon;
1582                                     this.lastInternalSearchParams.lat = this.store.baseParams.lat;
1583                                     this.lastInternalSearchParams.radius = this.store.baseParams.radius;
1584                                     this.lastInternalSearchParams.path = this.store.baseParams.path;
1585                                     this.lastInternalSearchParams.name = q;
1586 
1587                                     if (this.isValidExtent(this.mapSearchExtent)) {
1588                                         
1589 //                                        this.syncronizePoiOnMap = true;
1590 
1591 
1592                                         this.store.baseParams['cache'] = false;
1593                                             this.store.load({
1594                                                 params: this.getParams(q)
1595                                             });
1596 
1597                                         //  if (!this.isAdvancedSearch()) {
1598                                         if (this.searchExternalPoi) {
1599                                             this.storeExternalPois.load({
1600                                                 params: this.getParams(qb)
1601                                                         //  params: {format: 'json', q: qb, addressdetails: 1, limit: 100}
1602                                             });                                            
1603                                         }
1604                                         
1605                                         //  this.store.baseParams['bbox'] = mapExtent;//.left + ',' + mapExtent.bottom + ',' + mapExtent.right + ',' + mapExtent.top;
1606                                         //                                    }else{
1607                                         //                                        this.syncronizePoiOnMap = false;
1608                                         //                                    }       
1609                                         
1610                                         
1611                                        this.store.baseParams.radius = '';
1612                                        this.store.baseParams.path = '';
1613                                        this.store.baseParams.lon = '';
1614                                        this.store.baseParams.lat = '';
1615 
1616 
1617                                         this.expand();
1618                                     }
1619                                 }
1620                             }
1621 //                            else {
1622 //                                this.selectedIndex = -1;
1623 //                                this.onLoad();
1624 //                            }
1625                         }
1626                     },
1627                     clearBaseParams: function(store) {
1628                         if (store.isPoisExternal) {
1629                             this.storeExternalPois.baseParams.q = '';
1630                             this.storeExternalPois.baseParams.viewbox = '';
1631                             this.storeExternalPois.baseParams.bounded = '';
1632                             this.storeExternalPois.baseParams.countrycodes = '';
1633                         } else {
1634                             this.store.baseParams.term = '';
1635                             this.store.baseParams.category = '';
1636                             this.store.baseParams.bbox = '';
1637                             this.store.baseParams.istat = '';
1638                             this.store.baseParams.address = '';
1639                             this.store.baseParams.lon = '';
1640                             this.store.baseParams.lat = '';
1641                             this.store.baseParams.radius = '';
1642 
1643                             this.store.baseParams.path = '';
1644                             this.store.baseParams.name = '';
1645                         }
1646                     },
1647                     isAdvancedSearch: function() {
1648                         var bp = this.store.baseParams;
1649                         var str = bp.term + bp.category + bp.bbox + bp.istat + bp.address + bp.lon + bp.lat + bp.radius;
1650                         return str.length > 0;
1651                     },
1652                     isValidExtent: function(extent) {
1653                         var result = false;
1654                         if (extent !== null) {
1655                             if ((extent.left !== null) && (extent.top !== null) && (extent.right !== null) && (extent.bottom !== null))
1656                                 result = true;
1657                         }
1658                         return result;
1659                     },
1660                     getBoundedExtent: function(extent, maxExtent) {
1661                         var result = null;
1662                         if (this.isValidExtent(extent)) {
1663                             if (this.isValidExtent(maxExtent)) {
1664                                 if (extent.left < maxExtent.left)
1665                                     extent.left = maxExtent.left;
1666                                 if (extent.bottom < maxExtent.bottom)
1667                                     extent.bottom = maxExtent.bottom;
1668                                 if (extent.right > maxExtent.right)
1669                                     extent.right = maxExtent.right;
1670                                 if (extent.top > maxExtent.top)
1671                                     extent.top = maxExtent.top;
1672                             }
1673                             result = extent;
1674                         }
1675                         return result;
1676                     },
1677                     isPointContainedInSearchExtent: function(lon, lat) {
1678                         var result = false;
1679                         if ((lon !== null) && (lat !== null) && (this.isValidExtent(this.maxSearchExternalExtent))) {
1680                             if ((lon >= this.maxSearchExternalExtent.left) && (lon <= this.maxSearchExternalExtent.right) && (lat >= this.maxSearchExternalExtent.bottom) && (lat <= this.maxSearchExternalExtent.top))
1681                                 result = true;
1682                         }
1683                         return result;
1684                     },
1685                     updateISTAT: function(coord) {
1686 
1687                         Ext.Ajax.request({
1688                             method: 'POST',
1689                             url: this.urlProxy + this.urlWFS,
1690                             params: this.getParameters(coord),
1691                             success: function(result, request) {
1692                                 try {
1693                                     var obj = Ext.decode(result.responseText);
1694                                     if (obj && obj.features) {
1695                                         if (obj.features.length == 0) {
1696                                            // alert('Nessun comune presente in questa zona');
1697                                         }
1698                                         else if (obj.features.length == 1) {
1699                                            var nome_comune = obj.features[0].properties[this.properties_nome];
1700                                             document.getElementById('IdComune').innerHTML = nome_comune;
1701                                         }
1702                                       //  else if (obj.features.length > 1) {
1703                                            // alert('Trovati più risultati!\n Affinare la ricerca per stabilire un extent.');
1704                                       //  }
1705                                    } else
1706                                         alert('Il servizio non risponde');
1707                                 } catch (ex) {
1708                                     Ext.MessageBox.alert('Error', 'Il servizio è andato in errore!');
1709                                 }
1710 
1711                             },
1712                             scope: this
1713                         });
1714                     },
1715                     /** 
1716                     * Create query string for wfs catasto service
1717                     * @private
1718                     */
1719                    getParameters: function(coord) {
1720                        var parameters = {service: this.serviceType, version: this.version, request: this.requestType,
1721                            typeName: this.typeName, maxFeatures: this.maxFeatures, outputFormat: 'application/json',
1722                            FILTER: '<Filter xmlns="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml">' +
1723                                    '<Intersects><PropertyName>'+this.nameGeometry+'</PropertyName>' +
1724                                    '<gml:Point srsName="' + this.srs + '">' +
1725                                    '<gml:coordinates>' + coord.lon + ',' + coord.lat + '</gml:coordinates>' +
1726                                    '</gml:Point></Intersects></Filter>'};
1727                        return parameters;
1728                    }
1729                 });
1730 
1731         /** api: xtype = gxux_geonamessearchcombo */
1732         Ext.reg('framework_openpoisearchcombo', framework.form.OpenPOISearchCombo);
1733