@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
package/name-score.ts
CHANGED
|
@@ -23,7 +23,7 @@ export function cfNormalize(s: string): string {
|
|
|
23
23
|
/**
|
|
24
24
|
* Padded character-trigram set (a leading/trailing space pads short tokens).
|
|
25
25
|
*/
|
|
26
|
-
|
|
26
|
+
function trigrams(s: string): Set<string> {
|
|
27
27
|
const t = ` ${s} `
|
|
28
28
|
const out = new Set<string>()
|
|
29
29
|
|
|
@@ -36,10 +36,12 @@ export function trigrams(s: string): Set<string> {
|
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* Character-trigram Jaccard ∈ [0,1] — tolerant of the swallowed-leading-char fragments ("auen" vs "plauen") and minor
|
|
39
|
-
* misspellings without a heavyweight edit-distance pass.
|
|
40
|
-
*
|
|
39
|
+
* misspellings without a heavyweight edit-distance pass. The fuzzy component of {@link softNameScore}, and private to
|
|
40
|
+
* this module: the candidate backend scores typos with a WORD-level measure instead, on receipts that falsify trigram
|
|
41
|
+
* Jaccard for that job (see `candidate-lookup.ts`'s `FUZZY_FETCH`). A shared name here would assert a parity the two
|
|
42
|
+
* backends do not have.
|
|
41
43
|
*/
|
|
42
|
-
|
|
44
|
+
function trigramJaccard(a: string, b: string): number {
|
|
43
45
|
const A = trigrams(a)
|
|
44
46
|
const B = trigrams(b)
|
|
45
47
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"address-point-interpolation.d.ts","sourceRoot":"","sources":["../address-point-interpolation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAG9D,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AA6BjG,qBAAa,wBAAyB,YAAW,mBAAmB;;gBAMvD,IAAI,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,YAAY,CAAC;QAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;KAAE;
|
|
1
|
+
{"version":3,"file":"address-point-interpolation.d.ts","sourceRoot":"","sources":["../address-point-interpolation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAG9D,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AA6BjG,qBAAa,wBAAyB,YAAW,mBAAmB;;gBAMvD,IAAI,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,YAAY,CAAC;QAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;KAAE;IA6B7F,IAAI,CAAC,KAAK,EAAE,kBAAkB,GAAG,eAAe,GAAG,IAAI;IAyBvD,KAAK,IAAI,IAAI;CAKb"}
|
|
@@ -33,9 +33,9 @@
|
|
|
33
33
|
* Standalone like the segment tier — core wiring rides the Phase 2 ordered `spatialTiers` list.
|
|
34
34
|
*/
|
|
35
35
|
import { DatabaseSync } from "node:sqlite";
|
|
36
|
-
import { haversineKm } from "
|
|
37
|
-
import { hasTable } from "./sqlite-utils.js";
|
|
38
|
-
import { canonicalizeRouteKey,
|
|
36
|
+
import { haversineKm } from "@mailwoman/spatial";
|
|
37
|
+
import { hasTable, prepareAll } from "./sqlite-utils.js";
|
|
38
|
+
import { canonicalizeRouteKey, streetKeyVariants } from "./street-normalize.js";
|
|
39
39
|
/**
|
|
40
40
|
* Extrapolation cap for a single-sided bracket: at most one pair-span beyond the nearest known point (`t = 2`). Past
|
|
41
41
|
* it, the two-point line carries no evidence about the query number.
|
|
@@ -64,7 +64,7 @@ export class AddressPointInterpolator {
|
|
|
64
64
|
if (hasTable(this.#db, "address_point")) {
|
|
65
65
|
// Strictly-numeric neighbor numbers on the route-folded street key within the ZIP. The
|
|
66
66
|
// queried number itself is excluded HERE (see module doc: non-circular by construction).
|
|
67
|
-
this.#byPostcode = this.#db
|
|
67
|
+
this.#byPostcode = prepareAll(this.#db, `SELECT CAST(number AS INTEGER) AS n, lat, lon, source, release
|
|
68
68
|
FROM address_point
|
|
69
69
|
WHERE postcode = ? AND street_key = ?
|
|
70
70
|
AND number GLOB '[0-9]*' AND number NOT GLOB '*[^0-9]*'
|
|
@@ -72,15 +72,21 @@ export class AddressPointInterpolator {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
find(query) {
|
|
75
|
-
const streetKey = canonicalizeRouteKey(normalizeStreetForKey(query.street));
|
|
76
75
|
const numberRaw = query.number.trim();
|
|
77
|
-
if (
|
|
76
|
+
if (!/^\d+$/.test(numberRaw))
|
|
78
77
|
return null;
|
|
79
78
|
const n = Number(numberRaw);
|
|
80
79
|
// No own table (empty shard) or no postcode → defer to the segment fallback rather than query.
|
|
81
80
|
if (!this.#byPostcode || !query.postcode)
|
|
82
81
|
return this.#fallback?.find(query) ?? null;
|
|
83
|
-
|
|
82
|
+
// Key-variant ladder (see `streetKeyVariants`) — same probe order as the exact-point reader.
|
|
83
|
+
let rows = [];
|
|
84
|
+
for (const variant of streetKeyVariants(query.street)) {
|
|
85
|
+
const streetKey = canonicalizeRouteKey(variant);
|
|
86
|
+
rows = this.#byPostcode(query.postcode.trim(), streetKey, n);
|
|
87
|
+
if (rows.length)
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
84
90
|
const hit = rows.length >= 2 ? interpolateFromNeighbors(rows, n) : null;
|
|
85
91
|
return hit ?? this.#fallback?.find(query) ?? null;
|
|
86
92
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"address-point-interpolation.js","sourceRoot":"","sources":["../address-point-interpolation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"address-point-interpolation.js","sourceRoot":"","sources":["../address-point-interpolation.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* schema guards the contract; positional inserts keep the speed.)
|
|
17
17
|
*/
|
|
18
18
|
import type { Kysely } from "kysely";
|
|
19
|
+
import type { NameKey, RouteKey, StreetKey } from "./street-normalize.ts";
|
|
19
20
|
/**
|
|
20
21
|
* One rooftop address point. `(street_norm, number)` within a `postcode` (preferred) or `locality_norm` scope is the
|
|
21
22
|
* lookup; `street_key` is the #483 route-fold key for interpolation. Coordinates are non-null (the builder drops
|
|
@@ -25,11 +26,12 @@ export interface AddressPointTable {
|
|
|
25
26
|
/**
|
|
26
27
|
* Shared {@link normalizeStreetForKey} of the street — the build/query-consistent probe key.
|
|
27
28
|
*/
|
|
28
|
-
street_norm:
|
|
29
|
+
street_norm: StreetKey;
|
|
29
30
|
/**
|
|
30
|
-
* `canonicalizeRouteKey(street_norm)` — the route-fold key (#483 Method 2).
|
|
31
|
+
* `canonicalizeRouteKey(street_norm)` — the route-fold key (#483 Method 2). Its own brand, so it cannot be
|
|
32
|
+
* interchanged with the plain `street_norm` above.
|
|
31
33
|
*/
|
|
32
|
-
street_key:
|
|
34
|
+
street_key: RouteKey;
|
|
33
35
|
/**
|
|
34
36
|
* House number, normalized lower-case (kept TEXT — "123-A", "12 1/2" must survive).
|
|
35
37
|
*/
|
|
@@ -39,7 +41,7 @@ export interface AddressPointTable {
|
|
|
39
41
|
/**
|
|
40
42
|
* Shared {@link normalizeLocalityForKey} of the locality — the fallback scope.
|
|
41
43
|
*/
|
|
42
|
-
locality_norm:
|
|
44
|
+
locality_norm: NameKey | null;
|
|
43
45
|
/**
|
|
44
46
|
* The street as it appeared in the source (kept for display / debugging).
|
|
45
47
|
*/
|
|
@@ -61,6 +63,14 @@ export interface AddressPointTable {
|
|
|
61
63
|
export interface AddressPointDatabase {
|
|
62
64
|
address_point: AddressPointTable;
|
|
63
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* The slice of a Kysely handle the `address_point` DDL touches — the parameter type its builders take.
|
|
68
|
+
*
|
|
69
|
+
* Kysely is invariant in its schema parameter (the incompatibility is in `transaction()`), so a shard that EXTENDS
|
|
70
|
+
* `AddressPointTable` — OSM adds `h3_cell` — cannot pass its own handle to a `Kysely<AddressPointDatabase>` parameter.
|
|
71
|
+
* Naming only `schema` lets it, and the DDL below needs nothing else.
|
|
72
|
+
*/
|
|
73
|
+
export type AddressPointSchemaHandle = Pick<Kysely<AddressPointDatabase>, "schema">;
|
|
64
74
|
/**
|
|
65
75
|
* The `address_point` columns in INSERT order. The builder's positional prepared statement derives its placeholder list
|
|
66
76
|
* from this, so the positional order can't drift from the DDL / the reader.
|
|
@@ -69,9 +79,9 @@ export declare const ADDRESS_POINT_COLUMNS: readonly ["street_norm", "street_key
|
|
|
69
79
|
/**
|
|
70
80
|
* Create the `address_point` table — called before the streaming bulk load.
|
|
71
81
|
*/
|
|
72
|
-
export declare function createAddressPointTable(db:
|
|
82
|
+
export declare function createAddressPointTable(db: AddressPointSchemaHandle): Promise<void>;
|
|
73
83
|
/**
|
|
74
84
|
* Create the three probe indexes the reader relies on (postcode-scope, locality-scope, route-key).
|
|
75
85
|
*/
|
|
76
|
-
export declare function createAddressPointIndexes(db:
|
|
86
|
+
export declare function createAddressPointIndexes(db: AddressPointSchemaHandle): Promise<void>;
|
|
77
87
|
//# sourceMappingURL=address-point-schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"address-point-schema.d.ts","sourceRoot":"","sources":["../address-point-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEpC;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IACjC;;OAEG;IACH,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"address-point-schema.d.ts","sourceRoot":"","sources":["../address-point-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEpC,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAEzE;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IACjC;;OAEG;IACH,WAAW,EAAE,SAAS,CAAA;IACtB;;;OAGG;IACH,UAAU,EAAE,QAAQ,CAAA;IACpB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB;;OAEG;IACH,aAAa,EAAE,OAAO,GAAG,IAAI,CAAA;IAC7B;;OAEG;IACH,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;CACf;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC,aAAa,EAAE,iBAAiB,CAAA;CAChC;AAED;;;;;;GAMG;AACH,MAAM,MAAM,wBAAwB,GAAG,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,EAAE,QAAQ,CAAC,CAAA;AAEnF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,wIAYxB,CAAA;AAEV;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,EAAE,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBzF;AAED;;GAEG;AACH,wBAAsB,yBAAyB,CAAC,EAAE,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB3F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"address-point-schema.js","sourceRoot":"","sources":["../address-point-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;
|
|
1
|
+
{"version":3,"file":"address-point-schema.js","sourceRoot":"","sources":["../address-point-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AA+DH;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACpC,aAAa;IACb,YAAY;IACZ,QAAQ;IACR,MAAM;IACN,UAAU;IACV,eAAe;IACf,YAAY;IACZ,KAAK;IACL,KAAK;IACL,QAAQ;IACR,SAAS;CACA,CAAA;AAEV;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,EAA4B;IACzE,MAAM,EAAE,CAAC,MAAM;SACb,WAAW,CAAC,eAAe,CAAC;SAC5B,SAAS,CAAC,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QACrD,wFAAwF;SACvF,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SACnD,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAC/C,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;SACzB,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC;SAC7B,SAAS,CAAC,eAAe,EAAE,MAAM,CAAC;SAClC,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SACnD,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAC5C,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAC5C,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAC/C,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAChD,OAAO,EAAE,CAAA;AACZ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,EAA4B;IAC3E,MAAM,EAAE,CAAC,MAAM;SACb,WAAW,CAAC,iBAAiB,CAAC;SAC9B,EAAE,CAAC,eAAe,CAAC;SACnB,OAAO,CAAC,CAAC,UAAU,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;SAC9C,OAAO,EAAE,CAAA;IAEX,MAAM,EAAE,CAAC,MAAM;SACb,WAAW,CAAC,iBAAiB,CAAC;SAC9B,EAAE,CAAC,eAAe,CAAC;SACnB,OAAO,CAAC,CAAC,eAAe,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;SACnD,OAAO,EAAE,CAAA;IAEX,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,EAAE,CAAA;IACjH,oGAAoG;IACpG,uGAAuG;IACvG,wGAAwG;IACxG,yEAAyE;IACzE,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAA;AAC9G,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"address-point.d.ts","sourceRoot":"","sources":["../address-point.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAI9E,OAAO,
|
|
1
|
+
{"version":3,"file":"address-point.d.ts","sourceRoot":"","sources":["../address-point.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAI9E,OAAO,EAON,KAAK,YAAY,EACjB,MAAM,uBAAuB,CAAA;AAc9B,qBAAa,wBAAyB,YAAW,kBAAkB;;IAYlE;;;;OAIG;gBACS,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,YAAY,CAAC,EAAE,YAAY,CAAA;KAAO;IA2BtE,IAAI,CAAC,KAAK,EAAE;QACX,MAAM,EAAE,MAAM,CAAA;QACd,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,IAAI,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAA;KACzE,GAAG,eAAe,GAAG,IAAI;IAuH1B,KAAK,IAAI,IAAI;CAGb"}
|
package/out/address-point.js
CHANGED
|
@@ -15,13 +15,13 @@
|
|
|
15
15
|
* scopes missed). Multiple hits return the first by rowid — unit siblings share the building coord.
|
|
16
16
|
*/
|
|
17
17
|
import { DatabaseSync } from "node:sqlite";
|
|
18
|
-
import { hasTable } from "./sqlite-utils.js";
|
|
19
|
-
import { normalizeLocalityForKey,
|
|
18
|
+
import { hasTable, prepareGet } from "./sqlite-utils.js";
|
|
19
|
+
import { normalizeLocalityForKey, streetKeyVariants, streetLocaleForSurface, stripArrondissement, } from "./street-normalize.js";
|
|
20
20
|
/**
|
|
21
21
|
* The 4 columns the reader SELECTs, in the schema's order — referenced by the prepared SELECTs so the projected
|
|
22
22
|
* `AddressPointRow` stays in lockstep with the shared schema.
|
|
23
23
|
*/
|
|
24
|
-
const SELECT_COLS = "lat, lon, source, release";
|
|
24
|
+
const SELECT_COLS = "lat, lon, source, release, locality_norm, postcode";
|
|
25
25
|
export class AddressPointSqliteLookup {
|
|
26
26
|
#db;
|
|
27
27
|
#locale;
|
|
@@ -39,24 +39,82 @@ export class AddressPointSqliteLookup {
|
|
|
39
39
|
// Degrade gracefully on an empty/tableless shard (interrupted build, stray 0-byte file): with no
|
|
40
40
|
// `address_point` table this lookup is a no-op miss, not a crash that loses the whole state (#568).
|
|
41
41
|
if (hasTable(this.#db, "address_point")) {
|
|
42
|
-
this.#byPostcode = this.#db
|
|
42
|
+
this.#byPostcode = prepareGet(this.#db, `SELECT ${SELECT_COLS} FROM address_point
|
|
43
43
|
WHERE postcode = ? AND street_norm = ? AND number = ? LIMIT 1`);
|
|
44
|
-
this.#byLocality = this.#db
|
|
44
|
+
this.#byLocality = prepareGet(this.#db, `SELECT ${SELECT_COLS} FROM address_point
|
|
45
45
|
WHERE locality_norm = ? AND street_norm = ? AND number = ? LIMIT 1`);
|
|
46
|
-
this.#byBbox = this.#db
|
|
46
|
+
this.#byBbox = prepareGet(this.#db, `SELECT ${SELECT_COLS} FROM address_point
|
|
47
47
|
WHERE street_norm = ? AND number = ? AND lat BETWEEN ? AND ? AND lon BETWEEN ? AND ? LIMIT 1`);
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
find(query) {
|
|
51
51
|
if (!this.#byPostcode || !this.#byLocality || !this.#byBbox)
|
|
52
52
|
return null;
|
|
53
|
-
const streetNorm = normalizeStreetForKeyLocale(query.street, this.#locale);
|
|
54
53
|
const number = query.number.trim().toLowerCase();
|
|
55
|
-
if (!
|
|
54
|
+
if (!number)
|
|
56
55
|
return null;
|
|
56
|
+
// Key-variant ladder (see `streetKeyVariants`): the literal key first, then the doubled-type
|
|
57
|
+
// collapse and the saint↔st register swap — each variant runs the FULL number ladder below, and
|
|
58
|
+
// the first variant to answer wins, so an attested literal key is never second-guessed.
|
|
59
|
+
let row;
|
|
60
|
+
for (const streetNorm of streetKeyVariants(query.street, streetLocaleForSurface(query.street, this.#locale))) {
|
|
61
|
+
row = this.#findForKey(streetNorm, number, query);
|
|
62
|
+
if (row)
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
if (!row)
|
|
66
|
+
return null;
|
|
67
|
+
return {
|
|
68
|
+
lat: row.lat,
|
|
69
|
+
lon: row.lon,
|
|
70
|
+
source: row.source,
|
|
71
|
+
release: row.release,
|
|
72
|
+
...(row.locality_norm ? { localityNorm: row.locality_norm } : {}),
|
|
73
|
+
...(row.postcode ? { postcode: row.postcode } : {}),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The full number ladder for ONE normalized street key: exact, then the range low-end, then letter-suffix spacing
|
|
78
|
+
* with the base-number fall — see each rung's note in place.
|
|
79
|
+
*/
|
|
80
|
+
#findForKey(streetNorm, number, query) {
|
|
81
|
+
let row = this.#probe(streetNorm, number, query);
|
|
82
|
+
// Range-surface fallback: every register this reader serves stores ONE number per point
|
|
83
|
+
// (G-NAF `NUMBER_FIRST`, BAN, OA, OSM `addr:housenumber`), but the attested surface is often
|
|
84
|
+
// a range — "385-387 Esplanade" keys `385`. Null-only: an exact range key that matched above
|
|
85
|
+
// (some OSM points DO carry "385-387" verbatim) is never second-guessed.
|
|
86
|
+
if (!row) {
|
|
87
|
+
const low = /^(\d+[a-z]?)-\d+[a-z]?$/.exec(number)?.[1];
|
|
88
|
+
if (low) {
|
|
89
|
+
row = this.#probe(streetNorm, low, query);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Letter-suffix spacing fallback: the registers disagree on the joint — BAN stores "3 a"
|
|
93
|
+
// (space-separated), G-NAF and most OA sources store "3a" — and the parsed surface can arrive
|
|
94
|
+
// either way. On a miss, retry the OTHER spacing; on a double miss, the BASE number (the
|
|
95
|
+
// register attests no 3A but does attest 3 — the adjacent-parcel approximation, priced the
|
|
96
|
+
// same as the range fallback's low end). Null-only throughout, and only for the
|
|
97
|
+
// digits+single-letter shape (never touches "12 1/2" or unit-bearing forms).
|
|
98
|
+
if (!row) {
|
|
99
|
+
const joined = /^(\d+)\s+([a-z])$/.exec(number);
|
|
100
|
+
const spaced = /^(\d+)([a-z])$/.exec(number);
|
|
101
|
+
if (joined) {
|
|
102
|
+
row = this.#probe(streetNorm, `${joined[1]}${joined[2]}`, query) ?? this.#probe(streetNorm, joined[1], query);
|
|
103
|
+
}
|
|
104
|
+
else if (spaced) {
|
|
105
|
+
row = this.#probe(streetNorm, `${spaced[1]} ${spaced[2]}`, query) ?? this.#probe(streetNorm, spaced[1], query);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return row;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* The scope ladder for one (street, number) key: postcode, then locality, then the bbox fall-through — each rung only
|
|
112
|
+
* when the prior missed.
|
|
113
|
+
*/
|
|
114
|
+
#probe(streetNorm, number, query) {
|
|
57
115
|
let row;
|
|
58
116
|
if (query.postcode) {
|
|
59
|
-
row = this.#byPostcode
|
|
117
|
+
row = this.#byPostcode(query.postcode.trim(), streetNorm, number);
|
|
60
118
|
}
|
|
61
119
|
if (!row && query.locality) {
|
|
62
120
|
// FR shards key arrondissement communes at the base city (both-sides fold, see the BAN
|
|
@@ -65,17 +123,15 @@ export class AddressPointSqliteLookup {
|
|
|
65
123
|
const localityKey = this.#locale === "fr"
|
|
66
124
|
? stripArrondissement(normalizeLocalityForKey(query.locality))
|
|
67
125
|
: normalizeLocalityForKey(query.locality);
|
|
68
|
-
row = this.#byLocality
|
|
126
|
+
row = this.#byLocality(localityKey, streetNorm, number);
|
|
69
127
|
}
|
|
70
128
|
// Bbox fall-through (#247): the point carries no postcode/locality of its own, but its coordinate falls
|
|
71
129
|
// inside the resolved locality's box. Only reached when the scoped probes missed AND a bbox was supplied.
|
|
72
130
|
if (!row && query.bbox) {
|
|
73
131
|
const b = query.bbox;
|
|
74
|
-
row = this.#byBbox
|
|
132
|
+
row = this.#byBbox(streetNorm, number, b.minLat, b.maxLat, b.minLon, b.maxLon);
|
|
75
133
|
}
|
|
76
|
-
|
|
77
|
-
return null;
|
|
78
|
-
return { lat: row.lat, lon: row.lon, source: row.source, release: row.release };
|
|
134
|
+
return row;
|
|
79
135
|
}
|
|
80
136
|
close() {
|
|
81
137
|
this.#db.close();
|
package/out/address-point.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"address-point.js","sourceRoot":"","sources":["../address-point.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAK1C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"address-point.js","sourceRoot":"","sources":["../address-point.ts"],"names":[],"mappings":"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"}
|
package/out/ancestry.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* joined with `spr` for canonical names + centroids, ordered NEAREST-FIRST (deepest placetype
|
|
8
8
|
* first, country last).
|
|
9
9
|
*
|
|
10
|
-
* Factored out of `
|
|
10
|
+
* Factored out of `WOFSQLitePlaceLookup.ancestors()` (#404) so the reverse geocoder (`reverse.ts`,
|
|
11
11
|
* #484) reuses the SAME walk instead of growing a second one. The placetype-specificity ordering
|
|
12
12
|
* lives here as `PLACETYPE_DEPTH` — a single TS map instead of the previous SQL CASE, and
|
|
13
13
|
* extended below `localadmin` (locality/borough/neighbourhood/microhood now rank correctly
|
|
@@ -38,7 +38,7 @@ export interface AncestorPlaceRow {
|
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
40
|
* The ancestor lineage of `id` — self excluded, nearest-first. Returns `[]` when the place has no recorded ancestry.
|
|
41
|
-
* NOT memoized here; `
|
|
41
|
+
* NOT memoized here; `WOFSQLitePlaceLookup` keeps its own per-id cache.
|
|
42
42
|
*/
|
|
43
43
|
export declare function ancestorLineage(db: DatabaseSync, id: number, schemaName?: string): AncestorPlaceRow[];
|
|
44
44
|
//# sourceMappingURL=ancestry.d.ts.map
|
package/out/ancestry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ancestry.d.ts","sourceRoot":"","sources":["../ancestry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"ancestry.d.ts","sourceRoot":"","sources":["../ancestry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAI/C;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAY5D,CAAA;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;CACX;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,SAAS,GAAG,gBAAgB,EAAE,CAcrG"}
|
package/out/ancestry.js
CHANGED
|
@@ -7,13 +7,14 @@
|
|
|
7
7
|
* joined with `spr` for canonical names + centroids, ordered NEAREST-FIRST (deepest placetype
|
|
8
8
|
* first, country last).
|
|
9
9
|
*
|
|
10
|
-
* Factored out of `
|
|
10
|
+
* Factored out of `WOFSQLitePlaceLookup.ancestors()` (#404) so the reverse geocoder (`reverse.ts`,
|
|
11
11
|
* #484) reuses the SAME walk instead of growing a second one. The placetype-specificity ordering
|
|
12
12
|
* lives here as `PLACETYPE_DEPTH` — a single TS map instead of the previous SQL CASE, and
|
|
13
13
|
* extended below `localadmin` (locality/borough/neighbourhood/microhood now rank correctly
|
|
14
14
|
* instead of sorting last; forward resolution rarely saw those as ANCESTOR placetypes, reverse
|
|
15
15
|
* geocoding always does).
|
|
16
16
|
*/
|
|
17
|
+
import { allRows } from "./sqlite-utils.js";
|
|
17
18
|
/**
|
|
18
19
|
* WOF placetype → containment depth, coarsest = 1. Higher = finer. Placetypes we never resolve (continent, empire, …)
|
|
19
20
|
* map to 0 and sort last. NOT the same table as the FST's `PLACETYPE_ORDER` (fst-serialize.ts) — that one is a
|
|
@@ -40,15 +41,13 @@ export function placetypeDepth(placetype) {
|
|
|
40
41
|
}
|
|
41
42
|
/**
|
|
42
43
|
* The ancestor lineage of `id` — self excluded, nearest-first. Returns `[]` when the place has no recorded ancestry.
|
|
43
|
-
* NOT memoized here; `
|
|
44
|
+
* NOT memoized here; `WOFSQLitePlaceLookup` keeps its own per-id cache.
|
|
44
45
|
*/
|
|
45
46
|
export function ancestorLineage(db, id, schemaName = "main") {
|
|
46
|
-
const rows = db
|
|
47
|
-
.prepare(`SELECT a.ancestor_id AS id, a.ancestor_placetype AS placetype, s.name AS name,
|
|
47
|
+
const rows = allRows(db.prepare(`SELECT a.ancestor_id AS id, a.ancestor_placetype AS placetype, s.name AS name,
|
|
48
48
|
s.country AS country, s.latitude AS lat, s.longitude AS lon
|
|
49
49
|
FROM ${schemaName}.ancestors a JOIN ${schemaName}.spr s ON s.id = a.ancestor_id
|
|
50
|
-
WHERE a.id = ? AND a.ancestor_id != a.id`)
|
|
51
|
-
.all(id);
|
|
50
|
+
WHERE a.id = ? AND a.ancestor_id != a.id`), id);
|
|
52
51
|
rows.sort((a, b) => placetypeDepth(b.placetype) - placetypeDepth(a.placetype));
|
|
53
52
|
return rows;
|
|
54
53
|
}
|
package/out/ancestry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ancestry.js","sourceRoot":"","sources":["../ancestry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAqC;IAChE,OAAO,EAAE,CAAC;IACV,WAAW,EAAE,CAAC;IACd,MAAM,EAAE,CAAC;IACT,WAAW,EAAE,CAAC;IACd,MAAM,EAAE,CAAC;IACT,UAAU,EAAE,CAAC;IACb,QAAQ,EAAE,CAAC;IACX,OAAO,EAAE,CAAC;IACV,SAAS,EAAE,CAAC;IACZ,aAAa,EAAE,EAAE;IACjB,SAAS,EAAE,EAAE;CACb,CAAA;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC/C,OAAO,eAAe,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;AACvC,CAAC;AAcD;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,EAAgB,EAAE,EAAU,EAAE,UAAU,GAAG,MAAM;IAChF,MAAM,IAAI,GAAG,EAAE
|
|
1
|
+
{"version":3,"file":"ancestry.js","sourceRoot":"","sources":["../ancestry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAE3C;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAqC;IAChE,OAAO,EAAE,CAAC;IACV,WAAW,EAAE,CAAC;IACd,MAAM,EAAE,CAAC;IACT,WAAW,EAAE,CAAC;IACd,MAAM,EAAE,CAAC;IACT,UAAU,EAAE,CAAC;IACb,QAAQ,EAAE,CAAC;IACX,OAAO,EAAE,CAAC;IACV,SAAS,EAAE,CAAC;IACZ,aAAa,EAAE,EAAE;IACjB,SAAS,EAAE,EAAE;CACb,CAAA;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC/C,OAAO,eAAe,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;AACvC,CAAC;AAcD;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,EAAgB,EAAE,EAAU,EAAE,UAAU,GAAG,MAAM;IAChF,MAAM,IAAI,GAAG,OAAO,CACnB,EAAE,CAAC,OAAO,CACT;;UAEO,UAAU,qBAAqB,UAAU;4CACP,CACzC,EACD,EAAE,CACF,CAAA;IAED,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;IAE9E,OAAO,IAAI,CAAA;AACZ,CAAC"}
|
package/out/build-candidate.d.ts
CHANGED
|
@@ -26,7 +26,22 @@
|
|
|
26
26
|
*
|
|
27
27
|
* Measured (2026-06-20, vs the 2.6 GB full-DB FTS): ~5 M rows; ~12 range fetches per 8-query
|
|
28
28
|
* session (the full DB needs 243); US locality 96.8% (region bbox), EU coord parity 88.6%.
|
|
29
|
+
*
|
|
30
|
+
* #28 adds one more denormalized field, `importance` — the toponym-fame prior that decides a BARE
|
|
31
|
+
* city name, joined in from a separate score source by name rather than by id (see
|
|
32
|
+
* `candidate-importance.ts`, which owns that join and explains why the id would be wrong). It is
|
|
33
|
+
* optional: without {@link BuildCandidateOptions.importance} the column is NULL on every row, which
|
|
34
|
+
* the consumer reads as unmeasured and ignores.
|
|
35
|
+
*
|
|
36
|
+
* The build also materializes the ANCESTORS SIDECAR (`candidate_ancestor` closure rows +
|
|
37
|
+
* `candidate_interval` pre/post labels) from the source `ancestors` table — the containment
|
|
38
|
+
* lineage behind {@link WOFCandidateTableLookup.ancestors} and the admin-coherence check.
|
|
39
|
+
* `candidate-ancestors-schema.ts` owns the encoding decision and the DAG/absence semantics.
|
|
29
40
|
*/
|
|
41
|
+
import type { CapitalPoint } from "./capitals.ts";
|
|
42
|
+
export { stageCountryDisplayNames } from "./candidate/country-display-names.ts";
|
|
43
|
+
export { GLOSS_EXCLUDED_PLACETYPES, GLOSS_KEY_THRESHOLD } from "./candidate/name-roles.ts";
|
|
44
|
+
export type { PlaceAttrs } from "./candidate/place-attrs.ts";
|
|
30
45
|
export interface BuildCandidateOptions {
|
|
31
46
|
/**
|
|
32
47
|
* Source unified admin DB — needs spr, place_population, place_search, place_abbr, ancestors.
|
|
@@ -36,6 +51,12 @@ export interface BuildCandidateOptions {
|
|
|
36
51
|
* Output candidate DB path (overwritten if present).
|
|
37
52
|
*/
|
|
38
53
|
output: string;
|
|
54
|
+
/**
|
|
55
|
+
* The capital-status reference entries (#1880) to carry in-artifact — the parsed `data/gazetteer/capitals-v1.json`
|
|
56
|
+
* entries, passed by the CALLER because this module publishes to npm and must not read repo-root paths. Absent → the
|
|
57
|
+
* `capital` table is not created, and the session loader falls back to the repo file where one exists.
|
|
58
|
+
*/
|
|
59
|
+
capitals?: readonly CapitalPoint[];
|
|
39
60
|
/**
|
|
40
61
|
* Optional postcode shards (`spr` rows with `placetype='postalcode'` + real coords, e.g. postalcode-us.db) — folded
|
|
41
62
|
* in as `postalcode` candidate rows so `findPlace(postalcode)` resolves a ZIP directly (the demo's primary postcode
|
|
@@ -45,10 +66,50 @@ export interface BuildCandidateOptions {
|
|
|
45
66
|
* ("Brooklyn" for 11201), and they were previously reachable only through FTS.
|
|
46
67
|
*/
|
|
47
68
|
postcodes?: string[];
|
|
69
|
+
/**
|
|
70
|
+
* Optional LOCALITY shards (`spr` rows with `placetype='locality'` + real coords, e.g. localities-nz-linz.db — the
|
|
71
|
+
* #1564 NZ suburb tier) — folded through the same shard loop as the postcode shards, staged as `locality` candidate
|
|
72
|
+
* rows with no region scope and UNMEASURED population (`neg_rank 0`: a shard row ranks behind any populated namesake
|
|
73
|
+
* and wins only where its key is the answer). Each shard's `names` table folds as aliases, `is_primary = 0`, same as
|
|
74
|
+
* the delivery-city pass.
|
|
75
|
+
*/
|
|
76
|
+
localities?: string[];
|
|
77
|
+
/**
|
|
78
|
+
* Optional WOF admin database carrying a `place_importance` table — the source of the `importance` column (#28), the
|
|
79
|
+
* toponym-fame prior that decides the bare-city-name class. Joined by `(name_key, country, placetype)` + nearest
|
|
80
|
+
* centroid, NOT by id; see `candidate-importance.ts` for why the id join silently drops the foreign homonyms the
|
|
81
|
+
* prior exists to demote.
|
|
82
|
+
*
|
|
83
|
+
* Omit it and every row's `importance` is NULL — unmeasured, which is what the consumer's positive-evidence-only rule
|
|
84
|
+
* already treats as "do not participate", so the artifact is byte-identical to a pre-#28 build except for the empty
|
|
85
|
+
* column. That is the honest degradation and it is the DEFAULT: a caller with no score source must not get a
|
|
86
|
+
* population-derived stand-in written into a column that means fame.
|
|
87
|
+
*/
|
|
88
|
+
importance?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Cross-source currency backfill (#1737). WOF carries deprecated-with-no-successor records for real, populated
|
|
91
|
+
* settlements (Rochester Kent, Aldershot, Telford — 120 GB localities alone), and the currency filter correctly drops
|
|
92
|
+
* them, leaving holes no ranking can fill. When this option is set, pass 1c resurrects a dead locality ONLY under
|
|
93
|
+
* three gates, positive evidence throughout: no live same-name row of any placetype near the dead record (a distant
|
|
94
|
+
* same-name row is a NAMESAKE and does not block — Rochester, Northumberland pop 318 must not veto Rochester, Kent);
|
|
95
|
+
* an independent GeoNames P-class attestation of the same folded name within {@link CURRENCY_BACKFILL_RADIUS_KM}; and
|
|
96
|
+
* the attestor at or above {@link CURRENCY_BACKFILL_POP_FLOOR}. The staged row keeps the real WOF id, name, centroid
|
|
97
|
+
* and bbox — GeoNames only ATTESTS the place and supplies the population that lets it stand in prominence races.
|
|
98
|
+
* `countries` are judged only where `<cc>.txt` exists under `geonamesDir`; absent dumps are skipped loudly.
|
|
99
|
+
*/
|
|
100
|
+
currencyBackfill?: {
|
|
101
|
+
geonamesDir: string;
|
|
102
|
+
countries: readonly string[];
|
|
103
|
+
};
|
|
48
104
|
/**
|
|
49
105
|
* Optional progress callback for CLI / test introspection.
|
|
50
106
|
*/
|
|
51
107
|
onProgress?: (phase: string, message: string) => void;
|
|
108
|
+
/**
|
|
109
|
+
* Key-count threshold for the gloss anomaly detector — {@link GLOSS_KEY_THRESHOLD} unless a test passes a
|
|
110
|
+
* fixture-scale value. The production number is the #1730 sweep's own cut (4,000 places at >= 50 keys).
|
|
111
|
+
*/
|
|
112
|
+
glossKeyThreshold?: number;
|
|
52
113
|
}
|
|
53
114
|
export interface BuildCandidateResult {
|
|
54
115
|
rows: number;
|
|
@@ -63,6 +124,53 @@ export interface BuildCandidateResult {
|
|
|
63
124
|
* through `onProgress`.
|
|
64
125
|
*/
|
|
65
126
|
postcodeAliases: number;
|
|
127
|
+
/**
|
|
128
|
+
* Closure rows in the `candidate_ancestor` sidecar (see candidate-ancestors-schema.ts). Zero means the source
|
|
129
|
+
* `ancestors` table contributed nothing within the resolvable placetypes — a finding, reported rather than implied.
|
|
130
|
+
*/
|
|
131
|
+
ancestorRows: number;
|
|
132
|
+
/**
|
|
133
|
+
* Places carrying at least one closure row.
|
|
134
|
+
*/
|
|
135
|
+
ancestorPlaces: number;
|
|
136
|
+
/**
|
|
137
|
+
* Places that received a pre/post interval label — the canonical-parent forest's node count. Places outside it (no
|
|
138
|
+
* recorded ancestry, shard rows, cycle-skipped) have NO label: containment against them is unverifiable, never
|
|
139
|
+
* false.
|
|
140
|
+
*/
|
|
141
|
+
intervalPlaces: number;
|
|
142
|
+
/**
|
|
143
|
+
* Places that took an `importance` score from the join (#28).
|
|
144
|
+
*
|
|
145
|
+
* `undefined` and `0` mean different things. `undefined` is "the pass did not run" — no score source was given. A `0`
|
|
146
|
+
* would be the source matching NOTHING, which is a finding. Never collapse the two.
|
|
147
|
+
*/
|
|
148
|
+
importanceScored?: number;
|
|
149
|
+
/**
|
|
150
|
+
* Places whose `(name_key, country, placetype)` matched a scored group but whose nearest scored centroid was outside
|
|
151
|
+
* {@link IMPORTANCE_JOIN_GATE_KM} — a different town wearing the same name, refused rather than scored.
|
|
152
|
+
*
|
|
153
|
+
* Worth watching across rebuilds: a jump here means the score source and the admin source have drifted apart, and the
|
|
154
|
+
* join is being asked to guess.
|
|
155
|
+
*/
|
|
156
|
+
importanceGated?: number;
|
|
157
|
+
/**
|
|
158
|
+
* Alias rows stamped `name_role = 'gloss'` — the anomaly detector's certain core (#1730).
|
|
159
|
+
*/
|
|
160
|
+
roleGloss: number;
|
|
161
|
+
/**
|
|
162
|
+
* Alias rows stamped `name_role = 'abbr'` — the variant-in-official-language provenance signal (#1730/#936).
|
|
163
|
+
*/
|
|
164
|
+
roleAbbr: number;
|
|
165
|
+
/**
|
|
166
|
+
* Admin places whose staged key count reached {@link GLOSS_KEY_THRESHOLD} — the sweep's tail, reported so the stamped
|
|
167
|
+
* fraction has its denominator.
|
|
168
|
+
*/
|
|
169
|
+
keyTailPlaces: number;
|
|
170
|
+
/**
|
|
171
|
+
* Of {@link BuildCandidateResult.keyTailPlaces}, how many carry at least one stamped role row.
|
|
172
|
+
*/
|
|
173
|
+
keyTailWithRole: number;
|
|
66
174
|
}
|
|
67
175
|
export declare function buildCandidateTable(opts: BuildCandidateOptions): Promise<BuildCandidateResult>;
|
|
68
176
|
//# sourceMappingURL=build-candidate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-candidate.d.ts","sourceRoot":"","sources":["../build-candidate.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"build-candidate.d.ts","sourceRoot":"","sources":["../build-candidate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAuBH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAMjD,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAA;AAC/E,OAAO,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAC1F,YAAY,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAE5D,MAAM,WAAW,qBAAqB;IACrC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,YAAY,EAAE,CAAA;IAClC;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAA;IACxE;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACrD;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,eAAe,EAAE,MAAM,CAAA;IACvB;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAA;IACpB;;OAEG;IACH,cAAc,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAA;IACtB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAA;IACrB;;OAEG;IACH,eAAe,EAAE,MAAM,CAAA;CACvB;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA0ZpG"}
|