update full objects type
Some checks failed
Test / test (push) Has been cancelled

This commit is contained in:
2026-06-20 11:43:48 +02:00
parent 90e8e9d252
commit 365a15c32a
16 changed files with 4253 additions and 21 deletions

89
www/map-behavior-zones.js Normal file
View File

@@ -0,0 +1,89 @@
(() => {
/**
* Runtime hooks for Speed / Sound map zones (MiR §4.2.6.89).
* Vector overlay only — consumed by motion controller / mission runner.
*/
const TYPES = {
speed: "speed",
sound: "sound",
};
const BEHAVIOR_TYPES = new Set([TYPES.speed, TYPES.sound]);
const SPEED_MIN = 0.1;
const SPEED_MAX = 1.5;
const DEFAULT_SPEED_MPS = 0.8;
function pointInPolygon(px, py, points) {
return window.MapPlannerZones?.pointInPolygon(px, py, points) || false;
}
function clampSpeed(value) {
const n = Number(value);
if (!Number.isFinite(n)) return DEFAULT_SPEED_MPS;
return Math.min(SPEED_MAX, Math.max(SPEED_MIN, n));
}
function isBehaviorZoneType(type) {
return BEHAVIOR_TYPES.has(type);
}
function filterBehaviorZones(zones) {
return (Array.isArray(zones) ? zones : []).filter((z) => isBehaviorZoneType(z?.type));
}
/** Topmost behavior zones containing image pixel (newest wins for overlaps). */
function zonesAtPoint(zones, px, py) {
const list = Array.isArray(zones) ? zones : [];
const hits = [];
for (let i = list.length - 1; i >= 0; i--) {
const z = list[i];
if (!isBehaviorZoneType(z?.type) || !z.points?.length) continue;
if (pointInPolygon(px, py, z.points)) hits.push(z);
}
return hits;
}
function getSpeedLimit(zones, px, py) {
const hit = zonesAtPoint(zones, px, py).find((z) => z.type === TYPES.speed);
if (!hit) return null;
return clampSpeed(hit.speed_mps);
}
function getSoundAtPoint(zones, px, py) {
const hit = zonesAtPoint(zones, px, py).find((z) => z.type === TYPES.sound);
if (!hit?.sound_id) return null;
return {
sound_id: hit.sound_id,
zone_id: hit.id,
};
}
function classifyPoint(zones, px, py) {
const hits = zonesAtPoint(zones, px, py);
const speedZone = hits.find((z) => z.type === TYPES.speed);
const soundZone = hits.find((z) => z.type === TYPES.sound);
return {
speed_mps: speedZone ? clampSpeed(speedZone.speed_mps) : null,
sound_id: soundZone?.sound_id || null,
speed_zone: speedZone || null,
sound_zone: soundZone || null,
zones: hits,
};
}
window.MapBehaviorZones = {
TYPES,
BEHAVIOR_TYPES,
SPEED_MIN,
SPEED_MAX,
DEFAULT_SPEED_MPS,
clampSpeed,
isBehaviorZoneType,
filterBehaviorZones,
zonesAtPoint,
getSpeedLimit,
getSoundAtPoint,
classifyPoint,
};
})();