Format.GeoRSS didn't use Format.XML serializer, nor did it support reading
anything other than points. Both of these are resolved with the new GeoRSS support, which supports all of GeoRSS simple. Includes tests and significant review from Senor Schaub, and addition to the examples/vector-formats.html file. (Closes #973) git-svn-id: http://svn.openlayers.org/trunk/openlayers@4305 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
@@ -4,46 +4,216 @@
|
||||
|
||||
/**
|
||||
* @requires OpenLayers/Format.js
|
||||
* @requires OpenLayers/Format/XML.js
|
||||
*
|
||||
* Class: OpenLayers.Format.GeoRSS
|
||||
* Write-only GeoRSS. Create a new instance with the
|
||||
* Read/write GeoRSS parser. Create a new instance with the
|
||||
* <OpenLayers.Format.GeoRSS> constructor.
|
||||
*
|
||||
* Inherits from:
|
||||
* - <OpenLayers.Format>
|
||||
* - <OpenLayers.Format.XML>
|
||||
*/
|
||||
OpenLayers.Format.GeoRSS = OpenLayers.Class(OpenLayers.Format, {
|
||||
OpenLayers.Format.GeoRSS = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
|
||||
/**
|
||||
* APIProperty: rssns
|
||||
* RSS namespace to use.
|
||||
* {String} RSS namespace to use. Defaults to
|
||||
* "http://backend.userland.com/rss2"
|
||||
*/
|
||||
rssns: "http://backend.userland.com/rss2",
|
||||
|
||||
/**
|
||||
* APIProperty: featurens
|
||||
* Feature Attributes namespace
|
||||
* {String} Feature Attributes namespace. Defaults to
|
||||
* "http://mapserver.gis.umn.edu/mapserver"
|
||||
*/
|
||||
featureNS: "http://mapserver.gis.umn.edu/mapserver",
|
||||
|
||||
/**
|
||||
* APIProperty: georssns
|
||||
* GeoRSS namespace to use.
|
||||
* {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
|
||||
* Create a new parser for GeoRSS.
|
||||
*
|
||||
* Parameters:
|
||||
* options - {Object} An optional object whose properties will be set on
|
||||
* this instance.
|
||||
* this instance.
|
||||
*/
|
||||
initialize: function(options) {
|
||||
OpenLayers.Format.prototype.initialize.apply(this, [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
|
||||
@@ -52,14 +222,19 @@ OpenLayers.Format.GeoRSS = OpenLayers.Class(OpenLayers.Format, {
|
||||
* Parameters:
|
||||
* features - Array({<OpenLayers.Feature.Vector>}) List of features to serialize into a string.
|
||||
*/
|
||||
write: function(features) {
|
||||
var featureCollection = document.createElementNS(this.rssns, "rss");
|
||||
for (var i=0; i < features.length; i++) {
|
||||
featureCollection.appendChild(this.createFeatureXML(features[i]));
|
||||
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 featureCollection;
|
||||
},
|
||||
|
||||
return OpenLayers.Format.XML.prototype.write.apply(this, [georss]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: createFeatureXML
|
||||
* Accept an <OpenLayers.Feature.Vector>, and build a geometry for it.
|
||||
@@ -72,20 +247,26 @@ OpenLayers.Format.GeoRSS = OpenLayers.Class(OpenLayers.Format, {
|
||||
*/
|
||||
createFeatureXML: function(feature) {
|
||||
var geometryNode = this.buildGeometryNode(feature.geometry);
|
||||
var featureNode = document.createElementNS(this.rssns, "item");
|
||||
var titleNode = document.createElementNS(this.rssns, "title");
|
||||
titleNode.appendChild(document.createTextNode(feature.attributes.title ? feature.attributes.title : ""));
|
||||
var descNode = document.createElementNS(this.rssns, "description");
|
||||
descNode.appendChild(document.createTextNode(feature.attributes.description ? feature.attributes.description : ""));
|
||||
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) {
|
||||
var attrText = document.createTextNode(feature.attributes[attr]);
|
||||
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 = document.createElementNS(this.featureNS, "feature:"+nodename);
|
||||
var attrContainer = this.createElementNS(this.featureNS, "feature:"+nodename);
|
||||
attrContainer.appendChild(attrText);
|
||||
featureNode.appendChild(attrContainer);
|
||||
}
|
||||
@@ -98,30 +279,33 @@ OpenLayers.Format.GeoRSS = OpenLayers.Class(OpenLayers.Format, {
|
||||
* builds a GeoRSS node with a given geometry
|
||||
*
|
||||
* Parameters:
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement} A gml node.
|
||||
*/
|
||||
buildGeometryNode: function(geometry) {
|
||||
var gml = "";
|
||||
// match MultiPolygon or Polygon
|
||||
var node;
|
||||
// match Polygon
|
||||
if (geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") {
|
||||
gml = document.createElementNS(this.georssns, 'georss:polygon');
|
||||
|
||||
gml.appendChild(this.buildCoordinatesNode(geometry.components[0]));
|
||||
}
|
||||
// match MultiLineString or LineString
|
||||
node = this.createElementNS(this.georssns, 'georss:polygon');
|
||||
|
||||
node.appendChild(this.buildCoordinatesNode(geometry.components[0]));
|
||||
}
|
||||
// match LineString
|
||||
else if (geometry.CLASS_NAME == "OpenLayers.Geometry.LineString") {
|
||||
gml = document.createElementNS(this.georssns, 'georss:line');
|
||||
|
||||
gml.appendChild(this.buildCoordinatesNode(geometry));
|
||||
}
|
||||
// match MultiPoint or Point
|
||||
node = this.createElementNS(this.georssns, 'georss:line');
|
||||
|
||||
node.appendChild(this.buildCoordinatesNode(geometry));
|
||||
}
|
||||
// match Point
|
||||
else if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
|
||||
gml = document.createElementNS(this.georssns, 'georss:point');
|
||||
gml.appendChild(this.buildCoordinatesNode(geometry));
|
||||
} else {
|
||||
alert("Couldn't parse " + geometry.CLASS_NAME);
|
||||
node = this.createElementNS(this.georssns, 'georss:point');
|
||||
node.appendChild(this.buildCoordinatesNode(geometry));
|
||||
} else {
|
||||
throw "Couldn't parse " + geometry.CLASS_NAME;
|
||||
}
|
||||
return gml;
|
||||
return node;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -137,15 +321,18 @@ OpenLayers.Format.GeoRSS = OpenLayers.Class(OpenLayers.Format, {
|
||||
points = geometry.components;
|
||||
}
|
||||
|
||||
var path = "";
|
||||
var path;
|
||||
if (points) {
|
||||
for (var i = 0; i < points.length; i++) {
|
||||
path += points[i].y + " " + points[i].x + " ";
|
||||
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 + " ";
|
||||
path = geometry.y + " " + geometry.x;
|
||||
}
|
||||
return document.createTextNode(path);
|
||||
return this.createTextNode(path);
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Format.GeoRSS"
|
||||
|
||||
Reference in New Issue
Block a user