Set GeometryLayout correctly when reading GPX

Fixes #6148
This commit is contained in:
Roman Zoller
2016-11-21 17:47:41 +01:00
parent caef2b51b4
commit f56b2c8a75
3 changed files with 90 additions and 27 deletions

View File

@@ -66,12 +66,13 @@ ol.format.GPX.SCHEMA_LOCATION_ = 'http://www.topografix.com/GPX/1/1 ' +
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {ol.LayoutOptions} layoutOptions Layout options.
* @param {Node} node Node.
* @param {Object} values Values.
* @private
* @return {Array.<number>} Flat coordinates.
*/
ol.format.GPX.appendCoordinate_ = function(flatCoordinates, node, values) {
ol.format.GPX.appendCoordinate_ = function(flatCoordinates, layoutOptions, node, values) {
ol.DEBUG && console.assert(node.nodeType == Node.ELEMENT_NODE,
'node.nodeType should be ELEMENT');
flatCoordinates.push(
@@ -80,12 +81,14 @@ ol.format.GPX.appendCoordinate_ = function(flatCoordinates, node, values) {
if ('ele' in values) {
flatCoordinates.push(/** @type {number} */ (values['ele']));
delete values['ele'];
layoutOptions.hasZ = true;
} else {
flatCoordinates.push(0);
}
if ('time' in values) {
flatCoordinates.push(/** @type {number} */ (values['time']));
delete values['time'];
layoutOptions.hasM = true;
} else {
flatCoordinates.push(0);
}
@@ -93,6 +96,51 @@ ol.format.GPX.appendCoordinate_ = function(flatCoordinates, node, values) {
};
/**
* Choose GeometryLayout based on flags in layoutOptions and adjust flatCoordinates
* and ends arrays by shrinking them accordingly (removing unused zero entries).
*
* @param {ol.LayoutOptions} layoutOptions Layout options.
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {Array.<number>=} ends Ends.
* @return {ol.geom.GeometryLayout} Layout.
*/
ol.format.GPX.applyLayoutOptions_ = function(layoutOptions, flatCoordinates, ends) {
var layout = ol.geom.GeometryLayout.XY;
var stride = 2;
if (layoutOptions.hasZ && layoutOptions.hasM) {
layout = ol.geom.GeometryLayout.XYZM;
stride = 4;
} else if (layoutOptions.hasZ) {
layout = ol.geom.GeometryLayout.XYZ;
stride = 3;
} else if (layoutOptions.hasM) {
layout = ol.geom.GeometryLayout.XYM;
stride = 3;
}
if (stride !== 4) {
var i, ii;
for (i = 0, ii = flatCoordinates.length / 4; i < ii; i++) {
flatCoordinates[i * stride] = flatCoordinates[i * 4];
flatCoordinates[i * stride + 1] = flatCoordinates[i * 4 + 1];
if (layoutOptions.hasZ) {
flatCoordinates[i * stride + 2] = flatCoordinates[i * 4 + 2];
}
if (layoutOptions.hasM) {
flatCoordinates[i * stride + 2] = flatCoordinates[i * 4 + 3];
}
}
flatCoordinates.length = flatCoordinates.length / 4 * stride;
if (ends) {
for (i = 0, ii = ends.length; i < ii; i++) {
ends[i] = ends[i] / 4 * stride;
}
}
}
return layout;
};
/**
* @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack.
@@ -141,7 +189,9 @@ ol.format.GPX.parseRtePt_ = function(node, objectStack) {
var rteValues = /** @type {Object} */ (objectStack[objectStack.length - 1]);
var flatCoordinates = /** @type {Array.<number>} */
(rteValues['flatCoordinates']);
ol.format.GPX.appendCoordinate_(flatCoordinates, node, values);
var layoutOptions = /** @type {ol.LayoutOptions} */
(rteValues['layoutOptions']);
ol.format.GPX.appendCoordinate_(flatCoordinates, layoutOptions, node, values);
}
};
@@ -161,7 +211,9 @@ ol.format.GPX.parseTrkPt_ = function(node, objectStack) {
var trkValues = /** @type {Object} */ (objectStack[objectStack.length - 1]);
var flatCoordinates = /** @type {Array.<number>} */
(trkValues['flatCoordinates']);
ol.format.GPX.appendCoordinate_(flatCoordinates, node, values);
var layoutOptions = /** @type {ol.LayoutOptions} */
(trkValues['layoutOptions']);
ol.format.GPX.appendCoordinate_(flatCoordinates, layoutOptions, node, values);
}
};
@@ -197,7 +249,8 @@ ol.format.GPX.readRte_ = function(node, objectStack) {
ol.DEBUG && console.assert(node.localName == 'rte', 'localName should be rte');
var options = /** @type {olx.format.ReadOptions} */ (objectStack[0]);
var values = ol.xml.pushParseAndPop({
'flatCoordinates': []
'flatCoordinates': [],
'layoutOptions': {}
}, ol.format.GPX.RTE_PARSERS_, node, objectStack);
if (!values) {
return undefined;
@@ -205,8 +258,11 @@ ol.format.GPX.readRte_ = function(node, objectStack) {
var flatCoordinates = /** @type {Array.<number>} */
(values['flatCoordinates']);
delete values['flatCoordinates'];
var layoutOptions = /** @type {ol.LayoutOptions} */ (values['layoutOptions']);
delete values['layoutOptions'];
var layout = ol.format.GPX.applyLayoutOptions_(layoutOptions, flatCoordinates);
var geometry = new ol.geom.LineString(null);
geometry.setFlatCoordinates(ol.geom.GeometryLayout.XYZM, flatCoordinates);
geometry.setFlatCoordinates(layout, flatCoordinates);
ol.format.Feature.transformWithOptions(geometry, false, options);
var feature = new ol.Feature(geometry);
feature.setProperties(values);
@@ -227,7 +283,8 @@ ol.format.GPX.readTrk_ = function(node, objectStack) {
var options = /** @type {olx.format.ReadOptions} */ (objectStack[0]);
var values = ol.xml.pushParseAndPop({
'flatCoordinates': [],
'ends': []
'ends': [],
'layoutOptions': {}
}, ol.format.GPX.TRK_PARSERS_, node, objectStack);
if (!values) {
return undefined;
@@ -237,9 +294,11 @@ ol.format.GPX.readTrk_ = function(node, objectStack) {
delete values['flatCoordinates'];
var ends = /** @type {Array.<number>} */ (values['ends']);
delete values['ends'];
var layoutOptions = /** @type {ol.LayoutOptions} */ (values['layoutOptions']);
delete values['layoutOptions'];
var layout = ol.format.GPX.applyLayoutOptions_(layoutOptions, flatCoordinates, ends);
var geometry = new ol.geom.MultiLineString(null);
geometry.setFlatCoordinates(
ol.geom.GeometryLayout.XYZM, flatCoordinates, ends);
geometry.setFlatCoordinates(layout, flatCoordinates, ends);
ol.format.Feature.transformWithOptions(geometry, false, options);
var feature = new ol.Feature(geometry);
feature.setProperties(values);
@@ -263,9 +322,10 @@ ol.format.GPX.readWpt_ = function(node, objectStack) {
if (!values) {
return undefined;
}
var coordinates = ol.format.GPX.appendCoordinate_([], node, values);
var geometry = new ol.geom.Point(
coordinates, ol.geom.GeometryLayout.XYZM);
var layoutOptions = /** @type {ol.LayoutOptions} */ ({});
var coordinates = ol.format.GPX.appendCoordinate_([], layoutOptions, node, values);
var layout = ol.format.GPX.applyLayoutOptions_(layoutOptions, coordinates);
var geometry = new ol.geom.Point(coordinates, layout);
ol.format.Feature.transformWithOptions(geometry, false, options);
var feature = new ol.Feature(geometry);
feature.setProperties(values);