Fix scale line for EPSG:4326 maps
This commit is contained in:
@@ -168,17 +168,22 @@ ol.control.ScaleLine.prototype.updateElement_ = function() {
|
|||||||
|
|
||||||
var center = viewState.center;
|
var center = viewState.center;
|
||||||
var projection = viewState.projection;
|
var projection = viewState.projection;
|
||||||
var metersPerUnit = projection.getMetersPerUnit();
|
var units = this.getUnits();
|
||||||
|
var pointResolutionUnits = units == ol.control.ScaleLineUnits.DEGREES ?
|
||||||
|
ol.proj.Units.DEGREES :
|
||||||
|
ol.proj.Units.METERS;
|
||||||
var pointResolution =
|
var pointResolution =
|
||||||
ol.proj.getPointResolution(projection, viewState.resolution, center) *
|
ol.proj.getPointResolution(projection, viewState.resolution, center, pointResolutionUnits);
|
||||||
metersPerUnit;
|
|
||||||
|
|
||||||
var nominalCount = this.minWidth_ * pointResolution;
|
var nominalCount = this.minWidth_ * pointResolution;
|
||||||
var suffix = '';
|
var suffix = '';
|
||||||
var units = this.getUnits();
|
|
||||||
if (units == ol.control.ScaleLineUnits.DEGREES) {
|
if (units == ol.control.ScaleLineUnits.DEGREES) {
|
||||||
var metersPerDegree = ol.proj.METERS_PER_UNIT[ol.proj.Units.DEGREES];
|
var metersPerDegree = ol.proj.METERS_PER_UNIT[ol.proj.Units.DEGREES];
|
||||||
|
if (projection.getUnits() == ol.proj.Units.DEGREES) {
|
||||||
|
nominalCount *= metersPerDegree;
|
||||||
|
} else {
|
||||||
pointResolution /= metersPerDegree;
|
pointResolution /= metersPerDegree;
|
||||||
|
}
|
||||||
if (nominalCount < metersPerDegree / 60) {
|
if (nominalCount < metersPerDegree / 60) {
|
||||||
suffix = '\u2033'; // seconds
|
suffix = '\u2033'; // seconds
|
||||||
pointResolution *= 3600;
|
pointResolution *= 3600;
|
||||||
|
|||||||
@@ -63,10 +63,12 @@ if (ol.ENABLE_PROJ4JS) {
|
|||||||
* @param {ol.ProjectionLike} projection The projection.
|
* @param {ol.ProjectionLike} projection The projection.
|
||||||
* @param {number} resolution Nominal resolution in projection units.
|
* @param {number} resolution Nominal resolution in projection units.
|
||||||
* @param {ol.Coordinate} point Point to find adjusted resolution at.
|
* @param {ol.Coordinate} point Point to find adjusted resolution at.
|
||||||
* @return {number} Point resolution at point in projection units.
|
* @param {ol.proj.Units=} opt_units Units to get the point resolution in.
|
||||||
|
* Default is the projection's units.
|
||||||
|
* @return {number} Point resolution.
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
ol.proj.getPointResolution = function(projection, resolution, point) {
|
ol.proj.getPointResolution = function(projection, resolution, point, opt_units) {
|
||||||
projection = ol.proj.get(projection);
|
projection = ol.proj.get(projection);
|
||||||
var pointResolution;
|
var pointResolution;
|
||||||
var getter = projection.getPointResolutionFunc();
|
var getter = projection.getPointResolutionFunc();
|
||||||
@@ -74,7 +76,7 @@ ol.proj.getPointResolution = function(projection, resolution, point) {
|
|||||||
pointResolution = getter(resolution, point);
|
pointResolution = getter(resolution, point);
|
||||||
} else {
|
} else {
|
||||||
var units = projection.getUnits();
|
var units = projection.getUnits();
|
||||||
if (units == ol.proj.Units.DEGREES) {
|
if (units == ol.proj.Units.DEGREES && !opt_units || opt_units == ol.proj.Units.DEGREES) {
|
||||||
pointResolution = resolution;
|
pointResolution = resolution;
|
||||||
} else {
|
} else {
|
||||||
// Estimate point resolution by transforming the center pixel to EPSG:4326,
|
// Estimate point resolution by transforming the center pixel to EPSG:4326,
|
||||||
@@ -93,7 +95,9 @@ ol.proj.getPointResolution = function(projection, resolution, point) {
|
|||||||
var height = ol.proj.AUTHALIC_SPHERE_.haversineDistance(
|
var height = ol.proj.AUTHALIC_SPHERE_.haversineDistance(
|
||||||
vertices.slice(4, 6), vertices.slice(6, 8));
|
vertices.slice(4, 6), vertices.slice(6, 8));
|
||||||
pointResolution = (width + height) / 2;
|
pointResolution = (width + height) / 2;
|
||||||
var metersPerUnit = projection.getMetersPerUnit();
|
var metersPerUnit = opt_units ?
|
||||||
|
ol.proj.Units.METERS_PER_UNIT[opt_units] :
|
||||||
|
projection.getMetersPerUnit();
|
||||||
if (metersPerUnit !== undefined) {
|
if (metersPerUnit !== undefined) {
|
||||||
pointResolution /= metersPerUnit;
|
pointResolution /= metersPerUnit;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -262,6 +262,44 @@ describe('ol.control.ScaleLine', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('latitude may affect scale line in EPSG:4326', function() {
|
||||||
|
|
||||||
|
it('is rendered differently at different latitudes for metric', function() {
|
||||||
|
var ctrl = new ol.control.ScaleLine();
|
||||||
|
ctrl.setMap(map);
|
||||||
|
map.setView(new ol.View({
|
||||||
|
center: ol.proj.fromLonLat([7, 0]),
|
||||||
|
zoom: 2,
|
||||||
|
projection: 'EPSG:4326'
|
||||||
|
}));
|
||||||
|
map.renderSync();
|
||||||
|
var innerHtml0 = ctrl.element_.innerHTML;
|
||||||
|
map.getView().setCenter([7, 52]);
|
||||||
|
map.renderSync();
|
||||||
|
var innerHtml52 = ctrl.element_.innerHTML;
|
||||||
|
expect(innerHtml0).to.not.be(innerHtml52);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('is rendered the same at different latitudes for degrees', function() {
|
||||||
|
var ctrl = new ol.control.ScaleLine({
|
||||||
|
units: 'degrees'
|
||||||
|
});
|
||||||
|
ctrl.setMap(map);
|
||||||
|
map.setView(new ol.View({
|
||||||
|
center: ol.proj.fromLonLat([7, 0]),
|
||||||
|
zoom: 2,
|
||||||
|
projection: 'EPSG:4326'
|
||||||
|
}));
|
||||||
|
map.renderSync();
|
||||||
|
var innerHtml0 = ctrl.element_.innerHTML;
|
||||||
|
map.getView().setCenter([7, 52]);
|
||||||
|
map.renderSync();
|
||||||
|
var innerHtml52 = ctrl.element_.innerHTML;
|
||||||
|
expect(innerHtml0).to.be(innerHtml52);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
describe('zoom affects the scaleline', function() {
|
describe('zoom affects the scaleline', function() {
|
||||||
var currentZoom;
|
var currentZoom;
|
||||||
var ctrl;
|
var ctrl;
|
||||||
|
|||||||
@@ -212,6 +212,33 @@ describe('ol.proj', function() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getPointResolution()', function() {
|
||||||
|
it('returns the correct point resolution for EPSG:4326', function() {
|
||||||
|
var pointResolution = ol.proj.getPointResolution('EPSG:4326', 1, [0, 0]);
|
||||||
|
expect (pointResolution).to.be(1);
|
||||||
|
pointResolution = ol.proj.getPointResolution('EPSG:4326', 1, [0, 52]);
|
||||||
|
expect (pointResolution).to.be(1);
|
||||||
|
});
|
||||||
|
it('returns the correct point resolution for EPSG:4326 with custom units', function() {
|
||||||
|
var pointResolution = ol.proj.getPointResolution('EPSG:4326', 1, [0, 0], 'm');
|
||||||
|
expect (pointResolution).to.roughlyEqual(111194.874284, 1e-5);
|
||||||
|
pointResolution = ol.proj.getPointResolution('EPSG:4326', 1, [0, 52], 'm');
|
||||||
|
expect (pointResolution).to.roughlyEqual(89826.367538, 1e-5);
|
||||||
|
});
|
||||||
|
it('returns the correct point resolution for EPSG:3857', function() {
|
||||||
|
var pointResolution = ol.proj.getPointResolution('EPSG:3857', 1, [0, 0]);
|
||||||
|
expect (pointResolution).to.be(1);
|
||||||
|
pointResolution = ol.proj.getPointResolution('EPSG:3857', 1, ol.proj.fromLonLat([0, 52]));
|
||||||
|
expect (pointResolution).to.roughlyEqual(0.615661, 1e-5);
|
||||||
|
});
|
||||||
|
it('returns the correct point resolution for EPSG:3857 with custom units', function() {
|
||||||
|
var pointResolution = ol.proj.getPointResolution('EPSG:3857', 1, [0, 0], 'degrees');
|
||||||
|
expect (pointResolution).to.be(1);
|
||||||
|
pointResolution = ol.proj.getPointResolution('EPSG:4326', 1, ol.proj.fromLonLat([0, 52]), 'degrees');
|
||||||
|
expect (pointResolution).to.be(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('Proj4js integration', function() {
|
describe('Proj4js integration', function() {
|
||||||
|
|
||||||
var proj4 = window.proj4;
|
var proj4 = window.proj4;
|
||||||
|
|||||||
Reference in New Issue
Block a user