@@ -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);
|
||||
|
||||
@@ -311,6 +311,12 @@ ol.KMLGxTrackObject_;
|
||||
ol.LayerState;
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{hasZ: (boolean|undefined), hasM: (boolean|undefined)}}
|
||||
*/
|
||||
ol.LayoutOptions;
|
||||
|
||||
|
||||
/**
|
||||
* A function that takes an {@link ol.Extent} and a resolution as arguments, and
|
||||
* returns an array of {@link ol.Extent} with the extents to load. Usually this
|
||||
|
||||
@@ -42,7 +42,7 @@ describe('ol.format.GPX', function() {
|
||||
var g = f.getGeometry();
|
||||
expect(g).to.be.an(ol.geom.LineString);
|
||||
expect(g.getCoordinates()).to.eql([]);
|
||||
expect(g.getLayout()).to.be('XYZM');
|
||||
expect(g.getLayout()).to.be('XY');
|
||||
});
|
||||
|
||||
it('can read and write various rte attributes', function() {
|
||||
@@ -98,8 +98,8 @@ describe('ol.format.GPX', function() {
|
||||
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('XYZM');
|
||||
expect(g.getCoordinates()).to.eql([[2, 1], [4, 3]]);
|
||||
expect(g.getLayout()).to.be('XY');
|
||||
var serialized = format.writeFeaturesNode(fs);
|
||||
expect(serialized).to.xmleql(ol.xml.parse(text));
|
||||
});
|
||||
@@ -124,11 +124,9 @@ describe('ol.format.GPX', function() {
|
||||
var g = f.getGeometry();
|
||||
expect(g).to.be.an(ol.geom.LineString);
|
||||
var p1 = ol.proj.transform([2, 1], 'EPSG:4326', 'EPSG:3857');
|
||||
p1.push(0, 0);
|
||||
var p2 = ol.proj.transform([6, 5], 'EPSG:4326', 'EPSG:3857');
|
||||
p2.push(0, 0);
|
||||
expect(g.getCoordinates()).to.eql([p1, p2]);
|
||||
expect(g.getLayout()).to.be('XYZM');
|
||||
expect(g.getLayout()).to.be('XY');
|
||||
var serialized = format.writeFeaturesNode(fs, {
|
||||
featureProjection: 'EPSG:3857'
|
||||
});
|
||||
@@ -168,7 +166,7 @@ describe('ol.format.GPX', function() {
|
||||
var g = f.getGeometry();
|
||||
expect(g).to.be.an(ol.geom.MultiLineString);
|
||||
expect(g.getCoordinates()).to.eql([]);
|
||||
expect(g.getLayout()).to.be('XYZM');
|
||||
expect(g.getLayout()).to.be('XY');
|
||||
});
|
||||
|
||||
it('can read and write various trk attributes', function() {
|
||||
@@ -224,7 +222,7 @@ describe('ol.format.GPX', function() {
|
||||
var g = f.getGeometry();
|
||||
expect(g).to.be.an(ol.geom.MultiLineString);
|
||||
expect(g.getCoordinates()).to.eql([[]]);
|
||||
expect(g.getLayout()).to.be('XYZM');
|
||||
expect(g.getLayout()).to.be('XY');
|
||||
var serialized = format.writeFeaturesNode(fs);
|
||||
expect(serialized).to.xmleql(ol.xml.parse(text));
|
||||
});
|
||||
@@ -398,8 +396,8 @@ describe('ol.format.GPX', function() {
|
||||
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('XYZM');
|
||||
expect(g.getCoordinates()).to.eql([2, 1]);
|
||||
expect(g.getLayout()).to.be('XY');
|
||||
var serialized = format.writeFeaturesNode(fs);
|
||||
expect(serialized).to.xmleql(ol.xml.parse(text));
|
||||
});
|
||||
@@ -421,9 +419,8 @@ describe('ol.format.GPX', function() {
|
||||
var g = f.getGeometry();
|
||||
expect(g).to.be.an(ol.geom.Point);
|
||||
var expectedPoint = ol.proj.transform([2, 1], 'EPSG:4326', 'EPSG:3857');
|
||||
expectedPoint.push(0, 0);
|
||||
expect(g.getCoordinates()).to.eql(expectedPoint);
|
||||
expect(g.getLayout()).to.be('XYZM');
|
||||
expect(g.getLayout()).to.be('XY');
|
||||
var serialized = format.writeFeaturesNode(fs, {
|
||||
featureProjection: 'EPSG:3857'
|
||||
});
|
||||
@@ -446,8 +443,8 @@ describe('ol.format.GPX', function() {
|
||||
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('XYZM');
|
||||
expect(g.getCoordinates()).to.eql([2, 1, 3]);
|
||||
expect(g.getLayout()).to.be('XYZ');
|
||||
var serialized = format.writeFeaturesNode(fs);
|
||||
expect(serialized).to.xmleql(ol.xml.parse(text));
|
||||
});
|
||||
@@ -468,8 +465,8 @@ describe('ol.format.GPX', function() {
|
||||
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('XYZM');
|
||||
expect(g.getCoordinates()).to.eql([2, 1, 1263115752]);
|
||||
expect(g.getLayout()).to.be('XYM');
|
||||
var serialized = format.writeFeaturesNode(fs);
|
||||
expect(serialized).to.xmleql(ol.xml.parse(text));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user