mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 02:44:02 +00:00
Traffic roads come from OpenFreeMap vector tiles, or TomTom flow tiles with a key (Hybrid by default). Military areas use OpenFreeMap polygons with a bundled worldwide name index; wide views show named points. ALPR reads an hourly OpenStreetMap extract. Cockpit place context and country, state and US county outlines use bundled Natural Earth and US Census data. Overpass is used only when an operator configures their own endpoint. Also: camera arrivals no longer land below ground, keyless terrain retries on 429, bounded relation geometry for configured Overpass, one shared OpenStreetMap credit, and separate tile and API transports for embedders. Co-authored-by: theGaryLarson <[email protected]> Co-authored-by: Milan Khanal <[email protected]>
This commit is contained in:
200 files changed
+26665
-1977
No files matched your search
+157
-13
@@ -1,3 +1,4 @@
|
||||
import { isUnavailableCapability } from '../sources/capability.js';
|
||||
import { requireFeatureSource } from '../sources/featureSource.js';
|
||||
import { createOverpassFeatureSource } from '../sources/overpassFeatures.js';
|
||||
import {
|
||||
@@ -18,9 +19,11 @@ import {
|
||||
lookupNaturalRegionOutline,
|
||||
findNaturalRegion,
|
||||
} from '../data/naturalEarthRegions.js';
|
||||
import { findAdminArea, findAdminAreaAt } from '../data/adminBoundaries.js';
|
||||
import {
|
||||
registerDynamicCredit,
|
||||
NATURAL_EARTH_CREDIT,
|
||||
US_CENSUS_CREDIT,
|
||||
} from '../data/dataCredits.js';
|
||||
import { unavailablePlaceSearch } from '../search/placeSearch.js';
|
||||
import { isPickedWorldPosition } from '../data/scenePick.js';
|
||||
@@ -28,6 +31,14 @@ import { isPickedWorldPosition } from '../data/scenePick.js';
|
||||
/** Ms the analyst region lookup waits on geocode + admin boundary. */
|
||||
export const REGION_FALLBACK_BUDGET_MS = 3_000;
|
||||
|
||||
/** Entity facts that rule out a state/county reading of the ask. */
|
||||
const NON_ADMIN_ENTITY_KINDS = new Set([
|
||||
'building',
|
||||
'compound',
|
||||
'street',
|
||||
'point_feature',
|
||||
]);
|
||||
|
||||
/** Own annotation lookup caches and ranking of supplied feature candidates. */
|
||||
export function createAnnotationResolver({
|
||||
boundarySource,
|
||||
@@ -176,6 +187,23 @@ export function createAnnotationResolver({
|
||||
// ("the Texas Capitol" → the state), so geocode types must never grant it.
|
||||
const bypassNearViewGuards = Boolean(adminScopeFromAsk(target, entityKind));
|
||||
|
||||
// Bundled administrative outlines resolve settled names without a lookup.
|
||||
// Georgia uses its qualifier or camera; city/state homonyms defer to geocoding.
|
||||
if (
|
||||
footprint &&
|
||||
(!Number.isFinite(lat) || !Number.isFinite(lon)) &&
|
||||
trace.query &&
|
||||
!NON_ADMIN_ENTITY_KINDS.has(entityKind)
|
||||
) {
|
||||
const center =
|
||||
pickWorldFromScreen(viewer, 0.5, 0.5) || viewportProximity(viewer);
|
||||
const admin = await findAdminArea(trace.query, { near: center }).catch(
|
||||
() => null,
|
||||
);
|
||||
signal?.throwIfAborted();
|
||||
if (admin) return bundledAdminTarget(viewer, admin, trace.query);
|
||||
}
|
||||
|
||||
if (!Number.isFinite(lat) || !Number.isFinite(lon)) {
|
||||
const query = String(target || '').trim();
|
||||
if (query) {
|
||||
@@ -474,8 +502,32 @@ export function createAnnotationResolver({
|
||||
// GROUNDS-like ask must not short-circuit here: the model phrases "the Capitol
|
||||
// grounds" as around_the_thing, but the grounds ARE the thing — the real enclosing
|
||||
// polygon (below) beats a 400 m disc (field test 8's "spherical round one").
|
||||
const availability = await fetchEnclosingArea(
|
||||
lat,
|
||||
lon,
|
||||
signal,
|
||||
matchName,
|
||||
);
|
||||
if (
|
||||
isUnavailableCapability(availability) ||
|
||||
isRateLimitedOutcome(availability)
|
||||
)
|
||||
return availability;
|
||||
if (availability === undefined) return undefined;
|
||||
fp = synthesizeBufferedArea(lat, lon, AROUND_LANDMARK_RADIUS_M);
|
||||
} else if (isAdmin) {
|
||||
// A country, state or county the geocoder typed: the bundled unit that carries the
|
||||
// name AND contains the geocoded point (offline; the pack's ambiguity
|
||||
// marks don't apply — the geocoder already chose "Georgia" the state).
|
||||
if (scope === 'state' || scope === 'county' || scope === 'country') {
|
||||
const admin = await findAdminAreaAt(
|
||||
[target, matchName],
|
||||
lat,
|
||||
lon,
|
||||
scope,
|
||||
).catch(() => null);
|
||||
if (admin) return bundledAdminOutline(viewer, admin);
|
||||
}
|
||||
// Pure admin: only an admin boundary is correct — never fall back to a
|
||||
// building/landuse (a city is never a single building).
|
||||
fp = await fetchAdminArea(lat, lon, matchName, scope, signal);
|
||||
@@ -501,6 +553,7 @@ export function createAnnotationResolver({
|
||||
// A neighborhood whose canonical name carries a city suffix ("Presidio of San
|
||||
// Francisco") can match the CITY admin; treat an oversized admin as a DEFINITIVE
|
||||
// no-neighborhood-polygon so it still falls through to the named-landuse path.
|
||||
if (isUnavailableCapability(adminFp)) return adminFp;
|
||||
if (adminFp && exceedsScopeArea(adminFp, scope)) adminFp = null;
|
||||
if (adminFp) {
|
||||
fp = adminFp;
|
||||
@@ -515,6 +568,7 @@ export function createAnnotationResolver({
|
||||
signal,
|
||||
'strict',
|
||||
);
|
||||
if (isUnavailableCapability(footFp)) return footFp;
|
||||
if (footFp) {
|
||||
fp = footFp;
|
||||
} else if (footFp === null) {
|
||||
@@ -531,6 +585,7 @@ export function createAnnotationResolver({
|
||||
signal,
|
||||
'loose',
|
||||
);
|
||||
if (isUnavailableCapability(looseFp)) return looseFp;
|
||||
if (looseFp && looseFp.kind !== 'building') fp = looseFp;
|
||||
else if (looseFp === null)
|
||||
fp = synthesizeBufferedArea(lat, lon, NEIGHBORHOOD_RADIUS_M);
|
||||
@@ -580,6 +635,7 @@ export function createAnnotationResolver({
|
||||
// synthesized disc only when OSM DEFINITIVELY has none.
|
||||
if (groundsLike && (fp === null || fp?.kind === 'building')) {
|
||||
const area = await fetchEnclosingArea(lat, lon, signal, matchName);
|
||||
if (isUnavailableCapability(area)) return area;
|
||||
if (area) {
|
||||
fp = area; // real grounds polygon (synthesized:false) — beats both the dome and a disc
|
||||
// It's a grounds/compound feature (already capped at SCOPE_AREA_CAP_M2.compound inside
|
||||
@@ -619,7 +675,7 @@ export function createAnnotationResolver({
|
||||
) {
|
||||
fp = null;
|
||||
}
|
||||
if (isRateLimitedOutcome(fp)) return fp;
|
||||
if (isUnavailableCapability(fp) || isRateLimitedOutcome(fp)) return fp;
|
||||
if (fp === undefined) return undefined; // TRANSIENT — a backoff retry may still find it
|
||||
if (!fp || !Array.isArray(fp.ring) || fp.ring.length < 3) return null;
|
||||
const centroid = ringCentroid(fp.ring);
|
||||
@@ -646,10 +702,12 @@ export function createAnnotationResolver({
|
||||
let ring = null;
|
||||
let footprintKind = null; // 'building' | 'area'
|
||||
let buildingHeight = null; // meters, only for buildings
|
||||
let outlineUnavailable = false;
|
||||
let synthesized = false; // true = buffered/approximate area, render dashed/feathered
|
||||
if (footprint && !deferFootprint) {
|
||||
const fp = await resolveOutline();
|
||||
if (fp && !isRateLimitedOutcome(fp)) {
|
||||
outlineUnavailable = isUnavailableCapability(fp);
|
||||
if (fp && !outlineUnavailable && !isRateLimitedOutcome(fp)) {
|
||||
ring = fp.ring;
|
||||
footprintKind = fp.footprintKind;
|
||||
buildingHeight = fp.buildingHeight;
|
||||
@@ -680,6 +738,7 @@ export function createAnnotationResolver({
|
||||
label,
|
||||
source,
|
||||
synthesized,
|
||||
outlineUnavailable,
|
||||
viewport: placeViewport,
|
||||
...(footprint && deferFootprint ? { resolveOutline } : {}),
|
||||
};
|
||||
@@ -720,6 +779,65 @@ export function createAnnotationResolver({
|
||||
const GROUNDS_RADIUS_MIN_M = 150; // viewport-derived grounds disc is clamped to this band so a tiny
|
||||
const GROUNDS_RADIUS_MAX_M = 1200; // place can't shrink to a dot, nor a city-wide viewport balloon
|
||||
|
||||
/** Credit the pack a bundled boundary came from. */
|
||||
function creditAdminSource(viewer, admin) {
|
||||
registerDynamicCredit(
|
||||
viewer,
|
||||
admin.source === 'us-census' ? US_CENSUS_CREDIT : NATURAL_EARTH_CREDIT,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outline patch (resolveOutline's contract) for a bundled administrative unit.
|
||||
* `ring` is the main part, closed; `polygons` carries every part with its
|
||||
* holes (Hawaii's islands, Berlin inside Brandenburg) for renderers that
|
||||
* draw them. Like the Natural Earth rung, it bypasses the scope caps and the
|
||||
* centroid drift bound: the unit IS the asked scope.
|
||||
*/
|
||||
function bundledAdminOutline(viewer, admin) {
|
||||
creditAdminSource(viewer, admin);
|
||||
const { lat, lon } = admin.label;
|
||||
return {
|
||||
ring: closeRing([...admin.ring]), // copy: closeRing mutates, the pack is shared
|
||||
polygons: admin.polygons,
|
||||
footprintKind: 'area',
|
||||
buildingHeight: null,
|
||||
synthesized: false,
|
||||
adminArea: admin.name,
|
||||
lat,
|
||||
lon,
|
||||
height: sampleGroundHeight(viewer, lon, lat),
|
||||
};
|
||||
}
|
||||
|
||||
/** A complete resolved target for a bundled administrative unit (no outline pending). */
|
||||
function bundledAdminTarget(viewer, admin, query) {
|
||||
const outline = bundledAdminOutline(viewer, admin);
|
||||
const [west, south, east, north] = admin.bbox;
|
||||
console.log(
|
||||
`[Resolver] "${query}": bundled ${admin.kind} "${admin.name}"` +
|
||||
`${admin.region ? `, ${admin.region}` : ''} (${admin.source}, ` +
|
||||
`${admin.polygons.length} part(s), ${admin.candidates} candidate(s)) → FINAL source=bundled`,
|
||||
);
|
||||
return {
|
||||
lon: outline.lon,
|
||||
lat: outline.lat,
|
||||
height: outline.height,
|
||||
ring: outline.ring,
|
||||
polygons: outline.polygons,
|
||||
footprintKind: 'area',
|
||||
buildingHeight: null,
|
||||
label: admin.name,
|
||||
source: 'bundled',
|
||||
synthesized: false,
|
||||
outlineUnavailable: false,
|
||||
viewport: {
|
||||
low: { latitude: south, longitude: west },
|
||||
high: { latitude: north, longitude: east },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Synthesize an approximate circular AREA by buffering a label point. Returns a ring
|
||||
* marked `synthesized:true` so the renderers draw it "approximate" (dashed/feathered),
|
||||
@@ -1004,7 +1122,8 @@ export function createAnnotationResolver({
|
||||
{ lat, lon },
|
||||
{ signal: signal },
|
||||
);
|
||||
if (isRateLimitedOutcome(candidates)) return candidates;
|
||||
if (isUnavailableCapability(candidates) || isRateLimitedOutcome(candidates))
|
||||
return candidates;
|
||||
if (!candidates) return undefined; // transient upstream failure (vs null = definitive miss)
|
||||
|
||||
const queryWords = normalizedWords(query);
|
||||
@@ -1067,7 +1186,8 @@ export function createAnnotationResolver({
|
||||
// without first trying the place= polygon (and a named landuse via the caller).
|
||||
if (scope === 'neighborhood' && (!best || bestCoverage < 0.8)) {
|
||||
const place = await fetchPlaceArea(lat, lon, query, signal);
|
||||
if (isRateLimitedOutcome(place)) return place;
|
||||
if (isUnavailableCapability(place) || isRateLimitedOutcome(place))
|
||||
return place;
|
||||
if (place) {
|
||||
cacheWrite(footprintCache, cacheKey, place);
|
||||
return place;
|
||||
@@ -1097,7 +1217,8 @@ export function createAnnotationResolver({
|
||||
const relEls = await featureSource.getAreaGeometry(cand.el.id, {
|
||||
signal: signal,
|
||||
});
|
||||
if (isRateLimitedOutcome(relEls)) return relEls;
|
||||
if (isUnavailableCapability(relEls) || isRateLimitedOutcome(relEls))
|
||||
return relEls;
|
||||
if (relEls === null) {
|
||||
transient = true;
|
||||
break;
|
||||
@@ -1126,7 +1247,8 @@ export function createAnnotationResolver({
|
||||
if (exceedsScopeArea(fp, scope)) {
|
||||
if (scope === 'neighborhood') {
|
||||
const place = await fetchPlaceArea(lat, lon, query, signal);
|
||||
if (isRateLimitedOutcome(place)) return place;
|
||||
if (isUnavailableCapability(place) || isRateLimitedOutcome(place))
|
||||
return place;
|
||||
if (place) {
|
||||
cacheWrite(footprintCache, cacheKey, place);
|
||||
return place;
|
||||
@@ -1149,7 +1271,8 @@ export function createAnnotationResolver({
|
||||
// caller relies on that to gate named-landuse fallback / synthesis.
|
||||
if (scope === 'neighborhood') {
|
||||
const place = await fetchPlaceArea(lat, lon, query, signal);
|
||||
if (isRateLimitedOutcome(place)) return place;
|
||||
if (isUnavailableCapability(place) || isRateLimitedOutcome(place))
|
||||
return place;
|
||||
if (place) {
|
||||
cacheWrite(footprintCache, cacheKey, place);
|
||||
return place;
|
||||
@@ -1171,7 +1294,7 @@ export function createAnnotationResolver({
|
||||
{ lat, lon },
|
||||
{ signal: signal },
|
||||
);
|
||||
if (isRateLimitedOutcome(els)) return els;
|
||||
if (isUnavailableCapability(els) || isRateLimitedOutcome(els)) return els;
|
||||
if (els === null) return undefined; // transient upstream failure (vs [] = no match)
|
||||
let bestRing = null;
|
||||
let bestScore = 0;
|
||||
@@ -1220,7 +1343,8 @@ export function createAnnotationResolver({
|
||||
{ lat, lon },
|
||||
{ signal: signal },
|
||||
);
|
||||
if (isRateLimitedOutcome(areaEls)) return areaEls;
|
||||
if (isUnavailableCapability(areaEls) || isRateLimitedOutcome(areaEls))
|
||||
return areaEls;
|
||||
if (areaEls) {
|
||||
let bestRing = null;
|
||||
let bestScore = 0;
|
||||
@@ -1253,7 +1377,8 @@ export function createAnnotationResolver({
|
||||
{ lat, lon },
|
||||
{ signal: signal },
|
||||
);
|
||||
if (isRateLimitedOutcome(wayEls)) return wayEls;
|
||||
if (isUnavailableCapability(wayEls) || isRateLimitedOutcome(wayEls))
|
||||
return wayEls;
|
||||
if (wayEls) {
|
||||
const segments = [];
|
||||
for (const el of wayEls) {
|
||||
@@ -1326,7 +1451,8 @@ export function createAnnotationResolver({
|
||||
{ lat, lon },
|
||||
{ signal: signal },
|
||||
);
|
||||
if (isRateLimitedOutcome(elements)) return elements;
|
||||
if (isUnavailableCapability(elements) || isRateLimitedOutcome(elements))
|
||||
return elements;
|
||||
if (elements === null || signal?.aborted) return undefined;
|
||||
const fp = selectFootprint(elements, lat, lon, query, mode);
|
||||
if (fp) {
|
||||
@@ -1374,7 +1500,8 @@ export function createAnnotationResolver({
|
||||
{ lat, lon },
|
||||
{ signal: signal },
|
||||
);
|
||||
if (isRateLimitedOutcome(elements)) return elements;
|
||||
if (isUnavailableCapability(elements) || isRateLimitedOutcome(elements))
|
||||
return elements;
|
||||
if (elements === null) return undefined; // transient upstream failure (vs [] = definitive no-match)
|
||||
|
||||
const queryWords = normalizedWords(query);
|
||||
@@ -1497,7 +1624,11 @@ export function createAnnotationResolver({
|
||||
pending = featureSource
|
||||
.getMonuments({ lat, lon }, { signal: undefined })
|
||||
.then((elements) => {
|
||||
if (elements === null || isRateLimitedOutcome(elements))
|
||||
if (
|
||||
elements === null ||
|
||||
isUnavailableCapability(elements) ||
|
||||
isRateLimitedOutcome(elements)
|
||||
)
|
||||
return null; // transient — NEVER cached (a poisoned bucket
|
||||
// would silently disable the snap for the whole session, field test 7 §1)
|
||||
const feats = [];
|
||||
@@ -1912,6 +2043,10 @@ export function createAnnotationResolver({
|
||||
const ring = [...ne.polygons].sort((a, b) => b.length - a.length)[0];
|
||||
if (ring?.length >= 3) return { name: ne.name, ring };
|
||||
}
|
||||
// Bundled states/provinces/counties by name (offline); the main part only,
|
||||
// like the Natural Earth rung above.
|
||||
const admin = await findAdminArea(q).catch(() => null);
|
||||
if (admin) return { name: admin.name, ring: [...admin.ring] };
|
||||
const lookup = resolveAdminRegionRing(q, signal, placeSearch);
|
||||
if (!Number.isFinite(budgetMs)) return lookup;
|
||||
let timer;
|
||||
@@ -1935,6 +2070,15 @@ export function createAnnotationResolver({
|
||||
if (!geo) return null;
|
||||
const scope = scopeFromTypes(geo.types);
|
||||
if (!['country', 'state', 'county', 'city'].includes(scope)) return null;
|
||||
if (scope === 'state' || scope === 'county' || scope === 'country') {
|
||||
const admin = await findAdminAreaAt(
|
||||
[q, geo.primaryName],
|
||||
geo.lat,
|
||||
geo.lon,
|
||||
scope,
|
||||
).catch(() => null);
|
||||
if (admin) return { name: q, ring: [...admin.ring] };
|
||||
}
|
||||
const fp = await fetchAdminArea(geo.lat, geo.lon, q, scope, signal).catch(
|
||||
() => null,
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user