@mailwoman/resolver-wof-sqlite 4.16.2 → 5.0.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/out/address-point-interpolation.d.ts.map +1 -1
- package/out/address-point-interpolation.js +6 -6
- package/out/address-point-interpolation.js.map +1 -1
- package/out/address-point-schema.d.ts +5 -6
- package/out/address-point-schema.d.ts.map +1 -1
- package/out/address-point-schema.js +7 -2
- package/out/address-point-schema.js.map +1 -1
- package/out/address-point.d.ts +22 -8
- package/out/address-point.d.ts.map +1 -1
- package/out/address-point.js +29 -13
- package/out/address-point.js.map +1 -1
- package/out/ancestry-backfill.d.ts +53 -0
- package/out/ancestry-backfill.d.ts.map +1 -0
- package/out/ancestry-backfill.js +150 -0
- package/out/ancestry-backfill.js.map +1 -0
- package/out/ancestry.d.ts +6 -6
- package/out/ancestry.d.ts.map +1 -1
- package/out/ancestry.js +6 -6
- package/out/ancestry.js.map +1 -1
- package/out/build-candidate-cli.d.ts.map +1 -1
- package/out/build-candidate-cli.js.map +1 -1
- package/out/build-candidate.d.ts +4 -5
- package/out/build-candidate.d.ts.map +1 -1
- package/out/build-candidate.js +15 -14
- package/out/build-candidate.js.map +1 -1
- package/out/build-coincident-roles-cli.d.ts.map +1 -1
- package/out/build-coincident-roles-cli.js.map +1 -1
- package/out/build-fts-cli.d.ts +1 -1
- package/out/build-fts-cli.d.ts.map +1 -1
- package/out/build-fts-cli.js +6 -6
- package/out/build-fts-cli.js.map +1 -1
- package/out/build-slim-cli.d.ts +1 -1
- package/out/build-slim-cli.d.ts.map +1 -1
- package/out/build-slim-cli.js +3 -3
- package/out/build-slim-cli.js.map +1 -1
- package/out/build-slim.d.ts +7 -8
- package/out/build-slim.d.ts.map +1 -1
- package/out/build-slim.js +9 -9
- package/out/build-slim.js.map +1 -1
- package/out/candidate-fts.d.ts +5 -7
- package/out/candidate-fts.d.ts.map +1 -1
- package/out/candidate-fts.js +5 -7
- package/out/candidate-fts.js.map +1 -1
- package/out/candidate-lookup.d.ts +7 -7
- package/out/candidate-lookup.d.ts.map +1 -1
- package/out/candidate-lookup.js +31 -35
- package/out/candidate-lookup.js.map +1 -1
- package/out/candidate-schema.d.ts +13 -14
- package/out/candidate-schema.d.ts.map +1 -1
- package/out/candidate-schema.js +9 -9
- package/out/candidate-schema.js.map +1 -1
- package/out/coincident-roles.d.ts +9 -11
- package/out/coincident-roles.d.ts.map +1 -1
- package/out/coincident-roles.js +7 -7
- package/out/coincident-roles.js.map +1 -1
- package/out/convention.d.ts +30 -35
- package/out/convention.d.ts.map +1 -1
- package/out/convention.js +19 -21
- package/out/convention.js.map +1 -1
- package/out/fst-autocomplete.d.ts +5 -5
- package/out/fst-autocomplete.d.ts.map +1 -1
- package/out/fst-autocomplete.js +12 -13
- package/out/fst-autocomplete.js.map +1 -1
- package/out/fst-builder.d.ts +7 -7
- package/out/fst-builder.d.ts.map +1 -1
- package/out/fst-builder.js +9 -9
- package/out/fst-builder.js.map +1 -1
- package/out/fst-deserialize-web.d.ts +4 -4
- package/out/fst-deserialize-web.d.ts.map +1 -1
- package/out/fst-deserialize-web.js +4 -4
- package/out/fst-deserialize-web.js.map +1 -1
- package/out/fst-matcher.d.ts +12 -12
- package/out/fst-matcher.d.ts.map +1 -1
- package/out/fst-matcher.js +25 -25
- package/out/fst-matcher.js.map +1 -1
- package/out/fst-serialize.d.ts +5 -5
- package/out/fst-serialize.d.ts.map +1 -1
- package/out/fst-serialize.js +7 -6
- package/out/fst-serialize.js.map +1 -1
- package/out/fst-types.d.ts +13 -13
- package/out/fts.d.ts +74 -80
- package/out/fts.d.ts.map +1 -1
- package/out/fts.js +65 -71
- package/out/fts.js.map +1 -1
- package/out/geo.d.ts +14 -15
- package/out/geo.d.ts.map +1 -1
- package/out/geo.js +8 -8
- package/out/geo.js.map +1 -1
- package/out/geonames-aliases.d.ts +18 -9
- package/out/geonames-aliases.d.ts.map +1 -1
- package/out/geonames-aliases.js +70 -12
- package/out/geonames-aliases.js.map +1 -1
- package/out/index.d.ts +9 -9
- package/out/index.js +7 -7
- package/out/interpolation.d.ts +8 -10
- package/out/interpolation.d.ts.map +1 -1
- package/out/interpolation.js +6 -6
- package/out/interpolation.js.map +1 -1
- package/out/lookup.d.ts +74 -81
- package/out/lookup.d.ts.map +1 -1
- package/out/lookup.js +114 -128
- package/out/lookup.js.map +1 -1
- package/out/postal-city-alias-lookup.d.ts +9 -10
- package/out/postal-city-alias-lookup.d.ts.map +1 -1
- package/out/postal-city-alias-lookup.js +13 -14
- package/out/postal-city-alias-lookup.js.map +1 -1
- package/out/postal-city-alias-schema.d.ts +5 -6
- package/out/postal-city-alias-schema.d.ts.map +1 -1
- package/out/postal-city-alias-schema.js +3 -4
- package/out/postal-city-alias-schema.js.map +1 -1
- package/out/postal-city-candidate-schema.d.ts +7 -10
- package/out/postal-city-candidate-schema.d.ts.map +1 -1
- package/out/postal-city-candidate-schema.js +4 -6
- package/out/postal-city-candidate-schema.js.map +1 -1
- package/out/postcode-point-lookup.d.ts +3 -4
- package/out/postcode-point-lookup.d.ts.map +1 -1
- package/out/postcode-point-lookup.js +2 -2
- package/out/postcode-point-lookup.js.map +1 -1
- package/out/reverse.d.ts +26 -29
- package/out/reverse.d.ts.map +1 -1
- package/out/reverse.js +36 -38
- package/out/reverse.js.map +1 -1
- package/out/schema.d.ts +32 -33
- package/out/schema.d.ts.map +1 -1
- package/out/sharding.d.ts +26 -28
- package/out/sharding.d.ts.map +1 -1
- package/out/sharding.js +16 -16
- package/out/sharding.js.map +1 -1
- package/out/sqlite-convention-source.d.ts +3 -3
- package/out/sqlite-convention-source.d.ts.map +1 -1
- package/out/sqlite-convention-source.js +6 -6
- package/out/sqlite-convention-source.js.map +1 -1
- package/out/sqlite-utils.d.ts +4 -5
- package/out/sqlite-utils.d.ts.map +1 -1
- package/out/sqlite-utils.js +4 -5
- package/out/sqlite-utils.js.map +1 -1
- package/out/street-morphology-fst-builder.d.ts +15 -18
- package/out/street-morphology-fst-builder.d.ts.map +1 -1
- package/out/street-morphology-fst-builder.js +17 -17
- package/out/street-morphology-fst-builder.js.map +1 -1
- package/out/street-normalize.d.ts +43 -28
- package/out/street-normalize.d.ts.map +1 -1
- package/out/street-normalize.js +96 -34
- package/out/street-normalize.js.map +1 -1
- package/out/street-segment-schema.d.ts +5 -5
- package/out/street-segment-schema.js +2 -2
- package/out/types.d.ts +42 -47
- package/out/types.d.ts.map +1 -1
- package/out/types.js +1 -1
- package/out/unified-schema.d.ts +6 -6
- package/out/unified-schema.d.ts.map +1 -1
- package/out/unified-schema.js +10 -10
- package/out/unified-schema.js.map +1 -1
- package/package.json +26 -22
|
@@ -19,22 +19,22 @@
|
|
|
19
19
|
* Source: `core/data/libpostal/dictionaries/{locale}/street_types.txt`. Each line is pipe-delimited
|
|
20
20
|
* surface forms with the canonical form first: avenue|av|ave|aven|avenu|avn|avnu|avnue
|
|
21
21
|
*
|
|
22
|
-
* Output: an `
|
|
22
|
+
* Output: an `FSTMatcher` ready to serialize via `serializeFST` to e.g.
|
|
23
23
|
* `fst-street-morphology.bin`.
|
|
24
24
|
*/
|
|
25
25
|
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
26
26
|
import { join } from "node:path";
|
|
27
|
-
import {
|
|
27
|
+
import { FSTMatcher, normalizeTokens } from "./fst-matcher.js";
|
|
28
28
|
/**
|
|
29
|
-
* Reserved synthetic wofID base for street-morphology entries. 32-bit unsigned, well above any
|
|
30
|
-
*
|
|
31
|
-
*
|
|
29
|
+
* Reserved synthetic wofID base for street-morphology entries. 32-bit unsigned, well above any realistic WOF
|
|
30
|
+
* allocation. Reusing the same base across rebuilds keeps IDs stable for any consumer that caches them. See
|
|
31
|
+
* [[project-schema-storage-decision]] for the reserved range policy.
|
|
32
32
|
*/
|
|
33
33
|
const STREET_AFFIX_WOFID_BASE = 1_900_000_000;
|
|
34
34
|
const STREET_TYPES_FILENAME = "street_types.txt";
|
|
35
35
|
/**
|
|
36
|
-
* Parse one `street_types.txt` line into `{ canonical, variants }`. Canonical is the first token
|
|
37
|
-
*
|
|
36
|
+
* Parse one `street_types.txt` line into `{ canonical, variants }`. Canonical is the first token (pre-`|`); variants
|
|
37
|
+
* are all whitespace-stripped non-empty tokens including the canonical.
|
|
38
38
|
*
|
|
39
39
|
* Lines with no `|` are treated as a single-form entry where canonical == variant.
|
|
40
40
|
*/
|
|
@@ -50,7 +50,7 @@ function parseLine(line) {
|
|
|
50
50
|
return null;
|
|
51
51
|
return { canonical: parts[0], variants: parts };
|
|
52
52
|
}
|
|
53
|
-
export function
|
|
53
|
+
export function buildStreetMorphologyFST(opts) {
|
|
54
54
|
const progress = opts.onProgress ?? (() => { });
|
|
55
55
|
const minVariantLength = opts.minVariantLength ?? 3;
|
|
56
56
|
// Discover locales — either provided explicitly, or all directories containing street_types.txt.
|
|
@@ -92,9 +92,9 @@ export function buildStreetMorphologyFst(opts) {
|
|
|
92
92
|
progress("collect", `Collected ${canonicalToVariants.size} canonical affixes`);
|
|
93
93
|
// Assign stable synthetic wofIDs. Sort canonicals for determinism.
|
|
94
94
|
const sortedCanonicals = [...canonicalToVariants.keys()].sort();
|
|
95
|
-
const
|
|
95
|
+
const canonicalToWOFID = new Map();
|
|
96
96
|
for (let i = 0; i < sortedCanonicals.length; i++) {
|
|
97
|
-
|
|
97
|
+
canonicalToWOFID.set(sortedCanonicals[i], STREET_AFFIX_WOFID_BASE + i);
|
|
98
98
|
}
|
|
99
99
|
// Build the trie. Each variant is inserted as a token sequence pointing to its canonical's
|
|
100
100
|
// PlaceEntry — so all variants of "avenue" (av/ave/aven/...) lead to the same terminal entry.
|
|
@@ -102,18 +102,18 @@ export function buildStreetMorphologyFst(opts) {
|
|
|
102
102
|
function insertName(tokens, entry) {
|
|
103
103
|
if (tokens.length === 0)
|
|
104
104
|
return;
|
|
105
|
-
let
|
|
105
|
+
let stateID = 0;
|
|
106
106
|
for (const t of tokens) {
|
|
107
|
-
const node = nodes[
|
|
107
|
+
const node = nodes[stateID];
|
|
108
108
|
let next = node.edges.get(t);
|
|
109
109
|
if (next === undefined) {
|
|
110
110
|
next = nodes.length;
|
|
111
111
|
nodes.push({ edges: new Map(), places: [] });
|
|
112
112
|
node.edges.set(t, next);
|
|
113
113
|
}
|
|
114
|
-
|
|
114
|
+
stateID = next;
|
|
115
115
|
}
|
|
116
|
-
const existing = nodes[
|
|
116
|
+
const existing = nodes[stateID].places;
|
|
117
117
|
if (!existing.some((p) => p.wofID === entry.wofID && p.placetype === entry.placetype)) {
|
|
118
118
|
existing.push(entry);
|
|
119
119
|
}
|
|
@@ -122,7 +122,7 @@ export function buildStreetMorphologyFst(opts) {
|
|
|
122
122
|
let variantCount = 0;
|
|
123
123
|
for (const canonical of sortedCanonicals) {
|
|
124
124
|
const variants = canonicalToVariants.get(canonical);
|
|
125
|
-
const wofID =
|
|
125
|
+
const wofID = canonicalToWOFID.get(canonical);
|
|
126
126
|
const entry = {
|
|
127
127
|
wofID,
|
|
128
128
|
placetype: "street_affix",
|
|
@@ -151,7 +151,7 @@ export function buildStreetMorphologyFst(opts) {
|
|
|
151
151
|
}
|
|
152
152
|
progress("trie", `Built trie: ${nodes.length} states, ${insertCount} variant insertions`);
|
|
153
153
|
const edgeCount = nodes.reduce((sum, n) => sum + n.edges.size, 0);
|
|
154
|
-
const matcher =
|
|
154
|
+
const matcher = FSTMatcher.fromNodes(nodes);
|
|
155
155
|
const provenance = {
|
|
156
156
|
builtAt: new Date().toISOString(),
|
|
157
157
|
countries: locales, // Reuse `countries` slot for locale provenance — semantics differ from admin FST.
|
|
@@ -160,7 +160,7 @@ export function buildStreetMorphologyFst(opts) {
|
|
|
160
160
|
edgeCount,
|
|
161
161
|
nameInsertions: insertCount,
|
|
162
162
|
importanceMatches: 0, // No importance scoring for morphology — fixed at 1.0.
|
|
163
|
-
|
|
163
|
+
sourceDB: opts.dictionariesDir,
|
|
164
164
|
};
|
|
165
165
|
return {
|
|
166
166
|
matcher,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"street-morphology-fst-builder.js","sourceRoot":"","sources":["../street-morphology-fst-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"street-morphology-fst-builder.js","sourceRoot":"","sources":["../street-morphology-fst-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAGhC,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAG9D;;;;GAIG;AACH,MAAM,uBAAuB,GAAG,aAAa,CAAA;AAE7C,MAAM,qBAAqB,GAAG,kBAAkB,CAAA;AAgChD;;;;;GAKG;AACH,SAAS,SAAS,CAAC,IAAY;IAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;IAE3B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IAChE,MAAM,KAAK,GAAG,OAAO;SACnB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAE7B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAEnC,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,IAAkC;IAC1E,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IAC9C,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,IAAI,CAAC,CAAA;IAEnD,iGAAiG;IACjG,IAAI,OAAiB,CAAA;IAErB,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7C,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;IACvB,CAAC;SAAM,CAAC;QACP,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YAC5D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,CAAA;YAEpD,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE;gBAAE,OAAO,KAAK,CAAA;YAErD,IAAI,CAAC;gBACJ,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,qBAAqB,CAAC,CAAC,CAAA;gBAEjD,OAAO,IAAI,CAAA;YACZ,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO,KAAK,CAAA;YACb,CAAC;QACF,CAAC,CAAC,CAAA;IACH,CAAC;IACD,QAAQ,CAAC,UAAU,EAAE,SAAS,OAAO,CAAC,MAAM,iBAAiB,qBAAqB,EAAE,CAAC,CAAA;IAErF,4FAA4F;IAC5F,wEAAwE;IACxE,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAuB,CAAA;IAE1D,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,EAAE,qBAAqB,CAAC,CAAA;QAC1E,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;QAE9C,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;YAE9B,IAAI,CAAC,MAAM;gBAAE,SAAQ;YACrB,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,IAAI,GAAG,EAAU,CAAA;YAE/E,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ;gBAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YAC5D,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;QACpD,CAAC;IACF,CAAC;IACD,QAAQ,CAAC,SAAS,EAAE,aAAa,mBAAmB,CAAC,IAAI,oBAAoB,CAAC,CAAA;IAE9E,mEAAmE;IACnE,MAAM,gBAAgB,GAAG,CAAC,GAAG,mBAAmB,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IAC/D,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAkB,CAAA;IAElD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,gBAAgB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClD,gBAAgB,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAE,EAAE,uBAAuB,GAAG,CAAC,CAAC,CAAA;IACxE,CAAC;IAED,2FAA2F;IAC3F,8FAA8F;IAC9F,MAAM,KAAK,GAAc,CAAC,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAA;IAE3D,SAAS,UAAU,CAAC,MAAgB,EAAE,KAAiB;QACtD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QAC/B,IAAI,OAAO,GAAG,CAAC,CAAA;QAEf,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAE,CAAA;YAC5B,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;YAE5B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACxB,IAAI,GAAG,KAAK,CAAC,MAAM,CAAA;gBACnB,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAA;gBAC5C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;YACxB,CAAC;YACD,OAAO,GAAG,IAAI,CAAA;QACf,CAAC;QACD,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAE,CAAC,MAAM,CAAA;QAEvC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;YACvF,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACrB,CAAC;IACF,CAAC;IAED,IAAI,WAAW,GAAG,CAAC,CAAA;IACnB,IAAI,YAAY,GAAG,CAAC,CAAA;IAEpB,KAAK,MAAM,SAAS,IAAI,gBAAgB,EAAE,CAAC;QAC1C,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAE,CAAA;QACpD,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAE,CAAA;QAC9C,MAAM,KAAK,GAAe;YACzB,KAAK;YACL,SAAS,EAAE,cAAc;YACzB,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,EAAE;YACf,wFAAwF;YACxF,qFAAqF;YACrF,iDAAiD;YACjD,UAAU,EAAE,GAAG;YACf,GAAG,EAAE,CAAC;YACN,GAAG,EAAE,CAAC;SACN,CAAA;QAED,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAChC,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAA;YAEvC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAQ;YACjC,qFAAqF;YACrF,2FAA2F;YAC3F,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YAE9B,IAAI,MAAM,CAAC,MAAM,GAAG,gBAAgB;gBAAE,SAAQ;YAC9C,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;YACzB,WAAW,EAAE,CAAA;YACb,YAAY,EAAE,CAAA;QACf,CAAC;IACF,CAAC;IACD,QAAQ,CAAC,MAAM,EAAE,eAAe,KAAK,CAAC,MAAM,YAAY,WAAW,qBAAqB,CAAC,CAAA;IAEzF,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IACjE,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC3C,MAAM,UAAU,GAAkB;QACjC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACjC,SAAS,EAAE,OAAO,EAAE,kFAAkF;QACtG,UAAU,EAAE,KAAK,CAAC,MAAM;QACxB,UAAU,EAAE,gBAAgB,CAAC,MAAM;QACnC,SAAS;QACT,cAAc,EAAE,WAAW;QAC3B,iBAAiB,EAAE,CAAC,EAAE,uDAAuD;QAC7E,QAAQ,EAAE,IAAI,CAAC,eAAe;KAC9B,CAAA;IAED,OAAO;QACN,OAAO;QACP,UAAU;QACV,cAAc,EAAE,gBAAgB,CAAC,MAAM;QACvC,YAAY;QACZ,WAAW;QACX,OAAO;KACP,CAAA;AACF,CAAC"}
|
|
@@ -22,45 +22,60 @@
|
|
|
22
22
|
* cross-streets the source data spells with digits become reachable.
|
|
23
23
|
*/
|
|
24
24
|
/**
|
|
25
|
-
* Normalize a street name for address-point keying. Same function at build time and lookup time —
|
|
26
|
-
*
|
|
25
|
+
* Normalize a street name for address-point keying. Same function at build time and lookup time — see module docstring
|
|
26
|
+
* for the contract.
|
|
27
27
|
*/
|
|
28
28
|
export declare function normalizeStreetForKey(street: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* Street-name locale for the address-point key. The US path is the full USPS pipeline ({@link normalizeStreetForKey});
|
|
31
|
+
* the international paths fold + apply a SMALL, consistent per-locale type-token canonicalization. Same discipline as
|
|
32
|
+
* the US normalizer: build side and probe side call the identical function, so the key only needs to be CONSISTENT, not
|
|
33
|
+
* linguistically perfect — a folded "rue du chevaleret" keys the same on both sides whether or not we reorder the
|
|
34
|
+
* article, so no salient-token / multi-key index is built yet (deferred until probing shows the normalizer can't absorb
|
|
35
|
+
* the false-negatives).
|
|
36
|
+
*/
|
|
37
|
+
export type StreetLocale = "us" | "fr" | "de" | "nl";
|
|
38
|
+
/**
|
|
39
|
+
* Normalize a street name for the address-point key in a non-US locale. Same function build-side and probe-side (the
|
|
40
|
+
* one-function discipline). US delegates to {@link normalizeStreetForKey}.
|
|
41
|
+
*
|
|
42
|
+
* - **fr** — fold + expand leading type abbreviations and Saint/Sainte (token map).
|
|
43
|
+
* - **de** — fold + ß→ss + canonicalize the GLUED `-str(.)` suffix to `-strasse` ("Lindenstr." → "lindenstrasse",
|
|
44
|
+
* "Lindenstraße" → "lindenstrasse"); an already-full "-strasse" is left intact.
|
|
45
|
+
* - **nl** — fold + canonicalize the glued `-str` suffix to `-straat` ("Kerkstr." → "kerkstraat").
|
|
46
|
+
*/
|
|
47
|
+
export declare function normalizeStreetForKeyLocale(street: string, locale: StreetLocale): string;
|
|
29
48
|
/** Normalize a locality name for address-point keying (fold only — no street semantics). */
|
|
30
49
|
export declare function normalizeLocalityForKey(locality: string): string;
|
|
31
50
|
/**
|
|
32
|
-
* Strip a locality QUALIFIER for a query-side fallback — when an OA locality's exact normalized
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* (
|
|
39
|
-
* "" when nothing was stripped (no point re-probing the identical key).
|
|
51
|
+
* Strip a locality QUALIFIER for a query-side fallback — when an OA locality's exact normalized name misses the
|
|
52
|
+
* gazetteer's canonical name, retry with the qualifier removed. OA address data carries disambiguating qualifiers the
|
|
53
|
+
* gazetteer's canonical name omits: Austrian `Kraubath/Mur` and `Hart b.Graz` → `Hart`; Swiss `Lenk im Simmental` →
|
|
54
|
+
* `Lenk`, `Roche VD` → `Roche`; Danish `Odense S`, `Hurup Thy`. A FALLBACK ONLY — the exact name is tried first, and
|
|
55
|
+
* the region-bbox disambiguation resolves any base-name ambiguity downstream. The candidate table is unchanged (this is
|
|
56
|
+
* purely query-side); feed the result back through {@link normalizeLocalityForKey}. Returns "" when nothing was stripped
|
|
57
|
+
* (no point re-probing the identical key).
|
|
40
58
|
*
|
|
41
|
-
* Measured (`scripts/eval/candidate-recall.ts --strip-fallback`, EU OA holdouts): recovers AT
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* untouched.
|
|
59
|
+
* Measured (`scripts/eval/candidate-recall.ts --strip-fallback`, EU OA holdouts): recovers AT 74.1→88.2% (+14.1pp), DK
|
|
60
|
+
* 91.5→96.2%, CH 90.4→92.6%; +1.3pp overall (diluted by the already-100% locales). Conservative by design — only the
|
|
61
|
+
* qualifier forms above; FI/PT/SI misses are untouched.
|
|
45
62
|
*/
|
|
46
63
|
export declare function stripLocalityQualifier(locality: string): string;
|
|
47
64
|
/**
|
|
48
|
-
* Fold numbered-route designators to a canonical key, applied AFTER {@link normalizeStreetForKey}.
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* Street` and friends never match.
|
|
65
|
+
* Fold numbered-route designators to a canonical key, applied AFTER {@link normalizeStreetForKey}. Sources disagree
|
|
66
|
+
* systematically on how they spell a route: TIGER says `State Rte 100` / `US Hwy 5` where E911/Overture say `VT ROUTE
|
|
67
|
+
* 100` / `US ROUTE 5` — the dominant street-name miss class in the #483 interpolation eval (rural addresses live on
|
|
68
|
+
* routes). `us <designator> N…` folds to `us route N…`; `state <designator> N…` and `<2-letter-prefix> <designator> N…`
|
|
69
|
+
* (the state abbreviation form) fold to `state route N…`. Only digit-leading route numbers fold — `State Street` and
|
|
70
|
+
* friends never match.
|
|
55
71
|
*
|
|
56
|
-
* Used by BOTH the segment-shard builder (`scripts/build-interpolation-shard.ts`) and the
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* (noted on #483).
|
|
72
|
+
* Used by BOTH the segment-shard builder (`scripts/build-interpolation-shard.ts`) and the interpolation lookup — same
|
|
73
|
+
* one-function discipline as {@link normalizeStreetForKey}. The address-point tier (#476) does NOT apply it yet:
|
|
74
|
+
* adopting it there requires a shard rebuild (noted on #483).
|
|
60
75
|
*
|
|
61
|
-
* A same-numbered US and state route stay DISTINCT keys (`us route 5` vs `state route 5`); only the
|
|
62
|
-
*
|
|
63
|
-
*
|
|
76
|
+
* A same-numbered US and state route stay DISTINCT keys (`us route 5` vs `state route 5`); only the BARE `route N` form
|
|
77
|
+
* is ambiguous (designator unknown) and it stays unfolded — a bare-route query therefore misses rather than guessing a
|
|
78
|
+
* designator.
|
|
64
79
|
*/
|
|
65
80
|
export declare function canonicalizeRouteKey(streetNorm: string): string;
|
|
66
81
|
//# sourceMappingURL=street-normalize.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"street-normalize.d.ts","sourceRoot":"","sources":["../street-normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;
|
|
1
|
+
{"version":3,"file":"street-normalize.d.ts","sourceRoot":"","sources":["../street-normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAsDH;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAqD5D;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AA6BpD;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAgCxF;AAED,4FAA4F;AAC5F,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAU/D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAM/D"}
|
package/out/street-normalize.js
CHANGED
|
@@ -23,12 +23,11 @@
|
|
|
23
23
|
*/
|
|
24
24
|
import { AbbreviationToDirectional, US_STREET_SUFFIX_LOOKUP } from "@mailwoman/codex/us";
|
|
25
25
|
/**
|
|
26
|
-
* Spelled ordinal street names → their digit-ordinal form ("tenth" → "10th"), applied ONLY when a
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* no rebuild; a future rebuild folds any spelled-source key the same way (the one-function
|
|
26
|
+
* Spelled ordinal street names → their digit-ordinal form ("tenth" → "10th"), applied ONLY when a street-type suffix
|
|
27
|
+
* follows (#723 admin-tail) — so the ordinal cross-streets common in grid cities ("Tenth Street", "Fifth Avenue") match
|
|
28
|
+
* the shards' digit keys, WITHOUT rewriting ordinal-WORD names where the next token is not a suffix ("First National
|
|
29
|
+
* Bank Rd" stays "first national …"). Digit-source shards are unaffected (a digit token isn't in this map), so the
|
|
30
|
+
* existing keys need no rebuild; a future rebuild folds any spelled-source key the same way (the one-function
|
|
32
31
|
* discipline).
|
|
33
32
|
*/
|
|
34
33
|
const SPELLED_ORDINAL_TO_DIGIT = new Map([
|
|
@@ -72,8 +71,8 @@ function fold(input) {
|
|
|
72
71
|
.trim();
|
|
73
72
|
}
|
|
74
73
|
/**
|
|
75
|
-
* Normalize a street name for address-point keying. Same function at build time and lookup time —
|
|
76
|
-
*
|
|
74
|
+
* Normalize a street name for address-point keying. Same function at build time and lookup time — see module docstring
|
|
75
|
+
* for the contract.
|
|
77
76
|
*/
|
|
78
77
|
export function normalizeStreetForKey(street) {
|
|
79
78
|
const tokens = fold(street).split(" ");
|
|
@@ -120,24 +119,89 @@ export function normalizeStreetForKey(street) {
|
|
|
120
119
|
}
|
|
121
120
|
return tokens.join(" ");
|
|
122
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* French street-type abbreviations → canonical full form, applied per token after {@link fold}. French address types
|
|
124
|
+
* LEAD the name ("Av. de…", "Bd …", "Pl. …") and "St"/"Ste" abbreviate Saint/Sainte inside names ("Rue St-Honoré" →
|
|
125
|
+
* "rue saint honore"). fold() has already stripped the trailing period, so the keys are point-free ("av", "bd").
|
|
126
|
+
*/
|
|
127
|
+
const FR_STREET_ABBREV = new Map([
|
|
128
|
+
["av", "avenue"],
|
|
129
|
+
["ave", "avenue"],
|
|
130
|
+
["bd", "boulevard"],
|
|
131
|
+
["bld", "boulevard"],
|
|
132
|
+
["bvd", "boulevard"],
|
|
133
|
+
["boul", "boulevard"],
|
|
134
|
+
["pl", "place"],
|
|
135
|
+
["imp", "impasse"],
|
|
136
|
+
["all", "allee"],
|
|
137
|
+
["ch", "chemin"],
|
|
138
|
+
["che", "chemin"],
|
|
139
|
+
["sq", "square"],
|
|
140
|
+
["pas", "passage"],
|
|
141
|
+
["fg", "faubourg"],
|
|
142
|
+
["fbg", "faubourg"],
|
|
143
|
+
["rte", "route"],
|
|
144
|
+
["st", "saint"],
|
|
145
|
+
["ste", "sainte"],
|
|
146
|
+
["sts", "saints"],
|
|
147
|
+
]);
|
|
148
|
+
/**
|
|
149
|
+
* Normalize a street name for the address-point key in a non-US locale. Same function build-side and probe-side (the
|
|
150
|
+
* one-function discipline). US delegates to {@link normalizeStreetForKey}.
|
|
151
|
+
*
|
|
152
|
+
* - **fr** — fold + expand leading type abbreviations and Saint/Sainte (token map).
|
|
153
|
+
* - **de** — fold + ß→ss + canonicalize the GLUED `-str(.)` suffix to `-strasse` ("Lindenstr." → "lindenstrasse",
|
|
154
|
+
* "Lindenstraße" → "lindenstrasse"); an already-full "-strasse" is left intact.
|
|
155
|
+
* - **nl** — fold + canonicalize the glued `-str` suffix to `-straat` ("Kerkstr." → "kerkstraat").
|
|
156
|
+
*/
|
|
157
|
+
export function normalizeStreetForKeyLocale(street, locale) {
|
|
158
|
+
if (locale === "us")
|
|
159
|
+
return normalizeStreetForKey(street);
|
|
160
|
+
// Hyphen → space so a compound name keys the same whether the source or the query writes the
|
|
161
|
+
// hyphen ("Champs-Élysées", "St-Honoré") or a space — both sides fold identically, so this is pure
|
|
162
|
+
// robustness. It also splits a hyphenated abbreviation ("St-Honoré" → "st honore") into tokens the
|
|
163
|
+
// per-locale type/Saint map can see.
|
|
164
|
+
const tokens = fold(street).replace(/ß/g, "ss").replace(/-/g, " ").split(/\s+/).filter(Boolean);
|
|
165
|
+
if (tokens.length === 0)
|
|
166
|
+
return "";
|
|
167
|
+
switch (locale) {
|
|
168
|
+
case "fr":
|
|
169
|
+
for (let i = 0; i < tokens.length; i++)
|
|
170
|
+
tokens[i] = FR_STREET_ABBREV.get(tokens[i]) ?? tokens[i];
|
|
171
|
+
break;
|
|
172
|
+
case "de":
|
|
173
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
174
|
+
const t = tokens[i];
|
|
175
|
+
if (t.endsWith("str") && !t.endsWith("strasse"))
|
|
176
|
+
tokens[i] = t.replace(/str$/, "strasse");
|
|
177
|
+
}
|
|
178
|
+
break;
|
|
179
|
+
case "nl":
|
|
180
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
181
|
+
const t = tokens[i];
|
|
182
|
+
if (t.endsWith("str") && !t.endsWith("straat"))
|
|
183
|
+
tokens[i] = t.replace(/str$/, "straat");
|
|
184
|
+
}
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
return tokens.join(" ");
|
|
188
|
+
}
|
|
123
189
|
/** Normalize a locality name for address-point keying (fold only — no street semantics). */
|
|
124
190
|
export function normalizeLocalityForKey(locality) {
|
|
125
191
|
return fold(locality);
|
|
126
192
|
}
|
|
127
193
|
/**
|
|
128
|
-
* Strip a locality QUALIFIER for a query-side fallback — when an OA locality's exact normalized
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* (
|
|
135
|
-
* "" when nothing was stripped (no point re-probing the identical key).
|
|
194
|
+
* Strip a locality QUALIFIER for a query-side fallback — when an OA locality's exact normalized name misses the
|
|
195
|
+
* gazetteer's canonical name, retry with the qualifier removed. OA address data carries disambiguating qualifiers the
|
|
196
|
+
* gazetteer's canonical name omits: Austrian `Kraubath/Mur` and `Hart b.Graz` → `Hart`; Swiss `Lenk im Simmental` →
|
|
197
|
+
* `Lenk`, `Roche VD` → `Roche`; Danish `Odense S`, `Hurup Thy`. A FALLBACK ONLY — the exact name is tried first, and
|
|
198
|
+
* the region-bbox disambiguation resolves any base-name ambiguity downstream. The candidate table is unchanged (this is
|
|
199
|
+
* purely query-side); feed the result back through {@link normalizeLocalityForKey}. Returns "" when nothing was stripped
|
|
200
|
+
* (no point re-probing the identical key).
|
|
136
201
|
*
|
|
137
|
-
* Measured (`scripts/eval/candidate-recall.ts --strip-fallback`, EU OA holdouts): recovers AT
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
* untouched.
|
|
202
|
+
* Measured (`scripts/eval/candidate-recall.ts --strip-fallback`, EU OA holdouts): recovers AT 74.1→88.2% (+14.1pp), DK
|
|
203
|
+
* 91.5→96.2%, CH 90.4→92.6%; +1.3pp overall (diluted by the already-100% locales). Conservative by design — only the
|
|
204
|
+
* qualifier forms above; FI/PT/SI misses are untouched.
|
|
141
205
|
*/
|
|
142
206
|
export function stripLocalityQualifier(locality) {
|
|
143
207
|
let s = locality.trim();
|
|
@@ -150,22 +214,20 @@ export function stripLocalityQualifier(locality) {
|
|
|
150
214
|
return s === locality.trim() ? "" : s;
|
|
151
215
|
}
|
|
152
216
|
/**
|
|
153
|
-
* Fold numbered-route designators to a canonical key, applied AFTER {@link normalizeStreetForKey}.
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
* Street` and friends never match.
|
|
217
|
+
* Fold numbered-route designators to a canonical key, applied AFTER {@link normalizeStreetForKey}. Sources disagree
|
|
218
|
+
* systematically on how they spell a route: TIGER says `State Rte 100` / `US Hwy 5` where E911/Overture say `VT ROUTE
|
|
219
|
+
* 100` / `US ROUTE 5` — the dominant street-name miss class in the #483 interpolation eval (rural addresses live on
|
|
220
|
+
* routes). `us <designator> N…` folds to `us route N…`; `state <designator> N…` and `<2-letter-prefix> <designator> N…`
|
|
221
|
+
* (the state abbreviation form) fold to `state route N…`. Only digit-leading route numbers fold — `State Street` and
|
|
222
|
+
* friends never match.
|
|
160
223
|
*
|
|
161
|
-
* Used by BOTH the segment-shard builder (`scripts/build-interpolation-shard.ts`) and the
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
* (noted on #483).
|
|
224
|
+
* Used by BOTH the segment-shard builder (`scripts/build-interpolation-shard.ts`) and the interpolation lookup — same
|
|
225
|
+
* one-function discipline as {@link normalizeStreetForKey}. The address-point tier (#476) does NOT apply it yet:
|
|
226
|
+
* adopting it there requires a shard rebuild (noted on #483).
|
|
165
227
|
*
|
|
166
|
-
* A same-numbered US and state route stay DISTINCT keys (`us route 5` vs `state route 5`); only the
|
|
167
|
-
*
|
|
168
|
-
*
|
|
228
|
+
* A same-numbered US and state route stay DISTINCT keys (`us route 5` vs `state route 5`); only the BARE `route N` form
|
|
229
|
+
* is ambiguous (designator unknown) and it stays unfolded — a bare-route query therefore misses rather than guessing a
|
|
230
|
+
* designator.
|
|
169
231
|
*/
|
|
170
232
|
export function canonicalizeRouteKey(streetNorm) {
|
|
171
233
|
const match = /^(us|state|[a-z]{2}) (?:route|rte|rt|highway|hwy) (\d.*)$/.exec(streetNorm);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"street-normalize.js","sourceRoot":"","sources":["../street-normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAExF
|
|
1
|
+
{"version":3,"file":"street-normalize.js","sourceRoot":"","sources":["../street-normalize.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import type { Kysely } from "kysely";
|
|
18
18
|
/**
|
|
19
|
-
* One TIGER street-segment edge: a `(from_hn, to_hn)` house-number range on one `side` of a named
|
|
20
|
-
*
|
|
21
|
-
*
|
|
19
|
+
* One TIGER street-segment edge: a `(from_hn, to_hn)` house-number range on one `side` of a named street, with the
|
|
20
|
+
* geometry the interpolator walks. `min_hn`/`max_hn` are the sorted bounds (the probe filters on them); `parity` is
|
|
21
|
+
* `odd`/`even`/`mixed`.
|
|
22
22
|
*/
|
|
23
23
|
export interface StreetSegmentTable {
|
|
24
24
|
/** Shared {@link normalizeStreetForKey} of the street — the build/query-consistent probe key. */
|
|
@@ -50,8 +50,8 @@ export interface StreetSegmentDatabase {
|
|
|
50
50
|
street_segment: StreetSegmentTable;
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
|
-
* The `street_segment` columns in INSERT order. The builder's positional prepared statement derives
|
|
54
|
-
*
|
|
53
|
+
* The `street_segment` columns in INSERT order. The builder's positional prepared statement derives its placeholder
|
|
54
|
+
* list from this, so the positional order can't drift from the DDL / the reader.
|
|
55
55
|
*/
|
|
56
56
|
export declare const STREET_SEGMENT_COLUMNS: readonly ["street_norm", "side", "from_hn", "to_hn", "min_hn", "max_hn", "parity", "postcode", "county_fips", "street_raw", "geometry", "source", "release"];
|
|
57
57
|
/** Create the `street_segment` table — called before the streaming bulk load. */
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
* {@link STREET_SEGMENT_COLUMNS} so it can't drift from the DDL.
|
|
16
16
|
*/
|
|
17
17
|
/**
|
|
18
|
-
* The `street_segment` columns in INSERT order. The builder's positional prepared statement derives
|
|
19
|
-
*
|
|
18
|
+
* The `street_segment` columns in INSERT order. The builder's positional prepared statement derives its placeholder
|
|
19
|
+
* list from this, so the positional order can't drift from the DDL / the reader.
|
|
20
20
|
*/
|
|
21
21
|
export const STREET_SEGMENT_COLUMNS = [
|
|
22
22
|
"street_norm",
|
package/out/types.d.ts
CHANGED
|
@@ -7,33 +7,32 @@
|
|
|
7
7
|
*
|
|
8
8
|
* These mirror the conceptual model described in `docs/plan/phases/PHASE_4_2_wof_sqlite.md`. Phase
|
|
9
9
|
* 4.3 will extend `PlaceCandidate` with the resolver-decorated fields that flow into
|
|
10
|
-
* `AddressNode.source` / `
|
|
10
|
+
* `AddressNode.source` / `sourceID` (e.g. an explicit `wofURI: "wof-admin:101751113"` form).
|
|
11
11
|
*/
|
|
12
12
|
/**
|
|
13
|
-
* The placetype taxonomy used by Who's On First. Ordered roughly from coarsest (country) to finest
|
|
14
|
-
*
|
|
15
|
-
* definitions of each.
|
|
13
|
+
* The placetype taxonomy used by Who's On First. Ordered roughly from coarsest (country) to finest (address). See
|
|
14
|
+
* https://github.com/whosonfirst/whosonfirst-placetypes for the authoritative definitions of each.
|
|
16
15
|
*
|
|
17
16
|
* Phase 4.2 only emits the ones we actually look up; the union is open enough to extend later.
|
|
18
17
|
*/
|
|
19
|
-
export type
|
|
18
|
+
export type WOFPlacetype = "country" | "macroregion" | "region" | "macrocounty" | "county" | "localadmin" | "locality" | "borough" | "neighbourhood" | "microhood" | "postalcode" | "venue" | "campus" | "address";
|
|
20
19
|
/**
|
|
21
20
|
* One candidate match for a place lookup.
|
|
22
21
|
*
|
|
23
|
-
* `score` is the post-boost ranking number — higher is better, but the scale is implementation-
|
|
24
|
-
*
|
|
22
|
+
* `score` is the post-boost ranking number — higher is better, but the scale is implementation- defined. Callers should
|
|
23
|
+
* treat it as ordinal, not absolute.
|
|
25
24
|
*
|
|
26
|
-
* `id` is the WOF place id. It's named generically (not `wof_id`) so the shape stays structurally
|
|
27
|
-
*
|
|
28
|
-
*
|
|
25
|
+
* `id` is the WOF place id. It's named generically (not `wof_id`) so the shape stays structurally compatible with
|
|
26
|
+
* `@mailwoman/resolver`'s `ResolvedPlace` — `WOFSqlitePlaceLookup` satisfies the generic `ResolverBackend` contract
|
|
27
|
+
* without an adapter shim.
|
|
29
28
|
*
|
|
30
|
-
* `distanceKm` is populated only when the query carried `near` (and the place has a centroid).
|
|
31
|
-
*
|
|
29
|
+
* `distanceKm` is populated only when the query carried `near` (and the place has a centroid). Useful for downstream
|
|
30
|
+
* UIs that want to show "X km from you" alongside the result.
|
|
32
31
|
*/
|
|
33
32
|
export interface PlaceCandidate {
|
|
34
33
|
id: number;
|
|
35
34
|
name: string;
|
|
36
|
-
placetype:
|
|
35
|
+
placetype: WOFPlacetype;
|
|
37
36
|
/** ISO 3166-1 alpha-2 country code. */
|
|
38
37
|
country: string;
|
|
39
38
|
lat: number;
|
|
@@ -43,31 +42,28 @@ export interface PlaceCandidate {
|
|
|
43
42
|
distanceKm?: number;
|
|
44
43
|
/**
|
|
45
44
|
* True when this candidate's name OR an alias EXACTLY equals the query (the exact-match tier from
|
|
46
|
-
* {@link RankingWeights.exactMatchTiering}). Surfaced so a downstream country re-rank (#369's
|
|
47
|
-
*
|
|
48
|
-
* `
|
|
45
|
+
* {@link RankingWeights.exactMatchTiering}). Surfaced so a downstream country re-rank (#369's postcode anchor in
|
|
46
|
+
* `resolveTree`) can pin the country without crossing the tier — see the `exactMatch` field on `@mailwoman/core`'s
|
|
47
|
+
* `ResolvedPlace`.
|
|
49
48
|
*/
|
|
50
49
|
exactMatch?: boolean;
|
|
51
50
|
/**
|
|
52
|
-
* Population from WOF's `wof:population` property. Only present when the candidate has it on
|
|
53
|
-
*
|
|
54
|
-
* mean zero, just unknown.
|
|
51
|
+
* Population from WOF's `wof:population` property. Only present when the candidate has it on record — WOF carries
|
|
52
|
+
* population for ~15% of localities (mostly larger ones). Absent does NOT mean zero, just unknown.
|
|
55
53
|
*/
|
|
56
54
|
population?: number;
|
|
57
55
|
/**
|
|
58
|
-
* Bounding box from WOF's `spr.{min,max}_{latitude,longitude}` columns. Coarse outline for the
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* the underlying schema lacks the columns.
|
|
56
|
+
* Bounding box from WOF's `spr.{min,max}_{latitude,longitude}` columns. Coarse outline for the place — a city's bbox
|
|
57
|
+
* is the city's full extent, a postcode's is roughly the postcode polygon's envelope. Optional because not all
|
|
58
|
+
* callers ask for it; implementations are free to omit when the underlying schema lacks the columns.
|
|
62
59
|
*/
|
|
63
60
|
bbox?: GeoBbox;
|
|
64
61
|
/**
|
|
65
|
-
* Set by the coordinate-first path when the chosen locality and the sibling postcode's containing
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* differentiator.
|
|
62
|
+
* Set by the coordinate-first path when the chosen locality and the sibling postcode's containing locality are
|
|
63
|
+
* geographically far apart — the postcode and the parsed city name disagree (a transposed / wrong-for-the-city
|
|
64
|
+
* postcode). The candidate is still returned (the name wins for the locality), but the flag lets callers lower
|
|
65
|
+
* confidence / surface the conflict rather than silently mislocate. A retrieval/BM25 geocoder can't raise this — it's
|
|
66
|
+
* the falsehood-detection differentiator.
|
|
71
67
|
*/
|
|
72
68
|
mismatch?: boolean;
|
|
73
69
|
}
|
|
@@ -90,30 +86,29 @@ export interface GeoBbox {
|
|
|
90
86
|
/**
|
|
91
87
|
* Query against the resolver.
|
|
92
88
|
*
|
|
93
|
-
* `text` is the only required field; everything else narrows the search. When `country` and
|
|
94
|
-
* `
|
|
89
|
+
* `text` is the only required field; everything else narrows the search. When `country` and `parentID` are both set,
|
|
90
|
+
* `parentID` wins (it's more specific).
|
|
95
91
|
*
|
|
96
|
-
* `near` and `bbox` are independent. `near` is a soft signal — candidates close to the point get a
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
* compatibility).
|
|
92
|
+
* `near` and `bbox` are independent. `near` is a soft signal — candidates close to the point get a ranking boost but
|
|
93
|
+
* distant candidates aren't dropped. `bbox` is a hard filter — only candidates whose bbox intersects the query bbox are
|
|
94
|
+
* returned (uses the package-built R*Tree index when present; if the index is missing the option is silently ignored to
|
|
95
|
+
* preserve backwards compatibility).
|
|
101
96
|
*
|
|
102
|
-
* `near` may carry `maxDistanceKm` to escalate from a boost to a hard filter — candidates further
|
|
103
|
-
*
|
|
97
|
+
* `near` may carry `maxDistanceKm` to escalate from a boost to a hard filter — candidates further than that distance
|
|
98
|
+
* from the point are dropped at the SQL level via an R*Tree pre-filter.
|
|
104
99
|
*/
|
|
105
100
|
export interface FindPlaceQuery {
|
|
106
101
|
text: string;
|
|
107
|
-
placetype?:
|
|
102
|
+
placetype?: WOFPlacetype | WOFPlacetype[];
|
|
108
103
|
/** ISO 3166-1 alpha-2 — narrows to one country. */
|
|
109
104
|
country?: string;
|
|
110
105
|
/** WOF place id — narrows to descendants of this place. */
|
|
111
|
-
|
|
106
|
+
parentID?: number;
|
|
112
107
|
/**
|
|
113
|
-
* Sibling postcode. When set on a `locality` query AND a `postcode_locality` table is present,
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
108
|
+
* Sibling postcode. When set on a `locality` query AND a `postcode_locality` table is present, triggers the
|
|
109
|
+
* coordinate-first soft-score path: postcode→candidate localities are injected and scored `0.6·S_pc + 0.3·S_name +
|
|
110
|
+
* 0.1·S_pop` against the FTS name-match set, recovering small localities the name-match alone misses. Ignored when no
|
|
111
|
+
* postcode_locality shard is present.
|
|
117
112
|
*/
|
|
118
113
|
postcode?: string;
|
|
119
114
|
/** Proximity hint — candidates close to this point get a ranking boost. */
|
|
@@ -126,9 +121,9 @@ export interface FindPlaceQuery {
|
|
|
126
121
|
limit?: number;
|
|
127
122
|
}
|
|
128
123
|
/**
|
|
129
|
-
* The pull-based lookup surface. Implementations resolve a `FindPlaceQuery` to a ranked list of
|
|
130
|
-
*
|
|
131
|
-
*
|
|
124
|
+
* The pull-based lookup surface. Implementations resolve a `FindPlaceQuery` to a ranked list of `PlaceCandidate`s. The
|
|
125
|
+
* interface is async even though `node:sqlite` is sync — leaves room for `Worker`-backed implementations later without
|
|
126
|
+
* a public API break.
|
|
132
127
|
*/
|
|
133
128
|
export interface PlaceLookup {
|
|
134
129
|
findPlace(query: FindPlaceQuery): Promise<PlaceCandidate[]>;
|