]> dev.renevier.net Git - syp.git/blob - openlayers/lib/OpenLayers/Layer/GeoRSS.js
web interface to add co-administrators
[syp.git] / openlayers / lib / OpenLayers / Layer / GeoRSS.js
1 /* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
2  * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
3  * full text of the license. */
4
5
6 /**
7  * @requires OpenLayers/Layer/Markers.js
8  * @requires OpenLayers/Request/XMLHttpRequest.js
9  */
10
11 /**
12  * Class: OpenLayers.Layer.GeoRSS
13  * Add GeoRSS Point features to your map. 
14  * 
15  * Inherits from:
16  *  - <OpenLayers.Layer.Markers>
17  *  - <OpenLayers.Layer>
18  */
19 OpenLayers.Layer.GeoRSS = OpenLayers.Class(OpenLayers.Layer.Markers, {
20
21     /** 
22      * Property: location 
23      * {String} store url of text file 
24      */
25     location: null,
26
27     /** 
28      * Property: features 
29      * {Array(<OpenLayers.Feature>)} 
30      */
31     features: null,
32     
33     /**
34      * APIProperty: formatOptions
35      * {Object} Hash of options which should be passed to the format when it is
36      * created. Must be passed in the constructor.
37      */
38     formatOptions: null, 
39
40     /** 
41      * Property: selectedFeature 
42      * {<OpenLayers.Feature>} 
43      */
44     selectedFeature: null,
45
46     /** 
47      * APIProperty: icon 
48      * {<OpenLayers.Icon>}. This determines the Icon to be used on the map
49      * for this GeoRSS layer.
50      */
51     icon: null,
52
53     /**
54      * APIProperty: popupSize
55      * {<OpenLayers.Size>} This determines the size of GeoRSS popups. If 
56      * not provided, defaults to 250px by 120px. 
57      */
58     popupSize: null, 
59     
60     /** 
61      * APIProperty: useFeedTitle 
62      * {Boolean} Set layer.name to the first <title> element in the feed. Default is true. 
63      */
64     useFeedTitle: true,
65     
66     /**
67     * Constructor: OpenLayers.Layer.GeoRSS
68     * Create a GeoRSS Layer.
69     *
70     * Parameters:
71     * name - {String} 
72     * location - {String} 
73     * options - {Object}
74     */
75     initialize: function(name, location, options) {
76         OpenLayers.Layer.Markers.prototype.initialize.apply(this, [name, options]);
77         this.location = location;
78         this.features = [];
79     },
80
81     /**
82      * Method: destroy 
83      */
84     destroy: function() {
85         // Warning: Layer.Markers.destroy() must be called prior to calling
86         // clearFeatures() here, otherwise we leak memory. Indeed, if
87         // Layer.Markers.destroy() is called after clearFeatures(), it won't be
88         // able to remove the marker image elements from the layer's div since
89         // the markers will have been destroyed by clearFeatures().
90         OpenLayers.Layer.Markers.prototype.destroy.apply(this, arguments);
91         this.clearFeatures();
92         this.features = null;
93     },
94
95     /**
96      * Method: loadRSS
97      * Start the load of the RSS data. Don't do this when we first add the layer,
98      * since we may not be visible at any point, and it would therefore be a waste.
99      */
100     loadRSS: function() {
101         if (!this.loaded) {
102             this.events.triggerEvent("loadstart");
103             OpenLayers.Request.GET({
104                 url: this.location,
105                 success: this.parseData,
106                 scope: this
107             });
108             this.loaded = true;
109         }    
110     },    
111     
112     /**
113      * Method: moveTo
114      * If layer is visible and RSS has not been loaded, load RSS. 
115      * 
116      * Parameters:
117      * bounds - {Object} 
118      * zoomChanged - {Object} 
119      * minor - {Object} 
120      */
121     moveTo:function(bounds, zoomChanged, minor) {
122         OpenLayers.Layer.Markers.prototype.moveTo.apply(this, arguments);
123         if(this.visibility && !this.loaded){
124             this.loadRSS();
125         }
126     },
127         
128     /**
129      * Method: parseData
130      * Parse the data returned from the Events call.
131      *
132      * Parameters:
133      * ajaxRequest - {<OpenLayers.Request.XMLHttpRequest>} 
134      */
135     parseData: function(ajaxRequest) {
136         var doc = ajaxRequest.responseXML;
137         if (!doc || !doc.documentElement) {
138             doc = OpenLayers.Format.XML.prototype.read(ajaxRequest.responseText);
139         }
140         
141         if (this.useFeedTitle) {
142             var name = null;
143             try {
144                 name = doc.getElementsByTagNameNS('*', 'title')[0].firstChild.nodeValue;
145             }
146             catch (e) {
147                 name = doc.getElementsByTagName('title')[0].firstChild.nodeValue;
148             }
149             if (name) {
150                 this.setName(name);
151             }    
152         }
153        
154         var options = {};
155         
156         OpenLayers.Util.extend(options, this.formatOptions);
157         
158         if (this.map && !this.projection.equals(this.map.getProjectionObject())) {
159             options.externalProjection = this.projection;
160             options.internalProjection = this.map.getProjectionObject();
161         }    
162         
163         var format = new OpenLayers.Format.GeoRSS(options);
164         var features = format.read(doc);
165         
166         for (var i=0, len=features.length; i<len; i++) {
167             var data = {};
168             var feature = features[i];
169             
170             // we don't support features with no geometry in the GeoRSS
171             // layer at this time. 
172             if (!feature.geometry) {
173                 continue;
174             }    
175             
176             var title = feature.attributes.title ? 
177                          feature.attributes.title : "Untitled";
178             
179             var description = feature.attributes.description ? 
180                          feature.attributes.description : "No description.";
181             
182             var link = feature.attributes.link ? feature.attributes.link : "";
183
184             var location = feature.geometry.getBounds().getCenterLonLat();
185             
186             
187             data.icon = this.icon == null ? 
188                                      OpenLayers.Marker.defaultIcon() : 
189                                      this.icon.clone();
190             
191             data.popupSize = this.popupSize ? 
192                              this.popupSize.clone() :
193                              new OpenLayers.Size(250, 120);
194             
195             if (title || description) {
196                 // we have supplemental data, store them.
197                 data.title = title;
198                 data.description = description;
199             
200                 var contentHTML = '<div class="olLayerGeoRSSClose">[x]</div>'; 
201                 contentHTML += '<div class="olLayerGeoRSSTitle">';
202                 if (link) {
203                     contentHTML += '<a class="link" href="'+link+'" target="_blank">';
204                 }
205                 contentHTML += title;
206                 if (link) {
207                     contentHTML += '</a>';
208                 }
209                 contentHTML += '</div>';
210                 contentHTML += '<div style="" class="olLayerGeoRSSDescription">';
211                 contentHTML += description;
212                 contentHTML += '</div>';
213                 data['popupContentHTML'] = contentHTML;                
214             }
215             var feature = new OpenLayers.Feature(this, location, data);
216             this.features.push(feature);
217             var marker = feature.createMarker();
218             marker.events.register('click', feature, this.markerClick);
219             this.addMarker(marker);
220         }
221         this.events.triggerEvent("loadend");
222     },
223     
224     /**
225      * Method: markerClick
226      *
227      * Parameters:
228      * evt - {Event} 
229      */
230     markerClick: function(evt) {
231         var sameMarkerClicked = (this == this.layer.selectedFeature);
232         this.layer.selectedFeature = (!sameMarkerClicked) ? this : null;
233         for(var i=0, len=this.layer.map.popups.length; i<len; i++) {
234             this.layer.map.removePopup(this.layer.map.popups[i]);
235         }
236         if (!sameMarkerClicked) {
237             var popup = this.createPopup();
238             OpenLayers.Event.observe(popup.div, "click",
239                 OpenLayers.Function.bind(function() { 
240                     for(var i=0, len=this.layer.map.popups.length; i<len; i++) { 
241                         this.layer.map.removePopup(this.layer.map.popups[i]); 
242                     }
243                 }, this)
244             );
245             this.layer.map.addPopup(popup); 
246         }
247         OpenLayers.Event.stop(evt);
248     },
249
250     /**
251      * Method: clearFeatures
252      * Destroy all features in this layer.
253      */
254     clearFeatures: function() {
255         if (this.features != null) {
256             while(this.features.length > 0) {
257                 var feature = this.features[0];
258                 OpenLayers.Util.removeItem(this.features, feature);
259                 feature.destroy();
260             }
261         }        
262     },
263     
264     CLASS_NAME: "OpenLayers.Layer.GeoRSS"
265 });