From e8b4011cf4415b72cef6bd3888ae96e2d73fec8b Mon Sep 17 00:00:00 2001
From: mike-000 <49240900+mike-000@users.noreply.github.com>
Date: Wed, 29 Dec 2021 19:49:19 +0000
Subject: [PATCH 1/3] new example
---
examples/projection-and-scale.html | 18 ++++++++
examples/projection-and-scale.js | 68 ++++++++++++++++++++++++++++++
2 files changed, 86 insertions(+)
create mode 100644 examples/projection-and-scale.html
create mode 100644 examples/projection-and-scale.js
diff --git a/examples/projection-and-scale.html b/examples/projection-and-scale.html
new file mode 100644
index 0000000000..e98f25d8fd
--- /dev/null
+++ b/examples/projection-and-scale.html
@@ -0,0 +1,18 @@
+---
+layout: example.html
+title: Projection and Scale
+shortdesc: Example of maintaining scale when changing projection.
+docs: >
+ Example of maintaining scale when changing projection.
+ `getPointResolution()` is used to calculate the resolution for the
+ new projection which corresponds to that for the old projection.
+tags: "projection, scale"
+---
+
+
+ View projection
+
+ Spherical Mercator (EPSG:3857)
+ WGS 84 (EPSG:4326)
+
+
diff --git a/examples/projection-and-scale.js b/examples/projection-and-scale.js
new file mode 100644
index 0000000000..e32cb3bcaf
--- /dev/null
+++ b/examples/projection-and-scale.js
@@ -0,0 +1,68 @@
+import Map from '../src/ol/Map.js';
+import OSM from '../src/ol/source/OSM.js';
+import TileLayer from '../src/ol/layer/Tile.js';
+import View from '../src/ol/View.js';
+import {ScaleLine, defaults as defaultControls} from '../src/ol/control.js';
+import {
+ getPointResolution,
+ get as getProjection,
+ transform,
+} from '../src/ol/proj.js';
+
+const viewProjSelect = document.getElementById('view-projection');
+const projection = getProjection(viewProjSelect.value);
+
+const scaleControl = new ScaleLine({
+ units: 'metric',
+ bar: true,
+ steps: 4,
+ text: true,
+ minWidth: 140,
+});
+
+const map = new Map({
+ controls: defaultControls().extend([scaleControl]),
+ layers: [
+ new TileLayer({
+ source: new OSM(),
+ }),
+ ],
+ target: 'map',
+ view: new View({
+ center: transform([0, 52], 'EPSG:4326', projection),
+ zoom: 6,
+ projection: projection,
+ }),
+});
+
+function onChangeProjection() {
+ const currentView = map.getView();
+ const currentProjection = currentView.getProjection();
+ const newProjection = getProjection(viewProjSelect.value);
+ const currentResolution = currentView.getResolution();
+ const currentCenter = currentView.getCenter();
+ const currentRotation = currentView.getRotation();
+ const newCenter = transform(currentCenter, currentProjection, newProjection);
+ const currentPointResolution = getPointResolution(
+ currentProjection,
+ 1,
+ currentCenter,
+ 'm'
+ );
+ const newPointResolution = getPointResolution(
+ newProjection,
+ 1,
+ newCenter,
+ 'm'
+ );
+ const newResolution =
+ (currentResolution * currentPointResolution) / newPointResolution;
+ const newView = new View({
+ center: newCenter,
+ resolution: newResolution,
+ rotation: currentRotation,
+ projection: newProjection,
+ });
+ map.setView(newView);
+}
+viewProjSelect.addEventListener('change', onChangeProjection);
From c8a7a83e1fc3c4e478f5acd876ea9776fa966f4a Mon Sep 17 00:00:00 2001
From: mike-000 <49240900+mike-000@users.noreply.github.com>
Date: Wed, 29 Dec 2021 20:13:58 +0000
Subject: [PATCH 2/3] correct getScaleForResolution()
---
src/ol/control/ScaleLine.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/ol/control/ScaleLine.js b/src/ol/control/ScaleLine.js
index 79fc6afccc..d97f29d33e 100644
--- a/src/ol/control/ScaleLine.js
+++ b/src/ol/control/ScaleLine.js
@@ -484,12 +484,12 @@ class ScaleLine extends Control {
const resolution = getPointResolution(
this.viewState_.projection,
this.viewState_.resolution,
- this.viewState_.center
+ this.viewState_.center,
+ ProjUnits.METERS
);
const dpi = this.dpi_ || DEFAULT_DPI;
- const mpu = this.viewState_.projection.getMetersPerUnit();
const inchesPerMeter = 1000 / 25.4;
- return parseFloat(resolution.toString()) * mpu * inchesPerMeter * dpi;
+ return parseFloat(resolution.toString()) * inchesPerMeter * dpi;
}
/**
From 37f117b78227d71185e8bf055fc10ef8a2a3826b Mon Sep 17 00:00:00 2001
From: mike-000 <49240900+mike-000@users.noreply.github.com>
Date: Wed, 29 Dec 2021 23:55:50 +0000
Subject: [PATCH 3/3] Test scalebar text in EPSG:4326
---
.../browser/spec/ol/control/scaleline.test.js | 44 +++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/test/browser/spec/ol/control/scaleline.test.js b/test/browser/spec/ol/control/scaleline.test.js
index 2de14aadcc..076f83ff36 100644
--- a/test/browser/spec/ol/control/scaleline.test.js
+++ b/test/browser/spec/ol/control/scaleline.test.js
@@ -640,5 +640,49 @@ describe('ol.control.ScaleLine', function () {
expect(text.slice(0, 4)).to.be('1 : ');
expect(text.replace(/^1|\D/g, '')).to.eql(69885283);
});
+ it('it corresponds to the resolution in EPSG:4326', function () {
+ const ctrl = new ScaleLine({
+ bar: true,
+ text: true,
+ });
+ ctrl.setMap(map);
+ map.setView(
+ new View({
+ center: [0, 0],
+ zoom: 2,
+ multiWorld: true,
+ projection: 'EPSG:4326',
+ })
+ );
+ map.renderSync();
+ const element = document.querySelector('.ol-scale-text', map.getTarget());
+ expect(element).to.not.be(null);
+ expect(element).to.be.a(HTMLDivElement);
+ const text = element.innerText;
+ expect(text.slice(0, 4)).to.be('1 : ');
+ expect(text.replace(/^1|\D/g, '')).to.eql(139614359);
+ });
+ it('it changes with latitude in EPSG:4326', function () {
+ const ctrl = new ScaleLine({
+ bar: true,
+ text: true,
+ });
+ ctrl.setMap(map);
+ map.setView(
+ new View({
+ center: [0, 60],
+ zoom: 2,
+ multiWorld: true,
+ projection: 'EPSG:4326',
+ })
+ );
+ map.renderSync();
+ const element = document.querySelector('.ol-scale-text', map.getTarget());
+ expect(element).to.not.be(null);
+ expect(element).to.be.a(HTMLDivElement);
+ const text = element.innerText;
+ expect(text.slice(0, 4)).to.be('1 : ');
+ expect(text.replace(/^1|\D/g, '')).to.eql(104710728);
+ });
});
});