From 24f8cba0a104ef92c889bc152e5c978ad5142f56 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Wed, 6 Jan 2016 13:46:29 +0100 Subject: [PATCH] Simplify meters per unit handling --- externs/olx.js | 10 ++++++++++ src/ol/proj/epsg4326projection.js | 9 +++++++++ src/ol/proj/proj.js | 24 +++++++++++++----------- test/spec/ol/proj/proj.test.js | 4 +++- test/spec/ol/reproj/reproj.test.js | 3 ++- 5 files changed, 37 insertions(+), 13 deletions(-) diff --git a/externs/olx.js b/externs/olx.js index c38031e27d..24da980b50 100644 --- a/externs/olx.js +++ b/externs/olx.js @@ -429,6 +429,7 @@ olx.OverlayOptions.prototype.autoPanMargin; * extent: (ol.Extent|undefined), * axisOrientation: (string|undefined), * global: (boolean|undefined), + * metersPerUnit: (number|undefined), * worldExtent: (ol.Extent|undefined), * getPointResolution: (function(number, ol.Coordinate):number|undefined) }} * @api @@ -476,6 +477,15 @@ olx.ProjectionOptions.prototype.axisOrientation; olx.ProjectionOptions.prototype.global; +/** + * The meters per unit for the SRS. If not provided, the `units` are used to get + * the meters per unit from the {@link ol.proj.METERS_PER_UNIT} lookup table. + * @type {number|undefined} + * @api + */ +olx.ProjectionOptions.prototype.metersPerUnit; + + /** * The world extent for the SRS. * @type {ol.Extent|undefined} diff --git a/src/ol/proj/epsg4326projection.js b/src/ol/proj/epsg4326projection.js index cbbf571d8e..336f1edb4c 100644 --- a/src/ol/proj/epsg4326projection.js +++ b/src/ol/proj/epsg4326projection.js @@ -3,6 +3,7 @@ goog.provide('ol.proj.EPSG4326'); goog.require('ol.proj'); goog.require('ol.proj.Projection'); goog.require('ol.proj.Units'); +goog.require('ol.sphere.WGS84'); @@ -27,6 +28,7 @@ ol.proj.EPSG4326_ = function(code, opt_axisOrientation) { extent: ol.proj.EPSG4326.EXTENT, axisOrientation: opt_axisOrientation, global: true, + metersPerUnit: ol.proj.EPSG4326.METERS_PER_UNIT, worldExtent: ol.proj.EPSG4326.EXTENT }); }; @@ -50,6 +52,13 @@ ol.proj.EPSG4326_.prototype.getPointResolution = function(resolution, point) { ol.proj.EPSG4326.EXTENT = [-180, -90, 180, 90]; +/** + * @const + * @type {number} + */ +ol.proj.EPSG4326.METERS_PER_UNIT = Math.PI * ol.sphere.WGS84.radius / 180; + + /** * Projections equal to EPSG:4326. * diff --git a/src/ol/proj/proj.js b/src/ol/proj/proj.js index d7184c118a..15bf89ee9f 100644 --- a/src/ol/proj/proj.js +++ b/src/ol/proj/proj.js @@ -143,6 +143,12 @@ ol.proj.Projection = function(options) { */ this.defaultTileGrid_ = null; + /** + * @private + * @type {number|undefined} + */ + this.metersPerUnit_ = options.metersPerUnit; + var projections = ol.proj.projections_; var code = options.code; goog.asserts.assert(code !== undefined, @@ -155,16 +161,11 @@ ol.proj.Projection = function(options) { if (def.axis !== undefined && options.axisOrientation === undefined) { this.axisOrientation_ = def.axis; } + if (options.metersPerUnit === undefined) { + this.metersPerUnit_ = def.to_meter; + } if (options.units === undefined) { - var units = def.units; - if (def.to_meter !== undefined) { - if (units === undefined || - ol.proj.METERS_PER_UNIT[units] === undefined) { - units = def.to_meter.toString(); - ol.proj.METERS_PER_UNIT[units] = def.to_meter; - } - } - this.units_ = units; + this.units_ = def.units; } var currentCode, currentDef, currentProj, proj4Transform; for (currentCode in projections) { @@ -227,12 +228,13 @@ ol.proj.Projection.prototype.getUnits = function() { /** * Get the amount of meters per unit of this projection. If the projection is - * not configured with a units identifier, the return is `undefined`. + * not configured with `metersPerUnit` or a units identifier, the return is + * `undefined`. * @return {number|undefined} Meters. * @api stable */ ol.proj.Projection.prototype.getMetersPerUnit = function() { - return ol.proj.METERS_PER_UNIT[this.units_]; + return this.metersPerUnit_ || ol.proj.METERS_PER_UNIT[this.units_]; }; diff --git a/test/spec/ol/proj/proj.test.js b/test/spec/ol/proj/proj.test.js index c6b83fff26..3df67a36ad 100644 --- a/test/spec/ol/proj/proj.test.js +++ b/test/spec/ol/proj/proj.test.js @@ -554,7 +554,8 @@ describe('ol.proj', function() { it('returns value in meters', function() { var epsg4326 = ol.proj.get('EPSG:4326'); - expect(epsg4326.getMetersPerUnit()).to.eql(111194.87428468118); + expect(epsg4326.getMetersPerUnit()).to.eql( + ol.proj.EPSG4326.METERS_PER_UNIT); }); it('works for proj4js projections without units', function() { @@ -582,6 +583,7 @@ describe('ol.proj', function() { goog.require('ol.proj'); +goog.require('ol.proj.EPSG4326'); goog.require('ol.proj.Projection'); goog.require('ol.proj.Units'); goog.require('ol.proj.common'); diff --git a/test/spec/ol/reproj/reproj.test.js b/test/spec/ol/reproj/reproj.test.js index 44283a86c1..74a26a408b 100644 --- a/test/spec/ol/reproj/reproj.test.js +++ b/test/spec/ol/reproj/reproj.test.js @@ -31,7 +31,8 @@ describe('ol.reproj', function() { var resolution3857 = ol.reproj.calculateSourceResolution( proj3857, proj4326, point4326, resolution4326); expect(resolution3857).not.to.be(resolution4326); - expect(resolution3857).to.roughlyEqual(555974.3714343394, 1e-6); + expect(resolution3857).to.roughlyEqual( + 5 * proj4326.getMetersPerUnit(), 1e-4); var result = ol.reproj.calculateSourceResolution( proj4326, proj3857, point3857, resolution3857);