urja-atlas
v0.1.0
Published
Offline place lookup for astrology birth-location entry -- city name to lat/lon + IANA timezone, no network call. ~69k places (population >= 5000, GeoNames-derived). Companion to urja-client.
Downloads
149
Maintainers
Readme
urja-atlas
Offline place lookup for astrology birth-location entry — city name
in, lat/lon + IANA timezone out, no network call. A companion to
urja-client, published separately so consumers that don't need it
don't pay its bundle-size cost.
Status
v0.1.0 — ~69,463 places (population ≥ 5,000, or a seat of
administrative division), sourced from
GeoNames (CC BY 4.0). 1.4 MB gzipped.
Why this exists
Netra (the pro astrology studio at netra.insightsbyomkar.com) needs
its birth-location entry to work fully offline as part of its v3.0
offline program — Solar Fire ships its own bundled atlas for exactly
this reason. Netra's location search currently proxies OpenStreetMap
Nominatim through the engine (kriya), a live network dependency.
This package isn't ephemeris math (doesn't belong in the
kriya-ephemeris-* family) and isn't a visual/design asset either,
but it's the same category of thing this repo already ships for
other concerns — a shared, browser-shippable, data-heavy primitive —
so it lives here instead of being a one-off in Netra or the engine.
The consumer site (insightsbyomkar.com) can use the same package for
its own birth-location entry.
Surface
import { searchPlaces } from "urja-atlas";
searchPlaces("Paris", 5);
// [{ name: "Paris", countryCode: "FR", countryName: "France",
// admin1Code: "11", admin1Name: "Île-de-France",
// latitudeDeg: 48.85341, longitudeDeg: 2.3488,
// timezone: "Europe/Paris", population: 2138551,
// displayName: "Paris, Île-de-France, France" }, ...]Ranks exact-name matches first, then prefix matches, then substring matches — population descending as the tiebreaker within each tier, so well-known places surface before small towns sharing a name (e.g. Paris, France before Paris, Texas). Linear scan over the ~69k-place array; fast enough for interactive search in practice (single-digit milliseconds per call in a modern JS engine) — if this becomes a bottleneck for a specific consumer, a prefix index is the natural next step, not built here to avoid speculative complexity.
Also exports the raw tables directly (PLACES, TIMEZONES,
COUNTRY_NAMES, ADMIN1_NAMES) for consumers that want to build
their own lookup/ranking instead of using searchPlaces.
What's NOT in scope
- Comprehensive place coverage.
cities5000(population ≥ 5,000) was chosen as the size/usefulness tradeoff — a fuller GeoNames tier (cities500, ~200k+ places) would roughly triple the bundle for long-tail small-town coverage. Revisit if working astrologers report real gaps for their clients' birth locations. - Historical place names / boundary changes. GeoNames reflects current names and borders; a birth in 1950s "Bombay" needs the user to search "Mumbai" (or vice versa for now).
- Fuzzy/typo-tolerant matching. Exact/prefix/substring only, no edit-distance search. Add if real usage shows it's needed.
Regenerating the data
npm run atlas:syncDownloads fresh GeoNames dumps into scripts/atlas/cache/
(gitignored) and rewrites src/atlas.data.ts. See
scripts/atlas/build.ts for the generator.
Sourcing
Place data (names, coordinates, timezones, admin boundaries) from
GeoNames, licensed
CC BY 4.0. Attribution
is required and carried in src/atlas.data.ts's header comment — keep
it if this package is modified or its data regenerated.
