mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
address review findings on voice outlines
- remove the unused Nominatim reserve(); spacing tests now measure the actual transport start across processes - start each queued building's 2 s ground-sampling budget when it reaches the head of the queue, and request a frame on promotion - accept Nominatim and grounds outlines that cross the antimeridian - let an unnamed school, university, hospital, cemetery, stadium or zoo area answer a grounds ask whose head noun names that kind, using only the part that holds the point; compare grounds names symmetrically - charge shared OpenFreeMap consumers their own slice and keep the charged budget at the previous 64 MiB - share one place-name fold, point-in-polygon, line stitching and nextTask helper instead of duplicates - exclude Who's On First sources licensed only as "CC BY (equivalent)" or "CC0 (equivalent)"; rebuild the pack from the pinned archives - whole-word neighbourhood alias guard; correct the outline size-limit comment - restore DATA_SOURCES.md table formatting, keeping only real edits - test behaviour instead of private engine fields
This commit is contained in:
1 parent
5a1cfa6800
commit
2e82425d62
37 files changed
+921
-481
No files matched your search
@@ -1,6 +1,7 @@
|
||||
import crypto from 'node:crypto';
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { foldPlaceName } from '../../../src/data/placeNames.js';
|
||||
|
||||
const DAY_MS = 86_400_000;
|
||||
|
||||
@@ -15,24 +16,14 @@ export const NOMINATIM_CACHE_TTL_MS = Object.freeze({
|
||||
});
|
||||
|
||||
/**
|
||||
* Comparable form of a place name: Unicode-normalized (NFKC), Latin accents
|
||||
* removed, case folded, punctuation and symbols collapsed to single spaces,
|
||||
* and a leading article dropped. Non-Latin scripts are kept as they are:
|
||||
* "東京" stays "東京", while "São Paulo", "sao paulo" and "SÃO PAULO!" meet.
|
||||
* Comparable form of a place name for matching results to the ask: the
|
||||
* shared fold (see `foldPlaceName`), bounded in length.
|
||||
*
|
||||
* @param {string} value
|
||||
* @returns {string}
|
||||
*/
|
||||
export function normalizePlaceName(value) {
|
||||
return String(value ?? '')
|
||||
.normalize('NFKD')
|
||||
.replace(/(\p{Script=Latin})\p{M}+/gu, '$1')
|
||||
.normalize('NFKC')
|
||||
.toLocaleLowerCase('en-US')
|
||||
.replace(/[\p{P}\p{S}\p{Z}\s]+/gu, ' ')
|
||||
.trim()
|
||||
.replace(/^(?:the) /, '')
|
||||
.slice(0, 200);
|
||||
return foldPlaceName(value).slice(0, 200);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -489,63 +489,6 @@ export function createGateStateStore({
|
||||
nextStartAt: state.nextStartAt,
|
||||
})).count;
|
||||
},
|
||||
reserve(day, { now, dailyCap, minSpacingMs, latestStartAt = Infinity }) {
|
||||
if (!file) {
|
||||
const error = new Error(
|
||||
'no durable Nominatim usage state is configured',
|
||||
);
|
||||
report(error);
|
||||
return { status: 'unavailable', error };
|
||||
}
|
||||
try {
|
||||
let result;
|
||||
withLock(() => {
|
||||
if (pendingDispatches({ strict: true }).length)
|
||||
throw new Error('unfinished durable Nominatim dispatch');
|
||||
const disk = readDisk({ strict: true });
|
||||
if (disk) memory = merge(memory, disk);
|
||||
const pending = pendingPauses({ strict: true });
|
||||
if (pending.length)
|
||||
memory = merge(memory, {
|
||||
...memory,
|
||||
pausedUntil: Math.max(...pending.map((item) => item.pausedUntil)),
|
||||
});
|
||||
const state = memory;
|
||||
if ((state.pausedUntil || 0) > now) {
|
||||
result = {
|
||||
status: 'paused',
|
||||
retryAfterMs: state.pausedUntil - now,
|
||||
};
|
||||
return;
|
||||
}
|
||||
const count = state.day === day ? state.count : 0;
|
||||
if (count >= dailyCap) {
|
||||
result = { status: 'cap' };
|
||||
return;
|
||||
}
|
||||
const startAt = Math.max(now, state.nextStartAt || 0);
|
||||
if (startAt > latestStartAt) {
|
||||
result = { status: 'abandoned' };
|
||||
return;
|
||||
}
|
||||
const next = {
|
||||
day,
|
||||
count: count + 1,
|
||||
pausedUntil: state.pausedUntil || 0,
|
||||
nextStartAt: startAt + minSpacingMs,
|
||||
};
|
||||
writeDisk(next);
|
||||
memory = next;
|
||||
clearPersistedPauses(next.pausedUntil);
|
||||
lastError = null;
|
||||
result = { status: 'reserved', startAt, count: next.count };
|
||||
});
|
||||
return result;
|
||||
} catch (error) {
|
||||
report(error);
|
||||
return { status: 'unavailable', error };
|
||||
}
|
||||
},
|
||||
dispatch(
|
||||
day,
|
||||
{ clock, dailyCap, minSpacingMs, latestStartAt = Infinity },
|
||||
|
||||
@@ -30,7 +30,11 @@ export const OUTLINE_POLYGON_THRESHOLD = Object.freeze({
|
||||
building: 0.00005,
|
||||
});
|
||||
|
||||
/** Total vertices returned for one outline, and parts/holes kept. */
|
||||
/**
|
||||
* Size limits for one outline. Vertices beyond the budget are simplified away;
|
||||
* more parts, or more holes in one part, than these limits refuse the outline
|
||||
* whole, because a truncated multipart place would misrepresent it.
|
||||
*/
|
||||
const OUTLINE_MAX_VERTICES = 6000;
|
||||
const OUTLINE_MAX_PARTS = 24;
|
||||
const OUTLINE_MAX_HOLES = 16;
|
||||
|
||||
Reference in new issue
Block a user