Merge pull request #5935 from tschaub/friendly-transform
Keep transformed coordinates within valid y range
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
BIN
test_rendering/spec/ol/layer/expected/inverted-star.png
Normal file
BIN
test_rendering/spec/ol/layer/expected/inverted-star.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user