diff --git a/examples/data/gpx/yahoo.xml b/examples/data/gpx/yahoo.xml new file mode 100644 index 0000000000..ccaa9bc5cc --- /dev/null +++ b/examples/data/gpx/yahoo.xml @@ -0,0 +1,1073 @@ + + + + + + 44.586548 + + 5066 + + Crossing + + + + 57.607200 + + 5067 + + Dot + + + + 44.826904 + + 5096 + + Dot + + + + 50.594727 + + 5142 + + Dot + + + + 127.711200 + + 5156 + + Dot + + + + 96.926400 + + 5224 + + Dot + + + + 82.600800 + + 5229 + + Dot + + + + 82.905600 + + 5237 + + Dot + + + + 66.696655 + + 5254 + + Dot + + + + 74.627442 + + 5258 + + Dot + + + + 65.254761 + + 5264 + + Dot + + + + 77.419200 + + 526708 + + Dot + + + + 74.676000 + + 526750 + + Dot + + + + 78.713135 + + 527614 + + Dot + + + + 78.713135 + + 527631 + + Dot + + + + 68.275200 + + 5278 + + Dot + + + + 64.008000 + + 5289 + + Dot + + + + 52.997925 + + 5374FIRE + + Dot + + + + 56.388000 + + 5376 + + Dot + + + + 56.388000 + + 6006 + + Dot + + + + 46.028564 + + 6006BLUE + + Dot + + + + 37.616943 + + 6014MEADOW + + Dot + + + + 56.388000 + + 6029 + + Dot + + + + 50.292000 + + 6053 + + Dot + + + + 25.603200 + + 6066 + + Dot + + + + 34.442400 + + 6067 + + Dot + + + + 30.480000 + + 6071 + + Dot + + + + 15.240000 + + 6073 + + Dot + + + + 37.795200 + + 6084 + + Dot + + + + 64.008000 + + 6130 + + Dot + + + + 64.008000 + + 6131 + + Dot + + + + 62.788800 + + 6153 + + Dot + + + + 55.473600 + + 6171 + + Dot + + + + 62.484000 + + 6176 + + Dot + + + + 62.179200 + + 6177 + + Dot + + + + 69.799200 + + 6272 + + Dot + + + + 73.152000 + + 6272 + + Dot + + + + 70.104000 + + 6278 + + Dot + + + + 57.564209 + + 6280 + + Dot + + + + 66.696655 + + 6283 + + Dot + + + + 72.945191 + + 6289 + + Dot + + + + 72.847200 + + 6297 + + Dot + + + + 53.644800 + + 6328 + + Dot + + + + 43.891200 + + 6354 + + Dot + + + + 48.768000 + + 635722 + + Dot + + + + 49.072800 + + 635783 + + Dot + + + + 62.484000 + + 6373 + + Dot + + + + 3.962400 + + 6634 + + Dot + + + + 13.411200 + + 6979 + + Dot + + + + 34.012085 + + 6997 + + Dot + + + + 87.782400 + + BEAR HILL + BEAR HILL TOWER + + Tall Tower + + + + 23.469600 + + BELLEVUE + BELLEVUE + + Parking Area + + + + 43.384766 + + 6016 + + Trailhead + + + + 89.916000 + + 5236BRIDGE + + Bridge + + + + 55.473600 + + 5376BRIDGE + + Bridge + + + + 52.730400 + + 6181CROSS + + Crossing + + + + 45.110400 + + 6042CROSS + + Crossing + + + + DARKHOLLPO + + Fishing Area + + + 56.083200 + + 6121DEAD + + Danger Area + + + + 117.043200 + + 5179DEAD + + Danger Area + + + + 69.494400 + + 5299DEAD + + Danger Area + + + + 56.997600 + + 5376DEAD + + Danger Area + + + + 46.939200 + + 6353DEAD + + Danger Area + + + + 61.264800 + + 6155DEAD + + Danger Area + + + + 110.947200 + + GATE14 + + Truck Stop + + + + 77.724000 + + GATE16 + + Truck Stop + + + + 65.836800 + + GATE17 + + Truck Stop + + + + 57.302400 + + GATE19 + + Truck Stop + + + + 49.377600 + + GATE21 + + Truck Stop + + + + 81.076800 + + GATE24 + + Truck Stop + + + + 21.515015 + + GATE5 + + Truck Stop + + + + 26.561890 + + GATE6 + + Trailhead + + + + 32.004000 + + 6077LOGS + + Amusement Park + + + + 119.809082 + + 5148NANEPA + + Trailhead + + + + 73.761600 + + 5267OBSTAC + + Amusement Park + + + + 45.307495 + + PANTHRCAVE + + Tunnel + + + + 77.992066 + + 5252PURPLE + + Summit + + + + 67.970400 + + 5287WATER + + Swimming Area + + + + 81.076800 + + 5239ROAD + + Truck Stop + + + + 67.360800 + + 5278ROAD + + Truck Stop + + + + 53.949600 + + 5058ROAD + ROAD CROSSING + + Dot + + + + 69.799200 + + SHEEPFOLD + + Parking Area + + + + 64.008000 + + SOAPBOX + + Cemetery + + + + 64.533692 + + 5376STREAM + + Bridge + + + + 61.649902 + + 5144SUMMIT + + Summit + + + + 67.360800 + + 5150TANK + WATER TANK + + Museum + + + + BELLEVUE + + 1 + + 23.469600 + + BELLEVUE + BELLEVUE + + Parking Area + + + + 26.561890 + + GATE6 + + Trailhead + + + + 45.307495 + + PANTHRCAVE + + Tunnel + + + + 37.616943 + + 6014MEADOW + + Dot + + + + 56.388000 + + 6006 + + Dot + + + + 46.028564 + + 6006BLUE + + Dot + + + + 44.826904 + + 5096 + + Dot + + + + 44.586548 + + 5066 + + Crossing + + + + 57.607200 + + 5067 + + Dot + + + + 53.949600 + + 5058ROAD + ROAD CROSSING + + Dot + + + + 67.360800 + + 5150TANK + WATER TANK + + Museum + + + + 50.594727 + + 5142 + + Dot + + + + 61.649902 + + 5144SUMMIT + + Summit + + + + 127.711200 + + 5156 + + Dot + + + + 119.809082 + + 5148NANEPA + + Trailhead + + + + 74.627442 + + 5258 + + Dot + + + + 77.992066 + + 5252PURPLE + + Summit + + + + 78.713135 + + 527631 + + Dot + + + + 78.713135 + + 527614 + + Dot + + + + 73.761600 + + 5267OBSTAC + + Amusement Park + + + + 68.275200 + + 5278 + + Dot + + + + 64.008000 + + 5289 + + Dot + + + + 52.997925 + + 5374FIRE + + Dot + + + + 56.388000 + + 5376 + + Dot + + + + 64.533692 + + 5376STREAM + + Bridge + + + + 53.644800 + + 6328 + + Dot + + + + 48.768000 + + 635722 + + Dot + + + + 49.072800 + + 635783 + + Dot + + + + 62.484000 + + 6373 + + Dot + + + + 87.782400 + + BEAR HILL + BEAR HILL TOWER + + Tall Tower + + + + 72.945191 + + 6289 + + Dot + + + + 72.847200 + + 6297 + + Dot + + + + 66.696655 + + 6283 + + Dot + + + + 57.564209 + + 6280 + + Dot + + + + 62.179200 + + 6177 + + Dot + + + + 62.484000 + + 6176 + + Dot + + + + 62.788800 + + 6153 + + Dot + + + + 55.473600 + + 6171 + + Dot + + + + 64.008000 + + 6131 + + Dot + + + + 64.008000 + + 6130 + + Dot + + + + 56.388000 + + 6029 + + Dot + + + + 56.388000 + + 6006 + + Dot + + + + 37.616943 + + 6014MEADOW + + Dot + + + + 45.307495 + + PANTHRCAVE + + Tunnel + + + + 26.561890 + + GATE6 + + Trailhead + + + + 23.469600 + + BELLEVUE + BELLEVUE + + Parking Area + + + + + diff --git a/examples/gpx.html b/examples/gpx.html new file mode 100644 index 0000000000..1d557850f0 --- /dev/null +++ b/examples/gpx.html @@ -0,0 +1,55 @@ + + + + + + + + + + GPX example + + + + + +
+ +
+
+
+
+
+ +
+ +
+

GPX example

+

Example of using the GPX parser.

+
+

See the gpx.js source to see how this is done.

+
+
GPX
+
+ +
+ +
+ + + + + + diff --git a/examples/gpx.js b/examples/gpx.js new file mode 100644 index 0000000000..771fa6becf --- /dev/null +++ b/examples/gpx.js @@ -0,0 +1,49 @@ +goog.require('ol.Collection'); +goog.require('ol.Map'); +goog.require('ol.RendererHint'); +goog.require('ol.View2D'); +goog.require('ol.layer.TileLayer'); +goog.require('ol.layer.Vector'); +goog.require('ol.parser.GPX'); +goog.require('ol.projection'); +goog.require('ol.source.OSM'); +goog.require('ol.source.Vector'); + +var raster = new ol.layer.TileLayer({ + source: new ol.source.OSM() +}); + +var vector = new ol.layer.Vector({ + source: new ol.source.Vector({ + projection: ol.projection.get('EPSG:4326') + }) +}); + +var map = new ol.Map({ + layers: new ol.Collection([raster, vector]), + renderer: ol.RendererHint.CANVAS, + target: 'map', + view: new ol.View2D({ + center: [-7916461.9312699, 5226343.9091441], + zoom: 11 + }) +}); + +var gpx = new ol.parser.GPX(); + +var url = 'data/gpx/yahoo.xml'; +var xhr = new XMLHttpRequest(); +xhr.open('GET', url, true); + + +/** + * onload handler for the XHR request. + */ +xhr.onload = function() { + if (xhr.status == 200) { + // this is silly to have to tell the layer the destination projection + var projection = map.getView().getProjection(); + vector.parseFeatures(xhr.responseText, gpx, projection); + } +}; +xhr.send(); diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index 3c8d01753e..02269b07e0 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -340,6 +340,31 @@ * geometries. Default is `false´. This only applies to GML version 3. */ +/** + * @typedef {Object} ol.parser.GPXOptions + * @property {string|undefined} creator The creator attribute to be added to + * the written GPX files. Defaults to `OpenLayers´. + * @property {string|undefined} defaultDesc Default description for the + * waypoints/tracks in the case where the feature has no 'description' + * attribute. Default is 'No description available'. + * @property {boolean|undefined} extractAttributes Should we extract attributes + * from the GPX? Default is `true´. + * @property {boolean|undefined} extractWaypoints Extract waypoints from GPX. + * Default is `true´. + * @property {boolean|undefined} extractTracks Extract tracks from GPX. + * Default is `true´. + * @property {boolean|undefined} extractRoutes Extract routes from GPX. + * Default is `true´. + */ + +/** + * @typedef {Object} ol.parser.GPXWriteOptions + * @property {Array.|ol.Feature} features The features to write + * out. + * @property {Object|undefined} metadata Metadata key/value pair with keys: + * name, desc and author. + */ + /** * @typedef {Object} ol.source.BingMapsOptions * @property {string|undefined} culture Culture. diff --git a/src/ol/parser/gpx.exports b/src/ol/parser/gpx.exports new file mode 100644 index 0000000000..57d874bb80 --- /dev/null +++ b/src/ol/parser/gpx.exports @@ -0,0 +1,3 @@ +@exportSymbol ol.parser.GPX +@exportProperty ol.parser.GPX.prototype.read +@exportProperty ol.parser.GPX.prototype.write diff --git a/src/ol/parser/gpx.js b/src/ol/parser/gpx.js new file mode 100644 index 0000000000..de2b26cbbd --- /dev/null +++ b/src/ol/parser/gpx.js @@ -0,0 +1,308 @@ +goog.provide('ol.parser.GPX'); + +goog.require('goog.dom.xml'); +goog.require('ol.Feature'); +goog.require('ol.geom.GeometryType'); +goog.require('ol.geom.LineString'); +goog.require('ol.geom.MultiLineString'); +goog.require('ol.geom.Point'); +goog.require('ol.geom.Polygon'); +goog.require('ol.parser.DomFeatureParser'); +goog.require('ol.parser.ObjectFeatureParser'); +goog.require('ol.parser.ReadFeaturesOptions'); +goog.require('ol.parser.StringFeatureParser'); +goog.require('ol.parser.XML'); + + + +/** + * @constructor + * @implements {ol.parser.DomFeatureParser} + * @implements {ol.parser.StringFeatureParser} + * @implements {ol.parser.ObjectFeatureParser} + * @param {ol.parser.GPXOptions=} opt_options Optional configuration object. + * @extends {ol.parser.XML} + */ +ol.parser.GPX = function(opt_options) { + var options = /** @type {ol.parser.GPXOptions} */ + (goog.isDef(opt_options) ? opt_options : {}); + this.extractAttributes = goog.isDef(options.extractAttributes) ? + options.extractAttributes : true; + this.extractWaypoints = goog.isDef(options.extractWaypoints) ? + options.extractWaypoints : true; + this.extractTracks = goog.isDef(options.extractTracks) ? + options.extractTracks : true; + this.extractRoutes = goog.isDef(options.extractRoutes) ? + options.extractRoutes : true; + this.creator = goog.isDef(options.creator) ? + options.creator : 'OpenLayers'; + this.defaultDesc = goog.isDef(options.defaultDesc) ? + options.defaultDesc : 'No description available'; + this.defaultNamespaceURI = 'http://www.topografix.com/GPX/1/1'; + this.schemaLocation = 'http://www.topografix.com/GPX/1/1 ' + + 'http://www.topografix.com/GPX/1/1/gpx.xsd'; + this.readers = { + 'http://www.topografix.com/GPX/1/1': { + 'gpx': function(node, obj) { + if (!goog.isDef(obj.features)) { + obj.features = []; + } + this.readChildNodes(node, obj); + }, + 'wpt': function(node, obj) { + if (this.extractWaypoints) { + var properties = {}; + var coordinates = [parseFloat(node.getAttribute('lon')), + parseFloat(node.getAttribute('lat'))]; + this.readChildNodes(node, properties); + var feature = new ol.Feature(properties); + var sharedVertices; + if (this.readFeaturesOptions_) { + var callback = this.readFeaturesOptions_.callback; + if (callback) { + sharedVertices = callback(feature, ol.geom.GeometryType.POINT); + } + } + var geometry = new ol.geom.Point(coordinates, sharedVertices); + feature.setGeometry(geometry); + obj.features.push(feature); + } + }, + 'rte': function(node, obj) { + if (this.extractRoutes || obj.force) { + var type = ol.geom.GeometryType.LINESTRING; + var container = { + properties: {}, + geometry: { + type: type, + coordinates: [] + } + }; + this.readChildNodes(node, container); + var feature = new ol.Feature(container.properties); + var sharedVertices; + if (this.readFeaturesOptions_) { + var callback = this.readFeaturesOptions_.callback; + if (callback) { + sharedVertices = callback(feature, type); + } + } + var geometry = new ol.geom.LineString(container.geometry.coordinates, + sharedVertices); + feature.setGeometry(geometry); + obj.features.push(feature); + } + }, + 'rtept': function(node, container) { + var coordinate = [parseFloat(node.getAttribute('lon')), + parseFloat(node.getAttribute('lat'))]; + container.geometry.coordinates.push(coordinate); + }, + 'trk': function(node, obj) { + if (this.extractTracks) { + var readers = this.readers[this.defaultNamespaceURI]; + obj.force = true; + readers['rte'].apply(this, arguments); + } + }, + 'trkseg': function(node, container) { + this.readChildNodes(node, container); + }, + 'trkpt': function(node, container) { + var readers = this.readers[this.defaultNamespaceURI]; + readers['rtept'].apply(this, arguments); + }, + '*': function(node, obj) { + if (this.extractAttributes === true) { + var len = node.childNodes.length; + if ((len === 1 || len === 2) && (node.firstChild.nodeType === 3 || + node.firstChild.nodeType === 4)) { + var readers = this.readers[this.defaultNamespaceURI]; + readers['_attribute'].apply(this, arguments); + } + } + }, + '_attribute': function(node, obj) { + var local = node.localName || node.nodeName.split(':').pop(); + var value = this.getChildValue(node); + if (obj.properties) { + obj.properties[local] = value.replace(this.regExes.trimSpace, ''); + } + } + } + }; + // create an alias for GXP 1.0 + this.readers['http://www.topografix.com/GPX/1/0'] = + this.readers[this.defaultNamespaceURI]; + this.writers = { + 'http://www.topografix.com/GPX/1/1': { + '_feature': function(feature) { + var geom = feature.getGeometry(); + if (geom instanceof ol.geom.Point) { + return this.writeNode('wpt', feature); + } else if ((geom instanceof ol.geom.LineString) || + (geom instanceof ol.geom.MultiLineString) || + (geom instanceof ol.geom.Polygon)) { + return this.writeNode('trk', feature); + } + }, + 'wpt': function(feature) { + var node = this.createElementNS('wpt'); + var geom = feature.getGeometry(); + var coordinates = geom.getCoordinates(); + node.setAttribute('lon', coordinates[0]); + node.setAttribute('lat', coordinates[1]); + var attributes = feature.getAttributes(); + var name = attributes['name'] || goog.getUid(feature).toString(); + this.writeNode('name', name, undefined, node); + var desc = attributes['description'] || this.defaultDesc; + this.writeNode('desc', desc, undefined, node); + return node; + }, + 'trk': function(feature) { + var attributes = feature.getAttributes(); + var node = this.createElementNS('trk'); + var name = attributes['name'] || goog.getUid(feature).toString(); + this.writeNode('name', name, undefined, node); + var desc = attributes['description'] || this.defaultDesc; + this.writeNode('desc', desc, undefined, node); + var geom = feature.getGeometry(); + var i, ii; + if (geom instanceof ol.geom.LineString) { + this.writeNode('trkseg', feature.getGeometry(), undefined, node); + } else if (geom instanceof ol.geom.MultiLineString) { + for (i = 0, ii = geom.components.length; i < ii; ++i) { + this.writeNode('trkseg', geom.components[i], undefined, node); + } + } else if (geom instanceof ol.geom.Polygon) { + for (i = 0, ii = geom.rings.length; i < ii; ++i) { + this.writeNode('trkseg', geom.rings[i], undefined, node); + } + } + return node; + }, + 'trkseg': function(geometry) { + var node = this.createElementNS('trkseg'); + var coordinates = geometry.getCoordinates(); + for (var i = 0, ii = coordinates.length; i < ii; ++i) { + this.writeNode('trkpt', coordinates[i], undefined, node); + } + return node; + }, + 'trkpt': function(coord) { + var node = this.createElementNS('trkpt'); + node.setAttribute('lon', coord[0]); + node.setAttribute('lat', coord[1]); + return node; + }, + 'metadata': function(metadata) { + var node = this.createElementNS('metadata'); + if (goog.isDef(metadata['name'])) { + this.writeNode('name', metadata['name'], undefined, node); + } + if (goog.isDef(metadata['desc'])) { + this.writeNode('desc', metadata['desc'], undefined, node); + } + if (goog.isDef(metadata['author'])) { + this.writeNode('author', metadata['author'], undefined, node); + } + return node; + }, + 'name': function(name) { + var node = this.createElementNS('name'); + node.appendChild(this.createTextNode(name)); + return node; + }, + 'desc': function(desc) { + var node = this.createElementNS('desc'); + node.appendChild(this.createTextNode(desc)); + return node; + }, + 'author': function(author) { + var node = this.createElementNS('author'); + node.appendChild(this.createTextNode(author)); + return node; + } + } + }; + goog.base(this); +}; +goog.inherits(ol.parser.GPX, ol.parser.XML); + + +/** + * @param {string|Document|Element|Object} data Data to read. + * @return {Object} An object representing the document. + */ +ol.parser.GPX.prototype.read = function(data) { + if (goog.isString(data)) { + data = goog.dom.xml.loadXml(data); + } + if (data && data.nodeType == 9) { + data = data.documentElement; + } + var obj = {}; + this.readNode(data, obj); + return obj; +}; + + +/** + * Parse a GPX document provided as a string. + * @param {string} str GPX document. + * @param {ol.parser.ReadFeaturesOptions=} opt_options Reader options. + * @return {Array.} Array of features. + */ +ol.parser.GPX.prototype.readFeaturesFromString = + function(str, opt_options) { + this.readFeaturesOptions_ = opt_options; + return this.read(str).features; +}; + + +/** + * Parse a GPX document provided as a DOM structure. + * @param {Element|Document} node Document or element node. + * @param {ol.parser.ReadFeaturesOptions=} opt_options Feature reading options. + * @return {Array.} Array of features. + */ +ol.parser.GPX.prototype.readFeaturesFromNode = + function(node, opt_options) { + this.readFeaturesOptions_ = opt_options; + return this.read(node).features; +}; + + +/** + * @param {Object} obj Object representing features. + * @param {ol.parser.ReadFeaturesOptions=} opt_options Feature reading options. + * @return {Array.} Array of features. + */ +ol.parser.GPX.prototype.readFeaturesFromObject = + function(obj, opt_options) { + this.readFeaturesOptions_ = opt_options; + return this.read(obj).features; +}; + + +/** + * @param {ol.parser.GPXWriteOptions} obj Object structure to write out + * as GPX. + * @return {string} An string representing the GPX document. + */ +ol.parser.GPX.prototype.write = function(obj) { + var features = goog.isArray(obj.features) ? obj.features : [obj.features]; + var root = this.createElementNS('gpx'); + root.setAttribute('version', '1.1'); + root.setAttribute('creator', this.creator); + this.setAttributeNS( + root, 'http://www.w3.org/2001/XMLSchema-instance', + 'xsi:schemaLocation', this.schemaLocation); + if (goog.isDef(obj.metadata)) { + this.writeNode('metadata', obj.metadata, undefined, root); + } + for (var i = 0, ii = features.length; i < ii; i++) { + this.writeNode('_feature', features[i], undefined, root); + } + return this.serialize(root); +}; diff --git a/test/spec/ol/parser/gpx.test.js b/test/spec/ol/parser/gpx.test.js new file mode 100644 index 0000000000..91bda4ed78 --- /dev/null +++ b/test/spec/ol/parser/gpx.test.js @@ -0,0 +1,129 @@ +goog.provide('ol.test.parser.gpx'); + +describe('ol.parser.gpx', function() { + + var parser = new ol.parser.GPX(); + + describe('Test GPX parser', function() { + it('Read works correctly', function() { + var url = 'spec/ol/parser/gpx/data.xml'; + afterLoadXml(url, function(xml) { + var obj = parser.read(xml); + expect(obj.features.length).to.eql(3); + // waypoint feature + var feature = obj.features[0]; + var geom = feature.getGeometry(); + expect(geom.getType()).to.eql(ol.geom.GeometryType.POINT); + expect(geom.getCoordinates()).to.eql([-0.1853562259, 51.3697845627]); + // route feature + feature = obj.features[1]; + geom = feature.getGeometry(); + var attributes = feature.getAttributes(); + expect(geom.getType()).to.eql(ol.geom.GeometryType.LINESTRING); + expect(geom.getCoordinates()).to.eql([[-0.1829991904, 51.3761803674], + [-0.1758887005, 51.3697894659], [-0.1833202965, 51.3639790884], + [-0.1751119509, 51.3567607069]]); + expect(attributes['name']).to.eql('Route8'); + expect(attributes['type']).to.eql('Route'); + // track feature + feature = obj.features[2]; + geom = feature.getGeometry(); + attributes = feature.getAttributes(); + expect(geom.getType()).to.eql(ol.geom.GeometryType.LINESTRING); + expect(geom.getCoordinates()).to.eql([[-0.1721292044, 51.3768216433], + [-0.1649230916, 51.370833767], [-0.1736741378, 51.3644368725], + [-0.166259525, 51.3576354272]]); + expect(attributes['name']).to.eql('Track'); + expect(attributes['type']).to.eql('Track'); + }); + }); + it('Write works correctly for points', function() { + var feature1 = new ol.Feature({name: 'foo', description: 'bar'}); + feature1.setGeometry(new ol.geom.Point([-111.04, 45.68])); + var feature2 = new ol.Feature({name: 'foo', description: 'bar'}); + feature2.setGeometry(new ol.geom.Point([-112.04, 45.68])); + var output = parser.write({features: [feature1, feature2]}); + var expected = 'foo' + + 'bar' + + 'foobar'; + expect(goog.dom.xml.loadXml(expected)).to.xmleql( + goog.dom.xml.loadXml(output)); + }); + it('Write works correctly for lines', function() { + var feature1 = new ol.Feature({name: 'foo', description: 'bar'}); + feature1.setGeometry(new ol.geom.LineString([[-111.04, 45.68], + [-112.04, 45.68]])); + var feature2 = new ol.Feature({name: 'dude', description: 'truite'}); + feature2.setGeometry(new ol.geom.LineString([[1, 2], [3, 4]])); + var output = parser.write({features: [feature1, feature2]}); + var expected = 'foobar' + + 'dudetruite' + + '' + + ''; + expect(goog.dom.xml.loadXml(expected)).to.xmleql( + goog.dom.xml.loadXml(output)); + }); + it('Write works correctly for multilines', function() { + var multi = new ol.geom.MultiLineString([[[-111.04, 45.68], + [-112.04, 45.68]], [[1, 2], [3, 4]]]); + var feature = new ol.Feature({name: 'foo', description: 'bar'}); + feature.setGeometry(multi); + var output = parser.write({features: [feature]}); + var expected = 'foobar' + + '' + + ''; + expect(goog.dom.xml.loadXml(expected)).to.xmleql( + goog.dom.xml.loadXml(output)); + }); + it('Write works correctly for polygon', function() { + var polygon = new ol.geom.Polygon([[[-111.04, 45.68], + [-112.04, 45.68], [-111.04, 45.68]]]); + var feature = new ol.Feature({name: 'foo', description: 'bar'}); + feature.setGeometry(polygon); + var output = parser.write({features: [feature]}); + var expected = '' + + 'foobar'; + expect(goog.dom.xml.loadXml(expected)).to.xmleql( + goog.dom.xml.loadXml(output)); + }); + it('Write works correctly for metadata', function() { + var output = parser.write({features: [], metadata: {'name': 'foo', + 'desc': 'bar'}}); + var expected = '' + + 'foobar'; + expect(goog.dom.xml.loadXml(expected)).to.xmleql( + goog.dom.xml.loadXml(output)); + }); + }); +}); + +goog.require('ol.geom.GeometryType'); +goog.require('goog.dom.xml'); +goog.require('ol.Feature'); +goog.require('ol.geom.Point'); +goog.require('ol.geom.LineString'); +goog.require('ol.geom.MultiLineString'); +goog.require('ol.geom.Polygon'); +goog.require('ol.parser.GPX'); diff --git a/test/spec/ol/parser/gpx/data.xml b/test/spec/ol/parser/gpx/data.xml new file mode 100644 index 0000000000..3f1d0b8afb --- /dev/null +++ b/test/spec/ol/parser/gpx/data.xml @@ -0,0 +1 @@ +Mark