[OpenLayers-Commits] r12370 - in trunk/openlayers: examples lib/OpenLayers/Format tests/Format

commits-20090109 at openlayers.org commits-20090109 at openlayers.org
Thu Sep 15 08:27:58 EDT 2011


Author: pgiraud
Date: 2011-09-15 05:27:56 -0700 (Thu, 15 Sep 2011)
New Revision: 12370

Modified:
   trunk/openlayers/examples/vector-formats.html
   trunk/openlayers/lib/OpenLayers/Format/GPX.js
   trunk/openlayers/tests/Format/GPX.html
Log:
Adding support for write in the GPX format, r=marcjansen, (Closes #3495)

Modified: trunk/openlayers/examples/vector-formats.html
===================================================================
--- trunk/openlayers/examples/vector-formats.html	2011-09-14 19:44:29 UTC (rev 12369)
+++ trunk/openlayers/examples/vector-formats.html	2011-09-15 12:27:56 UTC (rev 12370)
@@ -86,7 +86,8 @@
                 gml2: new OpenLayers.Format.GML.v2(gmlOptionsIn),
                 gml3: new OpenLayers.Format.GML.v3(gmlOptionsIn),
                 kml: new OpenLayers.Format.KML(kmlOptionsIn),
-                atom: new OpenLayers.Format.Atom(in_options)
+                atom: new OpenLayers.Format.Atom(in_options),
+                gpx: new OpenLayers.Format.GPX(in_options)
               }, 
               'out': {
                 wkt: new OpenLayers.Format.WKT(out_options),
@@ -95,7 +96,8 @@
                 gml2: new OpenLayers.Format.GML.v2(gmlOptionsOut),
                 gml3: new OpenLayers.Format.GML.v3(gmlOptionsOut),
                 kml: new OpenLayers.Format.KML(out_options),
-                atom: new OpenLayers.Format.Atom(out_options)
+                atom: new OpenLayers.Format.Atom(out_options),
+                gpx: new OpenLayers.Format.GPX(out_options)
               } 
             };
         }
@@ -199,6 +201,7 @@
                 <option value="gml2">GML (v2)</option>
                 <option value="gml3">GML (v3)</option>
                 <option value="wkt">Well-Known Text (WKT)</option>
+                <option value="gpx">GPX</option>
             </select>
             &nbsp;
             <label for="prettyPrint">Pretty print</label>

Modified: trunk/openlayers/lib/OpenLayers/Format/GPX.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Format/GPX.js	2011-09-14 19:44:29 UTC (rev 12369)
+++ trunk/openlayers/lib/OpenLayers/Format/GPX.js	2011-09-15 12:27:56 UTC (rev 12370)
@@ -20,6 +20,16 @@
  *  - <OpenLayers.Format.XML>
  */
 OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
+    
+
+    /** 
+     * APIProperty: defaultDesc
+     * {String} Default description for the waypoints/tracks in the case
+     *     where the feature has no "description" attribute.
+     *     Default is "No description available".
+     */
+    defaultDesc: "No description available",
+
    /**
     * APIProperty: extractWaypoints
     * {Boolean} Extract waypoints from GPX. (default: true)
@@ -45,6 +55,13 @@
      *     be extracted.
      */
     extractAttributes: true,
+
+    /**
+     * APIProperty: gpxns
+     * {String} GPX namespace to use. Defaults to
+     *   "http://www.topografix.com/GPX/1/1"
+     */
+    gpxns: "http://www.topografix.com/GPX/1/1",
     
     /**
      * Constructor: OpenLayers.Format.GPX
@@ -179,6 +196,170 @@
         }
         return attributes;
     },
+
+    /**
+     * APIMethod: write
+     * Accepts Feature Collection, and returns a string. 
+     * 
+     * Parameters: 
+     * features - {Array(<OpenLayers.Feature.Vector>)} List of features to serialize into a string.
+     * metadata - {Object} A key/value pairs object to build a metadata node to
+     *      add to the gpx. Supported keys are 'name', 'desc', 'author'.
+     */
+    write: function(features, metadata) {
+        var gpx;
+        features = OpenLayers.Util.isArray(features) ?
+            features : [features];
+        gpx = this.createElementNS(this.gpxns, "gpx");
+
+        for(var i=0, len=features.length; i<len; i++) {
+            gpx.appendChild(this.buildFeatureNode(features[i]));
+        }
+        if (metadata && typeof metadata == 'object') {
+            gpx.appendChild(this.buildMetadataNode(metadata));
+        }
+        return OpenLayers.Format.XML.prototype.write.apply(this, [gpx]);
+    },
+
+    /**
+     * Method: buildMetadataNode
+     * Creates a "metadata" node.
+     *
+     * Returns:
+     * {DOMElement}
+     */
+    buildMetadataNode: function(metadata) {
+        var types = ['name', 'desc', 'author'],
+            node = this.createElementNS(this.gpxns, 'metadata');
+        for (var i=0; i < types.length; i++) {
+            var type = types[i];
+            if (metadata[type]) {
+                var n = this.createElementNS(this.gpxns, type);
+                n.appendChild(this.createTextNode(metadata[type]));
+                node.appendChild(n);
+            }
+        }
+        return node;
+    },
+
+    /**
+     * Method: buildFeatureNode
+     * Accepts an <OpenLayers.Feature.Vector>, and builds a node for it.
+     * 
+     * Parameters:
+     * feature - {<OpenLayers.Feature.Vector>}
+     *
+     * Returns:
+     * {DOMElement} - The created node, either a 'wpt' or a 'trk'.
+     */
+    buildFeatureNode: function(feature) {
+        var geometry = feature.geometry;
+            geometry = geometry.clone();
+        if (this.internalProjection && this.externalProjection) {
+            geometry.transform(this.internalProjection, 
+                               this.externalProjection);
+        }
+        if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
+            var wpt = this.buildWptNode(feature);
+            return wpt;
+        } else {
+            var trkNode = this.createElementNS(this.gpxns, "trk");
+            this.appendAttributesNode(trkNode, feature);
+            var trkSegNodes = this.buildTrkSegNode(geometry);
+            trkSegNodes = OpenLayers.Util.isArray(trkSegNodes) ?
+                trkSegNodes : [trkSegNodes];
+            for (var i = 0, len = trkSegNodes.length; i < len; i++) {
+                trkNode.appendChild(trkSegNodes[i]);
+            }
+            return trkNode;
+        }
+    },
+
+    /**
+     * Method: buildTrkSegNode
+     * Builds trkseg node(s) given a geometry
+     *
+     * Parameters:
+     * trknode
+     * geometry - {OpenLayers.Geometry}
+     */
+    buildTrkSegNode: function(geometry) {
+        var node,
+            i,
+            len,
+            point,
+            nodes;
+        if (geometry.CLASS_NAME == "OpenLayers.Geometry.LineString" ||
+            geometry.CLASS_NAME == "OpenLayers.Geometry.LinearRing") {
+            node = this.createElementNS(this.gpxns, "trkseg");
+            for (i = 0, len=geometry.components.length; i < len; i++) {
+                point = geometry.components[i];
+                node.appendChild(this.buildTrkPtNode(point));
+            }
+            return node;
+        } else {
+            nodes = [];
+            for (i = 0, len = geometry.components.length; i < len; i++) {
+                nodes.push(this.buildTrkSegNode(geometry.components[i]));
+            }
+            return nodes;
+        }
+    },
     
+    /**
+     * Method: buildTrkPtNode
+     * Builds a trkpt node given a point 
+     *
+     * Parameters:
+     * line - {OpenLayers.Geometry.Point}
+     *
+     * Returns:
+     * {DOMElement} A trkpt node
+     */
+    buildTrkPtNode: function(point) {
+        var node = this.createElementNS(this.gpxns, "trkpt");
+        node.setAttribute("lon", point.x);
+        node.setAttribute("lat", point.y);
+        return node;
+    },
+
+    /**
+     * Method: buildWptNode
+     * Builds a wpt node given a point
+     *
+     * Parameters:
+     * feature - {OpenLayers.Feature.Vector}
+     *
+     * Returns:
+     * {DOMElement} A wpt node
+     */
+    buildWptNode: function(feature) {
+        var node = this.createElementNS(this.gpxns, "wpt");
+        node.setAttribute("lon", feature.geometry.x);
+        node.setAttribute("lat", feature.geometry.y);
+        this.appendAttributesNode(node, feature);
+        return node;
+    },
+
+    /**
+     * Method: appendAttributesNode
+     * Adds some attributes node.
+     *
+     * Parameters:
+     * node - {DOMElement} the node to append the attribute nodes to.
+     * feature - {OpenLayers.Feature.Vector}
+     */
+    appendAttributesNode: function(node, feature) {
+        var name = this.createElementNS(this.gpxns, 'name');
+        name.appendChild(this.createTextNode(
+            feature.attributes.name || feature.id));
+        node.appendChild(name);
+        var desc = this.createElementNS(this.gpxns, 'desc');
+        desc.appendChild(this.createTextNode(
+            feature.attributes.description || this.defaultDesc));
+        node.appendChild(desc);
+        // TBD - deal with remaining (non name/description) attributes.
+    },
+
     CLASS_NAME: "OpenLayers.Format.GPX"
 });

Modified: trunk/openlayers/tests/Format/GPX.html
===================================================================
--- trunk/openlayers/tests/Format/GPX.html	2011-09-14 19:44:29 UTC (rev 12369)
+++ trunk/openlayers/tests/Format/GPX.html	2011-09-15 12:27:56 UTC (rev 12370)
@@ -34,6 +34,85 @@
         t.eq(features[2].attributes['name'], "Mark", "Text attribute node read correctly.");
         t.eq(features[2].attributes['sym'], "Flag", "CDATA attribute node read correctly.");
     }
+    function test_Format_GPX_serialize_points(t) { 
+        t.plan(1);
+
+        var parser = new OpenLayers.Format.GPX();
+
+        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);  
+        var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68); 
+        var features = [
+            new OpenLayers.Feature.Vector(point, {name: 'foo', description: 'bar'}),
+            new OpenLayers.Feature.Vector(point2, {name: 'foo', description: 'bar'})
+        ];
+        var data = parser.write(features);
+        t.xml_eq(data, '<?xml version="1.0" encoding="ISO-8859-1"?><gpx xmlns="http://www.topografix.com/GPX/1/1"><wpt lon="-111.04" lat="45.68"><name>foo</name><desc>bar</desc></wpt><wpt lon="-112.04" lat="45.68"><name>foo</name><desc>bar</desc></wpt></gpx>', 'GPX serializes points correctly');
+    }
+    function test_Format_GPX_serialize_line(t) { 
+        t.plan(1);
+
+        var parser = new OpenLayers.Format.GPX();
+
+        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);  
+        var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68); 
+        var line = new OpenLayers.Geometry.LineString([point, point2]);
+        var f = new OpenLayers.Feature.Vector(line, {name: 'foo', description: 'bar'});
+        var data = parser.write(f);
+        t.xml_eq(data, '<?xml version="1.0" encoding="ISO-8859-1"?><gpx xmlns="http://www.topografix.com/GPX/1/1"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.04" lat="45.68"/><trkpt lon="-112.04" lat="45.68"/></trkseg></trk></gpx>', 'GPX serializes line correctly');
+    }
+    function test_Format_GPX_serialize_lines(t) { 
+        t.plan(1);
+
+        var parser = new OpenLayers.Format.GPX();
+
+        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);  
+        var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68); 
+        var line = new OpenLayers.Geometry.LineString([point, point2]);
+        var point3 = new OpenLayers.Geometry.Point(1, 2);  
+        var point4 = new OpenLayers.Geometry.Point(3, 4); 
+        var line2 = new OpenLayers.Geometry.LineString([point3, point4]);
+        var f = new OpenLayers.Feature.Vector(line, {name: 'foo', description: 'bar'});
+        var f2 = new OpenLayers.Feature.Vector(line2, {name: 'dude', description: 'truite'});
+        var data = parser.write([f, f2]);
+        t.xml_eq(data, '<?xml version="1.0" encoding="ISO-8859-1"?><gpx xmlns="http://www.topografix.com/GPX/1/1"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.04" lat="45.68"/><trkpt lon="-112.04" lat="45.68"/></trkseg></trk><trk><name>dude</name><desc>truite</desc><trkseg><trkpt lon="1" lat="2"/><trkpt lon="3" lat="4"/></trkseg></trk></gpx>', 'GPX serializes lines correctly');
+    }
+    function test_Format_GPX_serialize_multiline(t) { 
+        t.plan(1);
+
+        var parser = new OpenLayers.Format.GPX();
+
+        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);  
+        var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68); 
+        var line = new OpenLayers.Geometry.LineString([point, point2]);
+        var point3 = new OpenLayers.Geometry.Point(1, 2);  
+        var point4 = new OpenLayers.Geometry.Point(3, 4); 
+        var line2 = new OpenLayers.Geometry.LineString([point3, point4]);
+        var multiline = new OpenLayers.Geometry.MultiLineString([line, line2]);
+        var f = new OpenLayers.Feature.Vector(multiline, {name: 'foo', description: 'bar'});
+        var data = parser.write([f]);
+        t.xml_eq(data, '<?xml version="1.0" encoding="ISO-8859-1"?><gpx xmlns="http://www.topografix.com/GPX/1/1"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.04" lat="45.68"/><trkpt lon="-112.04" lat="45.68"/></trkseg><trkseg><trkpt lon="1" lat="2"/><trkpt lon="3" lat="4"/></trkseg></trk></gpx>', 'GPX serializes multiline correctly');
+    }
+    function test_Format_GPX_serialize_polygon(t) { 
+        t.plan(1);
+
+        var parser = new OpenLayers.Format.GPX();
+
+        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);  
+        var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68); 
+        var linearRing = new OpenLayers.Geometry.LinearRing([point, point2, point.clone()]);
+        var polygon = new OpenLayers.Geometry.Polygon([linearRing]);
+        var f = new OpenLayers.Feature.Vector(polygon, {name: 'foo', description: 'bar'});
+        var data = parser.write([f]);
+        t.xml_eq(data, '<?xml version="1.0" encoding="ISO-8859-1"?><gpx xmlns="http://www.topografix.com/GPX/1/1"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.04" lat="45.68"/><trkpt lon="-112.04" lat="45.68"/><trkpt lon="-111.04" lat="45.68"/></trkseg></trk></gpx>', 'GPX serializes polygon correctly');
+    }
+    function test_Format_GPX_serialize_metadata(t) { 
+        t.plan(1);
+
+        var parser = new OpenLayers.Format.GPX();
+
+        var data = parser.write([], {name: 'foo', desc: 'bar'});
+        t.xml_eq(data, '<?xml version="1.0" encoding="ISO-8859-1"?><gpx xmlns="http://www.topografix.com/GPX/1/1"><metadata><name>foo</name><desc>bar</desc></metadata></gpx>', 'GPX serializes metadata correctly');
+    }
     </script> 
 </head> 
 <body> 



More information about the Commits mailing list