Merge pull request #5935 from tschaub/friendly-transform

Keep transformed coordinates within valid y range
This commit is contained in:
Tim Schaub
2016-10-07 06:40:04 -06:00
committed by GitHub
4 changed files with 103 additions and 4 deletions

View File

@@ -116,10 +116,17 @@ ol.proj.EPSG3857.fromEPSG4326 = function(input, opt_output, opt_dimension) {
}
ol.DEBUG && console.assert(output.length % dimension === 0,
'modulus of output.length with dimension should be 0');
var halfSize = ol.proj.EPSG3857.HALF_SIZE;
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 *
output[i] = halfSize * input[i] / 180;
var y = ol.proj.EPSG3857.RADIUS *
Math.log(Math.tan(Math.PI * (input[i + 1] + 90) / 360));
if (y > halfSize) {
y = halfSize;
} else if (y < -halfSize) {
y = -halfSize;
}
output[i + 1] = y;
}
return output;
};
@@ -148,7 +155,7 @@ ol.proj.EPSG3857.toEPSG4326 = function(input, opt_output, opt_dimension) {
ol.DEBUG && console.assert(output.length % dimension === 0,
'modulus of output.length with dimension should be 0');
for (var i = 0; i < length; i += dimension) {
output[i] = 180 * input[i] / (ol.proj.EPSG3857.RADIUS * Math.PI);
output[i] = 180 * input[i] / ol.proj.EPSG3857.HALF_SIZE;
output[i + 1] = 360 * Math.atan(
Math.exp(input[i + 1] / ol.proj.EPSG3857.RADIUS)) / Math.PI - 90;
}

View File

@@ -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);

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -3,6 +3,7 @@ goog.provide('ol.test.rendering.layer.Vector');
goog.require('ol.Feature');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.format.GeoJSON');
goog.require('ol.geom.Circle');
goog.require('ol.geom.LineString');
goog.require('ol.geom.Polygon');
@@ -271,6 +272,64 @@ describe('ol.rendering.layer.Vector', function() {
});
});
describe.only('polygon rendering', function() {
var map;
beforeEach(function() {
map = new ol.Map({
target: createMapDiv(128, 128),
view: new ol.View({
center: [0, 0],
zoom: 0
})
});
});
afterEach(function() {
disposeMap(map);
});
it('renders a feature that spans the world', function(done) {
var json = {
type: 'Feature',
geometry: {
type: 'Polygon',
coordinates: [
[
[-180, -90], [180, -90], [180, 90], [-180, 90], [-180, -90]
],
[
[0, 60], [-17.6336, 24.2705], [-57.0634, 18.5410], [-28.5317, -9.2705], [-35.2671, -48.5410], [0, -30], [35.2671, -48.5410], [28.5317, -9.2705], [57.0634, 18.5410], [17.6336, 24.2705], [0, 60]
]
]
},
properties: {}
};
var format = new ol.format.GeoJSON({featureProjection: 'EPSG:3857'});
var feature = format.readFeature(json);
var layer = new ol.layer.Vector({
source: new ol.source.Vector({
features: [feature]
}),
style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'blue'
})
})
});
map.addLayer(layer);
map.once('postrender', function() {
expectResemble(map, 'spec/ol/layer/expected/inverted-star.png', 1, done);
});
});
});
describe('Polygon simplification', function() {
var layer, map;