From 321c65b02312dac62f1fc78a1f25b789dfd3217e Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Wed, 5 Oct 2016 07:26:41 -0600 Subject: [PATCH] Keep transformed coordinates within valid y range --- src/ol/proj/epsg3857.js | 8 ++++++- test/spec/ol/proj/epsg3857.test.js | 35 +++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/ol/proj/epsg3857.js b/src/ol/proj/epsg3857.js index 16dfe11d98..189b770e64 100644 --- a/src/ol/proj/epsg3857.js +++ b/src/ol/proj/epsg3857.js @@ -118,8 +118,14 @@ ol.proj.EPSG3857.fromEPSG4326 = function(input, opt_output, opt_dimension) { 'modulus of output.length with dimension should be 0'); for (var i = 0; i < length; i += dimension) { output[i] = ol.proj.EPSG3857.RADIUS * Math.PI * input[i] / 180; - output[i + 1] = ol.proj.EPSG3857.RADIUS * + var y = ol.proj.EPSG3857.RADIUS * Math.log(Math.tan(Math.PI * (input[i + 1] + 90) / 360)); + if (y > ol.proj.EPSG3857.HALF_SIZE) { + y = ol.proj.EPSG3857.HALF_SIZE; + } else if (y < -ol.proj.EPSG3857.HALF_SIZE) { + y = -ol.proj.EPSG3857.HALF_SIZE; + } + output[i + 1] = y; } return output; }; diff --git a/test/spec/ol/proj/epsg3857.test.js b/test/spec/ol/proj/epsg3857.test.js index 9854d96c20..2402b2854e 100644 --- a/test/spec/ol/proj/epsg3857.test.js +++ b/test/spec/ol/proj/epsg3857.test.js @@ -2,6 +2,7 @@ goog.provide('ol.test.proj.EPSG3857'); goog.require('ol.proj'); goog.require('ol.proj.common'); + describe('ol.proj.EPSG3857', function() { afterEach(function() { @@ -9,6 +10,38 @@ describe('ol.proj.EPSG3857', function() { ol.proj.common.add(); }); + describe('fromEPSG4326()', function() { + + it('transforms from geographic to Web Mercator', function() { + var forward = ol.proj.EPSG3857.fromEPSG4326; + var edge = ol.proj.EPSG3857.HALF_SIZE; + + var tolerance = 1e-5; + + var cases = [{ + g: [0, 0], + m: [0, 0] + }, { + g: [-180, -90], + m: [-edge, -edge] + }, { + g: [180, 90], + m: [edge, edge] + }, { + g: [-111.0429, 45.6770], + m: [-12361239.084208, 5728738.469095] + }]; + + for (var i = 0, ii = cases.length; i < ii; ++i) { + var point = cases[i].g; + var transformed = forward(point); + expect(transformed[0]).to.roughlyEqual(cases[i].m[0], tolerance); + expect(transformed[1]).to.roughlyEqual(cases[i].m[1], tolerance); + } + }); + + }); + describe('getPointResolution', function() { it('returns the correct point scale at the equator', function() { @@ -37,7 +70,7 @@ describe('ol.proj.EPSG3857', function() { var epsg4326 = ol.proj.get('EPSG:4326'); var resolution = 19.11; var latitude; - for (latitude = 0; latitude < 90; ++latitude) { + for (latitude = 0; latitude <= 85; ++latitude) { var point = ol.proj.transform([0, latitude], epsg4326, epsg3857); expect(epsg3857.getPointResolution(resolution, point)). to.roughlyEqual(19.11 * Math.cos(Math.PI * latitude / 180), 1e-9);