Implement read/write transforms for ol.format.GPX
This commit is contained in:
@@ -124,15 +124,15 @@ ol.format.Feature.prototype.writeGeometry = goog.abstractMethod;
|
||||
|
||||
/**
|
||||
* @param {ol.geom.Geometry} geometry Geometry.
|
||||
* @param {boolean} write Set to true for writing, false for reading. For
|
||||
* writing, the geometry will be cloned before transforming.
|
||||
* @param {boolean} write Set to true for writing, false for reading.
|
||||
* @param {boolean} clone The geometry will be cloned before transforming.
|
||||
* @param {(olx.format.WriteOptions|olx.format.ReadOptions)=} opt_options
|
||||
* Options.
|
||||
* @return {ol.geom.Geometry} Transformed geometry.
|
||||
* @protected
|
||||
*/
|
||||
ol.format.Feature.transformWithOptions = function(
|
||||
geometry, write, opt_options) {
|
||||
geometry, write, clone, opt_options) {
|
||||
var featureProjection = goog.isDef(opt_options) ?
|
||||
ol.proj.get(opt_options.featureProjection) : null;
|
||||
var dataProjection = goog.isDef(opt_options) ?
|
||||
|
||||
@@ -76,7 +76,7 @@ ol.format.GeoJSON.readGeometry_ = function(object, opt_options) {
|
||||
var geometryReader = ol.format.GeoJSON.GEOMETRY_READERS_[object.type];
|
||||
goog.asserts.assert(goog.isDef(geometryReader));
|
||||
return ol.format.Feature.transformWithOptions(
|
||||
geometryReader(object), false, opt_options);
|
||||
geometryReader(object), false, false, opt_options);
|
||||
};
|
||||
|
||||
|
||||
@@ -177,7 +177,8 @@ ol.format.GeoJSON.writeGeometry_ = function(geometry, opt_options) {
|
||||
var geometryWriter = ol.format.GeoJSON.GEOMETRY_WRITERS_[geometry.getType()];
|
||||
goog.asserts.assert(goog.isDef(geometryWriter));
|
||||
return geometryWriter(
|
||||
ol.format.Feature.transformWithOptions(geometry, true, opt_options));
|
||||
ol.format.Feature.transformWithOptions(
|
||||
geometry, true, true, opt_options));
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -162,7 +162,8 @@ ol.format.GML.readGeometry = function(node, objectStack) {
|
||||
var geometry = ol.xml.pushParseAndPop(/** @type {ol.geom.Geometry} */(null),
|
||||
ol.format.GML.GEOMETRY_PARSERS_, node, objectStack);
|
||||
if (goog.isDefAndNotNull(geometry)) {
|
||||
return ol.format.Feature.transformWithOptions(geometry, false, context);
|
||||
return ol.format.Feature.transformWithOptions(
|
||||
geometry, false, false, context);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
@@ -1467,7 +1468,8 @@ ol.format.GML.writeGeometry = function(node, geometry, objectStack) {
|
||||
}
|
||||
} else {
|
||||
goog.asserts.assertInstanceof(geometry, ol.geom.Geometry);
|
||||
value = ol.format.Feature.transformWithOptions(geometry, true, context);
|
||||
value =
|
||||
ol.format.Feature.transformWithOptions(geometry, true, true, context);
|
||||
}
|
||||
ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */
|
||||
(item), ol.format.GML.GEOMETRY_SERIALIZERS_,
|
||||
|
||||
@@ -415,6 +415,7 @@ ol.format.GPX.prototype.handleReadExtensions_ = function(features) {
|
||||
*
|
||||
* @function
|
||||
* @param {ArrayBuffer|Document|Node|Object|string} source Source.
|
||||
* @param {olx.format.ReadOptions=} opt_options Read options.
|
||||
* @return {ol.Feature} Feature.
|
||||
* @api
|
||||
*/
|
||||
@@ -424,7 +425,7 @@ ol.format.GPX.prototype.readFeature;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.format.GPX.prototype.readFeatureFromNode = function(node) {
|
||||
ol.format.GPX.prototype.readFeatureFromNode = function(node, opt_options) {
|
||||
goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT);
|
||||
if (!goog.array.contains(ol.format.GPX.NAMESPACE_URIS_, node.namespaceURI)) {
|
||||
return null;
|
||||
@@ -438,6 +439,8 @@ ol.format.GPX.prototype.readFeatureFromNode = function(node) {
|
||||
return null;
|
||||
}
|
||||
this.handleReadExtensions_([feature]);
|
||||
ol.format.XMLFeature.transformFeaturesWithOptions(
|
||||
[feature], false, this.getReadOptions(node, opt_options));
|
||||
return feature;
|
||||
};
|
||||
|
||||
@@ -447,6 +450,7 @@ ol.format.GPX.prototype.readFeatureFromNode = function(node) {
|
||||
*
|
||||
* @function
|
||||
* @param {ArrayBuffer|Document|Node|Object|string} source Source.
|
||||
* @param {olx.format.ReadOptions=} opt_options Read options.
|
||||
* @return {Array.<ol.Feature>} Features.
|
||||
* @api
|
||||
*/
|
||||
@@ -456,7 +460,7 @@ ol.format.GPX.prototype.readFeatures;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.format.GPX.prototype.readFeaturesFromNode = function(node) {
|
||||
ol.format.GPX.prototype.readFeaturesFromNode = function(node, opt_options) {
|
||||
goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT);
|
||||
if (!goog.array.contains(ol.format.GPX.NAMESPACE_URIS_, node.namespaceURI)) {
|
||||
return [];
|
||||
@@ -467,6 +471,8 @@ ol.format.GPX.prototype.readFeaturesFromNode = function(node) {
|
||||
node, []);
|
||||
if (goog.isDef(features)) {
|
||||
this.handleReadExtensions_(features);
|
||||
ol.format.XMLFeature.transformFeaturesWithOptions(
|
||||
features, false, this.getReadOptions(node, opt_options));
|
||||
return features;
|
||||
} else {
|
||||
return [];
|
||||
@@ -845,6 +851,7 @@ ol.format.GPX.GPX_SERIALIZERS_ = ol.xml.makeStructureNS(
|
||||
*
|
||||
* @function
|
||||
* @param {Array.<ol.Feature>} features Features.
|
||||
* @param {olx.format.WriteOptions=} opt_options Write options.
|
||||
* @return {Node} Result.
|
||||
* @api
|
||||
*/
|
||||
@@ -854,9 +861,20 @@ ol.format.GPX.prototype.writeFeatures;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.format.GPX.prototype.writeFeaturesNode = function(features) {
|
||||
ol.format.GPX.prototype.writeFeaturesNode = function(features, opt_options) {
|
||||
//FIXME Serialize metadata
|
||||
var gpx = ol.xml.createElementNS('http://www.topografix.com/GPX/1/1', 'gpx');
|
||||
if (goog.isDef(opt_options)) {
|
||||
if (!goog.isDef(opt_options.dataProjection)) {
|
||||
// for convenience set a default dataProjection
|
||||
opt_options = {
|
||||
featureProjection: opt_options.featureProjection,
|
||||
dataProjection: this.readProjectionFromDocument(null)
|
||||
};
|
||||
}
|
||||
}
|
||||
features = ol.format.XMLFeature.transformFeaturesWithOptions(
|
||||
features, true, opt_options);
|
||||
ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */
|
||||
({node: gpx}), ol.format.GPX.GPX_SERIALIZERS_,
|
||||
ol.format.GPX.GPX_NODE_FACTORY_, features, []);
|
||||
|
||||
@@ -260,7 +260,7 @@ ol.format.TopoJSON.readFeatureFromGeometry_ = function(object, arcs,
|
||||
}
|
||||
var feature = new ol.Feature();
|
||||
feature.setGeometry(ol.format.Feature.transformWithOptions(
|
||||
geometry, false, opt_options));
|
||||
geometry, false, false, opt_options));
|
||||
if (goog.isDef(object.id)) {
|
||||
feature.setId(object.id);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ goog.require('goog.asserts');
|
||||
goog.require('goog.dom.NodeType');
|
||||
goog.require('ol.format.Feature');
|
||||
goog.require('ol.format.FormatType');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.xml');
|
||||
|
||||
|
||||
@@ -243,3 +244,36 @@ ol.format.XMLFeature.prototype.writeGeometry = function(geometry, opt_options) {
|
||||
* @return {Node} Node.
|
||||
*/
|
||||
ol.format.XMLFeature.prototype.writeGeometryNode = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @param {Array.<ol.Feature>} features Features.
|
||||
* @param {boolean} write Set to true for writing, false for reading. For
|
||||
* writing, the features will be cloned before transforming.
|
||||
* @param {(olx.format.WriteOptions|olx.format.ReadOptions)=} opt_options
|
||||
* Options.
|
||||
* @protected
|
||||
* @return {Array.<ol.Feature>} Features.
|
||||
*/
|
||||
ol.format.XMLFeature.transformFeaturesWithOptions = function(
|
||||
features, write, opt_options) {
|
||||
var featureProjection = goog.isDef(opt_options) ?
|
||||
ol.proj.get(opt_options.featureProjection) : null;
|
||||
var dataProjection = goog.isDef(opt_options) ?
|
||||
ol.proj.get(opt_options.dataProjection) : null;
|
||||
|
||||
if (!goog.isNull(featureProjection) && !goog.isNull(dataProjection) &&
|
||||
!ol.proj.equivalent(featureProjection, dataProjection)) {
|
||||
if (write) {
|
||||
features = goog.array.map(features, function(feature) {
|
||||
return feature.clone();
|
||||
});
|
||||
}
|
||||
|
||||
goog.array.forEach(features, function(feature) {
|
||||
feature.setGeometry(ol.format.Feature.transformWithOptions(
|
||||
feature.getGeometry(), write, false, opt_options));
|
||||
});
|
||||
}
|
||||
return features;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
goog.provide('ol.test.format.GPX');
|
||||
|
||||
goog.require('ol.proj');
|
||||
|
||||
describe('ol.format.GPX', function() {
|
||||
|
||||
@@ -80,6 +81,34 @@ describe('ol.format.GPX', function() {
|
||||
expect(serialized).to.xmleql(ol.xml.load(text));
|
||||
});
|
||||
|
||||
it('can transform, read and write a rte', function() {
|
||||
var text =
|
||||
'<gpx xmlns="http://www.topografix.com/GPX/1/1">' +
|
||||
' <rte>' +
|
||||
' <rtept lat="1" lon="2"/>' +
|
||||
' <rtept lat="5" lon="6"/>' +
|
||||
' </rte>' +
|
||||
'</gpx>';
|
||||
var fs = format.readFeatures(text, {
|
||||
featureProjection: 'EPSG:3857'
|
||||
});
|
||||
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);
|
||||
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(ol.geom.GeometryLayout.XYZM);
|
||||
var serialized = format.writeFeatures(fs, {
|
||||
featureProjection: 'EPSG:3857'
|
||||
});
|
||||
expect(serialized).to.xmleql(ol.xml.load(text));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('trk', function() {
|
||||
@@ -181,6 +210,42 @@ describe('ol.format.GPX', function() {
|
||||
expect(serialized).to.xmleql(ol.xml.load(text));
|
||||
});
|
||||
|
||||
it('can tranform, read and write a trk with a trkseg', 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, {
|
||||
featureProjection: 'EPSG:3857'
|
||||
});
|
||||
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);
|
||||
var p1 = ol.proj.transform([2, 1], 'EPSG:4326', 'EPSG:3857');
|
||||
p1.push(3, 1263115752);
|
||||
var p2 = ol.proj.transform([6, 5], 'EPSG:4326', 'EPSG:3857');
|
||||
p2.push(7, 1263115812);
|
||||
expect(g.getCoordinates()).to.eql([[p1, p2]]);
|
||||
expect(g.getLayout()).to.be(ol.geom.GeometryLayout.XYZM);
|
||||
var serialized = format.writeFeatures(fs, {
|
||||
featureProjection: 'EPSG:3857'
|
||||
});
|
||||
expect(serialized).to.xmleql(ol.xml.load(text));
|
||||
});
|
||||
|
||||
it('can read and write a trk with multiple trksegs', function() {
|
||||
var text =
|
||||
'<gpx xmlns="http://www.topografix.com/GPX/1/1">' +
|
||||
@@ -243,6 +308,29 @@ describe('ol.format.GPX', function() {
|
||||
expect(serialized).to.xmleql(ol.xml.load(text));
|
||||
});
|
||||
|
||||
it('can transform, read and write 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, {
|
||||
featureProjection: 'EPSG:3857'
|
||||
});
|
||||
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);
|
||||
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(ol.geom.GeometryLayout.XYZM);
|
||||
var serialized = format.writeFeatures(fs, {
|
||||
featureProjection: 'EPSG:3857'
|
||||
});
|
||||
expect(serialized).to.xmleql(ol.xml.load(text));
|
||||
});
|
||||
|
||||
it('can read and write a wpt with ele', function() {
|
||||
var text =
|
||||
'<gpx xmlns="http://www.topografix.com/GPX/1/1">' +
|
||||
|
||||
Reference in New Issue
Block a user