emergency: select routes that pass near the start city
This commit is contained in:
1 parent
4cb1e3a704
commit
f06c50409a
1 file changed
+45
-14
Vendored
+45
-14
@@ -3549,16 +3549,36 @@ function emergencyCollectCandidates(net, netKey, startCity, minKm, maxKm, nearLi
|
|||||||
var lastX = net.pts[last], lastZ = net.pts[last + 1], lastD = net.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 len = Math.max(0, lastD - firstD);
|
||||||
var lenKm = len * KM_PER_TILE;
|
var lenKm = len * KM_PER_TILE;
|
||||||
var dStart = Math.hypot(firstX - startCity.x, firstZ - startCity.z);
|
if (lenKm >= minKm && lenKm <= maxKm) {
|
||||||
|
var near = Math.hypot(firstX - startCity.x, firstZ - startCity.z);
|
||||||
|
var startD = 0;
|
||||||
var dEnd = Math.hypot(lastX - startCity.x, lastZ - startCity.z);
|
var dEnd = Math.hypot(lastX - startCity.x, lastZ - startCity.z);
|
||||||
var near = Math.min(dStart, dEnd);
|
if (dEnd < near) {
|
||||||
if (near <= nearLimit && lenKm >= minKm && lenKm <= maxKm) {
|
near = dEnd;
|
||||||
|
startD = len;
|
||||||
|
}
|
||||||
|
// A long road can pass close to the start city even when both
|
||||||
|
// of its endpoints are far away. Sample the chain coarsely.
|
||||||
|
if (near > nearLimit && n > 4) {
|
||||||
|
var step = Math.max(1, Math.floor(n / 16));
|
||||||
|
for (var q = step; q < n - step; q += step) {
|
||||||
|
var off = k + q * 3;
|
||||||
|
var dd = Math.hypot(net.pts[off] - startCity.x, net.pts[off + 1] - startCity.z);
|
||||||
|
if (dd < near) {
|
||||||
|
near = dd;
|
||||||
|
startD = Math.max(0, Math.min(len, net.pts[off + 2] - firstD));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (near <= nearLimit) {
|
||||||
out.push({
|
out.push({
|
||||||
net: net, netKey: netKey, ci: ci, len: len, lenKm: lenKm, near: near,
|
net: net, netKey: netKey, ci: ci, len: len, lenKm: lenKm,
|
||||||
|
near: near, startD: startD,
|
||||||
score: Math.abs(lenKm - targetKm) + near * 18,
|
score: Math.abs(lenKm - targetKm) + near * 18,
|
||||||
reverse: dEnd < dStart
|
reverse: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
k += n * 3;
|
k += n * 3;
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
@@ -3620,11 +3640,7 @@ function selectEmergencyRoutes() {
|
|||||||
if (used[usedKey]) continue;
|
if (used[usedKey]) continue;
|
||||||
used[usedKey] = true;
|
used[usedKey] = true;
|
||||||
var route = emergencyChainAt(cand.net, cand.ci);
|
var route = emergencyChainAt(cand.net, cand.ci);
|
||||||
if (cand.reverse) {
|
if (route.length) {
|
||||||
route.reverse();
|
|
||||||
var maxD = route.length ? route[0].d : 0;
|
|
||||||
for (var rp = 0; rp < route.length; rp++) route[rp].d = maxD - route[rp].d;
|
|
||||||
} else if (route.length) {
|
|
||||||
var base = route[0].d;
|
var base = route[0].d;
|
||||||
for (var rp2 = 0; rp2 < route.length; rp2++) route[rp2].d -= base;
|
for (var rp2 = 0; rp2 < route.length; rp2++) route[rp2].d -= base;
|
||||||
}
|
}
|
||||||
@@ -3637,12 +3653,20 @@ function selectEmergencyRoutes() {
|
|||||||
});
|
});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
emergencyRoutes.push({ pts: route, len: len, lenKm: len * KM_PER_TILE, nearKm: cand.near * KM_PER_TILE });
|
emergencyRoutes.push({
|
||||||
|
pts: route, len: len, lenKm: len * KM_PER_TILE,
|
||||||
|
nearKm: cand.near * KM_PER_TILE,
|
||||||
|
startD: Math.max(0, Math.min(len, cand.startD || 0))
|
||||||
|
});
|
||||||
}
|
}
|
||||||
for (var v = 0; v < emergencyRoutes.length; v++) {
|
for (var v = 0; v < emergencyRoutes.length; v++) {
|
||||||
|
var rr = emergencyRoutes[v];
|
||||||
|
var spread = rr.len * 0.18;
|
||||||
|
var d = (rr.startD || 0) + (Math.random() - 0.5) * spread;
|
||||||
|
d = Math.max(0, Math.min(rr.len, d));
|
||||||
emergencyVehicles.push({
|
emergencyVehicles.push({
|
||||||
route: v,
|
route: v,
|
||||||
d: emergencyRoutes[v].len * (0.05 + 0.85 * Math.random()),
|
d: d,
|
||||||
dir: Math.random() < 0.5 ? 1 : -1,
|
dir: Math.random() < 0.5 ? 1 : -1,
|
||||||
seed: Math.random()
|
seed: Math.random()
|
||||||
});
|
});
|
||||||
@@ -3662,12 +3686,19 @@ function selectEmergencyRoutes() {
|
|||||||
candidateSample: top.slice(0, 5).map(function (c) {
|
candidateSample: top.slice(0, 5).map(function (c) {
|
||||||
return {
|
return {
|
||||||
netKey: c.netKey, ci: c.ci, lenKm: +c.lenKm.toFixed(1),
|
netKey: c.netKey, ci: c.ci, lenKm: +c.lenKm.toFixed(1),
|
||||||
nearKm: +(c.near * KM_PER_TILE).toFixed(1), reverse: c.reverse
|
nearKm: +(c.near * KM_PER_TILE).toFixed(1),
|
||||||
|
startKm: +((c.startD || 0) * KM_PER_TILE).toFixed(1)
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
routeFailures: routeFailures.slice(0, 5),
|
routeFailures: routeFailures.slice(0, 5),
|
||||||
networks: nets.map(function (n) { return { key: n.key, chains: n.net.cnts.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) }; })
|
routes: emergencyRoutes.map(function (r) {
|
||||||
|
return {
|
||||||
|
km: +r.lenKm.toFixed(1),
|
||||||
|
nearKm: +r.nearKm.toFixed(1),
|
||||||
|
startKm: +(r.startD * KM_PER_TILE).toFixed(1)
|
||||||
|
};
|
||||||
|
})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user