Files
gods-eye-view/src/data/militaryNames.js
T
Sameh Khamis 73e789489b chore: drop exports nothing imports
Knip, configured with the application, package exports, scripts, QA
harnesses, workers, tools and tests as entry points, reports exports
that no module imports. Each was checked by hand against string-based
and namespace imports.

- Symbols that are still used inside their own module lose only the
  `export` keyword (176 constants and helpers).
- Unused re-exports are removed from barrel modules (flight, military,
  vessel, CCTV, directions, transit history, local ADS-B and street-level
  policy modules).
- Declarations that nothing uses at all are deleted, among them
  AIS_WATCHDOG_STATUSES, applyFilter, isRadioCountryCode, compactText,
  DENSITY_STOPS, the unused CCTV endpoint constants, and the SDR band
  constants.
- Default exports that nothing imports are removed. The ones in
  src/data/earthquakes.js, src/data/telegeographySubmarineCables.js,
  src/data/wind.js and src/data/bhoteKoshiLocator.js each constructed a
  layer instance at import time that nothing used; those instances are
  no longer created.

Every export of a package.json entry stays, as does TOMTOM_CREDIT,
which the traffic layer reads from the credits namespace it is given.
2026-10-22 19:00:40 -07:00

120 lines
3.7 KiB
JavaScript

import { militaryOsmKey } from '../sources/militaryTileGeometry.js';
export { militaryOsmKey } from '../sources/militaryTileGeometry.js';
import { requestWithDeadline } from '../sources/requestDeadline.js';
import { loadBundledJson } from './bundledJson.js';
import { createRetryableLoader } from './retryableLoad.js';
export const MILITARY_POINT_CAP = 512;
export const MILITARY_LABEL_CAP = 24;
const MILITARY_NAMES_TIMEOUT_MS = 10_000;
/** Share a bounded acquisition; failed assets become retryable after cooldown. */
export function createMilitaryNamesLoader({
loadPack = (signal) =>
loadBundledJson(
new URL('./local_data/osm_military_names/names.json', import.meta.url),
{ signal },
),
timeoutMs = MILITARY_NAMES_TIMEOUT_MS,
...retryOptions
} = {}) {
return createRetryableLoader(async () => {
const pack = await requestWithDeadline(loadPack, { timeoutMs });
const records = pack.records.map(
([
osmKey,
name,
longitude,
latitude,
west,
south,
east,
north,
kind,
areaM2,
]) => ({
id: `osm:military:${osmKey}`,
osmKey,
name,
longitude,
latitude,
bbox: [west, south, east, north],
class: pack.classes[kind],
areaM2,
kind: 'installation',
namedArea: true,
pointOnly: true,
validation: 'unreviewed',
sources: [
{ name: 'OpenStreetMap', id: osmKey },
{ name: 'Overture Maps Foundation', id: osmKey },
],
}),
);
records.sort(
(a, b) => b.areaM2 - a.areaM2 || a.osmKey.localeCompare(b.osmKey),
);
return { records, byId: new Map(records.map((r) => [r.osmKey, r])) };
}, retryOptions);
}
/** Load and index the separate data asset only when installation context needs it. */
export const loadMilitaryNames = createMilitaryNamesLoader();
/** Join exact source identity before parcel merging; reject geographically inconsistent ids. */
export function nameMilitaryFragment(fragment, names) {
const osmKey = militaryOsmKey(fragment.featureKey);
const named = names?.byId.get(osmKey);
if (!named || !fragment.footprint?.length) return fragment;
const [west, south, east, north] = named.bbox;
const epsilon = (fragment.tileEpsilon || 0) * 2 + 0.0001;
const xs = fragment.footprint.map((p) => p[0]);
const ys = fragment.footprint.map((p) => p[1]);
if (
Math.max(...xs) < west - epsilon ||
Math.min(...xs) > east + epsilon ||
Math.max(...ys) < south - epsilon ||
Math.min(...ys) > north + epsilon
)
return fragment;
return {
...fragment,
name: named.name,
class: named.class,
osmKey,
namedArea: true,
areaM2: named.areaM2,
nameRecord: named,
};
}
/**
* Area-ranked spatial thinning of visible label points, including dateline
* views. With `thinned` false every point in the box is kept, up to `cap`.
*/
export function militaryNamesInView(
names,
box,
cap = MILITARY_POINT_CAP,
thinned = true,
) {
const width =
box.east >= box.west ? box.east - box.west : 360 + box.east - box.west;
const height = box.north - box.south;
const cells = new Set(),
records = [];
let count = 0;
for (const record of names?.records || []) {
const x = (record.longitude - box.west + 360) % 360;
if (x > width || record.latitude < box.south || record.latitude > box.north)
continue;
count++;
const cell = `${Math.min(31, Math.floor((x / width) * 32))}:${Math.min(15, Math.floor(((record.latitude - box.south) / height) * 16))}`;
if ((thinned && cells.has(cell)) || records.length >= cap) continue;
cells.add(cell);
records.push(record);
}
return { records, count };
}