emergency: widen route fallback and include motorway chains

This commit is contained in:
Richard Zink committed 2026-10-13 07:21:06 +02:00
1 parent b8bdb842b4
commit 92bb9e651c
1 file changed
+38 -19
+38 -19
View File
@@ -3533,16 +3533,17 @@ function nearestEmergencyCity() {
return best;
}
function emergencyCollectCandidates(sec, startCity, minKm, maxKm, nearLimit) {
function emergencyCollectCandidates(net, netKey, startCity, minKm, maxKm, nearLimit) {
var targetKm = (minKm + maxKm) / 2;
var out = [];
if (!net || !net.cnts || !net.cnts.length) return out;
var k = 0;
for (var ci = 0; ci < sec.cnts.length; ci++) {
var n = sec.cnts[ci];
for (var ci = 0; ci < net.cnts.length; ci++) {
var n = net.cnts[ci];
if (n < 2) { k += n * 3; continue; }
var firstX = sec.pts[k], firstZ = sec.pts[k + 1], firstD = sec.pts[k + 2];
var firstX = net.pts[k], firstZ = net.pts[k + 1], firstD = net.pts[k + 2];
var last = k + (n - 1) * 3;
var lastX = sec.pts[last], lastZ = sec.pts[last + 1], lastD = sec.pts[last + 2];
var lastX = net.pts[last], lastZ = net.pts[last + 1], lastD = net.pts[last + 2];
var len = Math.max(0, lastD - firstD);
var lenKm = len * KM_PER_TILE;
var dStart = Math.hypot(firstX - startCity.x, firstZ - startCity.z);
@@ -3550,7 +3551,7 @@ function emergencyCollectCandidates(sec, startCity, minKm, maxKm, nearLimit) {
var near = Math.min(dStart, dEnd);
if (near <= nearLimit && lenKm >= minKm && lenKm <= maxKm) {
out.push({
ci: ci, len: len, lenKm: lenKm, near: near,
net: net, netKey: netKey, ci: ci, len: len, lenKm: lenKm, near: near,
score: Math.abs(lenKm - targetKm) + near * 18,
reverse: dEnd < dStart
});
@@ -3560,6 +3561,17 @@ function emergencyCollectCandidates(sec, startCity, minKm, maxKm, nearLimit) {
return out;
}
function emergencyNetworks() {
var out = [];
if (carGeo && carGeo.secondary && carGeo.secondary.cnts && carGeo.secondary.cnts.length) {
out.push({ net: carGeo.secondary, key: 'secondary' });
}
if (carGeo && carGeo.motorway && carGeo.motorway.cnts && carGeo.motorway.cnts.length) {
out.push({ net: carGeo.motorway, key: 'motorway' });
}
return out;
}
function emergencyShuffle(arr) {
for (var i = arr.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
@@ -3578,16 +3590,21 @@ function selectEmergencyRoutes() {
return;
}
emergencyStartCity = nearestEmergencyCity();
var sec = carGeo.secondary;
var pool = emergencyCollectCandidates(sec, emergencyStartCity, EMERGENCY_MIN_KM, EMERGENCY_MAX_KM, 1.2);
var poolMode = 'strict';
if (!pool.length) {
pool = emergencyCollectCandidates(sec, emergencyStartCity, EMERGENCY_MIN_KM * 0.55, EMERGENCY_MAX_KM * 1.45, 1.8);
poolMode = 'relaxed';
}
if (!pool.length) {
pool = emergencyCollectCandidates(sec, emergencyStartCity, 10, 160, 3.0);
poolMode = 'fallback';
var nets = emergencyNetworks();
var pool = [], poolMode = 'none';
var passes = [
{ minKm: EMERGENCY_MIN_KM, maxKm: EMERGENCY_MAX_KM, near: 1.2, mode: 'strict' },
{ minKm: EMERGENCY_MIN_KM * 0.55, maxKm: EMERGENCY_MAX_KM * 1.45, near: 1.8, mode: 'relaxed' },
{ minKm: 10, maxKm: 160, near: 3.0, mode: 'fallback' },
{ minKm: 3, maxKm: 220, near: 6.0, mode: 'wide' },
{ minKm: 0.5, maxKm: 400, near: 12.0, mode: 'last-resort' }
];
for (var p = 0; p < passes.length && !pool.length; p++) {
for (var ni = 0; ni < nets.length && !pool.length; ni++) {
pool = emergencyCollectCandidates(nets[ni].net, nets[ni].key, emergencyStartCity,
passes[p].minKm, passes[p].maxKm, passes[p].near);
if (pool.length) poolMode = passes[p].mode + ':' + nets[ni].key;
}
}
pool.sort(function (a, b) { return a.score - b.score; });
var top = pool.slice(0, Math.max(EMERGENCY_COUNT * 8, 24));
@@ -3595,9 +3612,10 @@ function selectEmergencyRoutes() {
var used = {};
for (var r = 0; r < top.length && emergencyRoutes.length < EMERGENCY_COUNT; r++) {
var cand = top[r];
if (used[cand.ci]) continue;
used[cand.ci] = true;
var route = emergencyChainAt(sec, cand.ci);
var usedKey = cand.netKey + ':' + cand.ci;
if (used[usedKey]) continue;
used[usedKey] = true;
var route = emergencyChainAt(cand.net, cand.ci);
if (cand.reverse) route.reverse();
var len = route.length ? route[route.length - 1].d - route[0].d : 0;
if (len <= 0) continue;
@@ -3623,6 +3641,7 @@ function selectEmergencyRoutes() {
} : null,
poolMode: poolMode,
candidates: pool.length,
networks: nets.map(function (n) { return { key: n.key, chains: n.net.cnts.length }; }),
routes: emergencyRoutes.map(function (r) { return { km: +r.lenKm.toFixed(1), nearKm: +r.nearKm.toFixed(1) }; })
};
}