mirror of
https://github.com/l5yth/potato-mesh.git
synced 2026-03-28 17:42:48 +01:00
Tighten map auto-fit behaviour (#435)
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright © 2025-26 l5yth & contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
|
||||
import { resolveAutoFitBoundsConfig, __testUtils } from '../map-auto-fit-settings.js';
|
||||
|
||||
const { MINIMUM_AUTO_FIT_RANGE_KM, AUTO_FIT_PADDING_FRACTION } = __testUtils;
|
||||
|
||||
test('resolveAutoFitBoundsConfig returns defaults without a distance limit', () => {
|
||||
const config = resolveAutoFitBoundsConfig({ hasDistanceLimit: false, maxDistanceKm: null });
|
||||
assert.equal(config.paddingFraction, AUTO_FIT_PADDING_FRACTION);
|
||||
assert.equal(config.minimumRangeKm, MINIMUM_AUTO_FIT_RANGE_KM);
|
||||
});
|
||||
|
||||
test('resolveAutoFitBoundsConfig constrains minimum range by the limit radius', () => {
|
||||
const config = resolveAutoFitBoundsConfig({ hasDistanceLimit: true, maxDistanceKm: 2 });
|
||||
assert.equal(config.paddingFraction, AUTO_FIT_PADDING_FRACTION);
|
||||
assert.ok(config.minimumRangeKm >= MINIMUM_AUTO_FIT_RANGE_KM);
|
||||
assert.ok(config.minimumRangeKm <= 2);
|
||||
});
|
||||
|
||||
test('resolveAutoFitBoundsConfig respects small distance limits', () => {
|
||||
const config = resolveAutoFitBoundsConfig({ hasDistanceLimit: true, maxDistanceKm: 0.1 });
|
||||
assert.equal(config.paddingFraction, AUTO_FIT_PADDING_FRACTION);
|
||||
assert.equal(config.minimumRangeKm, 0.1);
|
||||
});
|
||||
|
||||
test('resolveAutoFitBoundsConfig tolerates invalid input', () => {
|
||||
const config = resolveAutoFitBoundsConfig({ hasDistanceLimit: true, maxDistanceKm: -5 });
|
||||
assert.equal(config.paddingFraction, AUTO_FIT_PADDING_FRACTION);
|
||||
assert.equal(config.minimumRangeKm, MINIMUM_AUTO_FIT_RANGE_KM);
|
||||
});
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import { computeBoundingBox, computeBoundsForPoints, haversineDistanceKm } from './map-bounds.js';
|
||||
import { createMapAutoFitController } from './map-auto-fit-controller.js';
|
||||
import { resolveAutoFitBoundsConfig } from './map-auto-fit-settings.js';
|
||||
import { attachNodeInfoRefreshToMarker, overlayToPopupNode } from './map-marker-node-info.js';
|
||||
import { createShortInfoOverlayStack } from './short-info-overlay-manager.js';
|
||||
import { refreshNodeInformation } from './node-details.js';
|
||||
@@ -394,6 +395,10 @@ let messagesById = new Map();
|
||||
? config.maxDistanceKm
|
||||
: null;
|
||||
const LIMIT_DISTANCE = Number.isFinite(MAX_DISTANCE_KM);
|
||||
const autoFitBoundsConfig = resolveAutoFitBoundsConfig({
|
||||
hasDistanceLimit: LIMIT_DISTANCE,
|
||||
maxDistanceKm: MAX_DISTANCE_KM
|
||||
});
|
||||
const INITIAL_VIEW_PADDING_PX = 12;
|
||||
const AUTO_FIT_PADDING_PX = 12;
|
||||
const MAX_INITIAL_ZOOM = 13;
|
||||
@@ -3587,12 +3592,7 @@ let messagesById = new Map();
|
||||
});
|
||||
}
|
||||
if (pts.length && fitBoundsEl && fitBoundsEl.checked) {
|
||||
const bounds = computeBoundsForPoints(pts, {
|
||||
paddingFraction: 0.2,
|
||||
minimumRangeKm: LIMIT_DISTANCE
|
||||
? Math.min(Math.max(MAX_DISTANCE_KM * 0.1, 1), MAX_DISTANCE_KM)
|
||||
: 1
|
||||
});
|
||||
const bounds = computeBoundsForPoints(pts, { ...autoFitBoundsConfig });
|
||||
fitMapToBounds(bounds, { animate: false, paddingPx: AUTO_FIT_PADDING_PX });
|
||||
}
|
||||
overlayStack.cleanupOrphans();
|
||||
|
||||
54
web/public/assets/js/app/map-auto-fit-settings.js
Normal file
54
web/public/assets/js/app/map-auto-fit-settings.js
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright © 2025-26 l5yth & contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const MINIMUM_AUTO_FIT_RANGE_KM = 0.25;
|
||||
const AUTO_FIT_PADDING_FRACTION = 0.02;
|
||||
|
||||
/**
|
||||
* Resolve auto-fit bounds configuration for the active map constraints.
|
||||
*
|
||||
* @param {{ hasDistanceLimit: boolean, maxDistanceKm: number | null }} options
|
||||
* - ``hasDistanceLimit`` indicates whether a maximum display radius is enforced.
|
||||
* - ``maxDistanceKm`` provides the configured maximum distance in kilometres.
|
||||
* @returns {{ paddingFraction: number, minimumRangeKm: number }}
|
||||
* Bounds options suitable for ``computeBoundsForPoints``.
|
||||
*/
|
||||
export function resolveAutoFitBoundsConfig({ hasDistanceLimit, maxDistanceKm } = {}) {
|
||||
const effectiveMaxDistance = Number.isFinite(maxDistanceKm) && maxDistanceKm > 0
|
||||
? maxDistanceKm
|
||||
: null;
|
||||
|
||||
if (!hasDistanceLimit || !effectiveMaxDistance) {
|
||||
return {
|
||||
paddingFraction: AUTO_FIT_PADDING_FRACTION,
|
||||
minimumRangeKm: MINIMUM_AUTO_FIT_RANGE_KM
|
||||
};
|
||||
}
|
||||
|
||||
const minimumRange = Math.min(MINIMUM_AUTO_FIT_RANGE_KM, effectiveMaxDistance);
|
||||
const resolvedMinimumRange = Number.isFinite(minimumRange) && minimumRange > 0
|
||||
? minimumRange
|
||||
: MINIMUM_AUTO_FIT_RANGE_KM;
|
||||
return {
|
||||
paddingFraction: AUTO_FIT_PADDING_FRACTION,
|
||||
minimumRangeKm: resolvedMinimumRange
|
||||
};
|
||||
}
|
||||
|
||||
export const __testUtils = {
|
||||
MINIMUM_AUTO_FIT_RANGE_KM,
|
||||
AUTO_FIT_PADDING_FRACTION
|
||||
};
|
||||
Reference in New Issue
Block a user