Project

General

Profile

Download (14.4 KB) Statistics
| Branch: | Tag: | Revision:
1
/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
2
 * full list of contributors). Published under the 2-clause BSD license.
3
 * See license.txt in the OpenLayers distribution or repository for the
4
 * full text of the license. */
5

    
6
/**
7
 * @requires OpenLayers/Format/XML.js
8
 * @requires OpenLayers/Feature/Vector.js
9
 * @requires OpenLayers/Geometry/Point.js
10
 * @requires OpenLayers/Geometry/LineString.js
11
 * @requires OpenLayers/Geometry/Polygon.js
12
 */
13

    
14
/**
15
 * Class: OpenLayers.Format.GeoRSS
16
 * Read/write GeoRSS parser. Create a new instance with the 
17
 *     <OpenLayers.Format.GeoRSS> constructor.
18
 *
19
 * Inherits from:
20
 *  - <OpenLayers.Format.XML>
21
 */
22
OpenLayers.Format.GeoRSS = OpenLayers.Class(OpenLayers.Format.XML, {
23
    
24
    /**
25
     * APIProperty: rssns
26
     * {String} RSS namespace to use. Defaults to
27
     *   "http://backend.userland.com/rss2"
28
     */
29
    rssns: "http://backend.userland.com/rss2",
30
    
31
    /**
32
     * APIProperty: featurens
33
     * {String} Feature Attributes namespace.  Defaults to
34
     *    "http://mapserver.gis.umn.edu/mapserver"
35
     */
36
    featureNS: "http://mapserver.gis.umn.edu/mapserver",
37
    
38
    /**
39
     * APIProperty: georssns
40
     * {String} GeoRSS namespace to use.  Defaults to
41
     *     "http://www.georss.org/georss"
42
     */
43
    georssns: "http://www.georss.org/georss",
44

    
45
    /**
46
     * APIProperty: geons
47
     * {String} W3C Geo namespace to use.  Defaults to
48
     *     "http://www.w3.org/2003/01/geo/wgs84_pos#"
49
     */
50
    geons: "http://www.w3.org/2003/01/geo/wgs84_pos#",
51
    
52
    /**
53
     * APIProperty: featureTitle
54
     * {String} Default title for features.  Defaults to "Untitled"
55
     */
56
    featureTitle: "Untitled",
57
    
58
    /**
59
     * APIProperty: featureDescription
60
     * {String} Default description for features.  Defaults to "No Description"
61
     */
62
    featureDescription: "No Description",
63
    
64
    /**
65
     * Property: gmlParse
66
     * {Object} GML Format object for parsing features
67
     * Non-API and only created if necessary
68
     */
69
    gmlParser: null,
70

    
71
    /**
72
     * APIProperty: xy
73
     * {Boolean} Order of the GML coordinate: true:(x,y) or false:(y,x)
74
     * For GeoRSS the default is (y,x), therefore: false
75
     */ 
76
    xy: false,
77
    
78
    /**
79
     * Constructor: OpenLayers.Format.GeoRSS
80
     * Create a new parser for GeoRSS.
81
     *
82
     * Parameters:
83
     * options - {Object} An optional object whose properties will be set on
84
     *     this instance.
85
     */
86
    
87
    /**
88
     * Method: createGeometryFromItem
89
     * Return a geometry from a GeoRSS Item.
90
     *
91
     * Parameters:
92
     * item - {DOMElement} A GeoRSS item node.
93
     *
94
     * Returns:
95
     * {<OpenLayers.Geometry>} A geometry representing the node.
96
     */
97
    createGeometryFromItem: function(item) {
98
        var point = this.getElementsByTagNameNS(item, this.georssns, "point");
99
        var lat = this.getElementsByTagNameNS(item, this.geons, 'lat');
100
        var lon = this.getElementsByTagNameNS(item, this.geons, 'long');
101
        
102
        var line = this.getElementsByTagNameNS(item,
103
                                                this.georssns,
104
                                                "line");
105
        var polygon = this.getElementsByTagNameNS(item,
106
                                                this.georssns,
107
                                                "polygon");
108
        var where = this.getElementsByTagNameNS(item, 
109
                                                this.georssns, 
110
                                                "where");
111
        var box = this.getElementsByTagNameNS(item, 
112
                                              this.georssns, 
113
                                              "box");
114

    
115
        if (point.length > 0 || (lat.length > 0 && lon.length > 0)) {
116
            var location;
117
            if (point.length > 0) {
118
                location = OpenLayers.String.trim(
119
                                point[0].firstChild.nodeValue).split(/\s+/);
120
                if (location.length !=2) {
121
                    location = OpenLayers.String.trim(
122
                                point[0].firstChild.nodeValue).split(/\s*,\s*/);
123
                }
124
            } else {
125
                location = [parseFloat(lat[0].firstChild.nodeValue),
126
                                parseFloat(lon[0].firstChild.nodeValue)];
127
            }    
128

    
129
            var geometry = new OpenLayers.Geometry.Point(location[1], location[0]);
130
              
131
        } else if (line.length > 0) {
132
            var coords = OpenLayers.String.trim(this.getChildValue(line[0])).split(/\s+/);
133
            var components = []; 
134
            var point;
135
            for (var i=0, len=coords.length; i<len; i+=2) {
136
                point = new OpenLayers.Geometry.Point(coords[i+1], coords[i]);
137
                components.push(point);
138
            }
139
            geometry = new OpenLayers.Geometry.LineString(components);
140
        } else if (polygon.length > 0) { 
141
            var coords = OpenLayers.String.trim(this.getChildValue(polygon[0])).split(/\s+/);
142
            var components = []; 
143
            var point;
144
            for (var i=0, len=coords.length; i<len; i+=2) {
145
                point = new OpenLayers.Geometry.Point(coords[i+1], coords[i]);
146
                components.push(point);
147
            }
148
            geometry = new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(components)]);
149
        } else if (where.length > 0) { 
150
            if (!this.gmlParser) {
151
              this.gmlParser = new OpenLayers.Format.GML({'xy': this.xy});
152
            }
153
            var feature = this.gmlParser.parseFeature(where[0]);
154
            geometry = feature.geometry;
155
        } else if (box.length  > 0) {
156
            var coords = OpenLayers.String.trim(box[0].firstChild.nodeValue).split(/\s+/);
157
            var components = [];
158
            var point;
159
            if (coords.length > 3) {
160
                point = new OpenLayers.Geometry.Point(coords[1], coords[0]);
161
                components.push(point);
162
                point = new OpenLayers.Geometry.Point(coords[1], coords[2]);
163
                components.push(point);
164
                point = new OpenLayers.Geometry.Point(coords[3], coords[2]);
165
                components.push(point);
166
                point = new OpenLayers.Geometry.Point(coords[3], coords[0]);
167
                components.push(point);
168
                point = new OpenLayers.Geometry.Point(coords[1], coords[0]);
169
                components.push(point);
170
            }
171
            geometry = new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(components)]);
172
        }
173
        
174
        if (geometry && this.internalProjection && this.externalProjection) {
175
            geometry.transform(this.externalProjection, 
176
                               this.internalProjection);
177
        }
178

    
179
        return geometry;
180
    },        
181

    
182
    /**
183
     * Method: createFeatureFromItem
184
     * Return a feature from a GeoRSS Item.
185
     *
186
     * Parameters:
187
     * item - {DOMElement} A GeoRSS item node.
188
     *
189
     * Returns:
190
     * {<OpenLayers.Feature.Vector>} A feature representing the item.
191
     */
192
    createFeatureFromItem: function(item) {
193
        var geometry = this.createGeometryFromItem(item);
194
     
195
        /* Provide defaults for title and description */
196
        var title = this._getChildValue(item, "*", "title", this.featureTitle);
197
       
198
        /* First try RSS descriptions, then Atom summaries */
199
        var description = this._getChildValue(
200
            item, "*", "description",
201
            this._getChildValue(item, "*", "content",
202
                this._getChildValue(item, "*", "summary", this.featureDescription)));
203

    
204
        /* If no link URL is found in the first child node, try the
205
           href attribute */
206
        var link = this._getChildValue(item, "*", "link");
207
        if(!link) {
208
            try {
209
                link = this.getElementsByTagNameNS(item, "*", "link")[0].getAttribute("href");
210
            } catch(e) {
211
                link = null;
212
            }
213
        }
214

    
215
        var id = this._getChildValue(item, "*", "id", null);
216
        
217
        var data = {
218
            "title": title,
219
            "description": description,
220
            "link": link
221
        };
222
        var feature = new OpenLayers.Feature.Vector(geometry, data);
223
        feature.fid = id;
224
        return feature;
225
    },        
226
    
227
    /**
228
     * Method: _getChildValue
229
     *
230
     * Parameters:
231
     * node - {DOMElement}
232
     * nsuri - {String} Child node namespace uri ("*" for any).
233
     * name - {String} Child node name.
234
     * def - {String} Optional string default to return if no child found.
235
     *
236
     * Returns:
237
     * {String} The value of the first child with the given tag name.  Returns
238
     *     default value or empty string if none found.
239
     */
240
    _getChildValue: function(node, nsuri, name, def) {
241
        var value;
242
        var eles = this.getElementsByTagNameNS(node, nsuri, name);
243
        if(eles && eles[0] && eles[0].firstChild
244
            && eles[0].firstChild.nodeValue) {
245
            value = this.getChildValue(eles[0]);
246
        } else {
247
            value = (def == undefined) ? "" : def;
248
        }
249
        return value;
250
    },
251
    
252
    /**
253
     * APIMethod: read
254
     * Return a list of features from a GeoRSS doc
255
     *
256
     * Parameters:
257
     * doc - {Element} 
258
     *
259
     * Returns:
260
     * {Array(<OpenLayers.Feature.Vector>)}
261
     */
262
    read: function(doc) {
263
        if (typeof doc == "string") { 
264
            doc = OpenLayers.Format.XML.prototype.read.apply(this, [doc]);
265
        }
266

    
267
        /* Try RSS items first, then Atom entries */
268
        var itemlist = null;
269
        itemlist = this.getElementsByTagNameNS(doc, '*', 'item');
270
        if (itemlist.length == 0) {
271
            itemlist = this.getElementsByTagNameNS(doc, '*', 'entry');
272
        }
273
        
274
        var numItems = itemlist.length;
275
        var features = new Array(numItems);
276
        for(var i=0; i<numItems; i++) {
277
            features[i] = this.createFeatureFromItem(itemlist[i]);
278
        }
279
        return features;
280
    },
281
    
282

    
283
    /**
284
     * APIMethod: write
285
     * Accept Feature Collection, and return a string. 
286
     * 
287
     * Parameters: 
288
     * features - {Array(<OpenLayers.Feature.Vector>)} List of features to serialize into a string.
289
     */
290
    write: function(features) {
291
        var georss;
292
        if(OpenLayers.Util.isArray(features)) {
293
            georss = this.createElementNS(this.rssns, "rss");
294
            for(var i=0, len=features.length; i<len; i++) {
295
                georss.appendChild(this.createFeatureXML(features[i]));
296
            }
297
        } else {
298
            georss = this.createFeatureXML(features);
299
        }
300
        return OpenLayers.Format.XML.prototype.write.apply(this, [georss]);
301
    },
302

    
303
    /**
304
     * Method: createFeatureXML
305
     * Accept an <OpenLayers.Feature.Vector>, and build a geometry for it.
306
     * 
307
     * Parameters:
308
     * feature - {<OpenLayers.Feature.Vector>} 
309
     *
310
     * Returns:
311
     * {DOMElement}
312
     */
313
    createFeatureXML: function(feature) {
314
        var geometryNode = this.buildGeometryNode(feature.geometry);
315
        var featureNode = this.createElementNS(this.rssns, "item");
316
        var titleNode = this.createElementNS(this.rssns, "title");
317
        titleNode.appendChild(this.createTextNode(feature.attributes.title ? feature.attributes.title : ""));
318
        var descNode = this.createElementNS(this.rssns, "description");
319
        descNode.appendChild(this.createTextNode(feature.attributes.description ? feature.attributes.description : ""));
320
        featureNode.appendChild(titleNode);
321
        featureNode.appendChild(descNode);
322
        if (feature.attributes.link) {
323
            var linkNode = this.createElementNS(this.rssns, "link");
324
            linkNode.appendChild(this.createTextNode(feature.attributes.link));
325
            featureNode.appendChild(linkNode);
326
        }    
327
        for(var attr in feature.attributes) {
328
            if (attr == "link" || attr == "title" || attr == "description") { continue; } 
329
            var attrText = this.createTextNode(feature.attributes[attr]); 
330
            var nodename = attr;
331
            if (attr.search(":") != -1) {
332
                nodename = attr.split(":")[1];
333
            }    
334
            var attrContainer = this.createElementNS(this.featureNS, "feature:"+nodename);
335
            attrContainer.appendChild(attrText);
336
            featureNode.appendChild(attrContainer);
337
        }    
338
        featureNode.appendChild(geometryNode);
339
        return featureNode;
340
    },    
341
    
342
    /** 
343
     * Method: buildGeometryNode
344
     * builds a GeoRSS node with a given geometry
345
     * 
346
     * Parameters:
347
     * geometry - {<OpenLayers.Geometry>}
348
     *
349
     * Returns:
350
     * {DOMElement} A gml node.
351
     */
352
    buildGeometryNode: function(geometry) {
353
        if (this.internalProjection && this.externalProjection) {
354
            geometry = geometry.clone();
355
            geometry.transform(this.internalProjection, 
356
                               this.externalProjection);
357
        }
358
        var node;
359
        // match Polygon
360
        if (geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") {
361
            node = this.createElementNS(this.georssns, 'georss:polygon');
362
            
363
            node.appendChild(this.buildCoordinatesNode(geometry.components[0]));
364
        }
365
        // match LineString
366
        else if (geometry.CLASS_NAME == "OpenLayers.Geometry.LineString") {
367
            node = this.createElementNS(this.georssns, 'georss:line');
368
            
369
            node.appendChild(this.buildCoordinatesNode(geometry));
370
        }
371
        // match Point
372
        else if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
373
            node = this.createElementNS(this.georssns, 'georss:point');
374
            node.appendChild(this.buildCoordinatesNode(geometry));
375
        } else {
376
            throw "Couldn't parse " + geometry.CLASS_NAME;
377
        }  
378
        return node;         
379
    },
380
    
381
    /** 
382
     * Method: buildCoordinatesNode
383
     * 
384
     * Parameters:
385
     * geometry - {<OpenLayers.Geometry>}
386
     */
387
    buildCoordinatesNode: function(geometry) {
388
        var points = null;
389
        
390
        if (geometry.components) {
391
            points = geometry.components;
392
        }
393

    
394
        var path;
395
        if (points) {
396
            var numPoints = points.length;
397
            var parts = new Array(numPoints);
398
            for (var i = 0; i < numPoints; i++) {
399
                parts[i] = points[i].y + " " + points[i].x;
400
            }
401
            path = parts.join(" ");
402
        } else {
403
            path = geometry.y + " " + geometry.x;
404
        }
405
        return this.createTextNode(path);
406
    },
407

    
408
    CLASS_NAME: "OpenLayers.Format.GeoRSS" 
409
});     
(12-12/41)