[OpenLayers-Commits] r4206 - in trunk/openlayers: lib/OpenLayers/Format tests/Format
commits at openlayers.org
commits at openlayers.org
Mon Sep 10 18:02:19 EDT 2007
Author: tschaub
Date: 2007-09-10 18:02:18 -0400 (Mon, 10 Sep 2007)
New Revision: 4206
Modified:
trunk/openlayers/lib/OpenLayers/Format/GML.js
trunk/openlayers/tests/Format/test_GML.html
Log:
GML format rewrite - now subclasses from XML format. Refactored code to get ~2-3x improvement in parsing time. Thanks for all the tests crschmidt (closes #938).
Modified: trunk/openlayers/lib/OpenLayers/Format/GML.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Format/GML.js 2007-09-10 20:24:27 UTC (rev 4205)
+++ trunk/openlayers/lib/OpenLayers/Format/GML.js 2007-09-10 22:02:18 UTC (rev 4206)
@@ -3,78 +3,86 @@
* for the full text of the license. */
/**
- * @requires OpenLayers/Format.js
+ * @requires OpenLayers/Format/XML.js
* @requires OpenLayers/Feature/Vector.js
- * @requires OpenLayers/Ajax.js
* @requires OpenLayers/Geometry.js
*
* Class: OpenLayers.Format.GML
* Read/Wite GML. Create a new instance with the <OpenLayers.Format.GML>
- * constructor.
+ * constructor. Supports the GML simple features profile.
*
* Inherits from:
* - <OpenLayers.Format>
*/
-OpenLayers.Format.GML = OpenLayers.Class(OpenLayers.Format, {
+OpenLayers.Format.GML = OpenLayers.Class(OpenLayers.Format.XML, {
/*
* APIProperty: featureNS
- * Namespace used for feature attributes. Default matches the NS
- * used by MapServer output.
+ * {String} Namespace used for feature attributes. Default is
+ * "http://mapserver.gis.umn.edu/mapserver".
*/
featureNS: "http://mapserver.gis.umn.edu/mapserver",
+ /**
+ * APIProperty: featurePrefix
+ * {String} Namespace alias (or prefix) for feature nodes. Default is
+ * "feature".
+ */
+ featurePrefix: "feature",
+
/*
* APIProperty: featureName
- * element name for features. Default is 'featureMember'.
+ * {String} Element name for features. Default is "featureMember".
*/
featureName: "featureMember",
/*
* APIProperty: layerName
- * Name of data layer. Default is 'features'.
+ * {String} Name of data layer. Default is "features".
*/
-
layerName: "features",
/**
* APIProperty: geometry
- * Name of geometry element.
+ * {String} Name of geometry element. Defaults to "geometry".
*/
geometryName: "geometry",
/**
* APIProperty: collectionName
- * Name of featureCollection element
+ * {String} Name of featureCollection element.
*/
collectionName: "FeatureCollection",
/**
* APIProperty: gmlns
- * GML Namespace
+ * {String} GML Namespace.
*/
gmlns: "http://www.opengis.net/gml",
-
/**
* APIProperty: extractAttributes
- * {Boolean} Extract attributes from GML. Most of the time, this is a
- * significant time usage, due to the need to recursively descend the XML
- * to search for attributes.
+ * {Boolean} Extract attributes from GML.
*/
extractAttributes: true,
-
/**
* Constructor: OpenLayers.Format.GML
- * Create a new parser for GML
+ * Create a new parser for GML.
*
* 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]);
+ // compile regular expressions once instead of every time they are used
+ this.regExes = {
+ trimSpace: (/^\s*|\s*$/g),
+ removeSpace: (/\s*/g),
+ splitSpace: (/\s+/),
+ trimComma: (/\s*,\s*/g)
+ };
+ OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);
},
/**
@@ -82,391 +90,617 @@
* Read data from a string, and return a list of features.
*
* Parameters:
- * data - {String} or {XMLNode} data to read/parse.
+ * data - {String} or {DOMElement} data to read/parse.
+ *
+ * Returns:
+ * {Array(<OpenLayers.Feature.Vector>)} An array of features.
*/
- read: function(data) {
- if (typeof data == "string") {
- data = OpenLayers.parseXMLString(data);
- }
- var featureNodes = OpenLayers.Ajax.getElementsByTagNameNS(data, this.gmlns, "gml", this.featureName);
- if (featureNodes.length == 0) { return []; }
-
- // Determine dimension of the FeatureCollection. Ie, dim=2 means (x,y) coords
- // dim=3 means (x,y,z) coords
- // GML3 can have 2 or 3 dimensions. GML2 only 2.
- var dim;
- var coordNodes = OpenLayers.Ajax.getElementsByTagNameNS(featureNodes[0], this.gmlns, "gml", "posList");
- if (coordNodes.length == 0) {
- coordNodes = OpenLayers.Ajax.getElementsByTagNameNS(featureNodes[0], this.gmlns, "gml", "pos");
+ read: function(data) {
+ if(typeof data == "string") {
+ data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);
}
- if (coordNodes.length > 0) {
- dim = coordNodes[0].getAttribute("srsDimension");
- }
- this.dim = (dim == "3" || dim == 3) ? 3 : 2;
-
+ var featureNodes = this.getElementsByTagNameNS(data.documentElement,
+ this.gmlns,
+ this.featureName);
var features = [];
-
- // Process all the featureMembers
- for (var i = 0; i < featureNodes.length; i++) {
+ for(var i=0; i<featureNodes.length; i++) {
var feature = this.parseFeature(featureNodes[i]);
-
- if (feature) {
+ if(feature) {
features.push(feature);
}
}
return features;
- },
+ },
+
+ /**
+ * Method: parseFeature
+ * This function is the core of the GML parsing code in OpenLayers.
+ * It creates the geometries that are then attached to the returned
+ * feature, and calls parseAttributes() to get attribute data out.
+ *
+ * Parameters:
+ * node - {DOMElement} A GML feature node.
+ */
+ parseFeature: function(node) {
+ // only accept on geometry per feature - look for highest "order"
+ var order = ["MultiPolygon", "Polygon",
+ "MultiLineString", "LineString",
+ "MultiPoint", "Point"];
+ var type, nodeList, geometry, parser;
+ for(var i=0; i<order.length; ++i) {
+ type = order[i];
+ nodeList = this.getElementsByTagNameNS(node, this.gmlns, type);
+ if(nodeList.length > 0) {
+ // only deal with first geometry of this type
+ var parser = this.parseGeometry[type.toLowerCase()];
+ if(parser) {
+ geometry = parser.apply(this, [nodeList[0]]);
+ } else {
+ OpenLayers.Console.error("Unsupported geometry type: " +
+ type);
+ }
+ // stop looking for different geometry types
+ break;
+ }
+ }
+
+ // construct feature (optionally with attributes)
+ var attributes;
+ if(this.extractAttributes) {
+ attributes = this.parseAttributes(node);
+ }
+ var feature = new OpenLayers.Feature.Vector(geometry, attributes);
+ // assign fid - this can come from a "fid" or "id" attribute
+ var childNode = node.firstChild;
+ var fid;
+ while(childNode) {
+ if(childNode.nodeType == 1) {
+ fid = childNode.getAttribute("fid") ||
+ childNode.getAttribute("id");
+ if(fid) {
+ break;
+ }
+ }
+ childNode = childNode.nextSibling;
+ }
+ feature.fid = fid;
+ return feature;
+ },
+
+ /**
+ * Property: parseGeometry
+ * Properties of this object are the functions that parse geometries based
+ * on their type.
+ */
+ parseGeometry: {
+
+ /**
+ * Method: parseGeometry.point
+ * Given a GML node representing a point geometry, create an OpenLayers
+ * point geometry.
+ *
+ * Parameters:
+ * node - {DOMElement} A GML node.
+ *
+ * Returns:
+ * {<OpenLayers.Geometry.Point>} A point geometry.
+ */
+ point: function(node) {
+ /**
+ * Three coordinate variations to consider:
+ * 1) <gml:pos>x y z</gml:pos>
+ * 2) <gml:coordinates>x, y, z</gml:coordinates>
+ * 3) <gml:coord><gml:X>x</gml:X><gml:Y>y</gml:Y></gml:coord>
+ */
+ var nodeList;
+ var coords = [];
- /**
- * Method: parseFeature
- * This function is the core of the GML parsing code in OpenLayers.
- * It creates the geometries that are then attached to the returned
- * feature, and calls parseAttributes() to get attribute data out.
-
- * Parameters:
- * xmlNode - {<DOMElement>}
- */
- parseFeature: function(xmlNode) {
- var geom;
- var p; // [points,bounds]
+ // look for <gml:pos>
+ var nodeList = this.getElementsByTagNameNS(node, this.gmlns, "pos");
+ if(nodeList.length > 0) {
+ coordString = nodeList[0].firstChild.nodeValue;
+ coordString = coordString.replace(this.regExes.trimSpace, "");
+ coords = coordString.split(this.regExes.splitSpace);
+ }
- var feature = new OpenLayers.Feature.Vector();
+ // look for <gml:coordinates>
+ if(coords.length == 0) {
+ nodeList = this.getElementsByTagNameNS(node, this.gmlns,
+ "coordinates");
+ if(nodeList.length > 0) {
+ coordString = nodeList[0].firstChild.nodeValue;
+ coordString = coordString.replace(this.regExes.removeSpace,
+ "");
+ coords = coordString.split(",");
+ }
+ }
- // match MultiPolygon
- if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode, this.gmlns, "gml", "MultiPolygon").length != 0) {
- var multipolygon = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode, this.gmlns, "gml", "MultiPolygon")[0];
- feature.fid = multipolygon.parentNode.parentNode.getAttribute('fid');
-
- geom = new OpenLayers.Geometry.MultiPolygon();
- var polygons = OpenLayers.Ajax.getElementsByTagNameNS(multipolygon,
- this.gmlns, "gml", "Polygon");
- for (var i = 0; i < polygons.length; i++) {
- polygon = this.parsePolygonNode(polygons[i],geom);
- geom.addComponents(polygon);
- }
- }
- // match MultiLineString
- else if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
- this.gmlns, "gml", "MultiLineString").length != 0) {
- var multilinestring = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
- this.gmlns, "gml", "MultiLineString")[0];
- feature.fid = multilinestring.parentNode.parentNode.getAttribute('fid');
-
- geom = new OpenLayers.Geometry.MultiLineString();
- var lineStrings = OpenLayers.Ajax.getElementsByTagNameNS(multilinestring, this.gmlns, "gml", "LineString");
-
- for (var i = 0; i < lineStrings.length; i++) {
- p = this.parseCoords(lineStrings[i]);
- if(p.points){
- var lineString = new OpenLayers.Geometry.LineString(p.points);
- geom.addComponents(lineString);
- // TBD Bounds only set for one of multiple geometries
+ // look for <gml:coord>
+ if(coords.length == 0) {
+ nodeList = this.getElementsByTagNameNS(node, this.gmlns,
+ "coord");
+ if(nodeList.length > 0) {
+ var xList = this.getElementsByTagNameNS(nodeList[0],
+ this.gmlns, "X");
+ var yList = this.getElementsByTagNameNS(nodeList[0],
+ this.gmlns, "Y");
+ if(xList.length > 0 && yList.length > 0) {
+ coords = [xList[0].firstChild.nodeValue,
+ yList[0].firstChild.nodeValue];
+ }
}
}
- }
- // match MultiPoint
- else if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
- this.gmlns, "gml", "MultiPoint").length != 0) {
- var multiPoint = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
- this.gmlns, "gml", "MultiPoint")[0];
- feature.fid = multiPoint.parentNode.parentNode.getAttribute('fid');
- geom = new OpenLayers.Geometry.MultiPoint();
-
- var points = OpenLayers.Ajax.getElementsByTagNameNS(multiPoint, this.gmlns, "gml", "Point");
-
- for (var i = 0; i < points.length; i++) {
- p = this.parseCoords(points[i]);
- geom.addComponents(p.points[0]);
- // TBD Bounds only set for one of multiple geometries
+ // preserve third dimension
+ if(coords.length == 2) {
+ coords[2] = null;
}
- }
- // match Polygon
- else if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
- this.gmlns, "gml", "Polygon").length != 0) {
- var polygon = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
- this.gmlns, "gml", "Polygon")[0];
- feature.fid = polygon.parentNode.parentNode.getAttribute('fid');
-
- geom = this.parsePolygonNode(polygon);
- }
- // match LineString
- else if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
- this.gmlns, "gml", "LineString").length != 0) {
- var lineString = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
- this.gmlns, "gml", "LineString")[0];
- feature.fid = lineString.parentNode.parentNode.getAttribute('fid');
+ return new OpenLayers.Geometry.Point(coords[0], coords[1],
+ coords[2]);
+ },
+
+ /**
+ * Method: parseGeometry.multipoint
+ * Given a GML node representing a multipoint geometry, create an
+ * OpenLayers multipoint geometry.
+ *
+ * Parameters:
+ * node - {DOMElement} A GML node.
+ *
+ * Returns:
+ * {<OpenLayers.Geometry.MultiPoint>} A multipoint geometry.
+ */
+ multipoint: function(node) {
+ var nodeList = this.getElementsByTagNameNS(node, this.gmlns,
+ "Point");
+ var components = [];
+ if(nodeList.length > 0) {
+ var point;
+ for(var i=0; i<nodeList.length; ++i) {
+ point = this.parseGeometry.point.apply(this, [nodeList[i]]);
+ if(point) {
+ components.push(point);
+ }
+ }
+ }
+ return new OpenLayers.Geometry.MultiPoint(components);
+ },
+
+ /**
+ * Method: parseGeometry.linestring
+ * Given a GML node representing a linestring geometry, create an
+ * OpenLayers linestring geometry.
+ *
+ * Parameters:
+ * node - {DOMElement} A GML node.
+ *
+ * Returns:
+ * {<OpenLayers.Geometry.LineString>} A linestring geometry.
+ */
+ linestring: function(node, ring) {
+ /**
+ * Two coordinate variations to consider:
+ * 1) <gml:posList dimension="d">x0 y0 z0 x1 y1 z1</gml:posList>
+ * 2) <gml:coordinates>x0, y0, z0 x1, y1, z1</gml:coordinates>
+ */
+ var nodeList, coordString;
+ var coords = [];
+ var points = [];
- p = this.parseCoords(lineString);
- if (p.points) {
- geom = new OpenLayers.Geometry.LineString(p.points);
- // TBD Bounds only set for one of multiple geometries
+ // look for <gml:posList>
+ nodeList = this.getElementsByTagNameNS(node, this.gmlns, "posList");
+ if(nodeList.length > 0) {
+ coordString = nodeList[0].firstChild.nodeValue;
+ coordString = coordString.replace(this.regExes.trimSpace, "");
+ coords = coordString.split(this.regExes.splitSpace);
+ var dim = parseInt(nodeList[0].getAttribute("dimension"));
+ var j, x, y, z;
+ for(var i=0; i<coords.length/dim; ++i) {
+ j = i * dim;
+ x = coords[j];
+ y = coords[j+1];
+ z = (dim == 2) ? null : coords[j+2];
+ points.push(new OpenLayers.Geometry.Point(x, y, z));
+ }
}
- }
- // match Point
- else if (OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
- this.gmlns, "gml", "Point").length != 0) {
- var point = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,
- this.gmlns, "gml", "Point")[0];
- feature.fid = point.parentNode.parentNode.getAttribute('fid');
-
- p = this.parseCoords(point);
- if (p.points) {
- geom = p.points[0];
- // TBD Bounds only set for one of multiple geometries
+
+ // look for <gml:coordinates>
+ if(coords.length == 0) {
+ nodeList = this.getElementsByTagNameNS(node, this.gmlns,
+ "coordinates");
+ if(nodeList.length > 0) {
+ coordString = nodeList[0].firstChild.nodeValue;
+ coordString = coordString.replace(this.regExes.trimSpace,
+ "");
+ coordString = coordString.replace(this.regExes.trimComma,
+ ",");
+ var pointList = coordString.split(this.regExes.splitSpace);
+ for(var i=0; i<pointList.length; ++i) {
+ coords = pointList[i].split(",");
+ if(coords.length == 2) {
+ coords[2] = null;
+ }
+ points.push(new OpenLayers.Geometry.Point(coords[0],
+ coords[1],
+ coords[2]));
+ }
+ }
}
- }
+
+ var line = null;
+ if(points.length != 0) {
+ if(ring) {
+ line = new OpenLayers.Geometry.LinearRing(points);
+ } else {
+ line = new OpenLayers.Geometry.LineString(points);
+ }
+ }
+ return line;
+ },
- feature.geometry = geom;
- if (this.extractAttributes) {
- feature.attributes = this.parseAttributes(xmlNode);
- }
+ /**
+ * Method: parseGeometry.multilinestring
+ * Given a GML node representing a multilinestring geometry, create an
+ * OpenLayers multilinestring geometry.
+ *
+ * Parameters:
+ * node - {DOMElement} A GML node.
+ *
+ * Returns:
+ * {<OpenLayers.Geometry.MultiLineString>} A multilinestring geometry.
+ */
+ multilinestring: function(node) {
+ var nodeList = this.getElementsByTagNameNS(node, this.gmlns,
+ "LineString");
+ var components = [];
+ if(nodeList.length > 0) {
+ var line;
+ for(var i=0; i<nodeList.length; ++i) {
+ line = this.parseGeometry.linestring.apply(this,
+ [nodeList[i]]);
+ if(line) {
+ components.push(line);
+ }
+ }
+ }
+ return new OpenLayers.Geometry.MultiLineString(components);
+ },
- return feature;
- },
-
- /**
- * Method: parseAttributes
- * recursive function parse the attributes of a GML node.
- * Searches for any child nodes which aren't geometries,
- * and gets their value.
- *
- * Parameters:
- * xmlNode - {<DOMElement>}
- */
- parseAttributes: function(xmlNode) {
- var nodes = xmlNode.childNodes;
- var attributes = {};
- for(var i = 0; i < nodes.length; i++) {
- var name = nodes[i].nodeName;
- var value = OpenLayers.Util.getXmlNodeValue(nodes[i]);
- // Ignore Geometry attributes
- // match ".//gml:pos|.//gml:posList|.//gml:coordinates"
- if((name.search(":pos")!=-1)
- ||(name.search(":posList")!=-1)
- ||(name.search(":coordinates")!=-1)){
- continue;
+ /**
+ * Method: parseGeometry.polygon
+ * Given a GML node representing a polygon geometry, create an
+ * OpenLayers polygon geometry.
+ *
+ * Parameters:
+ * node - {DOMElement} A GML node.
+ *
+ * Returns:
+ * {<OpenLayers.Geometry.Polygon>} A polygon geometry.
+ */
+ polygon: function(node) {
+ var nodeList = this.getElementsByTagNameNS(node, this.gmlns,
+ "LinearRing");
+ var components = [];
+ if(nodeList.length > 0) {
+ // this assumes exterior ring first, inner rings after
+ var ring;
+ for(var i=0; i<nodeList.length; ++i) {
+ ring = this.parseGeometry.linestring.apply(this,
+ [nodeList[i], true]);
+ if(ring) {
+ components.push(ring);
+ }
+ }
}
-
- // Check for a leaf node
- if((nodes[i].childNodes.length == 1 && nodes[i].childNodes[0].nodeName == "#text")
- || (nodes[i].childNodes.length == 0 && nodes[i].nodeName!="#text")) {
- attributes[name] = value;
+ return new OpenLayers.Geometry.Polygon(components);
+ },
+
+ /**
+ * Method: parseGeometry.multipolygon
+ * Given a GML node representing a multipolygon geometry, create an
+ * OpenLayers multipolygon geometry.
+ *
+ * Parameters:
+ * node - {DOMElement} A GML node.
+ *
+ * Returns:
+ * {<OpenLayers.Geometry.MultiPolygon>} A multipolygon geometry.
+ */
+ multipolygon: function(node) {
+ var nodeList = this.getElementsByTagNameNS(node, this.gmlns,
+ "Polygon");
+ var components = [];
+ if(nodeList.length > 0) {
+ var polygon;
+ for(var i=0; i<nodeList.length; ++i) {
+ polygon = this.parseGeometry.polygon.apply(this,
+ [nodeList[i]]);
+ if(polygon) {
+ components.push(polygon);
+ }
+ }
}
- OpenLayers.Util.extend(attributes, this.parseAttributes(nodes[i]))
- }
- return attributes;
- },
-
- /**
- * Method: parsePolygonNode
- *
- * Parameters:
- * xmlNode - {XMLNode}
- *
- * Returns:
- * {<OpenLayers.Geometry.Polygon>} polygon geometry
- */
- parsePolygonNode: function(polygonNode) {
- var linearRings = OpenLayers.Ajax.getElementsByTagNameNS(polygonNode,
- this.gmlns, "gml", "LinearRing");
-
- var rings = [];
- var p;
- var polyBounds;
- for (var i = 0; i < linearRings.length; i++) {
- p = this.parseCoords(linearRings[i]);
- ring1 = new OpenLayers.Geometry.LinearRing(p.points);
- rings.push(ring1);
+ return new OpenLayers.Geometry.MultiPolygon(components);
}
-
- var poly = new OpenLayers.Geometry.Polygon(rings);
- return poly;
},
/**
- * Method: parseCoords
- * Extract Geographic coordinates from an XML node.
+ * Method: parseAttributes
*
* Parameters:
- * xmlNode - {<XMLNode>}
+ * node - {<DOMElement>}
*
* Returns:
- * An array of <OpenLayers.Geometry.Point> points.
+ * {Object} An attributes object.
*/
- parseCoords: function(xmlNode) {
- var x, y, left, bottom, right, top, bounds;
- var p = []; // return value = [points,bounds]
-
- if (xmlNode) {
- p.points = [];
-
- // match ".//gml:pos|.//gml:posList|.//gml:coordinates"
- // Note: GML2 coordinates are of the form:x y,x y,x y
- // GML2 can also be of the form <coord><x>1</x><y>2</y></coord>
- // GML3 posList is of the form:x y x y. OR x y z x y z.
-
- // GML3 Line or Polygon
- var coordNodes = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode, this.gmlns, "gml", "posList");
-
- // GML3 Point
- if (coordNodes.length == 0) {
- coordNodes = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode, this.gmlns, "gml", "pos");
- }
-
- // GML2
- if (coordNodes.length == 0) {
- coordNodes = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode, this.gmlns, "gml", "coordinates");
- }
-
- // TBD: Need to handle an array of coordNodes not just coordNodes[0]
-
- var coordString = OpenLayers.Util.getXmlNodeValue(coordNodes[0]);
-
- // Extract an array of Numbers from CoordString
- var nums = (coordString) ? coordString.split(/[, \n\t]+/) : [];
-
- // Remove elements caused by leading and trailing white space
- while (nums[0] == "")
- nums.shift();
-
- while (nums[nums.length-1] == "")
- nums.pop();
-
- for(var i = 0; i < nums.length; i = i + this.dim) {
- x = parseFloat(nums[i]);
- y = parseFloat(nums[i+1]);
- p.points.push(new OpenLayers.Geometry.Point(x, y));
+ parseAttributes: function(node) {
+ var attributes = {};
+ // assume attributes are children of the first type 1 child
+ var childNode = node.firstChild;
+ var children, i, child, grandchildren, grandchild, name, value;
+ while(childNode) {
+ if(childNode.nodeType == 1) {
+ // attributes are type 1 children with one type 3 child
+ children = childNode.childNodes;
+ for(i=0; i<children.length; ++i) {
+ child = children[i];
+ if(child.nodeType == 1) {
+ grandchildren = child.childNodes;
+ if(grandchildren.length == 1) {
+ grandchild = grandchildren[0];
+ if(grandchild.nodeType == 3) {
+ name = (child.prefix) ?
+ child.nodeName.split(":")[1] :
+ child.nodeName;
+ value = grandchild.nodeValue.replace(
+ this.regExes.trimSpace, "");
+ attributes[name] = value;
+ }
+ }
+ }
+ }
+ break;
}
+ childNode = childNode.nextSibling;
}
- return p;
+ return attributes;
},
/**
* APIMethod: write
- * Accept Feature Array, and return a string.
+ * Generate a GML document string given a list of features.
*
* Parameters:
- * features - Array({<OpenLayers.Feature.Vector>}> List of features to
- * serialize into a string.
+ * features - {Array(<OpenLayers.Feature.Vector>)} List of features to
+ * serialize into a string.
+ *
+ * Returns:
+ * {String} A string representing the GML document.
*/
- write: function(features) {
- var featureCollection = document.createElementNS("http://www.opengis.net/wfs", "wfs:" + this.collectionName);
- for (var i=0; i < features.length; i++) {
- featureCollection.appendChild(this.createFeatureXML(features[i]));
+ write: function(features) {
+ if(!(features instanceof Array)) {
+ features = [features];
}
- return featureCollection;
- },
-
+ var gml = this.createElementNS("http://www.opengis.net/wfs",
+ "wfs:" + this.collectionName);
+ for(var i=0; i<features.length; i++) {
+ gml.appendChild(this.createFeatureXML(features[i]));
+ }
+ return OpenLayers.Format.XML.prototype.write.apply(this, [gml]);
+ },
+
/**
* Method: createFeatureXML
- * Accept an OpenLayers.Feature.Vector, and build a geometry for it.
+ * Accept an OpenLayers.Feature.Vector, and build a GML node for it.
*
* Parameters:
- * feature - {<OpenLayers.Feature.Vector>}
+ * feature - {<OpenLayers.Feature.Vector>} The feature to be built as GML.
*
* Returns:
- * {DOMElement}
+ * {DOMElement} A node reprensting the feature in GML.
*/
createFeatureXML: function(feature) {
- var geometryNode = this.buildGeometryNode(feature.geometry);
- var geomContainer = document.createElementNS(this.featureNS, "feature:"+this.geometryName);
+ var geometry = feature.geometry;
+ var geometryNode = this.buildGeometryNode(geometry);
+ var geomContainer = this.createElementNS(this.featureNS,
+ this.featurePrefix + ":" +
+ this.geometryName);
geomContainer.appendChild(geometryNode);
- var featureNode = document.createElementNS(this.gmlns, "gml:" + this.featureName);
- var featureContainer = document.createElementNS(this.featureNS, "feature:"+this.layerName);
+ var featureNode = this.createElementNS(this.gmlns,
+ "gml:" + this.featureName);
+ var featureContainer = this.createElementNS(this.featureNS,
+ this.featurePrefix + ":" +
+ this.layerName);
+ var fid = feature.fid || feature.id;
+ featureContainer.setAttribute("fid", fid);
featureContainer.appendChild(geomContainer);
for(var attr in feature.attributes) {
- var attrText = document.createTextNode(feature.attributes[attr]);
- var nodename = attr;
- if (attr.search(":") != -1) {
- nodename = attr.split(":")[1];
- }
- var attrContainer = document.createElementNS(this.featureNS, "feature:"+nodename);
+ var attrText = this.createTextNode(feature.attributes[attr]);
+ var nodename = attr.substring(attr.lastIndexOf(":") + 1);
+ var attrContainer = this.createElementNS(this.featureNS,
+ this.featurePrefix + ":" +
+ nodename);
attrContainer.appendChild(attrText);
featureContainer.appendChild(attrContainer);
}
featureNode.appendChild(featureContainer);
return featureNode;
- },
+ },
/**
- * Method: buildGeometryNode
- * builds a GML file with a given geometry
- *
- * Parameters:
- * geometry - {<OpenLayers.Geometry>}
+ * APIMethod: buildGeometryNode
*/
buildGeometryNode: function(geometry) {
- // TBD test if geoserver can be given a Multi-geometry for a simple-geometry data store
- // ie if multipolygon can be sent for a polygon feature type
- var gml = "";
- // match MultiPolygon or Polygon
- if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPolygon"
- || geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") {
- gml = document.createElementNS(this.gmlns, 'gml:MultiPolygon');
-
- // TBD retrieve the srs from layer
- // srsName is non-standard, so not including it until it's right.
- //gml.setAttribute("srsName", "http://www.opengis.net/gml/srs/epsg.xml#4326");
-
- var polygonMember = document.createElementNS(this.gmlns, 'gml:polygonMember');
-
- var polygon = document.createElementNS(this.gmlns, 'gml:Polygon');
- var outerRing = document.createElementNS(this.gmlns, 'gml:outerBoundaryIs');
- var linearRing = document.createElementNS(this.gmlns, 'gml:LinearRing');
-
- // TBD manage polygons with holes
- linearRing.appendChild(this.buildCoordinatesNode(geometry.components[0]));
- outerRing.appendChild(linearRing);
- polygon.appendChild(outerRing);
- polygonMember.appendChild(polygon);
-
- gml.appendChild(polygonMember);
+ var className = geometry.CLASS_NAME;
+ var type = className.substring(className.lastIndexOf(".") + 1);
+ var builder = this.buildGeometry[type.toLowerCase()];
+ return builder.apply(this, [geometry]);
+ },
+
+ /**
+ * Property: buildGeometry
+ * Object containing methods to do the actual geometry node building
+ * based on geometry type.
+ */
+ buildGeometry: {
+ // TBD retrieve the srs from layer
+ // srsName is non-standard, so not including it until it's right.
+ // gml.setAttribute("srsName",
+ // "http://www.opengis.net/gml/srs/epsg.xml#4326");
+
+ /**
+ * Method: buildGeometry.point
+ * Given an OpenLayers point geometry, create a GML point.
+ *
+ * Parameters:
+ * geometry - {<OpenLayers.Geometry.Point>} A point geometry.
+ *
+ * Returns:
+ * {DOMElement} A GML point node.
+ */
+ point: function(geometry) {
+ var gml = this.createElementNS(this.gmlns, "gml:Point");
+ gml.appendChild(this.buildCoordinatesNode(geometry));
+ return gml;
+ },
+
+ /**
+ * Method: buildGeometry.multipoint
+ * Given an OpenLayers multipoint geometry, create a GML multipoint.
+ *
+ * Parameters:
+ * geometry - {<OpenLayers.Geometry.MultiPoint>} A multipoint geometry.
+ *
+ * Returns:
+ * {DOMElement} A GML multipoint node.
+ */
+ multipoint: function(geometry) {
+ var gml = this.createElementNS(this.gmlns, "gml:MultiPoint");
+ var points = geometry.components;
+ var pointMember, pointGeom;
+ for(var i=0; i<points.length; i++) {
+ pointMember = this.createElementNS(this.gmlns,
+ "gml:pointMember");
+ pointGeom = this.buildGeometry.point.apply(this,
+ [points[i]]);
+ pointMember.appendChild(pointGeom);
+ gml.appendChild(pointMember);
}
- // match MultiLineString or LineString
- else if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiLineString"
- || geometry.CLASS_NAME == "OpenLayers.Geometry.LineString") {
- gml = document.createElementNS(this.gmlns, 'gml:MultiLineString');
-
- // TBD retrieve the srs from layer
- // srsName is non-standard, so not including it until it's right.
- //gml.setAttribute("srsName", "http://www.opengis.net/gml/srs/epsg.xml#4326");
-
- var lineStringMember = document.createElementNS(this.gmlns, 'gml:lineStringMember');
-
- var lineString = document.createElementNS(this.gmlns, 'gml:LineString');
-
- lineString.appendChild(this.buildCoordinatesNode(geometry));
- lineStringMember.appendChild(lineString);
-
- gml.appendChild(lineStringMember);
- }
- // match MultiPoint or Point
- else if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point" ||
- geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPoint") {
- // TBD retrieve the srs from layer
- // srsName is non-standard, so not including it until it's right.
- //gml.setAttribute("srsName", "http://www.opengis.net/gml/srs/epsg.xml#4326");
-
- gml = document.createElementNS(this.gmlns, 'gml:MultiPoint');
- var parts = "";
- if (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPoint") {
- parts = geometry.components;
- } else {
- parts = [geometry];
- }
-
- for (var i = 0; i < parts.length; i++) {
- var pointMember = document.createElementNS(this.gmlns, 'gml:pointMember');
- var point = document.createElementNS(this.gmlns, 'gml:Point');
- point.appendChild(this.buildCoordinatesNode(parts[i]));
- pointMember.appendChild(point);
- gml.appendChild(pointMember);
- }
+ return gml;
+ },
+
+ /**
+ * Method: buildGeometry.linestring
+ * Given an OpenLayers linestring geometry, create a GML linestring.
+ *
+ * Parameters:
+ * geometry - {<OpenLayers.Geometry.LineString>} A linestring geometry.
+ *
+ * Returns:
+ * {DOMElement} A GML linestring node.
+ */
+ linestring: function(geometry) {
+ var gml = this.createElementNS(this.gmlns, "gml:LineString");
+ gml.appendChild(this.buildCoordinatesNode(geometry));
+ return gml;
+ },
+
+ /**
+ * Method: buildGeometry.multilinestring
+ * Given an OpenLayers multilinestring geometry, create a GML
+ * multilinestring.
+ *
+ * Parameters:
+ * geometry - {<OpenLayers.Geometry.MultiLineString>} A multilinestring
+ * geometry.
+ *
+ * Returns:
+ * {DOMElement} A GML multilinestring node.
+ */
+ multilinestring: function(geometry) {
+ var gml = this.createElementNS(this.gmlns, "gml:MultiLineString");
+ var lines = geometry.components;
+ var lineMember, lineGeom;
+ for(var i=0; i<lines.length; ++i) {
+ lineMember = this.createElementNS(this.gmlns,
+ "gml:lineStringMember");
+ lineGeom = this.buildGeometry.linestring.apply(this,
+ [lines[i]]);
+ lineMember.appendChild(lineGeom);
+ gml.appendChild(lineMember);
+ }
+ return gml;
+ },
+
+ /**
+ * Method: buildGeometry.linearring
+ * Given an OpenLayers linearring geometry, create a GML linearring.
+ *
+ * Parameters:
+ * geometry - {<OpenLayers.Geometry.LinearRing>} A linearring geometry.
+ *
+ * Returns:
+ * {DOMElement} A GML linearring node.
+ */
+ linearring: function(geometry) {
+ var gml = this.createElementNS(this.gmlns, "gml:LinearRing");
+ gml.appendChild(this.buildCoordinatesNode(geometry));
+ return gml;
+ },
+
+ /**
+ * Method: buildGeometry.polygon
+ * Given an OpenLayers polygon geometry, create a GML polygon.
+ *
+ * Parameters:
+ * geometry - {<OpenLayers.Geometry.Polygon>} A polygon geometry.
+ *
+ * Returns:
+ * {DOMElement} A GML polygon node.
+ */
+ polygon: function(geometry) {
+ var gml = this.createElementNS(this.gmlns, "gml:Polygon");
+ var rings = geometry.components;
+ var ringMember, ringGeom, type;
+ for(var i=0; i<rings.length; ++i) {
+ type = (i==0) ? "outerBoundaryIs" : "innerBoundaryIs";
+ ringMember = this.createElementNS(this.gmlns,
+ "gml:" + type);
+ ringGeom = this.buildGeometry.linearring.apply(this,
+ [rings[i]]);
+ ringMember.appendChild(ringGeom);
+ gml.appendChild(ringMember);
+ }
+ return gml;
+ },
+
+ /**
+ * Method: buildGeometry.multipolygon
+ * Given an OpenLayers multipolygon geometry, create a GML multipolygon.
+ *
+ * Parameters:
+ * geometry - {<OpenLayers.Geometry.MultiPolygon>} A multipolygon
+ * geometry.
+ *
+ * Returns:
+ * {DOMElement} A GML multipolygon node.
+ */
+ multipolygon: function(geometry) {
+ var gml = this.createElementNS(this.gmlns, "gml:MultiPolygon");
+ var polys = geometry.components;
+ var polyMember, polyGeom;
+ for(var i=0; i<polys.length; ++i) {
+ polyMember = this.createElementNS(this.gmlns,
+ "gml:polygonMember");
+ polyGeom = this.buildGeometry.polygon.apply(this,
+ [polys[i]]);
+ polyMember.appendChild(polyGeom);
+ gml.appendChild(polyMember);
+ }
+ return gml;
}
- return gml;
},
-
+
/**
* Method: buildCoordinates
* builds the coordinates XmlNode
@@ -479,30 +713,23 @@
* {XmlNode} created xmlNode
*/
buildCoordinatesNode: function(geometry) {
- var coordinatesNode = document.createElementNS(this.gmlns, "gml:coordinates");
+ var coordinatesNode = this.createElementNS(this.gmlns,
+ "gml:coordinates");
coordinatesNode.setAttribute("decimal", ".");
coordinatesNode.setAttribute("cs", ",");
coordinatesNode.setAttribute("ts", " ");
- var points = null;
- if (geometry.components) {
- points = geometry.components;
+ var points = (geometry.components) ? geometry.components : [geometry];
+ var parts = [];
+ for(var i=0; i<points.length; i++) {
+ parts.push(points[i].x + "," + points[i].y);
}
- var path = "";
- if (points) {
- for (var i = 0; i < points.length; i++) {
- path += points[i].x + "," + points[i].y + " ";
- }
- } else {
- path += geometry.x + "," + geometry.y + " ";
- }
-
- var txtNode = document.createTextNode(path);
+ var txtNode = this.createTextNode(parts.join(" "));
coordinatesNode.appendChild(txtNode);
return coordinatesNode;
},
CLASS_NAME: "OpenLayers.Format.GML"
-});
+});
Modified: trunk/openlayers/tests/Format/test_GML.html
===================================================================
--- trunk/openlayers/tests/Format/test_GML.html 2007-09-10 20:24:27 UTC (rev 4205)
+++ trunk/openlayers/tests/Format/test_GML.html 2007-09-10 22:02:18 UTC (rev 4206)
@@ -3,7 +3,158 @@
<script src="../../lib/OpenLayers.js"></script>
<script type="text/javascript">
- var test_content = '<wfs:FeatureCollection' +
+ function test_Format_GML_constructor(t) {
+ t.plan(4);
+
+ var options = {'foo': 'bar'};
+ var format = new OpenLayers.Format.GML(options);
+ t.ok(format instanceof OpenLayers.Format.GML,
+ "new OpenLayers.Format.GML returns object" );
+ t.eq(format.foo, "bar", "constructor sets options correctly");
+ t.eq(typeof format.read, "function", "format has a read function");
+ t.eq(typeof format.write, "function", "format has a write function");
+ }
+ function test_Format_GML_getFid(t) {
+ t.plan(2);
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(test_content[1]);
+ t.eq(data[0].fid, '221', 'fid on polygons set correctly (with whitespace)');
+ t.eq(data[1].fid, '8', 'fid on linestrings set correctly with whitespace');
+ }
+ function test_Format_GML_no_clobber(t) {
+ t.plan(1);
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(test_content[1]);
+ t.eq(window.i, undefined,
+ "i is undefined in window scope after reading.");
+ }
+ function test_Format_GML_read_3d(t) {
+ t.plan(2);
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(test_content[0]);
+ t.eq(data[0].geometry.getBounds().toBBOX(), "-1254041.389712,250906.951598,-634517.119991,762236.29408", "Reading 3d content returns geometry with correct bounds (no 0,0)");
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.Polygon", "Reading 3d content returns polygon geometry");
+ }
+ function test_Format_GML_write_geoms(t) {
+ t.plan(5);
+ var parser = new OpenLayers.Format.GML();
+
+ var point = shell_start + serialize_geoms['point'] + shell_end;
+ data = parser.read(point);
+ var output = parser.write(data);
+ t.eq(output, point, "Point geometry round trips correctly.");
+
+ var linestring = shell_start + serialize_geoms['linestring'] + shell_end;
+ data = parser.read(linestring);
+ var output = parser.write(data);
+ t.eq(output, linestring, "Line geometry round trips correctly.");
+
+ var polygon = shell_start + serialize_geoms['polygon'] + shell_end;
+ data = parser.read(polygon);
+ var output = parser.write(data);
+ t.eq(output, polygon, "Poly geometry round trips correctly.");
+
+ var multipoint = shell_start + serialize_geoms['multipoint'] + shell_end;
+ data = parser.read(multipoint);
+ var output = parser.write(data);
+ t.eq(output, multipoint, "MultiPoint geometry round trips correctly.");
+
+ var multilinestring = shell_start + serialize_geoms['multilinestring'] + shell_end;
+ data = parser.read(multilinestring);
+ var output = parser.write(data);
+ t.eq(output, multilinestring, "MultiLine geometry round trips correctly.");
+ }
+ function test_Format_GML_read_point_geom(t) {
+ t.plan(3);
+
+ var point = shell_start + geoms['point'] + shell_end;
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(point);
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.Point", "Point GML returns correct classname");
+ t.eq(data[0].geometry.x, 1, "x coord correct");
+ t.eq(data[0].geometry.y, 2, "y coord correct");
+ }
+ function test_Format_GML_read_linestring_geom(t) {
+ t.plan(5);
+
+ var line = shell_start + geoms['linestring'] + shell_end;
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(line);
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.LineString", "LineString GML returns correct classname");
+ t.eq(data[0].geometry.components[0].x, 1, "first x coord correct");
+ t.eq(data[0].geometry.components[0].y, 2, "first y coord correct");
+ t.eq(data[0].geometry.components[1].x, 4, "second x coord correct");
+ t.eq(data[0].geometry.components[1].y, 5, "second y coord correct");
+ }
+ function test_Format_GML_read_polygon_geom(t) {
+ t.plan(7);
+
+ var polygon = shell_start + geoms['polygon'] + shell_end;
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(polygon);
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.Polygon", "Polygon GML returns correct classname");
+ t.eq(data[0].geometry.components[0].components[0].x, 1, "first x coord correct");
+ t.eq(data[0].geometry.components[0].components[0].y, 2, "first y coord correct");
+ t.eq(data[0].geometry.components[0].components[1].x, 4, "second x coord correct");
+ t.eq(data[0].geometry.components[0].components[1].y, 5, "second y coord correct");
+ t.eq(data[0].geometry.components[0].components.length, 4, "coords length correct");
+ t.eq(data[0].geometry.components.length, 1, "rings length correct");
+ }
+ function test_Format_GML_read_multipoint_geom(t) {
+ t.plan(6);
+
+ var multipoint = shell_start + geoms['multipoint'] + shell_end;
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(multipoint);
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.MultiPoint", "MultiPoint GML returns correct classname");
+ t.eq(data[0].geometry.components[0].x, 1, "x coord correct");
+ t.eq(data[0].geometry.components[0].y, 2, "y coord correct");
+ t.eq(data[0].geometry.components.length, 2, "length correct");
+ t.eq(data[0].geometry.components[1].x, 4, "x coord correct");
+ t.eq(data[0].geometry.components[1].y, 5, "y coord correct");
+ }
+ function test_Format_GML_read_multilinestring_geom(t) {
+ t.plan(6);
+
+ var multilinestring = shell_start + geoms['multilinestring'] + shell_end;
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(multilinestring);
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.MultiLineString", "MultiLineString GML returns correct classname");
+ t.eq(data[0].geometry.components[0].components[0].x, 1, "x coord correct");
+ t.eq(data[0].geometry.components[0].components[0].y, 2, "y coord correct");
+ t.eq(data[0].geometry.components[0].components.length, 2, "length correct");
+ t.eq(data[0].geometry.components[0].components[1].x, 4, "x coord correct");
+ t.eq(data[0].geometry.components[0].components[1].y, 5, "y coord correct");
+
+ }
+ function test_Format_GML_read_polygon_with_holes_geom(t) {
+ t.plan(12);
+
+ var polygon_with_holes = shell_start + geoms['polygon_with_holes'] + shell_end;
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(polygon_with_holes);
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.Polygon", "Polygon GML returns correct classname");
+ t.eq(data[0].geometry.components[0].components[0].x, 1, "first x coord correct");
+ t.eq(data[0].geometry.components[0].components[0].y, 2, "first y coord correct");
+ t.eq(data[0].geometry.components[0].components[1].x, 4, "second x coord correct");
+ t.eq(data[0].geometry.components[0].components[1].y, 5, "second y coord correct");
+ t.eq(data[0].geometry.components[0].components.length, 4, "coords length correct");
+ t.eq(data[0].geometry.components[1].components[0].x, 11, "first x coord correct");
+ t.eq(data[0].geometry.components[1].components[0].y, 12, "first y coord correct");
+ t.eq(data[0].geometry.components[1].components[1].x, 14, "second x coord correct");
+ t.eq(data[0].geometry.components[1].components[1].y, 15, "second y coord correct");
+ t.eq(data[0].geometry.components[1].components.length, 4, "coords length correct");
+ t.eq(data[0].geometry.components.length, 2, "rings length correct");
+ }
+ function test_Format_GML_read_attributes(t) {
+ t.plan(1);
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(test_content[0]);
+ t.eq(data[0].attributes['NAME'], "WY", "Simple Attribute data is read correctly.");
+ }
+
+ var test_content = ['<?xml version="1.0" encoding="utf-8" ?>\n<ogr:FeatureCollection\n xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n xsi:schemaLocation="http://ogr.maptools.org/ testoutput.xsd"\n xmlns:ogr="http://ogr.maptools.org/"\n xmlns:gml="http://www.opengis.net/gml">\n <gml:boundedBy>\n <gml:Box>\n <gml:coord><gml:X>-1254041.389711702</gml:X><gml:Y>250906.9515983529</gml:Y></gml:coord>\n <gml:coord><gml:X>-634517.1199908922</gml:X><gml:Y>762236.2940800377</gml:Y></gml:coord>\n </gml:Box>\n </gml:boundedBy> \n <gml:featureMember>\n <ogr:states fid="F0">\n <ogr:geometryProperty><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-634517.11999089224,691849.77929356066,0 -653761.64509297756,471181.53429472551,0 -673343.60852865304,250906.9515983529,0 -1088825.734430399,299284.85108220269,0 -1254041.3897117018,324729.27754874947,0 -1235750.4212498858,434167.33911316615,0 -1190777.7803201093,704392.96327195223,0 -1181607.835811228,762236.29408003774,0 -634517.11999089224,691849.77929356066,0</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>\n <ogr:NAME>WY</ogr:NAME>\n </ogr:states>\n </gml:featureMember>\n</ogr:FeatureCollection>\n',
+ '<wfs:FeatureCollection' +
' xmlns:fs="http://example.com/featureserver"' +
' xmlns:wfs="http://www.opengis.net/wfs"' +
' xmlns:gml="http://www.opengis.net/gml"' +
@@ -28,37 +179,27 @@
'</gml:featureMember> ' +
' <gml:featureMember><fs:scribble fid="8"> <fs:geometry> <gml:Point><gml:coordinates>-81.38671875,27.0703125</gml:coordinates></gml:Point> </fs:geometry> ' +
' <fs:down>south</fs:down><fs:title>Florida</fs:title> </fs:scribble></gml:featureMember>' +
- '</wfs:FeatureCollection>';
-
- function test_Format_GML_constructor(t) {
- t.plan(4);
-
- var options = {'foo': 'bar'};
- var format = new OpenLayers.Format.GML(options);
- t.ok(format instanceof OpenLayers.Format.GML,
- "new OpenLayers.Format.GML returns object" );
- t.eq(format.foo, "bar", "constructor sets options correctly");
- t.eq(typeof format.read, "function", "format has a read function");
- t.eq(typeof format.write, "function", "format has a write function");
- }
-
- function test_Format_GML_getFid(t) {
- t.plan(2);
-
- var parser = new OpenLayers.Format.GML();
- data = parser.read(test_content);
- t.eq(data[0].fid, '221', 'fid on polygons set correctly (with whitespace)');
- t.eq(data[1].fid, '8', 'fid on linestrings set correctly with whitespace');
- }
-
- function test_Format_GML_no_clobber(t) {
- t.plan(1);
- var parser = new OpenLayers.Format.GML();
- data = parser.read(test_content);
- t.eq(window.i, undefined,
- "i is undefined in window scope after reading.");
- }
-
+ '</wfs:FeatureCollection>'
+ ];
+
+ var shell_start = '<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs"><gml:featureMember xmlns:gml="http://www.opengis.net/gml"><feature:features xmlns:feature="http://mapserver.gis.umn.edu/mapserver" fid="221"><feature:geometry>';
+ var shell_end = '</feature:geometry></feature:features></gml:featureMember></wfs:FeatureCollection>';
+ var serialize_geoms = {
+ 'point': '<gml:Point><gml:coordinates decimal="." cs="," ts=" ">1,2</gml:coordinates></gml:Point>',
+ 'linestring': '<gml:LineString><gml:coordinates decimal="." cs="," ts=" ">1,2 4,5</gml:coordinates></gml:LineString>',
+ 'polygon': '<gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates decimal="." cs="," ts=" ">1,2 4,5 3,6 1,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon>',
+ 'multipoint': '<gml:MultiPoint><gml:pointMember><gml:Point><gml:coordinates decimal="." cs="," ts=" ">1,2</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates decimal="." cs="," ts=" ">4,5</gml:coordinates></gml:Point></gml:pointMember></gml:MultiPoint>',
+ 'multilinestring': '<gml:MultiLineString><gml:lineStringMember><gml:LineString><gml:coordinates decimal="." cs="," ts=" ">1,2 4,5</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates decimal="." cs="," ts=" ">11,12 14,15</gml:coordinates></gml:LineString></gml:lineStringMember></gml:MultiLineString>'
+ };
+ var geoms = {
+ 'point': '<gml:Point><gml:coordinates>1,2,3</gml:coordinates></gml:Point>',
+ 'linestring': '<gml:LineString><gml:coordinates>1,2,3 4,5,6</gml:coordinates></gml:LineString>',
+ 'polygon': '<gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>1,2 4,5 3,6 1,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon>',
+ 'polygon_with_holes': '<gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>1,2 4,5 3,6 1,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:coordinates>11,12 14,15 13,16 11,12</gml:coordinates></gml:LinearRing></gml:innerBoundaryIs></gml:Polygon>',
+ 'multipoint': '<gml:MultiPoint><gml:Point><gml:coordinates>1,2,3</gml:coordinates></gml:Point><gml:Point><gml:coordinates>4,5,6</gml:coordinates></gml:Point></gml:MultiPoint>',
+ 'multilinestring': '<gml:MultiLineString><gml:LineString><gml:coordinates>1,2,3 4,5,6</gml:coordinates></gml:LineString><gml:LineString><gml:coordinates>11,12,13 14,15,16</gml:coordinates></gml:LineString></gml:MultiLineString>' // ,
+ // 'multipolygon_with_holes': '<gml:MultiPolygon><gml:Polygon><gml:outerBoundaryIs>1,2 4,5 3,6 1,2</gml:outerBoundaryIs><gml:innerBoundaryIs>11,12 14,15 13,16 11,12</gml:innerBoundaryIs></gml:Polygon><gml:Polygon><gml:outerBoundaryIs>101,102 104,105 103,106 101,102</gml:outerBoundaryIs><gml:innerBoundaryIs>111,112 114,115 113,116 111,112</gml:innerBoundaryIs></gml:Polygon></gml:MultiPolygon>'
+ };
</script>
</head>
<body>
More information about the Commits
mailing list