car: cap road chain stitching to avoid Set overflow
This commit is contained in:
1 parent
03ae45e0e5
commit
4ac48b188a
1 file changed
+31
-4
Vendored
+31
-4
@@ -4485,6 +4485,22 @@ function carMergeChains(polys, cfg) {
|
||||
eps.push(r);
|
||||
}
|
||||
}
|
||||
// Safety valve: dense residential/tertiary cells can create far more
|
||||
// endpoints than the join search can safely hold. In that case keep the
|
||||
// roads as individual chains instead of trying to stitch everything.
|
||||
var JOIN_ENDPOINT_LIMIT = 180000;
|
||||
if (eps.length > JOIN_ENDPOINT_LIMIT) {
|
||||
var isoOut = [], isoMax = 0;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (polys[i] && polys[i].length > 1) {
|
||||
isoOut.push(polys[i]);
|
||||
var isoSpan = Math.max(polys[i][0].d, polys[i][polys[i].length - 1].d);
|
||||
if (isoSpan > isoMax) isoMax = isoSpan;
|
||||
}
|
||||
}
|
||||
return { out: isoOut, n: n, joins: 0,
|
||||
maxChainKm: n ? isoMax * cfg.KM_PER_TILE : 0 };
|
||||
}
|
||||
// canonical numeric key for an endpoint pair (way index + end side)
|
||||
function pairKey(A, B) {
|
||||
var x = A.w * 2 + A.e, y = B.w * 2 + B.e;
|
||||
@@ -4510,25 +4526,36 @@ function carMergeChains(polys, cfg) {
|
||||
var T = TIERS[t];
|
||||
var cands = candsByTier[t];
|
||||
var seenPair = new Set();
|
||||
for (i = 0; i < eps.length; i++) {
|
||||
var seenFull = false;
|
||||
var SEEN_PAIR_LIMIT = 2000000;
|
||||
var CAND_LIMIT = 1200000;
|
||||
for (i = 0; i < eps.length && !seenFull; i++) {
|
||||
if ((i & 8191) === 8191) geoProgress('join tier ' + t, i, eps.length);
|
||||
var A2 = eps[i];
|
||||
var gx = Math.floor(A2.x / NEAR), gz = Math.floor(A2.z / NEAR);
|
||||
for (var ox = -1; ox <= 1; ox++) {
|
||||
for (var oz = -1; oz <= 1; oz++) {
|
||||
for (var ox = -1; ox <= 1 && !seenFull; ox++) {
|
||||
for (var oz = -1; oz <= 1 && !seenFull; oz++) {
|
||||
var bucket = grid.get((gx + ox) + '_' + (gz + oz));
|
||||
if (!bucket) continue;
|
||||
for (j = 0; j < bucket.length; j++) {
|
||||
for (j = 0; j < bucket.length && !seenFull; j++) {
|
||||
var B2 = bucket[j];
|
||||
if (B2.w === A2.w) continue;
|
||||
var pk2 = pairKey(A2, B2);
|
||||
if (seenPair.has(pk2)) continue;
|
||||
if (seenPair.size >= SEEN_PAIR_LIMIT) {
|
||||
seenFull = true;
|
||||
break;
|
||||
}
|
||||
seenPair.add(pk2);
|
||||
var gm = geomFor(A2, B2);
|
||||
if (gm.dot <= T.dot) continue;
|
||||
if (gm.lat > T.lat) continue; // opposite carriageway: reject
|
||||
if (gm.along < T.alongLo || gm.along > T.alongHi) continue;
|
||||
cands.push({ a: A2, b: B2, s: gm.s });
|
||||
if (cands.length >= CAND_LIMIT) {
|
||||
seenFull = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user