From e448f100fdea4a804957623b32ea2fcf6d0848c2 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Fri, 2 May 2014 11:47:59 -0600 Subject: [PATCH] Add a transform method to geometries This accepts CRS identifiers for source and destination, transforms the geometry in place, and returns a reference to the geometry. --- src/ol/geom/geometry.js | 19 +++++++++++++ test/spec/ol/geom/geometrycollection.test.js | 29 ++++++++++++++++++++ test/spec/ol/geom/multipoint.test.js | 19 +++++++++++++ test/spec/ol/geom/point.test.js | 25 +++++++++++++++++ 4 files changed, 92 insertions(+) diff --git a/src/ol/geom/geometry.js b/src/ol/geom/geometry.js index 664ab20a18..9e1559fae1 100644 --- a/src/ol/geom/geometry.js +++ b/src/ol/geom/geometry.js @@ -4,6 +4,7 @@ goog.provide('ol.geom.GeometryType'); goog.require('goog.asserts'); goog.require('goog.functions'); goog.require('ol.Observable'); +goog.require('ol.proj'); /** @@ -166,6 +167,24 @@ ol.geom.Geometry.prototype.getType = goog.abstractMethod; ol.geom.Geometry.prototype.applyTransform = goog.abstractMethod; +/** + * Transform a geometry from one coordinate reference system to another. + * Modifies the geometry in place. + * + * @param {ol.proj.ProjectionLike} source The current projection. Can be a + * string identifier or a {@link ol.proj.Projection} object. + * @param {ol.proj.ProjectionLike} destination The desired projection. Can be a + * string identifier or a {@link ol.proj.Projection} object. + * @return {ol.geom.Geometry} This geometry. Note that original geometry is + * modified in place. + * @todo api + */ +ol.geom.Geometry.prototype.transform = function(source, destination) { + this.applyTransform(ol.proj.getTransform(source, destination)); + return this; +}; + + /** * @typedef {ol.Coordinate} */ diff --git a/test/spec/ol/geom/geometrycollection.test.js b/test/spec/ol/geom/geometrycollection.test.js index 26d8d9f9eb..f5952be233 100644 --- a/test/spec/ol/geom/geometrycollection.test.js +++ b/test/spec/ol/geom/geometrycollection.test.js @@ -139,6 +139,35 @@ describe('ol.geom.GeometryCollection', function() { }); + describe('#transform()', function() { + + var line, multi, point; + beforeEach(function() { + point = new ol.geom.Point([10, 20]); + line = new ol.geom.LineString([[10, 20], [30, 40]]); + multi = new ol.geom.GeometryCollection([point, line]); + }); + + it('transforms all geometries', function() { + multi.transform('EPSG:4326', 'EPSG:3857'); + + var geometries = multi.getGeometries(); + expect(geometries[0]).to.be.a(ol.geom.Point); + expect(geometries[1]).to.be.a(ol.geom.LineString); + + var coords = geometries[0].getCoordinates(); + expect(coords[0]).to.roughlyEqual(1113194.90, 1e-2); + expect(coords[1]).to.roughlyEqual(2273030.92, 1e-2); + + coords = geometries[1].getCoordinates(); + expect(coords[0][0]).to.roughlyEqual(1113194.90, 1e-2); + expect(coords[0][1]).to.roughlyEqual(2273030.92, 1e-2); + expect(coords[1][0]).to.roughlyEqual(3339584.72, 1e-2); + expect(coords[1][1]).to.roughlyEqual(4865942.27, 1e-2); + }); + + }); + }); diff --git a/test/spec/ol/geom/multipoint.test.js b/test/spec/ol/geom/multipoint.test.js index c8c2ae877d..a6b3a472b6 100644 --- a/test/spec/ol/geom/multipoint.test.js +++ b/test/spec/ol/geom/multipoint.test.js @@ -230,6 +230,25 @@ describe('ol.geom.MultiPoint', function() { }); + describe('#transform()', function() { + + it('transforms a geometry given CRS identifiers', function() { + var multi = new ol.geom.MultiPoint([[-111, 45], [111, -45]]).transform( + 'EPSG:4326', 'EPSG:3857'); + + expect(multi).to.be.a(ol.geom.MultiPoint); + + var coords = multi.getCoordinates(); + + expect(coords[0][0]).to.roughlyEqual(-12356463.47, 1e-2); + expect(coords[0][1]).to.roughlyEqual(5621521.48, 1e-2); + + expect(coords[1][0]).to.roughlyEqual(12356463.47, 1e-2); + expect(coords[1][1]).to.roughlyEqual(-5621521.48, 1e-2); + }); + + }); + }); diff --git a/test/spec/ol/geom/point.test.js b/test/spec/ol/geom/point.test.js index d7fa67dbf2..f32f86f23c 100644 --- a/test/spec/ol/geom/point.test.js +++ b/test/spec/ol/geom/point.test.js @@ -142,6 +142,31 @@ describe('ol.geom.Point', function() { }); + describe('#transform()', function() { + + it('transforms a geometry given CRS identifiers', function() { + var point = new ol.geom.Point([-111, 45]).transform( + 'EPSG:4326', 'EPSG:3857'); + + expect(point).to.be.a(ol.geom.Point); + + var coords = point.getCoordinates(); + + expect(coords[0]).to.roughlyEqual(-12356463.47, 1e-2); + expect(coords[1]).to.roughlyEqual(5621521.48, 1e-2); + }); + + it('modifies the original', function() { + var point = new ol.geom.Point([-111, 45]); + point.transform('EPSG:4326', 'EPSG:3857'); + var coords = point.getCoordinates(); + + expect(coords[0]).to.roughlyEqual(-12356463.47, 1e-2); + expect(coords[1]).to.roughlyEqual(5621521.48, 1e-2); + }); + + }); + });