Add GPX-parsing format, courtesy Edgemaster. (Closes #1272)
git-svn-id: http://svn.openlayers.org/trunk/openlayers@7590 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
@@ -197,6 +197,7 @@
|
||||
"OpenLayers/Format/WFS.js",
|
||||
"OpenLayers/Format/WKT.js",
|
||||
"OpenLayers/Format/OSM.js",
|
||||
"OpenLayers/Format/GPX.js",
|
||||
"OpenLayers/Format/SLD.js",
|
||||
"OpenLayers/Format/SLD/v1.js",
|
||||
"OpenLayers/Format/SLD/v1_0_0.js",
|
||||
|
||||
175
lib/OpenLayers/Format/GPX.js
Normal file
175
lib/OpenLayers/Format/GPX.js
Normal file
@@ -0,0 +1,175 @@
|
||||
/* Copyright (c) 2006-2007 MetaCarta, Inc., published under a modified BSD license.
|
||||
* See http://svn.openlayers.org/trunk/openlayers/repository-license.txt
|
||||
* for the full text of the license. */
|
||||
|
||||
/**
|
||||
* @requires OpenLayers/Format/XML.js
|
||||
* @requires OpenLayers/Feature/Vector.js
|
||||
* @requires OpenLayers/Geometry/Point.js
|
||||
* @requires OpenLayers/Geometry/LineString.js
|
||||
*
|
||||
* Class: OpenLayers.Format.GPX
|
||||
* Read/write GPX parser. Create a new instance with the
|
||||
* <OpenLayers.Format.GPX> constructor.
|
||||
*
|
||||
* Inherits from:
|
||||
* - <OpenLayers.Format.XML>
|
||||
*/
|
||||
OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
|
||||
/**
|
||||
* APIProperty: extractWaypoints
|
||||
* {Boolean} Extract waypoints from GPX. (default: true)
|
||||
*/
|
||||
extractWaypoints: true,
|
||||
|
||||
/**
|
||||
* APIProperty: extractTracks
|
||||
* {Boolean} Extract tracks from GPX. (default: true)
|
||||
*/
|
||||
extractTracks: true,
|
||||
|
||||
/**
|
||||
* APIProperty: extractRoutes
|
||||
* {Boolean} Extract routes from GPX. (default: true)
|
||||
*/
|
||||
extractRoutes: true,
|
||||
|
||||
/**
|
||||
* APIProperty: extractAttributes
|
||||
* {Boolean} Extract feature attributes from GPX. (default: true)
|
||||
* NOTE: Attributes as part of extensions to the GPX standard may not
|
||||
* be extracted.
|
||||
*/
|
||||
extractAttributes: true,
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Format.GPX
|
||||
* Create a new parser for GPX.
|
||||
*
|
||||
* 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]);
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: read
|
||||
* Return a list of features from a GPX doc
|
||||
*
|
||||
* Parameters:
|
||||
* doc - {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]);
|
||||
}
|
||||
var features = [];
|
||||
|
||||
if(this.extractWaypoints) {
|
||||
var waypoints = doc.getElementsByTagName("wpt");
|
||||
for (var l = 0, len = waypoints.length; l < len; l++) {
|
||||
var attrs = {};
|
||||
if(this.extractAttributes) {
|
||||
attrs = this.parseAttributes(waypoints[l]);
|
||||
}
|
||||
var wpt = new OpenLayers.Geometry.Point(waypoints[l].getAttribute("lon"), waypoints[l].getAttribute("lat"));
|
||||
features.push(new OpenLayers.Feature.Vector(wpt, attrs));
|
||||
}
|
||||
}
|
||||
|
||||
if(this.extractTracks) {
|
||||
var tracks = doc.getElementsByTagName("trk");
|
||||
for (var i = 0, len = tracks.length; i < tracks.length; i++) {
|
||||
// Attributes are only in trk nodes, not trkseg nodes
|
||||
var attrs = {}
|
||||
if(this.extractAttributes) {
|
||||
attrs = this.parseAttributes(tracks[i]);
|
||||
}
|
||||
|
||||
var segs = this.getElementsByTagNameNS(tracks[i], tracks[i].namespaceURI, "trkseg");
|
||||
for (var j = 0, seglen = segs.length; j < seglen; j++) {
|
||||
// We don't yet support extraction of trkpt attributes
|
||||
// All trksegs of a trk get that trk's attributes
|
||||
var track = this.extractSegment(segs[j], "trkpt");
|
||||
features.push(new OpenLayers.Feature.Vector(track, attrs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(this.extractRoutes) {
|
||||
var routes = doc.getElementsByTagName("rte");
|
||||
for (var k = 0; k < routes.length; k++) {
|
||||
var attrs = {}
|
||||
if(this.extractAttributes) {
|
||||
attrs = this.parseAttributes(routes[k]);
|
||||
}
|
||||
var route = this.extractSegment(routes[k], "rtept");
|
||||
features.push(new OpenLayers.Feature.Vector(route, attrs));
|
||||
}
|
||||
}
|
||||
|
||||
if (this.internalProjection && this.externalProjection) {
|
||||
for (var g = 0, featLength = features.length; g < featLength; g++) {
|
||||
features[g].geometry.transform(this.externalProjection,
|
||||
this.internalProjection);
|
||||
}
|
||||
}
|
||||
|
||||
return features;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: extractSegment
|
||||
*
|
||||
* Parameters:
|
||||
* segment - {<DOMElement>} a trkseg or rte node to parse
|
||||
* segmentType - {String} nodeName of waypoints that form the line
|
||||
*
|
||||
* Returns:
|
||||
* {<OpenLayers.Geometry.LineString>} A linestring geometry
|
||||
*/
|
||||
extractSegment: function(segment, segmentType) {
|
||||
var points = this.getElementsByTagNameNS(segment, segment.namespaceURI, segmentType);
|
||||
var point_features = [];
|
||||
for (var i = 0, len = points.length; i < len; i++) {
|
||||
point_features.push(new OpenLayers.Geometry.Point(points[i].getAttribute("lon"), points[i].getAttribute("lat")));
|
||||
}
|
||||
return new OpenLayers.Geometry.LineString(point_features);
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: parseAttributes
|
||||
*
|
||||
* Parameters:
|
||||
* node - {<DOMElement>}
|
||||
*
|
||||
* Returns:
|
||||
* {Object} An attributes object.
|
||||
*/
|
||||
parseAttributes: function(node) {
|
||||
// node is either a wpt, trk or rte
|
||||
// attributes are children of the form <attr>value</attr>
|
||||
var attributes = {};
|
||||
var attrNode = node.firstChild;
|
||||
while(attrNode) {
|
||||
if(attrNode.nodeType == 1) {
|
||||
var value = attrNode.firstChild;
|
||||
if(value.nodeType == 3 || value.nodeType == 4) {
|
||||
name = (attrNode.prefix) ?
|
||||
attrNode.nodeName.split(":")[1] :
|
||||
attrNode.nodeName;
|
||||
attributes[name] = value.nodeValue;
|
||||
}
|
||||
}
|
||||
attrNode = attrNode.nextSibling;
|
||||
}
|
||||
return attributes;
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Format.GPX"
|
||||
});
|
||||
39
tests/Format/GPX.html
Normal file
39
tests/Format/GPX.html
Normal file
@@ -0,0 +1,39 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="../../lib/OpenLayers.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
var gpx_data = '<?xml version="1.0" encoding="ISO-8859-1"?><gpx version="1.1" creator="Memory-Map 5.1.3.715 http://www.memory-map.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.topografix.com/GPX/1/1" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"><wpt lat="51.3697845627" lon="-0.1853562259"><name>Mark</name><sym><![CDATA[Flag]]></sym><type><![CDATA[Marks]]></type></wpt><rte><name><![CDATA[Route8]]></name><type><![CDATA[Route]]></type><rtept lat="51.3761803674" lon="-0.1829991904"><name><![CDATA[WP0801]]></name><sym><![CDATA[Dot]]></sym><type><![CDATA[Waypoints]]></type></rtept><rtept lat="51.3697894659" lon="-0.1758887005"><name><![CDATA[WP0802]]></name><sym><![CDATA[Dot]]></sym><type><![CDATA[Waypoints]]></type></rtept><rtept lat="51.3639790884" lon="-0.1833202965"><name><![CDATA[WP0803]]></name><sym><![CDATA[Dot]]></sym><type><![CDATA[Waypoints]]></type></rtept><rtept lat="51.3567607069" lon="-0.1751119509"><name><![CDATA[WP0804]]></name><sym><![CDATA[Dot]]></sym><type><![CDATA[Waypoints]]></type></rtept></rte><trk><name><![CDATA[Track]]></name><type><![CDATA[Track]]></type><trkseg><trkpt lat="51.3768216433" lon="-0.1721292044"></trkpt><trkpt lat="51.3708337670" lon="-0.1649230916"></trkpt><trkpt lat="51.3644368725" lon="-0.1736741378"></trkpt><trkpt lat="51.3576354272" lon="-0.1662595250"></trkpt></trkseg></trk></gpx>';
|
||||
|
||||
function test_Format_GPX_constructor(t) {
|
||||
t.plan(4);
|
||||
|
||||
var options = {'foo': 'bar'};
|
||||
var format = new OpenLayers.Format.GPX(options);
|
||||
t.ok(format instanceof OpenLayers.Format.GPX,
|
||||
"new OpenLayers.Format.GPX 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_GPX_read(t) {
|
||||
t.plan(4);
|
||||
var f = new OpenLayers.Format.GPX();
|
||||
var features = f.read(gpx_data);
|
||||
t.eq(features.length, 3, "Number of features read is correct");
|
||||
t.eq(features[0].geometry.toString(), "POINT(-0.1853562259 51.3697845627)", "waypoint feature correctly created");
|
||||
t.eq(features[1].geometry.toString(), "LINESTRING(-0.1721292044 51.3768216433,-0.1649230916 51.370833767,-0.1736741378 51.3644368725,-0.166259525 51.3576354272)", "track feature correctly created");
|
||||
t.eq(features[2].geometry.toString(), "LINESTRING(-0.1829991904 51.3761803674,-0.1758887005 51.3697894659,-0.1833202965 51.3639790884,-0.1751119509 51.3567607069)", "route feature correctly created");
|
||||
}
|
||||
function test_format_GPX_read_attributes(t) {
|
||||
t.plan(2);
|
||||
var f = new OpenLayers.Format.GPX();
|
||||
var features = f.read(gpx_data);
|
||||
t.eq(features[0].attributes['name'], "Mark", "Text attribute node read correctly.");
|
||||
t.eq(features[0].attributes['sym'], "Flag", "CDATA attribute node read correctly.");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
@@ -26,6 +26,7 @@
|
||||
<li>Format/GeoJSON.html</li>
|
||||
<li>Format/GeoRSS.html</li>
|
||||
<li>Format/GML.html</li>
|
||||
<li>Format/GPX.html</li>
|
||||
<li>Format/JSON.html</li>
|
||||
<li>Format/OSM.html</li>
|
||||
<li>Format/KML.html</li>
|
||||
|
||||
Reference in New Issue
Block a user