diff --git a/src/ol/extent.js b/src/ol/extent.js index 0edfa2a8ca..5595382e7c 100644 --- a/src/ol/extent.js +++ b/src/ol/extent.js @@ -109,9 +109,9 @@ ol.Extent.prototype.getTopRight = function() { */ ol.Extent.prototype.transform = function(transformFn) { var input = [this.minX, this.minY, this.maxX, this.maxY]; - var output = transformFn(input, 2); - return new ol.Extent(Math.min(output[0], output[2]), - Math.min(output[1], output[3]), - Math.max(output[0], output[2]), - Math.max(output[1], output[3])); + input = transformFn(input, input, 2); + return new ol.Extent(Math.min(input[0], input[2]), + Math.min(input[1], input[3]), + Math.max(input[0], input[2]), + Math.max(input[1], input[3])); }; diff --git a/src/ol/geolocation.js b/src/ol/geolocation.js index 69052832b2..bb90723f15 100644 --- a/src/ol/geolocation.js +++ b/src/ol/geolocation.js @@ -233,6 +233,7 @@ goog.exportProperty( /** * @private * @param {Array.} input Input coordinate values. + * @param {Array.=} opt_output Output array of coordinate values. * @param {number=} opt_dimension Dimension (default is 2). * @return {Array.} Output coordinate values. */ diff --git a/src/ol/projection.js b/src/ol/projection.js index 80e8c1dbe2..86ac70b6a5 100644 --- a/src/ol/projection.js +++ b/src/ol/projection.js @@ -398,20 +398,24 @@ ol.projection.getTransform = function(source, destination) { transform = /** * @param {Array.} input Input coordinate values. + * @param {Array.=} opt_output Output array of coordinates. * @param {number=} opt_dimension Dimension. * @return {Array.} Output coordinate values. */ - function(input, opt_dimension) { + function(input, opt_output, opt_dimension) { var length = input.length, - dimension = goog.isDef(opt_dimension) ? opt_dimension : 2, - output, proj4jsPoint; - if (dimension > 2) { - // preserve values beyond second dimension - output = input.slice(); - } else { - output = new Array(length); + dimension = opt_dimension > 1 ? opt_dimension : 2, + output = opt_output; + if (!goog.isDef(output)) { + if (dimension > 2) { + // preserve values beyond second dimension + output = input.slice(); + } else { + output = new Array(length); + } } goog.asserts.assert(output.length % dimension === 0); + var proj4jsPoint; for (var i = 0; i < length; i += dimension) { proj4jsPoint = new Proj4js.Point(input[i], input[i + 1]); proj4jsPoint = Proj4js.transform( @@ -449,21 +453,23 @@ ol.projection.getTransformFromCodes = function(sourceCode, destinationCode) { /** * @param {Array.} input Input coordinate array. + * @param {Array.=} opt_output Output array of coordinate values. * @param {number=} opt_dimension Dimension. * @return {Array.} Input coordinate array (same array as input). */ -ol.projection.identityTransform = function(input, opt_dimension) { +ol.projection.identityTransform = function(input, opt_output, opt_dimension) { return input; }; /** * @param {Array.} input Input coordinate array. + * @param {Array.=} opt_output Output array of coordinate values. * @param {number=} opt_dimension Dimension. * @return {Array.} Output coordinate array (new array, same coordinate * values). */ -ol.projection.cloneTransform = function(input, opt_dimension) { +ol.projection.cloneTransform = function(input, opt_output, opt_dimension) { return input.slice(); }; diff --git a/src/ol/projection/epsg3857.js b/src/ol/projection/epsg3857.js index 2050aca7d2..0d183c3e66 100644 --- a/src/ol/projection/epsg3857.js +++ b/src/ol/projection/epsg3857.js @@ -73,18 +73,22 @@ ol.projection.EPSG3857.PROJECTIONS = goog.array.map( * Transformation from EPSG:4326 to EPSG:3857. * * @param {Array.} input Input array of coordinate values. + * @param {Array.=} opt_output Output array of coordinate values. * @param {number=} opt_dimension Dimension (default is 2). * @return {Array.} Output array of coordinate values. */ -ol.projection.EPSG3857.fromEPSG4326 = function(input, opt_dimension) { +ol.projection.EPSG3857.fromEPSG4326 = function( + input, opt_output, opt_dimension) { var length = input.length, - dimension = goog.isDef(opt_dimension) ? opt_dimension : 2, - output; - if (dimension > 2) { - // preserve values beyond second dimension - output = input.slice(); - } else { - output = new Array(length); + dimension = opt_dimension > 1 ? opt_dimension : 2, + output = opt_output; + if (!goog.isDef(output)) { + if (dimension > 2) { + // preserve values beyond second dimension + output = input.slice(); + } else { + output = new Array(length); + } } goog.asserts.assert(output.length % dimension === 0); for (var i = 0; i < length; i += dimension) { @@ -100,18 +104,21 @@ ol.projection.EPSG3857.fromEPSG4326 = function(input, opt_dimension) { * Transformation from EPSG:3857 to EPSG:4326. * * @param {Array.} input Input array of coordinate values. + * @param {Array.=} opt_output Output array of coordinate values. * @param {number=} opt_dimension Dimension (default is 2). * @return {Array.} Output array of coordinate values. */ -ol.projection.EPSG3857.toEPSG4326 = function(input, opt_dimension) { +ol.projection.EPSG3857.toEPSG4326 = function(input, opt_output, opt_dimension) { var length = input.length, - dimension = goog.isDef(opt_dimension) ? opt_dimension : 2, - output; - if (dimension > 2) { - // preserve values beyond second dimension - output = input.slice(); - } else { - output = new Array(length); + dimension = opt_dimension > 1 ? opt_dimension : 2, + output = opt_output; + if (!goog.isDef(output)) { + if (dimension > 2) { + // preserve values beyond second dimension + output = input.slice(); + } else { + output = new Array(length); + } } goog.asserts.assert(output.length % dimension === 0); for (var i = 0; i < length; i += dimension) { diff --git a/src/ol/transformfunction.js b/src/ol/transformfunction.js index 65b5a6c585..b5fb315d69 100644 --- a/src/ol/transformfunction.js +++ b/src/ol/transformfunction.js @@ -2,10 +2,11 @@ goog.provide('ol.TransformFunction'); /** - * A transform function accepts an array of input coordinate values and an - * optional dimension (default should be 2). The function transforms the - * coordinate values and returns an array of the same length as the input. + * A transform function accepts an array of input coordinate values, an optional + * output array, and an optional dimension (default should be 2). The function + * transforms the input coordinate values, populates the output array, and + * returns the output array. * - * @typedef {function(Array., number=): Array.} + * @typedef {function(Array., Array.=, number=): Array.} */ ol.TransformFunction; diff --git a/test/spec/ol/projection.test.js b/test/spec/ol/projection.test.js index a840a6f0f4..5a217e0f40 100644 --- a/test/spec/ol/projection.test.js +++ b/test/spec/ol/projection.test.js @@ -215,6 +215,21 @@ describe('ol.projection', function() { expect(output[5]).toRoughlyEqual(52.4827802220782, 1e-9); }); + it('accepts an optional destination array', function() { + var transform = ol.projection.getTransformFromCodes( + 'EPSG:3857', 'EPSG:4326'); + var input = [-12000000, 5000000]; + var output = []; + + var got = transform(input, output); + expect(got).toBe(output); + + expect(output[0]).toRoughlyEqual(-107.79783409434258, 1e-9); + expect(output[1]).toRoughlyEqual(40.91627447067577, 1e-9); + + expect(input).toEqual([-12000000, 5000000]); + }); + it('accepts a dimension', function() { var transform = ol.projection.getTransformFromCodes( 'GOOGLE', 'EPSG:4326'); @@ -225,7 +240,7 @@ describe('ol.projection', function() { -626172.13571216376, 6887893.4928337997, 100, -12000000, 5000000, 200, -626172.13571216376, 6887893.4928337997, 300 - ], dimension); + ], undefined, dimension); expect(output[0]).toRoughlyEqual(-5.625, 1e-9); expect(output[1]).toRoughlyEqual(52.4827802220782, 1e-9); @@ -247,7 +262,7 @@ describe('ol.projection', function() { it('removes functions cached by addTransform', function() { var foo = new ol.Projection('foo', units, extent); var bar = new ol.Projection('bar', units, extent); - var transform = function(intput, dimension) {return input}; + var transform = function(input, output, dimension) {return input}; ol.projection.addTransform(foo, bar, transform); expect(ol.projection.transforms_).not.toBeUndefined(); expect(ol.projection.transforms_.foo).not.toBeUndefined();