git-svn-id: http://svn.openlayers.org/tags/openlayers/release-2.5-rc1@4347 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
340 lines
12 KiB
JavaScript
340 lines
12 KiB
JavaScript
/* Copyright (c) 2006-2007 MetaCarta, Inc., published under the BSD license.
|
|
* See http://svn.openlayers.org/trunk/openlayers/release-license.txt
|
|
* for the full text of the license. */
|
|
|
|
/**
|
|
* @requires OpenLayers/Format.js
|
|
* @requires OpenLayers/Format/XML.js
|
|
*
|
|
* Class: OpenLayers.Format.GeoRSS
|
|
* Read/write GeoRSS parser. Create a new instance with the
|
|
* <OpenLayers.Format.GeoRSS> constructor.
|
|
*
|
|
* Inherits from:
|
|
* - <OpenLayers.Format.XML>
|
|
*/
|
|
OpenLayers.Format.GeoRSS = OpenLayers.Class(OpenLayers.Format.XML, {
|
|
|
|
/**
|
|
* APIProperty: rssns
|
|
* {String} RSS namespace to use. Defaults to
|
|
* "http://backend.userland.com/rss2"
|
|
*/
|
|
rssns: "http://backend.userland.com/rss2",
|
|
|
|
/**
|
|
* APIProperty: featurens
|
|
* {String} Feature Attributes namespace. Defaults to
|
|
* "http://mapserver.gis.umn.edu/mapserver"
|
|
*/
|
|
featureNS: "http://mapserver.gis.umn.edu/mapserver",
|
|
|
|
/**
|
|
* APIProperty: georssns
|
|
* {String} GeoRSS namespace to use. Defaults to
|
|
* "http://www.georss.org/georss"
|
|
*/
|
|
georssns: "http://www.georss.org/georss",
|
|
|
|
/**
|
|
* APIProperty: featureTitle
|
|
* {String} Default title for features. Defaults to "Untitled"
|
|
*/
|
|
featureTitle: "Untitled",
|
|
|
|
/**
|
|
* APIProperty: featureDescription
|
|
* {String} Default description for features. Defaults to "No Description"
|
|
*/
|
|
featureDescription: "No Description",
|
|
|
|
/**
|
|
* Constructor: OpenLayers.Format.GeoRSS
|
|
* Create a new parser for GeoRSS.
|
|
*
|
|
* Parameters:
|
|
* options - {Object} An optional object whose properties will be set on
|
|
* this instance.
|
|
*/
|
|
initialize: function(options) {
|
|
OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);
|
|
},
|
|
|
|
/**
|
|
* Method: createGeometryFromItem
|
|
* Return a geometry from a GeoRSS Item.
|
|
*
|
|
* Parameters:
|
|
* item - {DOMElement} A GeoRSS item node.
|
|
*
|
|
* Returns:
|
|
* {<OpenLayers.Geometry>} A geometry representing the node.
|
|
*/
|
|
createGeometryFromItem: function(item) {
|
|
var point = this.getElementsByTagNameNS(item, this.georssns, "point");
|
|
var lat = this.getElementsByTagNameNS(item, this.geons, 'lat');
|
|
var lon = this.getElementsByTagNameNS(item, this.geons, 'long');
|
|
|
|
var line = this.getElementsByTagNameNS(item,
|
|
this.georssns,
|
|
"line");
|
|
var polygon = this.getElementsByTagNameNS(item,
|
|
this.georssns,
|
|
"polygon");
|
|
|
|
if (point.length > 0 || (lat.length > 0 && lon.length > 0)) {
|
|
if (point.length > 0) {
|
|
var location = OpenLayers.String.trim(
|
|
point[0].firstChild.nodeValue).split(/\s+/);
|
|
|
|
if (location.length !=2) {
|
|
var location = OpenLayers.String.trim(
|
|
point[0].firstChild.nodeValue).split(/\s*,\s*/);
|
|
}
|
|
} else {
|
|
var location = [parseFloat(lat[0].firstChild.nodeValue),
|
|
parseFloat(lon[0].firstChild.nodeValue)];
|
|
}
|
|
var geometry = new OpenLayers.Geometry.Point(parseFloat(location[1]),
|
|
parseFloat(location[0]));
|
|
} else if (line.length > 0) {
|
|
var coords = OpenLayers.String.trim(line[0].firstChild.nodeValue).split(/\s+/);
|
|
var components = [];
|
|
for (var i=0; i < coords.length; i+=2) {
|
|
var point = new OpenLayers.Geometry.Point(parseFloat(coords[i+1]), parseFloat(coords[i]));
|
|
components.push(point);
|
|
}
|
|
geometry = new OpenLayers.Geometry.LineString(components);
|
|
} else if (polygon.length > 0) {
|
|
var coords = OpenLayers.String.trim(polygon[0].firstChild.nodeValue).split(/\s+/);
|
|
var components = [];
|
|
for (var i=0; i < coords.length; i+=2) {
|
|
var point = new OpenLayers.Geometry.Point(parseFloat(coords[i+1]), parseFloat(coords[i]));
|
|
components.push(point);
|
|
}
|
|
geometry = new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(components)]);
|
|
}
|
|
return geometry;
|
|
},
|
|
|
|
/**
|
|
* Method: createGeometryFromItem
|
|
* Return a feature from a GeoRSS Item.
|
|
*
|
|
* Parameters:
|
|
* item - {DOMElement} A GeoRSS item node.
|
|
*
|
|
* Returns:
|
|
* {<OpenLayers.Feature.Vector>} A feature representing the item.
|
|
*/
|
|
createFeatureFromItem: function(item) {
|
|
var geometry = this.createGeometryFromItem(item);
|
|
/* Provide defaults for title and description */
|
|
var title = this.getChildValue(item, "*", "title", this.featureTitle);
|
|
|
|
/* First try RSS descriptions, then Atom summaries */
|
|
var description = this.getChildValue(
|
|
item, "*", "description",
|
|
this.getChildValue(item, "*", "content", this.featureDescription)
|
|
);
|
|
|
|
/* If no link URL is found in the first child node, try the
|
|
href attribute */
|
|
var link = this.getChildValue(item, "*", "link");
|
|
if(!link) {
|
|
try {
|
|
link = this.getElementsByTagNameNS(item, "*", "link")[0].getAttribute("href");
|
|
} catch(e) {
|
|
link = null;
|
|
}
|
|
}
|
|
|
|
var id = this.getChildValue(item, "*", "id", null);
|
|
|
|
var data = {
|
|
"title": title,
|
|
"description": description,
|
|
"link": link
|
|
};
|
|
var feature = new OpenLayers.Feature.Vector(geometry, data);
|
|
feature.fid = id;
|
|
return feature;
|
|
},
|
|
|
|
/**
|
|
* Method: getChildValue
|
|
*
|
|
* Parameters:
|
|
* node - {DOMElement}
|
|
* nsuri - {String} Child node namespace uri ("*" for any).
|
|
* name - {String} Child node name.
|
|
* def - {String} Optional string default to return if no child found.
|
|
*
|
|
* Returns:
|
|
* {String} The value of the first child with the given tag name. Returns
|
|
* default value or empty string if none found.
|
|
*/
|
|
getChildValue: function(node, nsuri, name, def) {
|
|
var value;
|
|
try {
|
|
value = this.getElementsByTagNameNS(node, nsuri, name)[0].firstChild.nodeValue;
|
|
} catch(e) {
|
|
value = (def == undefined) ? "" : def;
|
|
}
|
|
return value;
|
|
},
|
|
|
|
/**
|
|
* APIMethod: read
|
|
* Return a list of features from a GeoRSS doc
|
|
|
|
* Parameters:
|
|
* data - {Element}
|
|
*
|
|
* Returns:
|
|
* An Array of <OpenLayers.Feature.Vector>s
|
|
*/
|
|
read: function(doc) {
|
|
if (typeof doc == "string") {
|
|
doc = OpenLayers.Format.XML.prototype.read.apply(this, [doc]);
|
|
}
|
|
|
|
/* Try RSS items first, then Atom entries */
|
|
var itemlist = null;
|
|
itemlist = this.getElementsByTagNameNS(doc, '*', 'item');
|
|
if (itemlist.length == 0) {
|
|
itemlist = this.getElementsByTagNameNS(doc, '*', 'entry');
|
|
}
|
|
|
|
var numItems = itemlist.length;
|
|
var features = new Array(numItems);
|
|
for(var i=0; i<numItems; i++) {
|
|
features[i] = this.createFeatureFromItem(itemlist[i]);
|
|
}
|
|
return features;
|
|
},
|
|
|
|
|
|
/**
|
|
* APIMethod: write
|
|
* Accept Feature Collection, and return a string.
|
|
*
|
|
* Parameters:
|
|
* features - Array({<OpenLayers.Feature.Vector>}) List of features to serialize into a string.
|
|
*/
|
|
write: function(features) {
|
|
var georss;
|
|
if(features instanceof Array) {
|
|
georss = this.createElementNS(this.rssns, "rss");
|
|
for(var i=0; i < features.length; i++) {
|
|
georss.appendChild(this.createFeatureXML(features[i]));
|
|
}
|
|
} else {
|
|
georss = this.createFeatureXML(features);
|
|
}
|
|
return OpenLayers.Format.XML.prototype.write.apply(this, [georss]);
|
|
},
|
|
|
|
/**
|
|
* Method: createFeatureXML
|
|
* Accept an <OpenLayers.Feature.Vector>, and build a geometry for it.
|
|
*
|
|
* Parameters:
|
|
* feature - {<OpenLayers.Feature.Vector>}
|
|
*
|
|
* Returns:
|
|
* {DOMElement}
|
|
*/
|
|
createFeatureXML: function(feature) {
|
|
var geometryNode = this.buildGeometryNode(feature.geometry);
|
|
var featureNode = this.createElementNS(this.rssns, "item");
|
|
var titleNode = this.createElementNS(this.rssns, "title");
|
|
titleNode.appendChild(this.createTextNode(feature.attributes.title ? feature.attributes.title : ""));
|
|
var descNode = this.createElementNS(this.rssns, "description");
|
|
descNode.appendChild(this.createTextNode(feature.attributes.description ? feature.attributes.description : ""));
|
|
featureNode.appendChild(titleNode);
|
|
featureNode.appendChild(descNode);
|
|
if (feature.attributes.link) {
|
|
var linkNode = this.createElementNS(this.rssns, "link");
|
|
linkNode.appendChild(this.createTextNode(feature.attributes.link));
|
|
featureNode.appendChild(linkNode);
|
|
}
|
|
for(var attr in feature.attributes) {
|
|
if (attr == "link" || attr == "title" || attr == "description") { continue; }
|
|
var attrText = this.createTextNode(feature.attributes[attr]);
|
|
var nodename = attr;
|
|
if (attr.search(":") != -1) {
|
|
nodename = attr.split(":")[1];
|
|
}
|
|
var attrContainer = this.createElementNS(this.featureNS, "feature:"+nodename);
|
|
attrContainer.appendChild(attrText);
|
|
featureNode.appendChild(attrContainer);
|
|
}
|
|
featureNode.appendChild(geometryNode);
|
|
return featureNode;
|
|
},
|
|
|
|
/**
|
|
* Method: buildGeometryNode
|
|
* builds a GeoRSS node with a given geometry
|
|
*
|
|
* Parameters:
|
|
* geometry - {<OpenLayers.Geometry>}
|
|
*
|
|
* Returns:
|
|
* {DOMElement} A gml node.
|
|
*/
|
|
buildGeometryNode: function(geometry) {
|
|
var node;
|
|
// match Polygon
|
|
if (geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") {
|
|
node = this.createElementNS(this.georssns, 'georss:polygon');
|
|
|
|
node.appendChild(this.buildCoordinatesNode(geometry.components[0]));
|
|
}
|
|
// match LineString
|
|
else if (geometry.CLASS_NAME == "OpenLayers.Geometry.LineString") {
|
|
node = this.createElementNS(this.georssns, 'georss:line');
|
|
|
|
node.appendChild(this.buildCoordinatesNode(geometry));
|
|
}
|
|
// match Point
|
|
else if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
|
|
node = this.createElementNS(this.georssns, 'georss:point');
|
|
node.appendChild(this.buildCoordinatesNode(geometry));
|
|
} else {
|
|
throw "Couldn't parse " + geometry.CLASS_NAME;
|
|
}
|
|
return node;
|
|
},
|
|
|
|
/**
|
|
* Method: buildCoordinatesNode
|
|
*
|
|
* Parameters:
|
|
* geometry - {<OpenLayers.Geometry>}
|
|
*/
|
|
buildCoordinatesNode: function(geometry) {
|
|
var points = null;
|
|
|
|
if (geometry.components) {
|
|
points = geometry.components;
|
|
}
|
|
|
|
var path;
|
|
if (points) {
|
|
var numPoints = points.length;
|
|
var parts = new Array(numPoints);
|
|
for (var i = 0; i < numPoints; i++) {
|
|
parts[i] = points[i].y + " " + points[i].x;
|
|
}
|
|
path = parts.join(" ");
|
|
} else {
|
|
path = geometry.y + " " + geometry.x;
|
|
}
|
|
return this.createTextNode(path);
|
|
},
|
|
|
|
CLASS_NAME: "OpenLayers.Format.GeoRSS"
|
|
});
|