Merge pull request #13171 from mike-000/4326-scale-bar
Correct scale bar in EPSG:4326
This commit is contained in:
@@ -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"
|
||||||
|
---
|
||||||
|
<div id="map" class="map"></div>
|
||||||
|
<div>
|
||||||
|
<label for="view-projection">View projection</label>
|
||||||
|
<select id="view-projection">
|
||||||
|
<option value="EPSG:3857">Spherical Mercator (EPSG:3857)</option>
|
||||||
|
<option value="EPSG:4326" selected>WGS 84 (EPSG:4326)</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
@@ -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);
|
||||||
@@ -484,12 +484,12 @@ class ScaleLine extends Control {
|
|||||||
const resolution = getPointResolution(
|
const resolution = getPointResolution(
|
||||||
this.viewState_.projection,
|
this.viewState_.projection,
|
||||||
this.viewState_.resolution,
|
this.viewState_.resolution,
|
||||||
this.viewState_.center
|
this.viewState_.center,
|
||||||
|
ProjUnits.METERS
|
||||||
);
|
);
|
||||||
const dpi = this.dpi_ || DEFAULT_DPI;
|
const dpi = this.dpi_ || DEFAULT_DPI;
|
||||||
const mpu = this.viewState_.projection.getMetersPerUnit();
|
|
||||||
const inchesPerMeter = 1000 / 25.4;
|
const inchesPerMeter = 1000 / 25.4;
|
||||||
return parseFloat(resolution.toString()) * mpu * inchesPerMeter * dpi;
|
return parseFloat(resolution.toString()) * inchesPerMeter * dpi;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -640,5 +640,49 @@ describe('ol.control.ScaleLine', function () {
|
|||||||
expect(text.slice(0, 4)).to.be('1 : ');
|
expect(text.slice(0, 4)).to.be('1 : ');
|
||||||
expect(text.replace(/^1|\D/g, '')).to.eql(69885283);
|
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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user