Merge pull request #9196 from ahocevar/pointresolution-scaleline
getPointResolution returns resolution in projection units
This commit is contained in:
@@ -201,20 +201,12 @@ class ScaleLine extends Control {
|
|||||||
ProjUnits.METERS;
|
ProjUnits.METERS;
|
||||||
let pointResolution =
|
let pointResolution =
|
||||||
getPointResolution(projection, viewState.resolution, center, pointResolutionUnits);
|
getPointResolution(projection, viewState.resolution, center, pointResolutionUnits);
|
||||||
if (projection.getUnits() != ProjUnits.DEGREES && projection.getMetersPerUnit()
|
|
||||||
&& pointResolutionUnits == ProjUnits.METERS) {
|
|
||||||
pointResolution *= projection.getMetersPerUnit();
|
|
||||||
}
|
|
||||||
|
|
||||||
let nominalCount = this.minWidth_ * pointResolution;
|
let nominalCount = this.minWidth_ * pointResolution;
|
||||||
let suffix = '';
|
let suffix = '';
|
||||||
if (units == Units.DEGREES) {
|
if (units == Units.DEGREES) {
|
||||||
const metersPerDegree = METERS_PER_UNIT[ProjUnits.DEGREES];
|
const metersPerDegree = METERS_PER_UNIT[ProjUnits.DEGREES];
|
||||||
if (projection.getUnits() == ProjUnits.DEGREES) {
|
nominalCount *= metersPerDegree;
|
||||||
nominalCount *= metersPerDegree;
|
|
||||||
} else {
|
|
||||||
pointResolution /= metersPerDegree;
|
|
||||||
}
|
|
||||||
if (nominalCount < metersPerDegree / 60) {
|
if (nominalCount < metersPerDegree / 60) {
|
||||||
suffix = '\u2033'; // seconds
|
suffix = '\u2033'; // seconds
|
||||||
pointResolution *= 3600;
|
pointResolution *= 3600;
|
||||||
|
|||||||
@@ -188,6 +188,12 @@ export function getPointResolution(projection, resolution, point, opt_units) {
|
|||||||
const getter = projection.getPointResolutionFunc();
|
const getter = projection.getPointResolutionFunc();
|
||||||
if (getter) {
|
if (getter) {
|
||||||
pointResolution = getter(resolution, point);
|
pointResolution = getter(resolution, point);
|
||||||
|
if (opt_units && opt_units !== projection.getUnits()) {
|
||||||
|
const metersPerUnit = projection.getMetersPerUnit();
|
||||||
|
if (metersPerUnit) {
|
||||||
|
pointResolution = pointResolution * metersPerUnit / METERS_PER_UNIT[opt_units];
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const units = projection.getUnits();
|
const units = projection.getUnits();
|
||||||
if (units == Units.DEGREES && !opt_units || opt_units == Units.DEGREES) {
|
if (units == Units.DEGREES && !opt_units || opt_units == Units.DEGREES) {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import {METERS_PER_UNIT} from './Units.js';
|
|||||||
* @property {function(number, import("../coordinate.js").Coordinate):number} [getPointResolution]
|
* @property {function(number, import("../coordinate.js").Coordinate):number} [getPointResolution]
|
||||||
* Function to determine resolution at a point. The function is called with a
|
* Function to determine resolution at a point. The function is called with a
|
||||||
* `{number}` view resolution and an `{import("../coordinate.js").Coordinate}` as arguments, and returns
|
* `{number}` view resolution and an `{import("../coordinate.js").Coordinate}` as arguments, and returns
|
||||||
* the `{number}` resolution at the passed coordinate. If this is `undefined`,
|
* the `{number}` resolution in projection units at the passed coordinate. If this is `undefined`,
|
||||||
* the default {@link module:ol/proj#getPointResolution} function will be used.
|
* the default {@link module:ol/proj#getPointResolution} function will be used.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import Map from '../../../../src/ol/Map.js';
|
import Map from '../../../../src/ol/Map.js';
|
||||||
import View from '../../../../src/ol/View.js';
|
import View from '../../../../src/ol/View.js';
|
||||||
import ScaleLine, {render} from '../../../../src/ol/control/ScaleLine.js';
|
import ScaleLine, {render} from '../../../../src/ol/control/ScaleLine.js';
|
||||||
import {fromLonLat} from '../../../../src/ol/proj.js';
|
import {fromLonLat, clearAllProjections, addCommon} from '../../../../src/ol/proj.js';
|
||||||
import Projection from '../../../../src/ol/proj/Projection.js';
|
import Projection from '../../../../src/ol/proj/Projection.js';
|
||||||
|
import proj4 from 'proj4';
|
||||||
|
import {register} from '../../../../src/ol/proj/proj4.js';
|
||||||
|
|
||||||
describe('ol.control.ScaleLine', function() {
|
describe('ol.control.ScaleLine', function() {
|
||||||
let map;
|
let map;
|
||||||
@@ -244,6 +246,25 @@ describe('ol.control.ScaleLine', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('projections affect the scaleline', function() {
|
describe('projections affect the scaleline', function() {
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
proj4.defs('Indiana-East', 'PROJCS["IN83-EF",GEOGCS["LL83",DATUM["NAD83",' +
|
||||||
|
'SPHEROID["GRS1980",6378137.000,298.25722210]],PRIMEM["Greenwich",0],' +
|
||||||
|
'UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],' +
|
||||||
|
'PARAMETER["false_easting",328083.333],' +
|
||||||
|
'PARAMETER["false_northing",820208.333],' +
|
||||||
|
'PARAMETER["scale_factor",0.999966666667],' +
|
||||||
|
'PARAMETER["central_meridian",-85.66666666666670],' +
|
||||||
|
'PARAMETER["latitude_of_origin",37.50000000000000],' +
|
||||||
|
'UNIT["Foot_US",0.30480060960122]]');
|
||||||
|
register(proj4);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
clearAllProjections();
|
||||||
|
addCommon();
|
||||||
|
});
|
||||||
|
|
||||||
it('is rendered differently for different projections', function() {
|
it('is rendered differently for different projections', function() {
|
||||||
const ctrl = new ScaleLine();
|
const ctrl = new ScaleLine();
|
||||||
ctrl.setMap(map);
|
ctrl.setMap(map);
|
||||||
@@ -253,15 +274,47 @@ describe('ol.control.ScaleLine', function() {
|
|||||||
projection: 'EPSG:3857'
|
projection: 'EPSG:3857'
|
||||||
}));
|
}));
|
||||||
map.renderSync();
|
map.renderSync();
|
||||||
const innerHtml3857 = ctrl.element.innerHTML;
|
expect(ctrl.element.innerText).to.be('2000 km');
|
||||||
map.setView(new View({
|
map.setView(new View({
|
||||||
center: [7, 52],
|
center: [7, 52],
|
||||||
zoom: 2,
|
zoom: 2,
|
||||||
projection: 'EPSG:4326'
|
projection: 'EPSG:4326'
|
||||||
}));
|
}));
|
||||||
map.renderSync();
|
map.renderSync();
|
||||||
const innerHtml4326 = ctrl.element.innerHTML;
|
expect(ctrl.element.innerText).to.be('5000 km');
|
||||||
expect(innerHtml4326).to.not.be(innerHtml3857);
|
map.setView(new View({
|
||||||
|
center: fromLonLat([-85.685, 39.891], 'Indiana-East'),
|
||||||
|
zoom: 7,
|
||||||
|
projection: 'Indiana-East'
|
||||||
|
}));
|
||||||
|
map.renderSync();
|
||||||
|
expect(ctrl.element.innerText).to.be('100 km');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('shows the same scale for different projections at higher resolutions', function() {
|
||||||
|
const ctrl = new ScaleLine();
|
||||||
|
ctrl.setMap(map);
|
||||||
|
map.setView(new View({
|
||||||
|
center: fromLonLat([-85.685, 39.891]),
|
||||||
|
zoom: 7,
|
||||||
|
projection: 'EPSG:3857'
|
||||||
|
}));
|
||||||
|
map.renderSync();
|
||||||
|
expect(ctrl.element.innerText).to.be('100 km');
|
||||||
|
map.setView(new View({
|
||||||
|
center: [-85.685, 39.891],
|
||||||
|
zoom: 7,
|
||||||
|
projection: 'EPSG:4326'
|
||||||
|
}));
|
||||||
|
map.renderSync();
|
||||||
|
expect(ctrl.element.innerText).to.be('100 km');
|
||||||
|
map.setView(new View({
|
||||||
|
center: fromLonLat([-85.685, 39.891], 'Indiana-East'),
|
||||||
|
zoom: 7,
|
||||||
|
projection: 'Indiana-East'
|
||||||
|
}));
|
||||||
|
map.renderSync();
|
||||||
|
expect(ctrl.element.innerText).to.be('100 km');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Projection\'s metersPerUnit affect scale for non-degree units', function() {
|
it('Projection\'s metersPerUnit affect scale for non-degree units', function() {
|
||||||
@@ -344,7 +397,7 @@ describe('ol.control.ScaleLine', function() {
|
|||||||
const ctrl = new ScaleLine();
|
const ctrl = new ScaleLine();
|
||||||
ctrl.setMap(map);
|
ctrl.setMap(map);
|
||||||
map.setView(new View({
|
map.setView(new View({
|
||||||
center: fromLonLat([7, 0]),
|
center: [7, 0],
|
||||||
zoom: 2,
|
zoom: 2,
|
||||||
projection: 'EPSG:4326'
|
projection: 'EPSG:4326'
|
||||||
}));
|
}));
|
||||||
@@ -362,7 +415,7 @@ describe('ol.control.ScaleLine', function() {
|
|||||||
});
|
});
|
||||||
ctrl.setMap(map);
|
ctrl.setMap(map);
|
||||||
map.setView(new View({
|
map.setView(new View({
|
||||||
center: fromLonLat([7, 0]),
|
center: [7, 0],
|
||||||
zoom: 2,
|
zoom: 2,
|
||||||
projection: 'EPSG:4326'
|
projection: 'EPSG:4326'
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -9,11 +9,12 @@ import {
|
|||||||
toLonLat,
|
toLonLat,
|
||||||
getTransform,
|
getTransform,
|
||||||
getPointResolution,
|
getPointResolution,
|
||||||
getTransformFromProjections
|
getTransformFromProjections,
|
||||||
|
METERS_PER_UNIT
|
||||||
} from '../../../src/ol/proj.js';
|
} from '../../../src/ol/proj.js';
|
||||||
import {register} from '../../../src/ol/proj/proj4.js';
|
import {register} from '../../../src/ol/proj/proj4.js';
|
||||||
import {HALF_SIZE} from '../../../src/ol/proj/epsg3857.js';
|
import {HALF_SIZE} from '../../../src/ol/proj/epsg3857.js';
|
||||||
import {METERS_PER_UNIT} from '../../../src/ol/proj/epsg4326.js';
|
import {METERS_PER_UNIT as metersPerDegree} from '../../../src/ol/proj/epsg4326.js';
|
||||||
import Projection from '../../../src/ol/proj/Projection.js';
|
import Projection from '../../../src/ol/proj/Projection.js';
|
||||||
|
|
||||||
|
|
||||||
@@ -268,7 +269,7 @@ describe('ol.proj', function() {
|
|||||||
expect(pointResolution).to.roughlyEqual(0.615661, 1e-5);
|
expect(pointResolution).to.roughlyEqual(0.615661, 1e-5);
|
||||||
});
|
});
|
||||||
it('returns the correct point resolution for EPSG:3857 with custom units', function() {
|
it('returns the correct point resolution for EPSG:3857 with custom units', function() {
|
||||||
let pointResolution = getPointResolution('EPSG:3857', 1, [0, 0], 'degrees');
|
let pointResolution = getPointResolution('EPSG:3857', METERS_PER_UNIT['degrees'], [0, 0], 'degrees');
|
||||||
expect(pointResolution).to.be(1);
|
expect(pointResolution).to.be(1);
|
||||||
pointResolution = getPointResolution('EPSG:4326', 1, fromLonLat([0, 52]), 'degrees');
|
pointResolution = getPointResolution('EPSG:4326', 1, fromLonLat([0, 52]), 'degrees');
|
||||||
expect(pointResolution).to.be(1);
|
expect(pointResolution).to.be(1);
|
||||||
@@ -600,7 +601,7 @@ describe('ol.proj', function() {
|
|||||||
|
|
||||||
it('returns value in meters', function() {
|
it('returns value in meters', function() {
|
||||||
const epsg4326 = getProjection('EPSG:4326');
|
const epsg4326 = getProjection('EPSG:4326');
|
||||||
expect(epsg4326.getMetersPerUnit()).to.eql(METERS_PER_UNIT);
|
expect(epsg4326.getMetersPerUnit()).to.eql(metersPerDegree);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('works for proj4js projections without units', function() {
|
it('works for proj4js projections without units', function() {
|
||||||
|
|||||||
Reference in New Issue
Block a user