Merge pull request #13531 from bartvde/scaleline_maxwidth

Add optional maxWidth for ScaleLine control
This commit is contained in:
Bart van den Eijnden
2022-04-01 14:40:39 +02:00
committed by GitHub
2 changed files with 51 additions and 0 deletions

View File

@@ -51,6 +51,8 @@ const DEFAULT_DPI = 25.4 / 0.28;
* @property {string} [className='ol-scale-line'] CSS Class name.
* @property {number} [minWidth=64] Minimum width in pixels at the OGC default dpi. The width will be
* adjusted to match the dpi used.
* @property {number} [maxWidth] Maximum width in pixels at the OGC default dpi. The width will be
* adjusted to match the dpi used.
* @property {function(import("../MapEvent.js").default):void} [render] Function called when the control
* should be re-rendered. This is called in a `requestAnimationFrame` callback.
* @property {HTMLElement|string} [target] Specify a target if you want the control
@@ -136,6 +138,12 @@ class ScaleLine extends Control {
*/
this.minWidth_ = options.minWidth !== undefined ? options.minWidth : 64;
/**
* @private
* @type {number|undefined}
*/
this.maxWidth_ = options.maxWidth;
/**
* @private
* @type {boolean}
@@ -249,6 +257,11 @@ class ScaleLine extends Control {
const minWidth =
(this.minWidth_ * (this.dpi_ || DEFAULT_DPI)) / DEFAULT_DPI;
const maxWidth =
this.maxWidth_ !== undefined
? (this.maxWidth_ * (this.dpi_ || DEFAULT_DPI)) / DEFAULT_DPI
: undefined;
let nominalCount = minWidth * pointResolution;
let suffix = '';
if (units == Units.DEGREES) {
@@ -307,6 +320,7 @@ class ScaleLine extends Control {
let i = 3 * Math.floor(Math.log(minWidth * pointResolution) / Math.log(10));
let count, width, decimalCount;
let previousCount, previousWidth, previousDecimalCount;
while (true) {
decimalCount = Math.floor(i / 3);
const decimal = Math.pow(10, decimalCount);
@@ -316,9 +330,18 @@ class ScaleLine extends Control {
this.element.style.display = 'none';
this.renderedVisible_ = false;
return;
}
if (maxWidth !== undefined && width >= maxWidth) {
count = previousCount;
width = previousWidth;
decimalCount = previousDecimalCount;
break;
} else if (width >= minWidth) {
break;
}
previousCount = count;
previousWidth = width;
previousDecimalCount = decimalCount;
++i;
}
let html;

View File

@@ -79,6 +79,19 @@ describe('ol.control.ScaleLine', function () {
});
});
describe('maxWidth', function () {
it('defaults to undefined', function () {
const ctrl = new ScaleLine();
expect(ctrl.maxWidth_).to.be(undefined);
});
it('can be configured', function () {
const ctrl = new ScaleLine({
maxWidth: 4711,
});
expect(ctrl.maxWidth_).to.be(4711);
});
});
describe('render', function () {
it('defaults to `ol.control.ScaleLine.render`', function () {
const ctrl = new ScaleLine();
@@ -325,6 +338,21 @@ describe('ol.control.ScaleLine', function () {
expect(ctrl.element.innerText).to.be('100 km');
});
it('maxWidth is applied correctly', function () {
const ctrl = new ScaleLine({maxWidth: 50});
ctrl.setMap(map);
map.setView(
new View({
center: fromLonLat([-85.685, 39.891], 'Indiana-East'),
zoom: 7,
projection: 'Indiana-East',
})
);
map.renderSync();
// without maxWidth set this would be 100 km
expect(ctrl.element.innerText).to.be('50 km');
});
it('shows the same scale for different projections at higher resolutions', function () {
const ctrl = new ScaleLine();
ctrl.setMap(map);