@mailwoman/resolver-wof-sqlite 9.0.0 → 9.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -9
- package/address-point-interpolation.ts +18 -8
- package/address-point-schema.ts +18 -6
- package/address-point.ts +111 -18
- package/ancestry.ts +9 -6
- package/build-candidate.ts +287 -157
- package/build-slim.ts +3 -3
- package/candidate/alias-bags.ts +54 -0
- package/candidate/ancestors-sidecar.ts +206 -0
- package/candidate/country-display-names.ts +79 -0
- package/candidate/name-roles.ts +237 -0
- package/candidate/own-name.ts +146 -0
- package/candidate/place-attrs.ts +44 -0
- package/candidate/shard-fold.ts +137 -0
- package/candidate-ancestors-schema.ts +195 -0
- package/candidate-fts.ts +4 -2
- package/candidate-importance.ts +228 -0
- package/candidate-lookup.ts +564 -174
- package/candidate-schema.ts +60 -3
- package/candidate-scoring.ts +268 -0
- package/capital-schema.ts +90 -0
- package/capitals.ts +148 -0
- package/coincident-roles.ts +69 -10
- package/convention-schema.ts +72 -0
- package/convention.ts +2 -2
- package/coverage-manifest-schema.ts +7 -7
- package/currency-backfill.ts +249 -0
- package/exact-match.ts +104 -0
- package/fst-autocomplete.ts +105 -122
- package/fst-builder.ts +39 -47
- package/fst-deserialize-web.ts +43 -7
- package/fst-freshness.ts +2 -2
- package/fst-serialize.ts +68 -12
- package/fst-types.ts +35 -1
- package/fts-query.ts +1 -1
- package/fts.ts +16 -4
- package/geonames-postal.ts +2 -2
- package/index.ts +26 -14
- package/interpolation.ts +113 -19
- package/lookup.ts +118 -560
- package/name-score.ts +6 -4
- package/out/address-point-interpolation.d.ts.map +1 -1
- package/out/address-point-interpolation.js +13 -7
- package/out/address-point-interpolation.js.map +1 -1
- package/out/address-point-schema.d.ts +16 -6
- package/out/address-point-schema.d.ts.map +1 -1
- package/out/address-point-schema.js.map +1 -1
- package/out/address-point.d.ts.map +1 -1
- package/out/address-point.js +70 -14
- package/out/address-point.js.map +1 -1
- package/out/ancestry.d.ts +2 -2
- package/out/ancestry.d.ts.map +1 -1
- package/out/ancestry.js +5 -6
- package/out/ancestry.js.map +1 -1
- package/out/build-candidate.d.ts +108 -0
- package/out/build-candidate.d.ts.map +1 -1
- package/out/build-candidate.js +151 -120
- package/out/build-candidate.js.map +1 -1
- package/out/build-slim.d.ts +1 -1
- package/out/build-slim.js +3 -3
- package/out/build-slim.js.map +1 -1
- package/out/candidate/alias-bags.d.ts +17 -0
- package/out/candidate/alias-bags.d.ts.map +1 -0
- package/out/candidate/alias-bags.js +39 -0
- package/out/candidate/alias-bags.js.map +1 -0
- package/out/candidate/ancestors-sidecar.d.ts +33 -0
- package/out/candidate/ancestors-sidecar.d.ts.map +1 -0
- package/out/candidate/ancestors-sidecar.js +140 -0
- package/out/candidate/ancestors-sidecar.js.map +1 -0
- package/out/candidate/country-display-names.d.ts +35 -0
- package/out/candidate/country-display-names.d.ts.map +1 -0
- package/out/candidate/country-display-names.js +59 -0
- package/out/candidate/country-display-names.js.map +1 -0
- package/out/candidate/name-roles.d.ts +55 -0
- package/out/candidate/name-roles.d.ts.map +1 -0
- package/out/candidate/name-roles.js +165 -0
- package/out/candidate/name-roles.js.map +1 -0
- package/out/candidate/own-name.d.ts +50 -0
- package/out/candidate/own-name.d.ts.map +1 -0
- package/out/candidate/own-name.js +132 -0
- package/out/candidate/own-name.js.map +1 -0
- package/out/candidate/place-attrs.d.ts +43 -0
- package/out/candidate/place-attrs.d.ts.map +1 -0
- package/out/candidate/place-attrs.js +15 -0
- package/out/candidate/place-attrs.js.map +1 -0
- package/out/candidate/shard-fold.d.ts +31 -0
- package/out/candidate/shard-fold.d.ts.map +1 -0
- package/out/candidate/shard-fold.js +104 -0
- package/out/candidate/shard-fold.js.map +1 -0
- package/out/candidate-ancestors-schema.d.ts +150 -0
- package/out/candidate-ancestors-schema.d.ts.map +1 -0
- package/out/candidate-ancestors-schema.js +123 -0
- package/out/candidate-ancestors-schema.js.map +1 -0
- package/out/candidate-fts.d.ts +4 -2
- package/out/candidate-fts.d.ts.map +1 -1
- package/out/candidate-fts.js +4 -2
- package/out/candidate-fts.js.map +1 -1
- package/out/candidate-importance.d.ts +132 -0
- package/out/candidate-importance.d.ts.map +1 -0
- package/out/candidate-importance.js +174 -0
- package/out/candidate-importance.js.map +1 -0
- package/out/candidate-lookup.d.ts +22 -37
- package/out/candidate-lookup.d.ts.map +1 -1
- package/out/candidate-lookup.js +446 -132
- package/out/candidate-lookup.js.map +1 -1
- package/out/candidate-schema.d.ts +52 -4
- package/out/candidate-schema.d.ts.map +1 -1
- package/out/candidate-schema.js +8 -0
- package/out/candidate-schema.js.map +1 -1
- package/out/candidate-scoring.d.ts +34 -0
- package/out/candidate-scoring.d.ts.map +1 -0
- package/out/candidate-scoring.js +200 -0
- package/out/candidate-scoring.js.map +1 -0
- package/out/capital-schema.d.ts +51 -0
- package/out/capital-schema.d.ts.map +1 -0
- package/out/capital-schema.js +63 -0
- package/out/capital-schema.js.map +1 -0
- package/out/capitals.d.ts +69 -0
- package/out/capitals.d.ts.map +1 -0
- package/out/capitals.js +98 -0
- package/out/capitals.js.map +1 -0
- package/out/coincident-roles.d.ts +7 -0
- package/out/coincident-roles.d.ts.map +1 -1
- package/out/coincident-roles.js +42 -8
- package/out/coincident-roles.js.map +1 -1
- package/out/convention-schema.d.ts +51 -0
- package/out/convention-schema.d.ts.map +1 -0
- package/out/convention-schema.js +34 -0
- package/out/convention-schema.js.map +1 -0
- package/out/convention.d.ts +1 -1
- package/out/convention.js +2 -2
- package/out/coverage-manifest-schema.js +3 -7
- package/out/coverage-manifest-schema.js.map +1 -1
- package/out/currency-backfill.d.ts +46 -0
- package/out/currency-backfill.d.ts.map +1 -0
- package/out/currency-backfill.js +180 -0
- package/out/currency-backfill.js.map +1 -0
- package/out/exact-match.d.ts +25 -0
- package/out/exact-match.d.ts.map +1 -0
- package/out/exact-match.js +89 -0
- package/out/exact-match.js.map +1 -0
- package/out/fst-autocomplete.d.ts +24 -14
- package/out/fst-autocomplete.d.ts.map +1 -1
- package/out/fst-autocomplete.js +84 -100
- package/out/fst-autocomplete.js.map +1 -1
- package/out/fst-builder.d.ts.map +1 -1
- package/out/fst-builder.js +32 -40
- package/out/fst-builder.js.map +1 -1
- package/out/fst-deserialize-web.d.ts.map +1 -1
- package/out/fst-deserialize-web.js +36 -7
- package/out/fst-deserialize-web.js.map +1 -1
- package/out/fst-freshness.d.ts +2 -2
- package/out/fst-freshness.js +2 -2
- package/out/fst-serialize.d.ts +14 -4
- package/out/fst-serialize.d.ts.map +1 -1
- package/out/fst-serialize.js +60 -12
- package/out/fst-serialize.js.map +1 -1
- package/out/fst-types.d.ts +35 -1
- package/out/fst-types.d.ts.map +1 -1
- package/out/fts-query.js +1 -1
- package/out/fts-query.js.map +1 -1
- package/out/fts.d.ts +15 -4
- package/out/fts.d.ts.map +1 -1
- package/out/fts.js +15 -4
- package/out/fts.js.map +1 -1
- package/out/geonames-postal.d.ts +2 -2
- package/out/geonames-postal.js +2 -2
- package/out/index.d.ts +4 -2
- package/out/index.d.ts.map +1 -1
- package/out/index.js +3 -2
- package/out/index.js.map +1 -1
- package/out/interpolation.d.ts +8 -0
- package/out/interpolation.d.ts.map +1 -1
- package/out/interpolation.js +91 -19
- package/out/interpolation.js.map +1 -1
- package/out/lookup.d.ts +4 -5
- package/out/lookup.d.ts.map +1 -1
- package/out/lookup.js +102 -444
- package/out/lookup.js.map +1 -1
- package/out/name-score.d.ts +0 -10
- package/out/name-score.d.ts.map +1 -1
- package/out/name-score.js +6 -4
- package/out/name-score.js.map +1 -1
- package/out/place-importance-schema.d.ts +226 -0
- package/out/place-importance-schema.d.ts.map +1 -0
- package/out/place-importance-schema.js +288 -0
- package/out/place-importance-schema.js.map +1 -0
- package/out/poi-lookup.d.ts +1 -1
- package/out/poi-lookup.d.ts.map +1 -1
- package/out/poi-lookup.js +12 -13
- package/out/poi-lookup.js.map +1 -1
- package/out/poi-schema.d.ts +7 -3
- package/out/poi-schema.d.ts.map +1 -1
- package/out/poi-schema.js.map +1 -1
- package/out/polygon-schema.d.ts +37 -0
- package/out/polygon-schema.d.ts.map +1 -0
- package/out/polygon-schema.js +23 -0
- package/out/polygon-schema.js.map +1 -0
- package/out/postal-city-alias-lookup.d.ts +1 -1
- package/out/postal-city-alias-lookup.js +1 -1
- package/out/postal-city-candidate-schema.d.ts +2 -1
- package/out/postal-city-candidate-schema.d.ts.map +1 -1
- package/out/postal-city-candidate-schema.js.map +1 -1
- package/out/postcode-point-lookup.d.ts +1 -1
- package/out/postcode-point-lookup.js +1 -1
- package/out/primary-preference.d.ts +125 -0
- package/out/primary-preference.d.ts.map +1 -0
- package/out/primary-preference.js +138 -0
- package/out/primary-preference.js.map +1 -0
- package/out/proximity-rerank.d.ts +77 -0
- package/out/proximity-rerank.d.ts.map +1 -0
- package/out/proximity-rerank.js +86 -0
- package/out/proximity-rerank.js.map +1 -0
- package/out/region-keys.d.ts +47 -0
- package/out/region-keys.d.ts.map +1 -0
- package/out/region-keys.js +121 -0
- package/out/region-keys.js.map +1 -0
- package/out/reverse.d.ts.map +1 -1
- package/out/reverse.js +6 -9
- package/out/reverse.js.map +1 -1
- package/out/schema.d.ts +1 -1
- package/out/search-fetch.d.ts +57 -0
- package/out/search-fetch.d.ts.map +1 -0
- package/out/search-fetch.js +183 -0
- package/out/search-fetch.js.map +1 -0
- package/out/sharding.d.ts +3 -3
- package/out/sharding.js +1 -1
- package/out/sqlite-convention-source.d.ts +1 -1
- package/out/sqlite-convention-source.js +1 -1
- package/out/sqlite-utils.d.ts +31 -1
- package/out/sqlite-utils.d.ts.map +1 -1
- package/out/sqlite-utils.js +38 -0
- package/out/sqlite-utils.js.map +1 -1
- package/out/street-centroid-schema.d.ts +7 -2
- package/out/street-centroid-schema.d.ts.map +1 -1
- package/out/street-centroid-schema.js.map +1 -1
- package/out/street-centroid.d.ts.map +1 -1
- package/out/street-centroid.js +7 -7
- package/out/street-centroid.js.map +1 -1
- package/out/street-morphology-fst-builder.d.ts.map +1 -1
- package/out/street-morphology-fst-builder.js +5 -4
- package/out/street-morphology-fst-builder.js.map +1 -1
- package/out/street-normalize.d.ts +83 -9
- package/out/street-normalize.d.ts.map +1 -1
- package/out/street-normalize.js +177 -10
- package/out/street-normalize.js.map +1 -1
- package/out/street-segment-schema.d.ts +6 -2
- package/out/street-segment-schema.d.ts.map +1 -1
- package/out/street-segment-schema.js.map +1 -1
- package/out/types.d.ts +74 -1
- package/out/types.d.ts.map +1 -1
- package/out/unified-schema.d.ts +1 -1
- package/out/unified-schema.js +1 -1
- package/out/uprn-lookup.d.ts +85 -0
- package/out/uprn-lookup.d.ts.map +1 -0
- package/out/uprn-lookup.js +152 -0
- package/out/uprn-lookup.js.map +1 -0
- package/out/uprn-schema.d.ts +93 -0
- package/out/uprn-schema.d.ts.map +1 -0
- package/out/uprn-schema.js +78 -0
- package/out/uprn-schema.js.map +1 -0
- package/out/weights-overlay-linker.d.ts +141 -0
- package/out/weights-overlay-linker.d.ts.map +1 -0
- package/out/weights-overlay-linker.js +259 -0
- package/out/weights-overlay-linker.js.map +1 -0
- package/package.json +296 -16
- package/place-importance-schema.ts +402 -0
- package/poi-lookup.ts +12 -13
- package/poi-schema.ts +8 -3
- package/polygon-schema.ts +47 -0
- package/postal-city-alias-lookup.ts +1 -1
- package/postal-city-candidate-schema.ts +3 -1
- package/postcode-point-lookup.ts +1 -1
- package/primary-preference.ts +207 -0
- package/proximity-rerank.ts +120 -0
- package/region-keys.ts +144 -0
- package/reverse.ts +17 -16
- package/schema.ts +1 -1
- package/search-fetch.ts +256 -0
- package/sharding.ts +3 -3
- package/sqlite-convention-source.ts +1 -1
- package/sqlite-utils.ts +63 -1
- package/street-centroid-schema.ts +8 -2
- package/street-centroid.ts +13 -8
- package/street-morphology-fst-builder.ts +5 -4
- package/street-normalize.ts +254 -24
- package/street-segment-schema.ts +7 -2
- package/types.ts +74 -1
- package/unified-schema.ts +1 -1
- package/uprn-lookup.ts +210 -0
- package/uprn-schema.ts +124 -0
- package/weights-overlay-linker.ts +377 -0
- package/geo.ts +0 -121
- package/out/geo.d.ts +0 -74
- package/out/geo.d.ts.map +0 -1
- package/out/geo.js +0 -71
- package/out/geo.js.map +0 -1
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* The TWO-SCORE SPLIT (ROAD_TO_V9 §2 R1) — typed schema, table builder, and the two derivations, in
|
|
7
|
+
* one module so the read contract and the DDL cannot drift.
|
|
8
|
+
*
|
|
9
|
+
* THE POLICY THIS ENCODES, ratified 2026-08-06: **the importance of a knowledge-base article is not
|
|
10
|
+
* the probability that this is the place the user means.** The geocoder ranks by REFERENTIAL
|
|
11
|
+
* likelihood; encyclopedic importance is carried as data and is never the ranking key. So the one
|
|
12
|
+
* `place_importance.importance` column — which was a Wikipedia score where the concordance join
|
|
13
|
+
* landed and a population-derived pseudo-score everywhere else — becomes two named columns that can
|
|
14
|
+
* never be confused for one another:
|
|
15
|
+
*
|
|
16
|
+
* - {@link PlaceImportanceTable.referential} — population-anchored, ALWAYS derivable, the ranking
|
|
17
|
+
* backbone. {@link referentialFromPopulation} is the normalization the FST builder's population
|
|
18
|
+
* fallback has always used; naming it here is the whole change.
|
|
19
|
+
* - {@link PlaceImportanceTable.encyclopedic} — the fan-out-guarded Wikipedia join
|
|
20
|
+
* (`importance-fanout.ts`, #1497). NULLABLE, and null means ABSENT, never "an importance of
|
|
21
|
+
* zero": ~1.5 M of the 1.54 M rows in the 2026-08-05 build have no Wikipedia article at all, and
|
|
22
|
+
* a consumer that reads a 0 there would be reading a fact nobody recorded.
|
|
23
|
+
*
|
|
24
|
+
* WHY SAINT-DENIS IS THE TEST. The Seine-Saint-Denis suburb (pop 96,128) carries encyclopedic
|
|
25
|
+
* 0.1173; the Aude hamlet (pop 418) carries 0.5683 — the encyclopedic signal ranks the hamlet 4.8x
|
|
26
|
+
* ABOVE the place every user means. Referentially the suburb wins by 230x on population. One score
|
|
27
|
+
* cannot serve both readers, which is why there are two.
|
|
28
|
+
*
|
|
29
|
+
* THE LEGACY COLUMN STAYS, AND IS DERIVED. `importance` is written by {@link blendImportance} — the
|
|
30
|
+
* bounded blend the bare-toponym fame consumer (#28) ranks on. It is the CONFLATION, and nothing new
|
|
31
|
+
* should read it; new code reads the split columns.
|
|
32
|
+
*/
|
|
33
|
+
import { referentialFromPopulation } from "@mailwoman/core/resolver";
|
|
34
|
+
import { allRows } from "./sqlite-utils.js";
|
|
35
|
+
/**
|
|
36
|
+
* The columns in declaration order. The builder's INSERT derives its column list from this, so a field added to
|
|
37
|
+
* {@link PlaceImportanceTable} without a matching DDL column is a compile error at the insert site.
|
|
38
|
+
*/
|
|
39
|
+
export const PLACE_IMPORTANCE_COLUMNS = [
|
|
40
|
+
"id",
|
|
41
|
+
"referential",
|
|
42
|
+
"encyclopedic",
|
|
43
|
+
"importance",
|
|
44
|
+
];
|
|
45
|
+
/**
|
|
46
|
+
* Create `place_importance` at the split schema. Drops any existing table first — this is a rebuild-in-place step of
|
|
47
|
+
* `mailwoman gazetteer importance`, never a migration.
|
|
48
|
+
*/
|
|
49
|
+
export async function createPlaceImportanceTable(db) {
|
|
50
|
+
await db.schema.dropTable("place_importance").ifExists().execute();
|
|
51
|
+
await db.schema
|
|
52
|
+
.createTable("place_importance")
|
|
53
|
+
.addColumn("id", "integer", (c) => c.primaryKey())
|
|
54
|
+
.addColumn("referential", "real", (c) => c.notNull())
|
|
55
|
+
.addColumn("encyclopedic", "real")
|
|
56
|
+
.addColumn("importance", "real", (c) => c.notNull())
|
|
57
|
+
.execute();
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
//#region The referential derivation
|
|
61
|
+
/**
|
|
62
|
+
* Re-exported from `@mailwoman/core/resolver`, which is where the derivation lives so that `@mailwoman/resolver`
|
|
63
|
+
* (backend-agnostic — it cannot import this package) reads the same number. Re-exported HERE so the schema module stays
|
|
64
|
+
* the one-stop read for the table: the column and the function that fills it are one hop apart.
|
|
65
|
+
*/
|
|
66
|
+
export { compareReferential, REFERENTIAL_LOG2_SCALE, REFERENTIAL_POPULATION_DIVISOR, REFERENTIAL_SATURATION_POPULATION, referentialFromPopulation, } from "@mailwoman/core/resolver";
|
|
67
|
+
//#endregion
|
|
68
|
+
//#region The legacy blend
|
|
69
|
+
/**
|
|
70
|
+
* The most the encyclopedic channel may raise a place's blended importance above its population-anchored referential
|
|
71
|
+
* score.
|
|
72
|
+
*
|
|
73
|
+
* In referential units 0.25 is 3.5 population doublings (the referential curve divides log2 by 14), so an article can
|
|
74
|
+
* promote a place as if it were up to ~11x its recorded population — never more. The bound exists because the two
|
|
75
|
+
* channels' scales CROSS at the article floor: merely having a Wikipedia article scores ~0.25–0.35, which exceeds the
|
|
76
|
+
* referential score of a mid-size town, so an unbounded blend ranks a 136-person village with an article above a
|
|
77
|
+
* 16,026-person town without one.
|
|
78
|
+
*
|
|
79
|
+
* The value is bracketed by two decided contests, measured on the 2026-08-24 staging build:
|
|
80
|
+
*
|
|
81
|
+
* - `> 0.2282`, or bare `Whitby` stops answering Whitby GB (pop 13,130, referential 0.2729, encyclopedic 0.5496) over
|
|
82
|
+
* Whitby CA (pop 128,377, referential 0.5011) — the #28 design case the fame prior exists to serve.
|
|
83
|
+
* - `< 0.2790`, or bare `Tó`/`To` answers Tó PT (pop 136, referential 0.0131, encyclopedic 0.3375) over Tô BF (pop
|
|
84
|
+
* 16,026, no article) — the `bf-gloss-to-*` board pair.
|
|
85
|
+
*
|
|
86
|
+
* 0.25 sits mid-interval with ~0.02 margin to each bound.
|
|
87
|
+
*/
|
|
88
|
+
export const ENCYCLOPEDIC_BOOST_CAP = 0.25;
|
|
89
|
+
/**
|
|
90
|
+
* The legacy `importance` blend — one cross-bearer fame scale for the #28 consumer, derived from the two split
|
|
91
|
+
* channels:
|
|
92
|
+
*
|
|
93
|
+
* - No article → the referential score.
|
|
94
|
+
* - No population evidence (`referential` 0) → the encyclopedic score stands alone: there is nothing to bound the
|
|
95
|
+
* article's claim against, and a constant cap would demote every famous place WOF records no population for
|
|
96
|
+
* (meaning-of-zero: referential 0 is "unmeasured", not "tiny").
|
|
97
|
+
* - Both present → the encyclopedic value clamped to at most {@link ENCYCLOPEDIC_BOOST_CAP} above the referential score,
|
|
98
|
+
* and never below it. The floor half repairs the downward inversion (the Seine-Saint-Denis suburb's weak article
|
|
99
|
+
* scored 0.1173 and REPLACED its referential 0.4716 under the old `COALESCE`, so a 418-person Aude hamlet outranked
|
|
100
|
+
* it 4.8x); the cap half repairs the upward one (`Tó`, above).
|
|
101
|
+
*
|
|
102
|
+
* Scale of the clamp on the 2026-08-24 staging build: of 628,202 article-bearing rows, 209,738 sit above the cap and
|
|
103
|
+
* 13,888 sit below their referential floor; the 305,168 article-without-population rows pass through unchanged.
|
|
104
|
+
*/
|
|
105
|
+
export function blendImportance(referential, encyclopedic) {
|
|
106
|
+
if (encyclopedic === null || encyclopedic === undefined)
|
|
107
|
+
return referential;
|
|
108
|
+
if (referential <= 0)
|
|
109
|
+
return encyclopedic;
|
|
110
|
+
return Math.max(referential, Math.min(encyclopedic, referential + ENCYCLOPEDIC_BOOST_CAP));
|
|
111
|
+
}
|
|
112
|
+
//#endregion
|
|
113
|
+
//#region Reading a database that may or may not carry the split
|
|
114
|
+
/**
|
|
115
|
+
* Where a reader's two scores came from. Recorded into the FST stamp so an artifact says, in its own provenance,
|
|
116
|
+
* whether its encyclopedic channel is real, reconstructed, or absent.
|
|
117
|
+
*/
|
|
118
|
+
export const IMPORTANCE_SPLIT_SOURCES = {
|
|
119
|
+
/**
|
|
120
|
+
* `place_importance` carries `referential` + `encyclopedic` — the post-split build.
|
|
121
|
+
*/
|
|
122
|
+
splitColumns: "split-columns",
|
|
123
|
+
/**
|
|
124
|
+
* `place_importance` carries only the conflated `importance`; the split was RECONSTRUCTED against `place_population`
|
|
125
|
+
* (see {@link splitLegacyImportance}).
|
|
126
|
+
*/
|
|
127
|
+
legacyReconstructed: "legacy-reconstructed",
|
|
128
|
+
/**
|
|
129
|
+
* No `place_importance` at all — referential from `place_population`, encyclopedic absent for every place.
|
|
130
|
+
*/
|
|
131
|
+
populationOnly: "population-only",
|
|
132
|
+
/**
|
|
133
|
+
* Neither table. Every score is 0, and 0 here means the database carries no salience evidence whatsoever.
|
|
134
|
+
*/
|
|
135
|
+
none: "none",
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* The `SELECT` term and `LEFT JOIN` a name lookup needs in order to CARRY `encyclopedic` onto its results, probed
|
|
139
|
+
* against `schemaName`'s `place_importance`.
|
|
140
|
+
*
|
|
141
|
+
* THE PROBE IS A COLUMN, NOT A TABLE, and that is the whole reason this lives here rather than beside a caller's other
|
|
142
|
+
* table probes. The pre-split table exists and holds a single conflated `importance` column whose value is a Wikipedia
|
|
143
|
+
* score on some rows and a population proxy on others, with nothing in the row to say which — reading that as
|
|
144
|
+
* encyclopedic would surface the exact confusion ROAD_TO_V9 §2 exists to end.
|
|
145
|
+
*
|
|
146
|
+
* There is deliberately no ORDER BY counterpart, and there should never be one: §2's policy is that this score is
|
|
147
|
+
* carried and never ranked on. Without the column the select degrades to a literal `NULL` and the join is the empty
|
|
148
|
+
* string, so a pre-split shard's query plan is byte-identical to what it was before the split. No shipped gazetteer
|
|
149
|
+
* carries the column yet, so today that degraded form is the only one anything builds.
|
|
150
|
+
*
|
|
151
|
+
* Call it ONCE per shard and cache the result — it runs a `PRAGMA`, and the callers are per-keystroke hot.
|
|
152
|
+
*/
|
|
153
|
+
export function encyclopedicClauses(db, schemaName) {
|
|
154
|
+
let present;
|
|
155
|
+
try {
|
|
156
|
+
const rows = allRows(db.prepare(`PRAGMA ${schemaName}.table_info(place_importance)`));
|
|
157
|
+
present = rows.some((r) => r.name === "encyclopedic");
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
present = false;
|
|
161
|
+
}
|
|
162
|
+
if (!present)
|
|
163
|
+
return { select: "NULL AS encyclopedic", join: "" };
|
|
164
|
+
return {
|
|
165
|
+
select: "place_importance.encyclopedic AS encyclopedic",
|
|
166
|
+
join: `LEFT JOIN ${schemaName}.place_importance ON place_importance.id = spr.id`,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* The tolerance {@link splitLegacyImportance} treats as "this value reproduces the population curve". Eight ULP —
|
|
171
|
+
* comfortably wider than the one-ULP `log2` spread measured between CPython and V8 (see that function's docstring), and
|
|
172
|
+
* ~1e-15 absolute against scores Nominatim publishes to four decimals.
|
|
173
|
+
*/
|
|
174
|
+
export const LEGACY_FALLBACK_EPSILON = 8 * Number.EPSILON;
|
|
175
|
+
/**
|
|
176
|
+
* Split one row of a LEGACY (pre-split) `place_importance` table back into its two components.
|
|
177
|
+
*
|
|
178
|
+
* WHY THIS IS RECOVERABLE AT ALL. The legacy builder ran in two passes: Wikipedia scores first, then `INSERT OR IGNORE`
|
|
179
|
+
* of `min(1, log2(1+pop/1000)/14)` for every place with a population that Wikipedia had missed. So a legacy value is a
|
|
180
|
+
* fallback row IFF it reproduces {@link referentialFromPopulation} of that place's population — the two passes wrote
|
|
181
|
+
* different arithmetic, and a score from Nominatim's four-decimal TSV landing on the log2 curve is a measure-zero
|
|
182
|
+
* event.
|
|
183
|
+
*
|
|
184
|
+
* THE COMPARISON IS ULP-TOLERANT, AND THAT IS NOT DEFENSIVE PADDING. The first version compared for exact bit equality,
|
|
185
|
+
* which is correct — in the runtime that wrote the values. Cross-checking the same rule in CPython returned 166,638
|
|
186
|
+
* encyclopedic rows against Node's 133,096: `math.log2` and V8's `Math.log2` disagree by one ULP on 33,542 of the 1.5 M
|
|
187
|
+
* inputs (worked example: wof 85803233, population 21,299 — stored 0.31992193633838988953, CPython
|
|
188
|
+
* 0.31992193633838994504, delta 5.55e-17). Bit equality would therefore INVENT 33,542 encyclopedic scores for anyone
|
|
189
|
+
* who ported this rule to another runtime, and invented data is the failure mode this whole module exists to end. The
|
|
190
|
+
* tolerance is a few ULP of the score's own magnitude; a genuine Wikipedia value that close to the population curve is
|
|
191
|
+
* not distinguishable from it by any consequence.
|
|
192
|
+
*
|
|
193
|
+
* MEASURED, not reasoned (2026-08-06, `wof/fst-staging-2026-08-05/admin-global-priority-importance.db`): 1,543,753 rows
|
|
194
|
+
* split **1,410,657 fallback / 133,096 encyclopedic**, and the arithmetic closes on itself — 1,410,657 + 108,861
|
|
195
|
+
* (encyclopedic rows that ALSO have a population) = 1,519,518, which is exactly the count of `place_population` rows
|
|
196
|
+
* with `population > 0`, i.e. every row the fallback pass could have written. The remaining 24,235 encyclopedic rows
|
|
197
|
+
* have no population row at all. Under the exact-equality rule, Node found ZERO mismatches within one ULP, so the
|
|
198
|
+
* tolerance changes no classification on this database — it only makes the answer runtime-independent.
|
|
199
|
+
*
|
|
200
|
+
* Referential is NOT read out of the legacy column under any branch — it is always re-derived from population, because
|
|
201
|
+
* a legacy Wikipedia row overwrote whatever population would have said.
|
|
202
|
+
*/
|
|
203
|
+
export function splitLegacyImportance(legacy, population) {
|
|
204
|
+
const referential = referentialFromPopulation(population);
|
|
205
|
+
if (legacy === undefined)
|
|
206
|
+
return { referential };
|
|
207
|
+
if (Math.abs(legacy - referential) <= LEGACY_FALLBACK_EPSILON * Math.max(referential, 1))
|
|
208
|
+
return { referential };
|
|
209
|
+
return { referential, encyclopedic: legacy };
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Does `table` exist in `db`, and if so which of `columns` does it have?
|
|
213
|
+
*/
|
|
214
|
+
function tableColumns(db, table) {
|
|
215
|
+
try {
|
|
216
|
+
const rows = allRows(db.prepare(`PRAGMA table_info(${table})`));
|
|
217
|
+
return new Set(rows.map((r) => r.name));
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
return new Set();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Load both scores from a WOF admin database, whatever schema generation it is at.
|
|
225
|
+
*
|
|
226
|
+
* Handles all four states in {@link IMPORTANCE_SPLIT_SOURCES} so callers never branch on schema themselves — the FST
|
|
227
|
+
* builder in particular must read the shipped population-only databases, the read-only 2026-08-05 staging database
|
|
228
|
+
* (legacy conflated column), and post-split builds with one code path.
|
|
229
|
+
*/
|
|
230
|
+
export function loadImportanceSplit(db) {
|
|
231
|
+
const referential = new Map();
|
|
232
|
+
const encyclopedic = new Map();
|
|
233
|
+
const population = new Map();
|
|
234
|
+
const populationColumns = tableColumns(db, "place_population");
|
|
235
|
+
if (populationColumns.has("population")) {
|
|
236
|
+
const rows = allRows(db.prepare("SELECT id, population FROM place_population"));
|
|
237
|
+
for (const row of rows) {
|
|
238
|
+
population.set(row.id, row.population);
|
|
239
|
+
const score = referentialFromPopulation(row.population);
|
|
240
|
+
if (score > 0) {
|
|
241
|
+
referential.set(row.id, score);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
const importanceColumns = tableColumns(db, "place_importance");
|
|
246
|
+
if (importanceColumns.has("referential")) {
|
|
247
|
+
// Post-split build: the columns ARE the contract. Referential is read verbatim rather than
|
|
248
|
+
// re-derived, so a build that scored referential differently stays visible instead of being
|
|
249
|
+
// silently overwritten by this reader's own formula.
|
|
250
|
+
const rows = allRows(db.prepare("SELECT id, referential, encyclopedic FROM place_importance"));
|
|
251
|
+
for (const row of rows) {
|
|
252
|
+
if (row.referential > 0) {
|
|
253
|
+
referential.set(row.id, row.referential);
|
|
254
|
+
}
|
|
255
|
+
if (row.encyclopedic !== null) {
|
|
256
|
+
encyclopedic.set(row.id, row.encyclopedic);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return { referential, encyclopedic, source: IMPORTANCE_SPLIT_SOURCES.splitColumns, legacyFallbackRows: 0 };
|
|
260
|
+
}
|
|
261
|
+
if (importanceColumns.has("importance")) {
|
|
262
|
+
const rows = allRows(db.prepare("SELECT id, importance FROM place_importance"));
|
|
263
|
+
let legacyFallbackRows = 0;
|
|
264
|
+
for (const row of rows) {
|
|
265
|
+
const split = splitLegacyImportance(row.importance, population.get(row.id));
|
|
266
|
+
if (split.encyclopedic === undefined) {
|
|
267
|
+
legacyFallbackRows++;
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
encyclopedic.set(row.id, split.encyclopedic);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return {
|
|
274
|
+
referential,
|
|
275
|
+
encyclopedic,
|
|
276
|
+
source: IMPORTANCE_SPLIT_SOURCES.legacyReconstructed,
|
|
277
|
+
legacyFallbackRows,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
return {
|
|
281
|
+
referential,
|
|
282
|
+
encyclopedic,
|
|
283
|
+
source: referential.size ? IMPORTANCE_SPLIT_SOURCES.populationOnly : IMPORTANCE_SPLIT_SOURCES.none,
|
|
284
|
+
legacyFallbackRows: 0,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
//#endregion
|
|
288
|
+
//# sourceMappingURL=place-importance-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"place-importance-schema.js","sourceRoot":"","sources":["../place-importance-schema.ts"],"names":[],"mappings":"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"}
|
package/out/poi-lookup.d.ts
CHANGED
|
@@ -90,7 +90,7 @@ export interface POILookupOpts {
|
|
|
90
90
|
/**
|
|
91
91
|
* Node reader over `poi.db`. `implements Disposable` so callers can `using lookup = new POILookup(...)` (or call
|
|
92
92
|
* `[Symbol.dispose]()` explicitly), the same precedent as {@link WOFCandidateTableLookup} /
|
|
93
|
-
* {@link
|
|
93
|
+
* {@link WOFSQLitePlaceLookup}.
|
|
94
94
|
*/
|
|
95
95
|
export declare class POILookup implements Disposable {
|
|
96
96
|
#private;
|
package/out/poi-lookup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"poi-lookup.d.ts","sourceRoot":"","sources":["../poi-lookup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"poi-lookup.d.ts","sourceRoot":"","sources":["../poi-lookup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAQ1C;;GAEG;AACH,eAAO,MAAM,iBAAiB,IAAI,CAAA;AA6BlC,MAAM,WAAW,cAAc;IAC9B;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;OAEG;IACH,MAAM,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;IAChD;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,aAAa;IAC7B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,YAAY,CAAA;CACvB;AAkBD;;;;GAIG;AACH,qBAAa,SAAU,YAAW,UAAU;;gBAmB/B,IAAI,EAAE,aAAa;IA+B/B,MAAM,CAAC,KAAK,EAAE,cAAc,GAAG,YAAY,EAAE;IA8J7C,KAAK,IAAI,IAAI;IAMb,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;CAGxB"}
|
package/out/poi-lookup.js
CHANGED
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
import { DatabaseSync } from "node:sqlite";
|
|
28
28
|
import { haversineKm, shortCellToInt } from "@mailwoman/spatial";
|
|
29
29
|
import { gridDisk, latLngToCell } from "h3-js";
|
|
30
|
+
import { allRows } from "./sqlite-utils.js";
|
|
30
31
|
/**
|
|
31
32
|
* Resolution the `poi` table's `h3_cell` column is keyed at — matches the builder (spec §3.4).
|
|
32
33
|
*/
|
|
@@ -58,7 +59,7 @@ const DEFAULT_LIMIT = 20;
|
|
|
58
59
|
/**
|
|
59
60
|
* Node reader over `poi.db`. `implements Disposable` so callers can `using lookup = new POILookup(...)` (or call
|
|
60
61
|
* `[Symbol.dispose]()` explicitly), the same precedent as {@link WOFCandidateTableLookup} /
|
|
61
|
-
* {@link
|
|
62
|
+
* {@link WOFSQLitePlaceLookup}.
|
|
62
63
|
*/
|
|
63
64
|
export class POILookup {
|
|
64
65
|
#db;
|
|
@@ -91,9 +92,7 @@ export class POILookup {
|
|
|
91
92
|
}
|
|
92
93
|
// The category dictionary is tiny (poi-taxonomy's category count) — load it once at
|
|
93
94
|
// construction so `search` never round-trips to it.
|
|
94
|
-
for (const r of this.#db
|
|
95
|
-
.prepare("SELECT id, category FROM poi_category_codes")
|
|
96
|
-
.all()) {
|
|
95
|
+
for (const r of allRows(this.#db.prepare("SELECT id, category FROM poi_category_codes"))) {
|
|
97
96
|
this.#categoryToID.set(String(r.category), Number(r.id));
|
|
98
97
|
this.#idToCategory.set(Number(r.id), String(r.category));
|
|
99
98
|
}
|
|
@@ -127,7 +126,7 @@ export class POILookup {
|
|
|
127
126
|
* nearest at any distance — the reach ceiling k-ring hits on sparse brand rows is gone.
|
|
128
127
|
*/
|
|
129
128
|
#searchBrand(brandWikidata, center, limit) {
|
|
130
|
-
const rows = this.#brandProbe
|
|
129
|
+
const rows = allRows(this.#brandProbe, brandWikidata);
|
|
131
130
|
return sortByDistance(rows, center)
|
|
132
131
|
.filter((row) => haversineKm(center.latitude, center.longitude, row.latitude, row.longitude) <= BRAND_MAX_DISTANCE_KM)
|
|
133
132
|
.slice(0, limit)
|
|
@@ -139,18 +138,18 @@ export class POILookup {
|
|
|
139
138
|
#searchKRing(query, limit) {
|
|
140
139
|
const center = query.center;
|
|
141
140
|
const maxRings = query.maxRings ?? DEFAULT_MAX_RINGS;
|
|
142
|
-
const
|
|
141
|
+
const categoryIDs = [];
|
|
143
142
|
// `categoryIDs` (the fan-out list) supersedes the single `categoryID`; either way, resolve each id through the
|
|
144
143
|
// dictionary and drop the ones the db doesn't carry (Overture-taxonomy drift, or an identity id with no rows).
|
|
145
144
|
const seedIDs = query.categoryIDs?.length ? query.categoryIDs : query.categoryID ? [query.categoryID] : [];
|
|
146
145
|
for (const id of seedIDs) {
|
|
147
146
|
const resolved = this.#categoryToID.get(id);
|
|
148
147
|
if (resolved !== undefined) {
|
|
149
|
-
|
|
148
|
+
categoryIDs.push(resolved);
|
|
150
149
|
}
|
|
151
150
|
}
|
|
152
151
|
// No resolvable leaf (every id unknown to the dictionary) can't have rows — a clean miss, not a throw.
|
|
153
|
-
if (!
|
|
152
|
+
if (!categoryIDs.length)
|
|
154
153
|
return [];
|
|
155
154
|
const origin = latLngToCell(center.latitude, center.longitude, POI_H3_RESOLUTION);
|
|
156
155
|
const seenCells = new Set();
|
|
@@ -166,8 +165,8 @@ export class POILookup {
|
|
|
166
165
|
const shortCell = shortCellToInt(cell);
|
|
167
166
|
// Fan-out: probe every resolved Overture leaf for this canonical category, unioning the rows. The
|
|
168
167
|
// post-ring distance sort + `slice(0, limit)` below dedupes the pool down to the nearest `limit`.
|
|
169
|
-
for (const categoryID of
|
|
170
|
-
rows.push(...this.#categoryCellProbe
|
|
168
|
+
for (const categoryID of categoryIDs) {
|
|
169
|
+
rows.push(...allRows(this.#categoryCellProbe, shortCell, categoryID, limit));
|
|
171
170
|
}
|
|
172
171
|
}
|
|
173
172
|
rows = sortByDistance(rows, center);
|
|
@@ -187,7 +186,7 @@ export class POILookup {
|
|
|
187
186
|
const matchQuery = sanitizePOINameQuery(name);
|
|
188
187
|
if (!matchQuery)
|
|
189
188
|
return [];
|
|
190
|
-
const ftsHits = this.#nameFTSProbe
|
|
189
|
+
const ftsHits = allRows(this.#nameFTSProbe, matchQuery, limit);
|
|
191
190
|
const uniqueKeys = [];
|
|
192
191
|
const seenKeys = new Set();
|
|
193
192
|
for (const hit of ftsHits) {
|
|
@@ -229,7 +228,7 @@ export class POILookup {
|
|
|
229
228
|
const columns = "name, category_id, brand_wikidata, latitude, longitude, country, confidence, name_key, gers_id";
|
|
230
229
|
const placeholders = nameKeys.map(() => "?").join(", ");
|
|
231
230
|
const stmt = this.#db.prepare(`SELECT ${columns} FROM poi WHERE name_key IN (${placeholders})`);
|
|
232
|
-
return stmt
|
|
231
|
+
return allRows(stmt, ...nameKeys);
|
|
233
232
|
}
|
|
234
233
|
close() {
|
|
235
234
|
if (this.#ownsDB) {
|
|
@@ -273,7 +272,7 @@ function sanitizePOINameQuery(text) {
|
|
|
273
272
|
.replaceAll(/["*:]/g, "")
|
|
274
273
|
.trim()
|
|
275
274
|
.split(/\s+/u)
|
|
276
|
-
.filter(
|
|
275
|
+
.filter((token) => token.length > 0)
|
|
277
276
|
.map((token) => `"${token.replaceAll('"', '""')}"`)
|
|
278
277
|
.join(" ");
|
|
279
278
|
}
|
package/out/poi-lookup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"poi-lookup.js","sourceRoot":"","sources":["../poi-lookup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,EAAE,WAAW,EAAE,cAAc,EAAe,MAAM,oBAAoB,CAAA;AAC7E,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"poi-lookup.js","sourceRoot":"","sources":["../poi-lookup.ts"],"names":[],"mappings":"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"}
|
package/out/poi-schema.d.ts
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import type { DatabaseSync } from "node:sqlite";
|
|
15
15
|
import type { LayerContractDatabase } from "@mailwoman/core/layers";
|
|
16
16
|
import { type Kysely } from "kysely";
|
|
17
|
+
import type { NameKey } from "./street-normalize.ts";
|
|
17
18
|
/**
|
|
18
19
|
* One POI row. Clustered PK: h3_cell → category_id → neg_rank → rowid_key.
|
|
19
20
|
*/
|
|
@@ -36,9 +37,12 @@ export interface POITable {
|
|
|
36
37
|
rowid_key: number;
|
|
37
38
|
name: string | null;
|
|
38
39
|
/**
|
|
39
|
-
*
|
|
40
|
+
* Probe key for exact name lookups, minted by {@link normalizeLocalityForKey} at build AND at query.
|
|
41
|
+
*
|
|
42
|
+
* Branded because a `toLowerCase()` approximation of the fold is still a `string`: it binds to the parameter, returns
|
|
43
|
+
* fewer rows, and the shortfall reads as a coverage gap in the data rather than a defect in the probe.
|
|
40
44
|
*/
|
|
41
|
-
name_key:
|
|
45
|
+
name_key: NameKey | null;
|
|
42
46
|
brand_wikidata: string | null;
|
|
43
47
|
latitude: number;
|
|
44
48
|
longitude: number;
|
|
@@ -65,7 +69,7 @@ export interface POIStageTable {
|
|
|
65
69
|
neg_rank: number | null;
|
|
66
70
|
rowid_key: number | null;
|
|
67
71
|
name: string | null;
|
|
68
|
-
name_key:
|
|
72
|
+
name_key: NameKey | null;
|
|
69
73
|
brand_wikidata: string | null;
|
|
70
74
|
latitude: number;
|
|
71
75
|
longitude: number;
|
package/out/poi-schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"poi-schema.d.ts","sourceRoot":"","sources":["../poi-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE/C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AACnE,OAAO,EAAO,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEzC;;GAEG;AACH,MAAM,WAAW,QAAQ;IACxB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB
|
|
1
|
+
{"version":3,"file":"poi-schema.d.ts","sourceRoot":"","sources":["../poi-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE/C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AACnE,OAAO,EAAO,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAEpD;;GAEG;AACH,MAAM,WAAW,QAAQ;IACxB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB;;;;;OAKG;IACH,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAA;IACxB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,UAAU,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAA;IACxB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,WAAY,SAAQ,qBAAqB;IACzD,GAAG,EAAE,QAAQ,CAAA;IACb,SAAS,EAAE,aAAa,CAAA;IACxB,kBAAkB,EAAE,oBAAoB,CAAA;CACxC;AAED;;GAEG;AACH,eAAO,MAAM,WAAW,iKAad,CAAA;AAEV,wBAAsB,sBAAsB,CAAC,EAAE,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBnF;AAED,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB3E;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,EAAE,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAElF;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,EAAE,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAOhF;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,eAAe,CAAA;AAEzC;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAIzD"}
|
package/out/poi-schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"poi-schema.js","sourceRoot":"","sources":["../poi-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,EAAE,GAAG,EAAe,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"poi-schema.js","sourceRoot":"","sources":["../poi-schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* Typed schema for the polygon sidecar (`wof-polygons.db`) — the one table `WOFReverseGeocoder` probes for a
|
|
7
|
+
* place's geometry. The interface is the read/write contract and {@link createPolygonsTable} creates the table, so a
|
|
8
|
+
* column added to one is a compile error against the other.
|
|
9
|
+
*
|
|
10
|
+
* The sidecar is OPTIONAL to the reverse geocoder: without it every result falls back to a centroid, so the reader
|
|
11
|
+
* checks for the table's presence rather than assuming it.
|
|
12
|
+
*/
|
|
13
|
+
import type { Kysely } from "kysely";
|
|
14
|
+
/**
|
|
15
|
+
* One admin polygon, keyed by WOF id.
|
|
16
|
+
*/
|
|
17
|
+
export interface PolygonsTable {
|
|
18
|
+
id: number;
|
|
19
|
+
/**
|
|
20
|
+
* The GeoJSON geometry, JSON-encoded. A row that fails to parse reads as no-polygon, never as an error — a malformed
|
|
21
|
+
* geometry must not fail the whole reverse query.
|
|
22
|
+
*/
|
|
23
|
+
geom: string;
|
|
24
|
+
}
|
|
25
|
+
export interface PolygonDatabase {
|
|
26
|
+
polygons: PolygonsTable;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The slice of a Kysely handle the polygon DDL touches. Kysely is invariant in its schema parameter, so naming only
|
|
30
|
+
* `schema` lets a builder holding a wider handle pass it without a cast.
|
|
31
|
+
*/
|
|
32
|
+
export type PolygonSchemaHandle = Pick<Kysely<PolygonDatabase>, "schema">;
|
|
33
|
+
/**
|
|
34
|
+
* Create the `polygons` table — called before the streaming bulk load.
|
|
35
|
+
*/
|
|
36
|
+
export declare function createPolygonsTable(db: PolygonSchemaHandle): Promise<void>;
|
|
37
|
+
//# sourceMappingURL=polygon-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polygon-schema.d.ts","sourceRoot":"","sources":["../polygon-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEpC;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,eAAe;IAC/B,QAAQ,EAAE,aAAa,CAAA;CACvB;AAED;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,QAAQ,CAAC,CAAA;AAEzE;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,EAAE,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAMhF"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* Typed schema for the polygon sidecar (`wof-polygons.db`) — the one table `WOFReverseGeocoder` probes for a
|
|
7
|
+
* place's geometry. The interface is the read/write contract and {@link createPolygonsTable} creates the table, so a
|
|
8
|
+
* column added to one is a compile error against the other.
|
|
9
|
+
*
|
|
10
|
+
* The sidecar is OPTIONAL to the reverse geocoder: without it every result falls back to a centroid, so the reader
|
|
11
|
+
* checks for the table's presence rather than assuming it.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Create the `polygons` table — called before the streaming bulk load.
|
|
15
|
+
*/
|
|
16
|
+
export async function createPolygonsTable(db) {
|
|
17
|
+
await db.schema
|
|
18
|
+
.createTable("polygons")
|
|
19
|
+
.addColumn("id", "integer", (column) => column.primaryKey())
|
|
20
|
+
.addColumn("geom", "text", (column) => column.notNull())
|
|
21
|
+
.execute();
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=polygon-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polygon-schema.js","sourceRoot":"","sources":["../polygon-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA0BH;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,EAAuB;IAChE,MAAM,EAAE,CAAC,MAAM;SACb,WAAW,CAAC,UAAU,CAAC;SACvB,SAAS,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;SAC3D,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;SACvD,OAAO,EAAE,CAAA;AACZ,CAAC"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Node reader over the POSTAL-CITY ALIAS table (`postal-city-alias-<cc>.db`) — the observed
|
|
7
7
|
* `postal_city → geo_locality` aliases per postcode (`build-postal-city-alias.ts`). Consumed by
|
|
8
|
-
* {@link
|
|
8
|
+
* {@link WOFSQLitePlaceLookup}'s coordinate-first locality scorer: a user-typed postal city
|
|
9
9
|
* ("Antioch", postcode 37013) becomes a name-match alias for the geographic locality the postcode
|
|
10
10
|
* actually sits in ("Nashville"), so the right place tiers to the top instead of a same-named
|
|
11
11
|
* town in another state. Opt-in — the lookup is only constructed when a path is supplied, and
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Node reader over the POSTAL-CITY ALIAS table (`postal-city-alias-<cc>.db`) — the observed
|
|
7
7
|
* `postal_city → geo_locality` aliases per postcode (`build-postal-city-alias.ts`). Consumed by
|
|
8
|
-
* {@link
|
|
8
|
+
* {@link WOFSQLitePlaceLookup}'s coordinate-first locality scorer: a user-typed postal city
|
|
9
9
|
* ("Antioch", postcode 37013) becomes a name-match alias for the geographic locality the postcode
|
|
10
10
|
* actually sits in ("Nashville"), so the right place tiers to the top instead of a same-named
|
|
11
11
|
* town in another state. Opt-in — the lookup is only constructed when a path is supplied, and
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* untouched.
|
|
19
19
|
*/
|
|
20
20
|
import { type Kysely } from "kysely";
|
|
21
|
+
import type { NameKey } from "./street-normalize.ts";
|
|
21
22
|
/**
|
|
22
23
|
* One postal-city → geo-locality edge, keyed exactly by `(name_key, postcode)`. The probe returns the geographic
|
|
23
24
|
* locality directly; the denormalized name/coord avoid a join back to `candidate`.
|
|
@@ -26,7 +27,7 @@ export interface PostalCityCandidateTable {
|
|
|
26
27
|
/**
|
|
27
28
|
* {@link normalizeLocalityForKey} of the postal-city name — the build/query-consistent probe key.
|
|
28
29
|
*/
|
|
29
|
-
name_key:
|
|
30
|
+
name_key: NameKey;
|
|
30
31
|
/**
|
|
31
32
|
* The postcode the alias is scoped to (the second half of the exact key).
|
|
32
33
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postal-city-candidate-schema.d.ts","sourceRoot":"","sources":["../postal-city-candidate-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAO,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEzC;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACxC;;OAEG;IACH,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"postal-city-candidate-schema.d.ts","sourceRoot":"","sources":["../postal-city-candidate-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAO,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAEpD;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACxC;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAA;IACjB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC3C,qBAAqB,EAAE,wBAAwB,CAAA;CAC/C;AAED;;GAEG;AACH,eAAO,MAAM,2BAA2B,0BAA0B,CAAA;AAElE;;GAEG;AACH,eAAO,MAAM,6BAA6B,8EAOhC,CAAA;AAEV;;;;GAIG;AACH,wBAAsB,8BAA8B,CAAC,EAAE,EAAE,MAAM,CAAC,2BAA2B,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAc3G"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postal-city-candidate-schema.js","sourceRoot":"","sources":["../postal-city-candidate-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,GAAG,EAAe,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"postal-city-candidate-schema.js","sourceRoot":"","sources":["../postal-city-candidate-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,GAAG,EAAe,MAAM,QAAQ,CAAA;AAoCzC;;GAEG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,uBAAuB,CAAA;AAElE;;GAEG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC5C,UAAU;IACV,UAAU;IACV,QAAQ;IACR,MAAM;IACN,UAAU;IACV,WAAW;CACF,CAAA;AAEV;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAAC,EAAuC;IAC3F,MAAM,EAAE,CAAC,MAAM;SACb,WAAW,CAAC,2BAA2B,CAAC;SACxC,WAAW,EAAE;SACb,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SACjD,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SACjD,SAAS,CAAC,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAClD,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAC7C,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SACjD,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAClD,uBAAuB,CAAC,0BAA0B,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QAC9E,0FAA0F;SACzF,SAAS,CAAC,GAAG,CAAA,eAAe,CAAC;SAC7B,OAAO,EAAE,CAAA;AACZ,CAAC"}
|