Merge pull request #1541 from twpayne/vector-api-gpx
[vector-api] Add ol.format.GPX
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,37 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
|
||||||
<gpx xmlns="http://www.topografix.com/GPX/1/1" creator="gpx4j" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
|
|
||||||
<trk>
|
|
||||||
<name>290311</name>
|
|
||||||
<desc>(null)</desc>
|
|
||||||
<trkseg>
|
|
||||||
<trkpt lat="39.114318" lon="-0.425692">
|
|
||||||
<ele>126.951324</ele>
|
|
||||||
<time>2011-03-29T14:45:52Z</time>
|
|
||||||
</trkpt>
|
|
||||||
<trkpt lat="39.114226" lon="-0.425648">
|
|
||||||
<ele>122.974365</ele>
|
|
||||||
<time>2011-03-29T14:46:03Z</time>
|
|
||||||
</trkpt>
|
|
||||||
<trkpt lat="39.114226" lon="-0.425648">
|
|
||||||
<ele>122.974365</ele>
|
|
||||||
<time>2011-03-29T14:46:07Z</time>
|
|
||||||
</trkpt>
|
|
||||||
<trkpt lat="39.114134" lon="-0.425608">
|
|
||||||
<ele>120.310211</ele>
|
|
||||||
<time>2011-03-29T14:46:09Z</time>
|
|
||||||
</trkpt>
|
|
||||||
<trkpt lat="39.114239" lon="-0.425657">
|
|
||||||
<ele>117.177261</ele>
|
|
||||||
<time>2011-03-29T14:46:18Z</time>
|
|
||||||
</trkpt>
|
|
||||||
<trkpt lat="39.114317" lon="-0.425718">
|
|
||||||
<ele>116.083771</ele>
|
|
||||||
<time>2011-03-29T14:46:21Z</time>
|
|
||||||
</trkpt>
|
|
||||||
<trkpt lat="39.114412" lon="-0.425789">
|
|
||||||
<ele>115.956726</ele>
|
|
||||||
<time>2011-03-29T14:46:25Z</time>
|
|
||||||
</trkpt>
|
|
||||||
</trkseg>
|
|
||||||
</trk>
|
|
||||||
</gpx>
|
|
||||||
@@ -31,11 +31,11 @@
|
|||||||
|
|
||||||
<div class="span4">
|
<div class="span4">
|
||||||
<h4 id="title">Drag-and-Drop example</h4>
|
<h4 id="title">Drag-and-Drop example</h4>
|
||||||
<p id="shortdesc">Example of using the drag-and-drop interaction. Drag and drop KML files on to the map.</p>
|
<p id="shortdesc">Example of using the drag-and-drop interaction. Drag and drop GPX, GeoJSON, IGC, KML, or TopoJSON files on to the map.</p>
|
||||||
<div id="docs">
|
<div id="docs">
|
||||||
<p>See the <a href="drag-and-drop.js" target="_blank">drag-and-drop.js source</a> to see how this is done.</p>
|
<p>See the <a href="drag-and-drop.js" target="_blank">drag-and-drop.js source</a> to see how this is done.</p>
|
||||||
</div>
|
</div>
|
||||||
<div id="tags">drag-and-drop, kml</div>
|
<div id="tags">drag-and-drop, gpx, geojson, igc, kml, topojson</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="span4 offset4">
|
<div class="span4 offset4">
|
||||||
<div id="info" class="alert alert-success">
|
<div id="info" class="alert alert-success">
|
||||||
|
|||||||
@@ -1,19 +1,98 @@
|
|||||||
goog.require('ol.Map');
|
goog.require('ol.Map');
|
||||||
goog.require('ol.RendererHint');
|
goog.require('ol.RendererHint');
|
||||||
goog.require('ol.View2D');
|
goog.require('ol.View2D');
|
||||||
|
goog.require('ol.format.GPX');
|
||||||
|
goog.require('ol.format.GeoJSON');
|
||||||
|
goog.require('ol.format.IGC');
|
||||||
goog.require('ol.format.KML');
|
goog.require('ol.format.KML');
|
||||||
|
goog.require('ol.format.TopoJSON');
|
||||||
goog.require('ol.interaction');
|
goog.require('ol.interaction');
|
||||||
goog.require('ol.interaction.DragAndDrop');
|
goog.require('ol.interaction.DragAndDrop');
|
||||||
goog.require('ol.layer.Tile');
|
goog.require('ol.layer.Tile');
|
||||||
goog.require('ol.source.BingMaps');
|
goog.require('ol.source.BingMaps');
|
||||||
|
goog.require('ol.style.Circle');
|
||||||
|
goog.require('ol.style.Fill');
|
||||||
|
goog.require('ol.style.Stroke');
|
||||||
|
goog.require('ol.style.Style');
|
||||||
|
|
||||||
|
|
||||||
|
var defaultStyle = {
|
||||||
|
'Point': [new ol.style.Style({
|
||||||
|
image: new ol.style.Circle({
|
||||||
|
fill: new ol.style.Fill({
|
||||||
|
color: 'rgba(255,255,0,0.5)'
|
||||||
|
}),
|
||||||
|
radius: 5,
|
||||||
|
stroke: new ol.style.Stroke({
|
||||||
|
color: '#ff0',
|
||||||
|
width: 1
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})],
|
||||||
|
'LineString': [new ol.style.Style({
|
||||||
|
stroke: new ol.style.Stroke({
|
||||||
|
color: '#f00',
|
||||||
|
width: 3
|
||||||
|
})
|
||||||
|
})],
|
||||||
|
'Polygon': [new ol.style.Style({
|
||||||
|
fill: new ol.style.Fill({
|
||||||
|
color: 'rgba(0,255,255,0.5)'
|
||||||
|
}),
|
||||||
|
stroke: new ol.style.Stroke({
|
||||||
|
color: '#0ff',
|
||||||
|
width: 1
|
||||||
|
})
|
||||||
|
})],
|
||||||
|
'MultiPoint': [new ol.style.Style({
|
||||||
|
image: new ol.style.Circle({
|
||||||
|
fill: new ol.style.Fill({
|
||||||
|
color: 'rgba(255,0,255,0.5)'
|
||||||
|
}),
|
||||||
|
radius: 5,
|
||||||
|
stroke: new ol.style.Stroke({
|
||||||
|
color: '#f0f',
|
||||||
|
width: 1
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})],
|
||||||
|
'MultiLineString': [new ol.style.Style({
|
||||||
|
stroke: new ol.style.Stroke({
|
||||||
|
color: '#0f0',
|
||||||
|
width: 3
|
||||||
|
})
|
||||||
|
})],
|
||||||
|
'MultiPolygon': [new ol.style.Style({
|
||||||
|
fill: new ol.style.Fill({
|
||||||
|
color: 'rgba(0,0,255,0.5)'
|
||||||
|
}),
|
||||||
|
stroke: new ol.style.Stroke({
|
||||||
|
color: '#00f',
|
||||||
|
width: 1
|
||||||
|
})
|
||||||
|
})]
|
||||||
|
};
|
||||||
|
|
||||||
|
var styleFunction = function(feature, resolution) {
|
||||||
|
var featureStyleFunction = feature.getStyleFunction();
|
||||||
|
if (featureStyleFunction) {
|
||||||
|
return featureStyleFunction.call(feature, resolution);
|
||||||
|
} else {
|
||||||
|
return defaultStyle[feature.getGeometry().getType()];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var map = new ol.Map({
|
var map = new ol.Map({
|
||||||
interactions: ol.interaction.defaults().extend([
|
interactions: ol.interaction.defaults().extend([
|
||||||
new ol.interaction.DragAndDrop({
|
new ol.interaction.DragAndDrop({
|
||||||
formatConstructors: [
|
formatConstructors: [
|
||||||
ol.format.KML
|
ol.format.GPX,
|
||||||
]
|
ol.format.GeoJSON,
|
||||||
|
ol.format.IGC,
|
||||||
|
ol.format.KML,
|
||||||
|
ol.format.TopoJSON
|
||||||
|
],
|
||||||
|
styleFunction: styleFunction
|
||||||
})
|
})
|
||||||
]),
|
]),
|
||||||
layers: [
|
layers: [
|
||||||
|
|||||||
55
examples/gpx.html
Normal file
55
examples/gpx.html
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||||
|
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
|
||||||
|
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap.min.css" type="text/css">
|
||||||
|
<link rel="stylesheet" href="../resources/layout.css" type="text/css">
|
||||||
|
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap-responsive.min.css" type="text/css">
|
||||||
|
<title>GPX example</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||||
|
<div class="navbar-inner">
|
||||||
|
<div class="container">
|
||||||
|
<a class="brand" href="./"><img src="../resources/logo.png"> OpenLayers 3 Examples</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
|
||||||
|
<div class="row-fluid">
|
||||||
|
<div class="span12">
|
||||||
|
<div id="map" class="map"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row-fluid">
|
||||||
|
|
||||||
|
<div class="span4">
|
||||||
|
<h4 id="title">GPX example</h4>
|
||||||
|
<p id="shortdesc">Example of using the GPX source.</p>
|
||||||
|
<div id="docs">
|
||||||
|
<p>See the <a href="gpx.js" target="_blank">gpx.js source</a> to see how this is done.</p>
|
||||||
|
</div>
|
||||||
|
<div id="tags">GPX</div>
|
||||||
|
</div>
|
||||||
|
<div class="span4 offset4">
|
||||||
|
<div id="info" class="alert alert-success">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="jquery.min.js" type="text/javascript"></script>
|
||||||
|
<script src="loader.js?id=gpx" type="text/javascript"></script>
|
||||||
|
<script src="../resources/example-behaviour.js" type="text/javascript"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
94
examples/gpx.js
Normal file
94
examples/gpx.js
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
goog.require('ol.Map');
|
||||||
|
goog.require('ol.RendererHint');
|
||||||
|
goog.require('ol.View2D');
|
||||||
|
goog.require('ol.layer.Tile');
|
||||||
|
goog.require('ol.layer.Vector');
|
||||||
|
goog.require('ol.source.BingMaps');
|
||||||
|
goog.require('ol.source.GPX');
|
||||||
|
goog.require('ol.style.Circle');
|
||||||
|
goog.require('ol.style.Fill');
|
||||||
|
goog.require('ol.style.Stroke');
|
||||||
|
goog.require('ol.style.Style');
|
||||||
|
|
||||||
|
var raster = new ol.layer.Tile({
|
||||||
|
source: new ol.source.BingMaps({
|
||||||
|
imagerySet: 'Aerial',
|
||||||
|
key: 'Ak-dzM4wZjSqTlzveKz5u0d4IQ4bRzVI309GxmkgSVr1ewS6iPSrOvOKhA-CJlm3'
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
var style = {
|
||||||
|
'Point': [new ol.style.Style({
|
||||||
|
image: new ol.style.Circle({
|
||||||
|
fill: new ol.style.Fill({
|
||||||
|
color: 'rgba(255,255,0,0.4)'
|
||||||
|
}),
|
||||||
|
radius: 5,
|
||||||
|
stroke: new ol.style.Stroke({
|
||||||
|
color: '#ff0',
|
||||||
|
width: 1
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})],
|
||||||
|
'LineString': [new ol.style.Style({
|
||||||
|
stroke: new ol.style.Stroke({
|
||||||
|
color: '#f00',
|
||||||
|
width: 3
|
||||||
|
})
|
||||||
|
})],
|
||||||
|
'MultiLineString': [new ol.style.Style({
|
||||||
|
stroke: new ol.style.Stroke({
|
||||||
|
color: '#0f0',
|
||||||
|
width: 3
|
||||||
|
})
|
||||||
|
})]
|
||||||
|
};
|
||||||
|
|
||||||
|
var vector = new ol.layer.Vector({
|
||||||
|
source: new ol.source.GPX({
|
||||||
|
reprojectTo: 'EPSG:3857',
|
||||||
|
url: 'data/gpx/fells_loop.gpx'
|
||||||
|
}),
|
||||||
|
styleFunction: function(feature, resolution) {
|
||||||
|
return style[feature.getGeometry().getType()];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var map = new ol.Map({
|
||||||
|
layers: [raster, vector],
|
||||||
|
renderer: ol.RendererHint.CANVAS,
|
||||||
|
target: document.getElementById('map'),
|
||||||
|
view: new ol.View2D({
|
||||||
|
center: [-7916041.528716288, 5228379.045749711],
|
||||||
|
zoom: 12
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
var displayFeatureInfo = function(pixel) {
|
||||||
|
var features = [];
|
||||||
|
map.forEachFeatureAtPixel(pixel, function(feature, layer) {
|
||||||
|
features.push(feature);
|
||||||
|
});
|
||||||
|
if (features.length > 0) {
|
||||||
|
var info = [];
|
||||||
|
var i, ii;
|
||||||
|
for (i = 0, ii = features.length; i < ii; ++i) {
|
||||||
|
info.push(features[i].get('desc'));
|
||||||
|
}
|
||||||
|
document.getElementById('info').innerHTML = info.join(', ') || '(unknown)';
|
||||||
|
map.getTarget().style.cursor = 'pointer';
|
||||||
|
} else {
|
||||||
|
document.getElementById('info').innerHTML = ' ';
|
||||||
|
map.getTarget().style.cursor = '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$(map.getViewport()).on('mousemove', function(evt) {
|
||||||
|
var pixel = map.getEventPixel(evt.originalEvent);
|
||||||
|
displayFeatureInfo(pixel);
|
||||||
|
});
|
||||||
|
|
||||||
|
map.on('singleclick', function(evt) {
|
||||||
|
var pixel = evt.getPixel();
|
||||||
|
displayFeatureInfo(pixel);
|
||||||
|
});
|
||||||
@@ -291,6 +291,8 @@
|
|||||||
* features will be added to this layer's source. If neither `source` nor
|
* features will be added to this layer's source. If neither `source` nor
|
||||||
* `layer` are defined then the dropped features will be added as a new
|
* `layer` are defined then the dropped features will be added as a new
|
||||||
* layer.
|
* layer.
|
||||||
|
* @property {ol.feature.StyleFunction|undefined} styleFunction Style function.
|
||||||
|
* This is used to configure any new layers created.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -554,6 +556,20 @@
|
|||||||
* @property {Array.<string>|undefined} urls URLs.
|
* @property {Array.<string>|undefined} urls URLs.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} olx.source.GPXOptions
|
||||||
|
* @property {Array.<ol.Attribution>|undefined} attributions Attributions.
|
||||||
|
* @property {Document|undefined} doc Document.
|
||||||
|
* @property {ol.Extent|undefined} extent Extent.
|
||||||
|
* @property {string|undefined} logo Logo.
|
||||||
|
* @property {Node|undefined| node Node.
|
||||||
|
* @property {ol.proj.ProjectionLike} projection Projection.
|
||||||
|
* @property {ol.proj.ProjectionLike} reprojectTo Re-project to.
|
||||||
|
* @property {string|undefined} text Text.
|
||||||
|
* @property {string|undefined} url URL.
|
||||||
|
* @property {Array.<string>|undefined} urls URLs.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} olx.source.TopoJSONOptions
|
* @typedef {Object} olx.source.TopoJSONOptions
|
||||||
* @property {Array.<ol.Attribution>|undefined} attributions Attributions.
|
* @property {Array.<ol.Attribution>|undefined} attributions Attributions.
|
||||||
|
|||||||
3
src/ol/format/gpxformat.exports
Normal file
3
src/ol/format/gpxformat.exports
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
@exportSymbol ol.format.GPX
|
||||||
|
@exportProperty ol.format.GPX.prototype.readFeature
|
||||||
|
@exportProperty ol.format.GPX.prototype.readFeatures
|
||||||
420
src/ol/format/gpxformat.js
Normal file
420
src/ol/format/gpxformat.js
Normal file
@@ -0,0 +1,420 @@
|
|||||||
|
goog.provide('ol.format.GPX');
|
||||||
|
|
||||||
|
goog.require('goog.array');
|
||||||
|
goog.require('goog.asserts');
|
||||||
|
goog.require('goog.dom.NodeType');
|
||||||
|
goog.require('goog.object');
|
||||||
|
goog.require('ol.Feature');
|
||||||
|
goog.require('ol.format.XML');
|
||||||
|
goog.require('ol.format.XSD');
|
||||||
|
goog.require('ol.geom.LineString');
|
||||||
|
goog.require('ol.geom.MultiLineString');
|
||||||
|
goog.require('ol.geom.Point');
|
||||||
|
goog.require('ol.proj');
|
||||||
|
goog.require('ol.xml');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.format.XML}
|
||||||
|
*/
|
||||||
|
ol.format.GPX = function() {
|
||||||
|
goog.base(this);
|
||||||
|
};
|
||||||
|
goog.inherits(ol.format.GPX, ol.format.XML);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @private
|
||||||
|
* @type {Array.<string>}
|
||||||
|
*/
|
||||||
|
ol.format.GPX.NAMESPACE_URIS_ = [
|
||||||
|
null,
|
||||||
|
'http://www.topografix.com/GPX/1/0',
|
||||||
|
'http://www.topografix.com/GPX/1/1'
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||||
|
* @param {Node} node Node.
|
||||||
|
* @param {Object} values Values.
|
||||||
|
* @private
|
||||||
|
* @return {Array.<number>} Flat coordinates.
|
||||||
|
*/
|
||||||
|
ol.format.GPX.appendCoordinate_ = function(flatCoordinates, node, values) {
|
||||||
|
goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT);
|
||||||
|
flatCoordinates.push(
|
||||||
|
parseFloat(node.getAttribute('lon')),
|
||||||
|
parseFloat(node.getAttribute('lat')));
|
||||||
|
if (goog.object.containsKey(values, 'ele')) {
|
||||||
|
flatCoordinates.push(
|
||||||
|
/** @type {number} */ (goog.object.get(values, 'ele')));
|
||||||
|
goog.object.remove(values, 'ele');
|
||||||
|
} else {
|
||||||
|
flatCoordinates.push(0);
|
||||||
|
}
|
||||||
|
if (goog.object.containsKey(values, 'time')) {
|
||||||
|
flatCoordinates.push(
|
||||||
|
/** @type {number} */ (goog.object.get(values, 'time')));
|
||||||
|
goog.object.remove(values, 'time');
|
||||||
|
} else {
|
||||||
|
flatCoordinates.push(0);
|
||||||
|
}
|
||||||
|
return flatCoordinates;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Node} node Node.
|
||||||
|
* @param {Array.<*>} objectStack Object stack.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.format.GPX.parseLink_ = function(node, objectStack) {
|
||||||
|
goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT);
|
||||||
|
goog.asserts.assert(node.localName == 'link');
|
||||||
|
var values = /** @type {Object} */ (objectStack[objectStack.length - 1]);
|
||||||
|
var href = node.getAttribute('href');
|
||||||
|
if (!goog.isNull(href)) {
|
||||||
|
goog.object.set(values, 'link', href);
|
||||||
|
}
|
||||||
|
ol.xml.parse(ol.format.GPX.LINK_PARSERS_, node, objectStack);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Node} node Node.
|
||||||
|
* @param {Array.<*>} objectStack Object stack.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.format.GPX.parseRtePt_ = function(node, objectStack) {
|
||||||
|
goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT);
|
||||||
|
goog.asserts.assert(node.localName == 'rtept');
|
||||||
|
var values = ol.xml.pushAndParse(
|
||||||
|
{}, ol.format.GPX.RTEPT_PARSERS_, node, objectStack);
|
||||||
|
if (goog.isDef(values)) {
|
||||||
|
var rteValues = /** @type {Object} */ (objectStack[objectStack.length - 1]);
|
||||||
|
var flatCoordinates = /** @type {Array.<number>} */
|
||||||
|
(goog.object.get(rteValues, 'flatCoordinates'));
|
||||||
|
ol.format.GPX.appendCoordinate_(flatCoordinates, node, values);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Node} node Node.
|
||||||
|
* @param {Array.<*>} objectStack Object stack.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.format.GPX.parseTrkPt_ = function(node, objectStack) {
|
||||||
|
goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT);
|
||||||
|
goog.asserts.assert(node.localName == 'trkpt');
|
||||||
|
var values = ol.xml.pushAndParse(
|
||||||
|
{}, ol.format.GPX.TRKPT_PARSERS_, node, objectStack);
|
||||||
|
if (goog.isDef(values)) {
|
||||||
|
var trkValues = /** @type {Object} */ (objectStack[objectStack.length - 1]);
|
||||||
|
var flatCoordinates = /** @type {Array.<number>} */
|
||||||
|
(goog.object.get(trkValues, 'flatCoordinates'));
|
||||||
|
ol.format.GPX.appendCoordinate_(flatCoordinates, node, values);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Node} node Node.
|
||||||
|
* @param {Array.<*>} objectStack Object stack.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.format.GPX.parseTrkSeg_ = function(node, objectStack) {
|
||||||
|
goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT);
|
||||||
|
goog.asserts.assert(node.localName == 'trkseg');
|
||||||
|
var values = /** @type {Object} */ (objectStack[objectStack.length - 1]);
|
||||||
|
ol.xml.parse(ol.format.GPX.TRKSEG_PARSERS_, node, objectStack);
|
||||||
|
var flatCoordinates = /** @type {Array.<number>} */
|
||||||
|
(goog.object.get(values, 'flatCoordinates'));
|
||||||
|
var ends = /** @type {Array.<number>} */ (goog.object.get(values, 'ends'));
|
||||||
|
ends.push(flatCoordinates.length);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Node} node Node.
|
||||||
|
* @param {Array.<*>} objectStack Object stack.
|
||||||
|
* @private
|
||||||
|
* @return {ol.Feature|undefined} Track.
|
||||||
|
*/
|
||||||
|
ol.format.GPX.readRte_ = function(node, objectStack) {
|
||||||
|
goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT);
|
||||||
|
goog.asserts.assert(node.localName == 'rte');
|
||||||
|
var values = ol.xml.pushAndParse({
|
||||||
|
'flatCoordinates': []
|
||||||
|
}, ol.format.GPX.RTE_PARSERS_, node, objectStack);
|
||||||
|
if (!goog.isDef(values)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
var flatCoordinates = /** @type {Array.<number>} */
|
||||||
|
(goog.object.get(values, 'flatCoordinates'));
|
||||||
|
goog.object.remove(values, 'flatCoordinates');
|
||||||
|
var geometry = new ol.geom.LineString(null);
|
||||||
|
geometry.setFlatCoordinates(ol.geom.GeometryLayout.XYZM, flatCoordinates);
|
||||||
|
var feature = new ol.Feature(geometry);
|
||||||
|
feature.setValues(values);
|
||||||
|
return feature;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Node} node Node.
|
||||||
|
* @param {Array.<*>} objectStack Object stack.
|
||||||
|
* @private
|
||||||
|
* @return {ol.Feature|undefined} Track.
|
||||||
|
*/
|
||||||
|
ol.format.GPX.readTrk_ = function(node, objectStack) {
|
||||||
|
goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT);
|
||||||
|
goog.asserts.assert(node.localName == 'trk');
|
||||||
|
var values = ol.xml.pushAndParse({
|
||||||
|
'flatCoordinates': [],
|
||||||
|
'ends': []
|
||||||
|
}, ol.format.GPX.TRK_PARSERS_, node, objectStack);
|
||||||
|
if (!goog.isDef(values)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
var flatCoordinates = /** @type {Array.<number>} */
|
||||||
|
(goog.object.get(values, 'flatCoordinates'));
|
||||||
|
goog.object.remove(values, 'flatCoordinates');
|
||||||
|
var ends = /** @type {Array.<number>} */ (goog.object.get(values, 'ends'));
|
||||||
|
goog.object.remove(values, 'ends');
|
||||||
|
var geometry = new ol.geom.MultiLineString(null);
|
||||||
|
geometry.setFlatCoordinates(
|
||||||
|
ol.geom.GeometryLayout.XYZM, flatCoordinates, ends);
|
||||||
|
var feature = new ol.Feature(geometry);
|
||||||
|
feature.setValues(values);
|
||||||
|
return feature;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Node} node Node.
|
||||||
|
* @param {Array.<*>} objectStack Object stack.
|
||||||
|
* @private
|
||||||
|
* @return {ol.Feature|undefined} Waypoint.
|
||||||
|
*/
|
||||||
|
ol.format.GPX.readWpt_ = function(node, objectStack) {
|
||||||
|
goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT);
|
||||||
|
goog.asserts.assert(node.localName == 'wpt');
|
||||||
|
var values = ol.xml.pushAndParse(
|
||||||
|
{}, ol.format.GPX.WPT_PARSERS_, node, objectStack);
|
||||||
|
if (!goog.isDef(values)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
var coordinates = ol.format.GPX.appendCoordinate_([], node, values);
|
||||||
|
var geometry = new ol.geom.Point(
|
||||||
|
coordinates, ol.geom.GeometryLayout.XYZM);
|
||||||
|
var feature = new ol.Feature(geometry);
|
||||||
|
feature.setValues(values);
|
||||||
|
return feature;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Object.<string, function(Node, Array.<*>): (ol.Feature|undefined)>}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.format.GPX.FEATURE_READER_ = {
|
||||||
|
'rte': ol.format.GPX.readRte_,
|
||||||
|
'trk': ol.format.GPX.readTrk_,
|
||||||
|
'wpt': ol.format.GPX.readWpt_
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Object.<string, Object.<string, ol.xml.Parser>>}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.format.GPX.GPX_PARSERS_ = ol.xml.makeParsersNS(
|
||||||
|
ol.format.GPX.NAMESPACE_URIS_, {
|
||||||
|
'rte': ol.xml.makeArrayPusher(ol.format.GPX.readRte_),
|
||||||
|
'trk': ol.xml.makeArrayPusher(ol.format.GPX.readTrk_),
|
||||||
|
'wpt': ol.xml.makeArrayPusher(ol.format.GPX.readWpt_)
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Object.<string, Object.<string, ol.xml.Parser>>}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.format.GPX.LINK_PARSERS_ = ol.xml.makeParsersNS(
|
||||||
|
ol.format.GPX.NAMESPACE_URIS_, {
|
||||||
|
'text':
|
||||||
|
ol.xml.makeObjectPropertySetter(ol.format.XSD.readString, 'linkText'),
|
||||||
|
'type':
|
||||||
|
ol.xml.makeObjectPropertySetter(ol.format.XSD.readString, 'linkType')
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Object.<string, Object.<string, ol.xml.Parser>>}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.format.GPX.RTE_PARSERS_ = ol.xml.makeParsersNS(
|
||||||
|
ol.format.GPX.NAMESPACE_URIS_, {
|
||||||
|
'name': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
|
||||||
|
'cmt': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
|
||||||
|
'desc': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
|
||||||
|
'src': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
|
||||||
|
'link': ol.format.GPX.parseLink_,
|
||||||
|
'number':
|
||||||
|
ol.xml.makeObjectPropertySetter(ol.format.XSD.readNonNegativeInteger),
|
||||||
|
'type': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
|
||||||
|
'rtept': ol.format.GPX.parseRtePt_
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Object.<string, Object.<string, ol.xml.Parser>>}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.format.GPX.RTEPT_PARSERS_ = ol.xml.makeParsersNS(
|
||||||
|
ol.format.GPX.NAMESPACE_URIS_, {
|
||||||
|
'ele': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
|
||||||
|
'time': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDateTime)
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Object.<string, Object.<string, ol.xml.Parser>>}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.format.GPX.TRK_PARSERS_ = ol.xml.makeParsersNS(
|
||||||
|
ol.format.GPX.NAMESPACE_URIS_, {
|
||||||
|
'name': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
|
||||||
|
'cmt': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
|
||||||
|
'desc': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
|
||||||
|
'src': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
|
||||||
|
'link': ol.format.GPX.parseLink_,
|
||||||
|
'number':
|
||||||
|
ol.xml.makeObjectPropertySetter(ol.format.XSD.readNonNegativeInteger),
|
||||||
|
'type': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
|
||||||
|
'trkseg': ol.format.GPX.parseTrkSeg_
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Object.<string, Object.<string, ol.xml.Parser>>}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.format.GPX.TRKSEG_PARSERS_ = ol.xml.makeParsersNS(
|
||||||
|
ol.format.GPX.NAMESPACE_URIS_, {
|
||||||
|
'trkpt': ol.format.GPX.parseTrkPt_
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Object.<string, Object.<string, ol.xml.Parser>>}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.format.GPX.TRKPT_PARSERS_ = ol.xml.makeParsersNS(
|
||||||
|
ol.format.GPX.NAMESPACE_URIS_, {
|
||||||
|
'ele': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
|
||||||
|
'time': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDateTime)
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Object.<string, Object.<string, ol.xml.Parser>>}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.format.GPX.WPT_PARSERS_ = ol.xml.makeParsersNS(
|
||||||
|
ol.format.GPX.NAMESPACE_URIS_, {
|
||||||
|
'ele': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
|
||||||
|
'time': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDateTime),
|
||||||
|
'magvar': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
|
||||||
|
'geoidheight': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
|
||||||
|
'name': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
|
||||||
|
'cmt': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
|
||||||
|
'desc': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
|
||||||
|
'src': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
|
||||||
|
'link': ol.format.GPX.parseLink_,
|
||||||
|
'sym': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
|
||||||
|
'type': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
|
||||||
|
'fix': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
|
||||||
|
'sat': ol.xml.makeObjectPropertySetter(
|
||||||
|
ol.format.XSD.readNonNegativeInteger),
|
||||||
|
'hdop': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
|
||||||
|
'vdop': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
|
||||||
|
'pdop': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
|
||||||
|
'ageofdgpsdata':
|
||||||
|
ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
|
||||||
|
'dgpsid':
|
||||||
|
ol.xml.makeObjectPropertySetter(ol.format.XSD.readNonNegativeInteger)
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.format.GPX.prototype.readFeatureFromNode = function(node) {
|
||||||
|
goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT);
|
||||||
|
if (goog.array.indexOf(ol.format.GPX.NAMESPACE_URIS_, node.namespaceURI) ==
|
||||||
|
-1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var featureReader = ol.format.GPX.FEATURE_READER_[node.localName];
|
||||||
|
if (!goog.isDef(featureReader)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var feature = featureReader(node, []);
|
||||||
|
if (!goog.isDef(feature)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return feature;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.format.GPX.prototype.readFeaturesFromNode = function(node) {
|
||||||
|
goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT);
|
||||||
|
if (goog.array.indexOf(ol.format.GPX.NAMESPACE_URIS_, node.namespaceURI) ==
|
||||||
|
-1) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if (node.localName == 'gpx') {
|
||||||
|
var features = ol.xml.pushAndParse(/** @type {Array.<ol.Feature>} */ ([]),
|
||||||
|
ol.format.GPX.GPX_PARSERS_, node, []);
|
||||||
|
if (goog.isDef(features)) {
|
||||||
|
return features;
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.format.GPX.prototype.readProjectionFromDocument = function(doc) {
|
||||||
|
return ol.proj.get('EPSG:4326');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.format.GPX.prototype.readProjectionFromNode = function(node) {
|
||||||
|
return ol.proj.get('EPSG:4326');
|
||||||
|
};
|
||||||
83
src/ol/format/xsdformat.js
Normal file
83
src/ol/format/xsdformat.js
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
goog.provide('ol.format.XSD');
|
||||||
|
|
||||||
|
goog.require('goog.string');
|
||||||
|
goog.require('ol.xml');
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.format.XSD.NAMESPACE_URI = 'http://www.w3.org/2001/XMLSchema';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Node} node Node.
|
||||||
|
* @return {number|undefined} DateTime.
|
||||||
|
*/
|
||||||
|
ol.format.XSD.readDateTime = function(node) {
|
||||||
|
var s = ol.xml.getAllTextContent(node, false);
|
||||||
|
var re =
|
||||||
|
/^\s*(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(Z|(?:([+\-])(\d{2})(?::(\d{2}))?))\s*$/;
|
||||||
|
var m = re.exec(s);
|
||||||
|
if (m) {
|
||||||
|
var year = parseInt(m[1], 10);
|
||||||
|
var month = parseInt(m[2], 10) - 1;
|
||||||
|
var day = parseInt(m[3], 10);
|
||||||
|
var hour = parseInt(m[4], 10);
|
||||||
|
var minute = parseInt(m[5], 10);
|
||||||
|
var second = parseInt(m[6], 10);
|
||||||
|
var dateTime = Date.UTC(year, month, day, hour, minute, second, 0) / 1000;
|
||||||
|
if (m[7] != 'Z') {
|
||||||
|
var sign = m[8] == '-' ? -1 : 1;
|
||||||
|
dateTime += sign * 60 * parseInt(m[9], 10);
|
||||||
|
if (goog.isDef(m[10])) {
|
||||||
|
dateTime += sign * 60 * 60 * parseInt(m[10], 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dateTime;
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Node} node Node.
|
||||||
|
* @return {number|undefined} Decimal.
|
||||||
|
*/
|
||||||
|
ol.format.XSD.readDecimal = function(node) {
|
||||||
|
// FIXME check spec
|
||||||
|
var s = ol.xml.getAllTextContent(node, false);
|
||||||
|
var m = /^\s*([+\-]?\d+(?:\.\d*)?)\s*$/.exec(s);
|
||||||
|
if (m) {
|
||||||
|
return parseFloat(m[1]);
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Node} node Node.
|
||||||
|
* @return {number|undefined} Decimal.
|
||||||
|
*/
|
||||||
|
ol.format.XSD.readNonNegativeInteger = function(node) {
|
||||||
|
var s = ol.xml.getAllTextContent(node, false);
|
||||||
|
var m = /^\s*(\d+)\s*$/.exec(s);
|
||||||
|
if (m) {
|
||||||
|
return parseInt(m[1], 10);
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Node} node Node.
|
||||||
|
* @return {string|undefined} String.
|
||||||
|
*/
|
||||||
|
ol.format.XSD.readString = function(node) {
|
||||||
|
var s = ol.xml.getAllTextContent(node, false);
|
||||||
|
return goog.string.trim(s);
|
||||||
|
};
|
||||||
@@ -52,6 +52,12 @@ ol.interaction.DragAndDrop = function(opt_options) {
|
|||||||
*/
|
*/
|
||||||
this.layer_ = goog.isDef(options.layer) ? options.layer : null;
|
this.layer_ = goog.isDef(options.layer) ? options.layer : null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {ol.feature.StyleFunction|undefined}
|
||||||
|
*/
|
||||||
|
this.styleFunction_ = options.styleFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {goog.events.FileDropHandler}
|
* @type {goog.events.FileDropHandler}
|
||||||
@@ -149,6 +155,7 @@ ol.interaction.DragAndDrop.prototype.handleResult_ = function(result) {
|
|||||||
}
|
}
|
||||||
if (goog.isNull(this.layer_)) {
|
if (goog.isNull(this.layer_)) {
|
||||||
map.getLayers().push(new ol.layer.Vector({
|
map.getLayers().push(new ol.layer.Vector({
|
||||||
|
styleFunction: this.styleFunction_,
|
||||||
source: source
|
source: source
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|||||||
1
src/ol/source/gpxsource.exports
Normal file
1
src/ol/source/gpxsource.exports
Normal file
@@ -0,0 +1 @@
|
|||||||
|
@exportSymbol ol.source.GPX
|
||||||
32
src/ol/source/gpxsource.js
Normal file
32
src/ol/source/gpxsource.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
goog.provide('ol.source.GPX');
|
||||||
|
|
||||||
|
goog.require('ol.format.GPX');
|
||||||
|
goog.require('ol.source.VectorFile');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.source.VectorFile}
|
||||||
|
* @param {olx.source.GPXOptions=} opt_options Options.
|
||||||
|
*/
|
||||||
|
ol.source.GPX = function(opt_options) {
|
||||||
|
|
||||||
|
var options = goog.isDef(opt_options) ? opt_options : {};
|
||||||
|
|
||||||
|
goog.base(this, {
|
||||||
|
attributions: options.attributions,
|
||||||
|
doc: options.doc,
|
||||||
|
extent: options.extent,
|
||||||
|
format: new ol.format.GPX(),
|
||||||
|
logo: options.logo,
|
||||||
|
node: options.node,
|
||||||
|
projection: options.projection,
|
||||||
|
reprojectTo: options.reprojectTo,
|
||||||
|
text: options.text,
|
||||||
|
url: options.url,
|
||||||
|
urls: options.urls
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
goog.inherits(ol.source.GPX, ol.source.VectorFile);
|
||||||
380
test/spec/ol/format/gpxformat.test.js
Normal file
380
test/spec/ol/format/gpxformat.test.js
Normal file
@@ -0,0 +1,380 @@
|
|||||||
|
goog.provide('ol.test.format.GPX');
|
||||||
|
|
||||||
|
|
||||||
|
describe('ol.format.GPX', function() {
|
||||||
|
|
||||||
|
var format;
|
||||||
|
beforeEach(function() {
|
||||||
|
format = new ol.format.GPX();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('readFeatures', function() {
|
||||||
|
|
||||||
|
describe('rte', function() {
|
||||||
|
|
||||||
|
it('can read an empty rte', function() {
|
||||||
|
var text =
|
||||||
|
'<gpx xmlns="http://www.topografix.com/GPX/1/1">' +
|
||||||
|
' <rte/>' +
|
||||||
|
'</gpx>';
|
||||||
|
var fs = format.readFeatures(text);
|
||||||
|
expect(fs).to.have.length(1);
|
||||||
|
var f = fs[0];
|
||||||
|
expect(f).to.be.an(ol.Feature);
|
||||||
|
var g = f.getGeometry();
|
||||||
|
expect(g).to.be.an(ol.geom.LineString);
|
||||||
|
expect(g.getCoordinates()).to.eql([]);
|
||||||
|
expect(g.getLayout()).to.be(ol.geom.GeometryLayout.XYZM);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can read various rte attributes', function() {
|
||||||
|
var text =
|
||||||
|
'<gpx xmlns="http://www.topografix.com/GPX/1/1">' +
|
||||||
|
' <rte>' +
|
||||||
|
' <name>Name</name>' +
|
||||||
|
' <cmt>Comment</cmt>' +
|
||||||
|
' <desc>Description</desc>' +
|
||||||
|
' <src>Source</src>' +
|
||||||
|
' <link href="http://example.com/">' +
|
||||||
|
' <text>Link text</text>' +
|
||||||
|
' <type>Link type</type>' +
|
||||||
|
' </link>' +
|
||||||
|
' <number>1</number>' +
|
||||||
|
' <type>Type</type>' +
|
||||||
|
' </rte>' +
|
||||||
|
'</gpx>';
|
||||||
|
var fs = format.readFeatures(text);
|
||||||
|
expect(fs).to.have.length(1);
|
||||||
|
var f = fs[0];
|
||||||
|
expect(f).to.be.an(ol.Feature);
|
||||||
|
expect(f.get('name')).to.be('Name');
|
||||||
|
expect(f.get('cmt')).to.be('Comment');
|
||||||
|
expect(f.get('desc')).to.be('Description');
|
||||||
|
expect(f.get('src')).to.be('Source');
|
||||||
|
expect(f.get('link')).to.be('http://example.com/');
|
||||||
|
expect(f.get('linkText')).to.be('Link text');
|
||||||
|
expect(f.get('linkType')).to.be('Link type');
|
||||||
|
expect(f.get('number')).to.be(1);
|
||||||
|
expect(f.get('type')).to.be('Type');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can read a rte with multiple rtepts', function() {
|
||||||
|
var text =
|
||||||
|
'<gpx xmlns="http://www.topografix.com/GPX/1/1">' +
|
||||||
|
' <rte>' +
|
||||||
|
' <rtept lat="1" lon="2"/>' +
|
||||||
|
' <rtept lat="3" lon="4"/>' +
|
||||||
|
' </rte>' +
|
||||||
|
'</gpx>';
|
||||||
|
var fs = format.readFeatures(text);
|
||||||
|
expect(fs).to.have.length(1);
|
||||||
|
var f = fs[0];
|
||||||
|
expect(f).to.be.an(ol.Feature);
|
||||||
|
var g = f.getGeometry();
|
||||||
|
expect(g).to.be.an(ol.geom.LineString);
|
||||||
|
expect(g.getCoordinates()).to.eql([[2, 1, 0, 0], [4, 3, 0, 0]]);
|
||||||
|
expect(g.getLayout()).to.be(ol.geom.GeometryLayout.XYZM);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('trk', function() {
|
||||||
|
|
||||||
|
it('can read an empty trk', function() {
|
||||||
|
var text =
|
||||||
|
'<gpx xmlns="http://www.topografix.com/GPX/1/1">' +
|
||||||
|
' <trk/>' +
|
||||||
|
'</gpx>';
|
||||||
|
var fs = format.readFeatures(text);
|
||||||
|
expect(fs).to.have.length(1);
|
||||||
|
var f = fs[0];
|
||||||
|
expect(f).to.be.an(ol.Feature);
|
||||||
|
var g = f.getGeometry();
|
||||||
|
expect(g).to.be.an(ol.geom.MultiLineString);
|
||||||
|
expect(g.getCoordinates()).to.eql([]);
|
||||||
|
expect(g.getLayout()).to.be(ol.geom.GeometryLayout.XYZM);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can read various trk attributes', function() {
|
||||||
|
var text =
|
||||||
|
'<gpx xmlns="http://www.topografix.com/GPX/1/1">' +
|
||||||
|
' <trk>' +
|
||||||
|
' <name>Name</name>' +
|
||||||
|
' <cmt>Comment</cmt>' +
|
||||||
|
' <desc>Description</desc>' +
|
||||||
|
' <src>Source</src>' +
|
||||||
|
' <link href="http://example.com/">' +
|
||||||
|
' <text>Link text</text>' +
|
||||||
|
' <type>Link type</type>' +
|
||||||
|
' </link>' +
|
||||||
|
' <number>1</number>' +
|
||||||
|
' <type>Type</type>' +
|
||||||
|
' </trk>' +
|
||||||
|
'</gpx>';
|
||||||
|
var fs = format.readFeatures(text);
|
||||||
|
expect(fs).to.have.length(1);
|
||||||
|
var f = fs[0];
|
||||||
|
expect(f).to.be.an(ol.Feature);
|
||||||
|
expect(f.get('name')).to.be('Name');
|
||||||
|
expect(f.get('cmt')).to.be('Comment');
|
||||||
|
expect(f.get('desc')).to.be('Description');
|
||||||
|
expect(f.get('src')).to.be('Source');
|
||||||
|
expect(f.get('link')).to.be('http://example.com/');
|
||||||
|
expect(f.get('linkText')).to.be('Link text');
|
||||||
|
expect(f.get('linkType')).to.be('Link type');
|
||||||
|
expect(f.get('number')).to.be(1);
|
||||||
|
expect(f.get('type')).to.be('Type');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can read a trk with an empty trkseg', function() {
|
||||||
|
var text =
|
||||||
|
'<gpx xmlns="http://www.topografix.com/GPX/1/1">' +
|
||||||
|
' <trk>' +
|
||||||
|
' <trkseg/>' +
|
||||||
|
' </trk>' +
|
||||||
|
'</gpx>';
|
||||||
|
var fs = format.readFeatures(text);
|
||||||
|
expect(fs).to.have.length(1);
|
||||||
|
var f = fs[0];
|
||||||
|
expect(f).to.be.an(ol.Feature);
|
||||||
|
var g = f.getGeometry();
|
||||||
|
expect(g).to.be.an(ol.geom.MultiLineString);
|
||||||
|
expect(g.getCoordinates()).to.eql([[]]);
|
||||||
|
expect(g.getLayout()).to.be(ol.geom.GeometryLayout.XYZM);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can read a trk with a trkseg with multiple trkpts', function() {
|
||||||
|
var text =
|
||||||
|
'<gpx xmlns="http://www.topografix.com/GPX/1/1">' +
|
||||||
|
' <trk>' +
|
||||||
|
' <trkseg>' +
|
||||||
|
' <trkpt lat="1" lon="2">' +
|
||||||
|
' <ele>3</ele>' +
|
||||||
|
' <time>2010-01-10T09:29:12Z</time>' +
|
||||||
|
' </trkpt>' +
|
||||||
|
' <trkpt lat="5" lon="6">' +
|
||||||
|
' <ele>7</ele>' +
|
||||||
|
' <time>2010-01-10T09:30:12Z</time>' +
|
||||||
|
' </trkpt>' +
|
||||||
|
' </trkseg>' +
|
||||||
|
' </trk>' +
|
||||||
|
'</gpx>';
|
||||||
|
var fs = format.readFeatures(text);
|
||||||
|
expect(fs).to.have.length(1);
|
||||||
|
var f = fs[0];
|
||||||
|
expect(f).to.be.an(ol.Feature);
|
||||||
|
var g = f.getGeometry();
|
||||||
|
expect(g).to.be.an(ol.geom.MultiLineString);
|
||||||
|
expect(g.getCoordinates()).to.eql([
|
||||||
|
[[2, 1, 3, 1263115752], [6, 5, 7, 1263115812]]
|
||||||
|
]);
|
||||||
|
expect(g.getLayout()).to.be(ol.geom.GeometryLayout.XYZM);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can read a trk with multiple trksegs', function() {
|
||||||
|
var text =
|
||||||
|
'<gpx xmlns="http://www.topografix.com/GPX/1/1">' +
|
||||||
|
' <trk>' +
|
||||||
|
' <trkseg>' +
|
||||||
|
' <trkpt lat="1" lon="2">' +
|
||||||
|
' <ele>3</ele>' +
|
||||||
|
' <time>2010-01-10T09:29:12Z</time>' +
|
||||||
|
' </trkpt>' +
|
||||||
|
' <trkpt lat="5" lon="6">' +
|
||||||
|
' <ele>7</ele>' +
|
||||||
|
' <time>2010-01-10T09:30:12Z</time>' +
|
||||||
|
' </trkpt>' +
|
||||||
|
' </trkseg>' +
|
||||||
|
' <trkseg>' +
|
||||||
|
' <trkpt lat="8" lon="9">' +
|
||||||
|
' <ele>10</ele>' +
|
||||||
|
' <time>2010-01-10T09:31:12Z</time>' +
|
||||||
|
' </trkpt>' +
|
||||||
|
' <trkpt lat="11" lon="12">' +
|
||||||
|
' <ele>13</ele>' +
|
||||||
|
' <time>2010-01-10T09:32:12Z</time>' +
|
||||||
|
' </trkpt>' +
|
||||||
|
' </trkseg>' +
|
||||||
|
' </trk>' +
|
||||||
|
'</gpx>';
|
||||||
|
var fs = format.readFeatures(text);
|
||||||
|
expect(fs).to.have.length(1);
|
||||||
|
var f = fs[0];
|
||||||
|
expect(f).to.be.an(ol.Feature);
|
||||||
|
var g = f.getGeometry();
|
||||||
|
expect(g).to.be.an(ol.geom.MultiLineString);
|
||||||
|
expect(g.getCoordinates()).to.eql([
|
||||||
|
[[2, 1, 3, 1263115752], [6, 5, 7, 1263115812]],
|
||||||
|
[[9, 8, 10, 1263115872], [12, 11, 13, 1263115932]]
|
||||||
|
]);
|
||||||
|
expect(g.getLayout()).to.be(ol.geom.GeometryLayout.XYZM);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('wpt', function() {
|
||||||
|
|
||||||
|
it('can read a wpt', function() {
|
||||||
|
var text =
|
||||||
|
'<gpx xmlns="http://www.topografix.com/GPX/1/1">' +
|
||||||
|
' <wpt lat="1" lon="2"/>' +
|
||||||
|
'</gpx>';
|
||||||
|
var fs = format.readFeatures(text);
|
||||||
|
expect(fs).to.have.length(1);
|
||||||
|
var f = fs[0];
|
||||||
|
expect(f).to.be.an(ol.Feature);
|
||||||
|
var g = f.getGeometry();
|
||||||
|
expect(g).to.be.an(ol.geom.Point);
|
||||||
|
expect(g.getCoordinates()).to.eql([2, 1, 0, 0]);
|
||||||
|
expect(g.getLayout()).to.be(ol.geom.GeometryLayout.XYZM);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can read a wpt with ele', function() {
|
||||||
|
var text =
|
||||||
|
'<gpx xmlns="http://www.topografix.com/GPX/1/1">' +
|
||||||
|
' <wpt lat="1" lon="2">' +
|
||||||
|
' <ele>3</ele>' +
|
||||||
|
' </wpt>' +
|
||||||
|
'</gpx>';
|
||||||
|
var fs = format.readFeatures(text);
|
||||||
|
expect(fs).to.have.length(1);
|
||||||
|
var f = fs[0];
|
||||||
|
expect(f).to.be.an(ol.Feature);
|
||||||
|
var g = f.getGeometry();
|
||||||
|
expect(g).to.be.an(ol.geom.Point);
|
||||||
|
expect(g.getCoordinates()).to.eql([2, 1, 3, 0]);
|
||||||
|
expect(g.getLayout()).to.be(ol.geom.GeometryLayout.XYZM);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can read a wpt with time', function() {
|
||||||
|
var text =
|
||||||
|
'<gpx xmlns="http://www.topografix.com/GPX/1/1">' +
|
||||||
|
' <wpt lat="1" lon="2">' +
|
||||||
|
' <time>2010-01-10T09:29:12Z</time>' +
|
||||||
|
' </wpt>' +
|
||||||
|
'</gpx>';
|
||||||
|
var fs = format.readFeatures(text);
|
||||||
|
expect(fs).to.have.length(1);
|
||||||
|
var f = fs[0];
|
||||||
|
expect(f).to.be.an(ol.Feature);
|
||||||
|
var g = f.getGeometry();
|
||||||
|
expect(g).to.be.an(ol.geom.Point);
|
||||||
|
expect(g.getCoordinates()).to.eql([2, 1, 0, 1263115752]);
|
||||||
|
expect(g.getLayout()).to.be(ol.geom.GeometryLayout.XYZM);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can read a wpt with ele and time', function() {
|
||||||
|
var text =
|
||||||
|
'<gpx xmlns="http://www.topografix.com/GPX/1/1">' +
|
||||||
|
' <wpt lat="1" lon="2">' +
|
||||||
|
' <ele>3</ele>' +
|
||||||
|
' <time>2010-01-10T09:29:12Z</time>' +
|
||||||
|
' </wpt>' +
|
||||||
|
'</gpx>';
|
||||||
|
var fs = format.readFeatures(text);
|
||||||
|
expect(fs).to.have.length(1);
|
||||||
|
var f = fs[0];
|
||||||
|
expect(f).to.be.an(ol.Feature);
|
||||||
|
var g = f.getGeometry();
|
||||||
|
expect(g).to.be.an(ol.geom.Point);
|
||||||
|
expect(g.getCoordinates()).to.eql([2, 1, 3, 1263115752]);
|
||||||
|
expect(g.getLayout()).to.be(ol.geom.GeometryLayout.XYZM);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can read various wpt attributes', function() {
|
||||||
|
var text =
|
||||||
|
'<gpx xmlns="http://www.topografix.com/GPX/1/1">' +
|
||||||
|
' <wpt lat="1" lon="2">' +
|
||||||
|
' <magvar>11</magvar>' +
|
||||||
|
' <geoidheight>4</geoidheight>' +
|
||||||
|
' <name>Name</name>' +
|
||||||
|
' <cmt>Comment</cmt>' +
|
||||||
|
' <desc>Description</desc>' +
|
||||||
|
' <src>Source</src>' +
|
||||||
|
' <link href="http://example.com/">' +
|
||||||
|
' <text>Link text</text>' +
|
||||||
|
' <type>Link type</type>' +
|
||||||
|
' </link>' +
|
||||||
|
' <sym>Symbol</sym>' +
|
||||||
|
' <type>Type</type>' +
|
||||||
|
' <fix>2d</fix>' +
|
||||||
|
' <sat>5</sat>' +
|
||||||
|
' <hdop>6</hdop>' +
|
||||||
|
' <vdop>7</vdop>' +
|
||||||
|
' <pdop>8</pdop>' +
|
||||||
|
' <ageofdgpsdata>9</ageofdgpsdata>' +
|
||||||
|
' <dgpsid>10</dgpsid>' +
|
||||||
|
' </wpt>' +
|
||||||
|
'</gpx>';
|
||||||
|
var fs = format.readFeatures(text);
|
||||||
|
expect(fs).to.have.length(1);
|
||||||
|
var f = fs[0];
|
||||||
|
expect(f).to.be.an(ol.Feature);
|
||||||
|
expect(f.get('magvar')).to.be(11);
|
||||||
|
expect(f.get('geoidheight')).to.be(4);
|
||||||
|
expect(f.get('name')).to.be('Name');
|
||||||
|
expect(f.get('cmt')).to.be('Comment');
|
||||||
|
expect(f.get('desc')).to.be('Description');
|
||||||
|
expect(f.get('src')).to.be('Source');
|
||||||
|
expect(f.get('link')).to.be('http://example.com/');
|
||||||
|
expect(f.get('linkText')).to.be('Link text');
|
||||||
|
expect(f.get('linkType')).to.be('Link type');
|
||||||
|
expect(f.get('sym')).to.be('Symbol');
|
||||||
|
expect(f.get('type')).to.be('Type');
|
||||||
|
expect(f.get('fix')).to.be('2d');
|
||||||
|
expect(f.get('hdop')).to.be(6);
|
||||||
|
expect(f.get('vdop')).to.be(7);
|
||||||
|
expect(f.get('pdop')).to.be(8);
|
||||||
|
expect(f.get('ageofdgpsdata')).to.be(9);
|
||||||
|
expect(f.get('dgpsid')).to.be(10);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('XML namespace support', function() {
|
||||||
|
|
||||||
|
it('can read features with a version 1.0 namespace', function() {
|
||||||
|
var text =
|
||||||
|
'<gpx xmlns="http://www.topografix.com/GPX/1/0">' +
|
||||||
|
' <wpt/>' +
|
||||||
|
' <rte/>' +
|
||||||
|
' <trk/>' +
|
||||||
|
'</gpx>';
|
||||||
|
var fs = format.readFeatures(text);
|
||||||
|
expect(fs).to.have.length(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can read features with a version 1.1 namespace', function() {
|
||||||
|
var text =
|
||||||
|
'<gpx xmlns="http://www.topografix.com/GPX/1/1">' +
|
||||||
|
' <wpt/>' +
|
||||||
|
' <rte/>' +
|
||||||
|
' <trk/>' +
|
||||||
|
'</gpx>';
|
||||||
|
var fs = format.readFeatures(text);
|
||||||
|
expect(fs).to.have.length(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can read features with no namespace', function() {
|
||||||
|
var text =
|
||||||
|
'<gpx>' +
|
||||||
|
' <wpt/>' +
|
||||||
|
' <rte/>' +
|
||||||
|
' <trk/>' +
|
||||||
|
'</gpx>';
|
||||||
|
var fs = format.readFeatures(text);
|
||||||
|
expect(fs).to.have.length(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
goog.require('ol.Feature');
|
||||||
|
goog.require('ol.format.GPX');
|
||||||
|
goog.require('ol.geom.LineString');
|
||||||
|
goog.require('ol.geom.MultiLineString');
|
||||||
|
goog.require('ol.geom.Point');
|
||||||
Reference in New Issue
Block a user