@mailwoman/resolver-wof-sqlite 10.1.0 → 10.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 +1 -0
- package/lib/address/point/interpolation.ts +6 -2
- package/lib/address/point.ts +15 -14
- package/lib/build/candidate.ts +11 -21
- package/lib/build/slim.ts +1 -1
- package/lib/candidate/importance.ts +1 -1
- package/lib/candidate/lookup.ts +47 -34
- package/lib/candidate/own-name.ts +1 -1
- package/lib/candidate/scoring.ts +29 -29
- package/lib/capitals.ts +3 -3
- package/lib/coincident-roles.ts +15 -4
- package/lib/convention/schema.ts +2 -9
- package/lib/convention.ts +7 -7
- package/lib/coverage-manifest-schema.ts +6 -6
- package/lib/currency-backfill.ts +13 -13
- package/lib/exact-match.ts +1 -1
- package/lib/extracts.ts +1 -1
- package/lib/fst/autocomplete.ts +2 -2
- package/lib/fst/builder.ts +9 -7
- package/lib/fst/deserialize-web.ts +8 -8
- package/lib/fst/freshness.ts +27 -26
- package/lib/fst/matcher.ts +5 -3
- package/lib/fst/serialize.ts +12 -17
- package/lib/fst/types.ts +14 -23
- package/lib/fst.ts +1 -0
- package/lib/fts.ts +1 -1
- package/lib/geonames/aliases.ts +3 -3
- package/lib/geonames/postal.ts +1 -1
- package/lib/index.ts +3 -2
- package/lib/interpolation.ts +7 -6
- package/lib/lookup.ts +26 -20
- package/lib/nsul/lookup.ts +1 -1
- package/lib/place-importance-schema.ts +5 -5
- package/lib/poi/lookup.ts +13 -21
- package/lib/postcode-point-lookup.ts +1 -10
- package/lib/primary-preference.ts +2 -2
- package/lib/proximity-rerank.ts +1 -1
- package/lib/ranking-weights.ts +15 -10
- package/lib/region-keys.ts +2 -2
- package/lib/reverse.ts +45 -18
- package/lib/schema.ts +3 -12
- package/lib/sqlite/convention-source.ts +3 -3
- package/lib/sqlite/utils.ts +1 -1
- package/lib/street/centroid.ts +1 -1
- package/lib/street/morphology/fst/builder.ts +16 -7
- package/lib/street/morphology/fst/loader.ts +8 -7
- package/lib/street/name-lookup.ts +4 -8
- package/lib/street/normalize.ts +3 -3
- package/lib/street/segment-schema.ts +2 -2
- package/lib/types.ts +17 -12
- package/lib/uprn/lookup.ts +1 -1
- package/lib/weights-overlay-linker.ts +38 -26
- package/out/address/point/interpolation.d.ts +1 -0
- package/out/address/point/interpolation.d.ts.map +1 -1
- package/out/address/point/interpolation.js +5 -2
- package/out/address/point/interpolation.js.map +1 -1
- package/out/address/point.d.ts +5 -4
- package/out/address/point.d.ts.map +1 -1
- package/out/address/point.js +11 -10
- package/out/address/point.js.map +1 -1
- package/out/build/candidate.d.ts +7 -17
- package/out/build/candidate.d.ts.map +1 -1
- package/out/build/candidate.js +4 -11
- package/out/build/candidate.js.map +1 -1
- package/out/build/slim.js +1 -1
- package/out/build/slim.js.map +1 -1
- package/out/candidate/importance.js +1 -1
- package/out/candidate/importance.js.map +1 -1
- package/out/candidate/lookup.d.ts +8 -5
- package/out/candidate/lookup.d.ts.map +1 -1
- package/out/candidate/lookup.js +35 -25
- package/out/candidate/lookup.js.map +1 -1
- package/out/candidate/own-name.js +1 -1
- package/out/candidate/own-name.js.map +1 -1
- package/out/candidate/scoring.js +27 -25
- package/out/candidate/scoring.js.map +1 -1
- package/out/capitals.d.ts +1 -1
- package/out/capitals.d.ts.map +1 -1
- package/out/capitals.js.map +1 -1
- package/out/coincident-roles.d.ts +4 -4
- package/out/coincident-roles.d.ts.map +1 -1
- package/out/coincident-roles.js +11 -0
- package/out/coincident-roles.js.map +1 -1
- package/out/convention/schema.d.ts +2 -8
- package/out/convention/schema.d.ts.map +1 -1
- package/out/convention/schema.js.map +1 -1
- package/out/convention.d.ts +4 -4
- package/out/convention.d.ts.map +1 -1
- package/out/convention.js +3 -3
- package/out/convention.js.map +1 -1
- package/out/coverage-manifest-schema.d.ts +1 -1
- package/out/coverage-manifest-schema.d.ts.map +1 -1
- package/out/coverage-manifest-schema.js +5 -5
- package/out/coverage-manifest-schema.js.map +1 -1
- package/out/currency-backfill.d.ts +6 -6
- package/out/currency-backfill.d.ts.map +1 -1
- package/out/currency-backfill.js +7 -7
- package/out/currency-backfill.js.map +1 -1
- package/out/exact-match.js +1 -1
- package/out/exact-match.js.map +1 -1
- package/out/extracts.d.ts +1 -1
- package/out/extracts.d.ts.map +1 -1
- package/out/extracts.js.map +1 -1
- package/out/fst/autocomplete.d.ts +1 -1
- package/out/fst/autocomplete.d.ts.map +1 -1
- package/out/fst/autocomplete.js +1 -1
- package/out/fst/autocomplete.js.map +1 -1
- package/out/fst/builder.d.ts.map +1 -1
- package/out/fst/builder.js +9 -7
- package/out/fst/builder.js.map +1 -1
- package/out/fst/deserialize-web.d.ts +1 -1
- package/out/fst/deserialize-web.d.ts.map +1 -1
- package/out/fst/deserialize-web.js +7 -7
- package/out/fst/deserialize-web.js.map +1 -1
- package/out/fst/freshness.d.ts +9 -9
- package/out/fst/freshness.d.ts.map +1 -1
- package/out/fst/freshness.js +19 -18
- package/out/fst/freshness.js.map +1 -1
- package/out/fst/matcher.d.ts +4 -3
- package/out/fst/matcher.d.ts.map +1 -1
- package/out/fst/matcher.js.map +1 -1
- package/out/fst/serialize.d.ts +1 -5
- package/out/fst/serialize.d.ts.map +1 -1
- package/out/fst/serialize.js +11 -15
- package/out/fst/serialize.js.map +1 -1
- package/out/fst/types.d.ts +14 -22
- package/out/fst/types.d.ts.map +1 -1
- package/out/fst.d.ts +1 -0
- package/out/fst.d.ts.map +1 -1
- package/out/fst.js +1 -0
- package/out/fst.js.map +1 -1
- package/out/fts.js +1 -1
- package/out/fts.js.map +1 -1
- package/out/geonames/aliases.d.ts +1 -1
- package/out/geonames/aliases.d.ts.map +1 -1
- package/out/geonames/aliases.js +2 -2
- package/out/geonames/aliases.js.map +1 -1
- package/out/geonames/postal.js +1 -1
- package/out/geonames/postal.js.map +1 -1
- package/out/index.d.ts +3 -2
- package/out/index.d.ts.map +1 -1
- package/out/index.js +1 -0
- package/out/index.js.map +1 -1
- package/out/interpolation.d.ts +4 -4
- package/out/interpolation.d.ts.map +1 -1
- package/out/interpolation.js +4 -3
- package/out/interpolation.js.map +1 -1
- package/out/lookup.d.ts +4 -3
- package/out/lookup.d.ts.map +1 -1
- package/out/lookup.js +22 -14
- package/out/lookup.js.map +1 -1
- package/out/nsul/lookup.js.map +1 -1
- package/out/place-importance-schema.d.ts +2 -2
- package/out/place-importance-schema.d.ts.map +1 -1
- package/out/place-importance-schema.js +3 -3
- package/out/place-importance-schema.js.map +1 -1
- package/out/poi/lookup.d.ts +10 -13
- package/out/poi/lookup.d.ts.map +1 -1
- package/out/poi/lookup.js +3 -7
- package/out/poi/lookup.js.map +1 -1
- package/out/postcode-point-lookup.d.ts +1 -9
- package/out/postcode-point-lookup.d.ts.map +1 -1
- package/out/postcode-point-lookup.js.map +1 -1
- package/out/primary-preference.js +2 -2
- package/out/primary-preference.js.map +1 -1
- package/out/proximity-rerank.d.ts +1 -1
- package/out/proximity-rerank.d.ts.map +1 -1
- package/out/ranking-weights.d.ts +15 -10
- package/out/ranking-weights.d.ts.map +1 -1
- package/out/ranking-weights.js.map +1 -1
- package/out/region-keys.d.ts +2 -2
- package/out/region-keys.d.ts.map +1 -1
- package/out/region-keys.js.map +1 -1
- package/out/reverse.d.ts +7 -4
- package/out/reverse.d.ts.map +1 -1
- package/out/reverse.js +38 -13
- package/out/reverse.js.map +1 -1
- package/out/schema.d.ts +2 -11
- package/out/schema.d.ts.map +1 -1
- package/out/sqlite/convention-source.d.ts +1 -1
- package/out/sqlite/convention-source.d.ts.map +1 -1
- package/out/sqlite/convention-source.js +2 -2
- package/out/sqlite/convention-source.js.map +1 -1
- package/out/sqlite/utils.d.ts +1 -1
- package/out/sqlite/utils.d.ts.map +1 -1
- package/out/street/centroid.js +1 -1
- package/out/street/centroid.js.map +1 -1
- package/out/street/morphology/fst/builder.d.ts +3 -3
- package/out/street/morphology/fst/builder.d.ts.map +1 -1
- package/out/street/morphology/fst/builder.js +13 -4
- package/out/street/morphology/fst/builder.js.map +1 -1
- package/out/street/morphology/fst/loader.d.ts +4 -4
- package/out/street/morphology/fst/loader.d.ts.map +1 -1
- package/out/street/morphology/fst/loader.js +4 -3
- package/out/street/morphology/fst/loader.js.map +1 -1
- package/out/street/name-lookup.d.ts +2 -2
- package/out/street/name-lookup.d.ts.map +1 -1
- package/out/street/name-lookup.js +2 -4
- package/out/street/name-lookup.js.map +1 -1
- package/out/street/normalize.js +3 -3
- package/out/street/normalize.js.map +1 -1
- package/out/street/segment-schema.d.ts +2 -2
- package/out/street/segment-schema.js +2 -2
- package/out/types.d.ts +16 -12
- package/out/types.d.ts.map +1 -1
- package/out/uprn/lookup.js +1 -1
- package/out/uprn/lookup.js.map +1 -1
- package/out/weights-overlay-linker.d.ts +9 -6
- package/out/weights-overlay-linker.d.ts.map +1 -1
- package/out/weights-overlay-linker.js +21 -7
- package/out/weights-overlay-linker.js.map +1 -1
- package/package.json +13 -13
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
* `fst-street-morphology.bin`.
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
import {
|
|
27
|
+
import { readLocalTextFile } from "@mailwoman/core/fs/readers"
|
|
28
|
+
import { isDirectory, isFile } from "@mailwoman/core/fs/readers/stat"
|
|
28
29
|
import { PathBuilder, type PathBuilderLike } from "path-ts"
|
|
29
30
|
import { TextSpliterator } from "spliterator"
|
|
30
31
|
import { Globerator } from "spliterator/node/fs"
|
|
@@ -52,14 +53,12 @@ export interface BuildStreetMorphologyFSTOpts {
|
|
|
52
53
|
/**
|
|
53
54
|
* Optional locale filter — only ingest these locale subfolders.
|
|
54
55
|
*
|
|
55
|
-
*
|
|
56
|
+
* @defaultValue all that have a `street_types.txt`.
|
|
56
57
|
*/
|
|
57
58
|
locales?: string[]
|
|
58
59
|
/**
|
|
59
60
|
* Minimum length (in characters, post-normalization) of variant surface forms to insert into the trie.
|
|
60
61
|
*
|
|
61
|
-
* Defaults to 3.
|
|
62
|
-
*
|
|
63
62
|
* Rationale: libpostal's street_types dictionaries contain 1-2 character abbreviations
|
|
64
63
|
* (`a`, `b`, `av`, `bd`, `br`, ...) that collide with non-affix tokens at parse time,
|
|
65
64
|
* including US state abbreviations (`or`, `CA`, `ND`, `NY`).
|
|
@@ -69,6 +68,8 @@ export interface BuildStreetMorphologyFSTOpts {
|
|
|
69
68
|
* abbreviations as `street_suffix`.
|
|
70
69
|
*
|
|
71
70
|
* A minimum length of 3 retains useful forms (`ave`, `blvd`, `rue`, `str`) while filtering out the noise.
|
|
71
|
+
*
|
|
72
|
+
* @defaultValue `3`
|
|
72
73
|
*/
|
|
73
74
|
minVariantLength?: number
|
|
74
75
|
/**
|
|
@@ -97,7 +98,7 @@ export interface BuildStreetMorphologyFSTResult {
|
|
|
97
98
|
function parseLine(line: string): { canonical: string; variants: string[] } | null {
|
|
98
99
|
const trimmed = line.trim()
|
|
99
100
|
|
|
100
|
-
if (!trimmed
|
|
101
|
+
if (!trimmed || trimmed.startsWith("#")) return null
|
|
101
102
|
|
|
102
103
|
const parts = TextSpliterator.from(trimmed, { delimiter: "|" }).toArray()
|
|
103
104
|
|
|
@@ -223,11 +224,12 @@ export async function buildStreetMorphologyFST(
|
|
|
223
224
|
// (Avenue is almost never anything but street-typing).
|
|
224
225
|
// The morphology prior caps bias separately.
|
|
225
226
|
// This value just feeds the cap formula `referential * cap`.
|
|
226
|
-
// No encyclopedic
|
|
227
|
-
// Absence here is the correct statement.
|
|
227
|
+
// No encyclopedic score — a street affix is not a place and has no article.
|
|
228
228
|
referential: 1,
|
|
229
|
+
encyclopedic: null,
|
|
229
230
|
lat: 0,
|
|
230
231
|
lon: 0,
|
|
232
|
+
crossCountryBranches: null,
|
|
231
233
|
}
|
|
232
234
|
|
|
233
235
|
for (const variant of variants) {
|
|
@@ -260,7 +262,14 @@ export async function buildStreetMorphologyFST(
|
|
|
260
262
|
edgeCount,
|
|
261
263
|
nameInsertions: insertCount,
|
|
262
264
|
importanceMatches: 0, // No importance scoring for morphology — fixed at 1.0.
|
|
265
|
+
encyclopedicMatches: null,
|
|
266
|
+
importanceSource: null,
|
|
263
267
|
sourceDB: dictionariesDir.toString(),
|
|
268
|
+
sourceDBMD5: null,
|
|
269
|
+
sourceDBBytes: null,
|
|
270
|
+
modelCardVersion: null,
|
|
271
|
+
exclusionPolicy: null,
|
|
272
|
+
excludedInsertions: null,
|
|
264
273
|
}
|
|
265
274
|
|
|
266
275
|
return {
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
* artifact through `fst-deserialize-web.ts` (see the docs demo loader).
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
import {
|
|
22
|
+
import { readLocalBuffer } from "@mailwoman/core/fs/readers"
|
|
23
|
+
import { pathExists } from "@mailwoman/core/fs/readers/stat"
|
|
23
24
|
import { resourceDictionaryPath } from "@mailwoman/core/paths"
|
|
24
25
|
import type { PathBuilder, PathBuilderLike } from "path-ts"
|
|
25
26
|
|
|
@@ -53,13 +54,13 @@ export interface LoadStreetMorphologyFSTOpts {
|
|
|
53
54
|
/**
|
|
54
55
|
* Dictionaries dir for the build fallback.
|
|
55
56
|
*
|
|
56
|
-
*
|
|
57
|
+
* @defaultValue core's bundled libpostal dictionaries.
|
|
57
58
|
*/
|
|
58
59
|
dictionariesDir?: PathBuilderLike
|
|
59
60
|
/**
|
|
60
61
|
* Unreadable-artifact diagnostics.
|
|
61
62
|
*
|
|
62
|
-
*
|
|
63
|
+
* @defaultValue silent (the caller owns its warn channel).
|
|
63
64
|
*/
|
|
64
65
|
onWarn?: (message: string) => void
|
|
65
66
|
}
|
|
@@ -73,11 +74,11 @@ export interface LoadedStreetMorphologyFST {
|
|
|
73
74
|
/**
|
|
74
75
|
* The artifact path when `source === "artifact"`.
|
|
75
76
|
*/
|
|
76
|
-
path
|
|
77
|
+
path: PathBuilderLike | null
|
|
77
78
|
/**
|
|
78
79
|
* Build provenance, read from the artifact trailer or copied from the fallback build.
|
|
79
80
|
*/
|
|
80
|
-
provenance
|
|
81
|
+
provenance: FSTProvenance | null
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
/**
|
|
@@ -96,7 +97,7 @@ export async function loadStreetMorphologyFST(
|
|
|
96
97
|
const matcher = deserializeFST(buf)
|
|
97
98
|
const provenance = readFSTProvenance(buf)
|
|
98
99
|
|
|
99
|
-
return { matcher, source: "artifact", path: artifactPath,
|
|
100
|
+
return { matcher, source: "artifact", path: artifactPath, provenance }
|
|
100
101
|
} catch (error) {
|
|
101
102
|
warn(
|
|
102
103
|
`street-morphology artifact at ${artifactPath} unreadable (${(error as Error).message}) — falling back to the dictionary build`
|
|
@@ -108,5 +109,5 @@ export async function loadStreetMorphologyFST(
|
|
|
108
109
|
dictionariesDir: (opts.dictionariesDir ?? resourceDictionaryPath("libpostal")).toString(),
|
|
109
110
|
})
|
|
110
111
|
|
|
111
|
-
return { matcher: built.matcher, source: "built", provenance: built.provenance }
|
|
112
|
+
return { matcher: built.matcher, source: "built", path: null, provenance: built.provenance }
|
|
112
113
|
}
|
|
@@ -29,13 +29,13 @@ export interface SQLiteStreetNameLookupOpts {
|
|
|
29
29
|
/**
|
|
30
30
|
* ISO-2 (upper-case) countries this index answers for.
|
|
31
31
|
*
|
|
32
|
-
*
|
|
32
|
+
* @defaultValue `["FR"]` (the BAN street-centroids instance).
|
|
33
33
|
*/
|
|
34
34
|
countries?: Iterable<string>
|
|
35
35
|
/**
|
|
36
36
|
* Table name.
|
|
37
37
|
*
|
|
38
|
-
*
|
|
38
|
+
* @defaultValue `street_centroid`
|
|
39
39
|
*/
|
|
40
40
|
table?: string
|
|
41
41
|
}
|
|
@@ -88,15 +88,11 @@ export class SQLiteStreetNameLookup extends SQLiteLookup<WOFDatabase> implements
|
|
|
88
88
|
// Scoped lookups tighten precision when the hypothesis includes a locality/postcode.
|
|
89
89
|
// A scoped miss falls back to the unscoped probe.
|
|
90
90
|
// The scope column may be incomplete, so a miss there does not establish absence.
|
|
91
|
-
if (
|
|
92
|
-
scope?.locality &&
|
|
93
|
-
this.#byNameLocality &&
|
|
94
|
-
this.#byNameLocality.get(norm, foldStreetSurface(scope.locality)) !== undefined
|
|
95
|
-
) {
|
|
91
|
+
if (scope?.locality && this.#byNameLocality && this.#byNameLocality.get(norm, foldStreetSurface(scope.locality))) {
|
|
96
92
|
return true
|
|
97
93
|
}
|
|
98
94
|
|
|
99
|
-
if (scope?.postcode && this.#byNamePostcode && this.#byNamePostcode.get(norm, scope.postcode)
|
|
95
|
+
if (scope?.postcode && this.#byNamePostcode && this.#byNamePostcode.get(norm, scope.postcode)) {
|
|
100
96
|
return true
|
|
101
97
|
}
|
|
102
98
|
|
package/lib/street/normalize.ts
CHANGED
|
@@ -377,7 +377,7 @@ export function stripLocalityQualifier(locality: string): string {
|
|
|
377
377
|
}
|
|
378
378
|
|
|
379
379
|
const words = [...s.matchAll(/\S+/gu)].map((match) => ({ value: match[0], index: match.index }))
|
|
380
|
-
let qualifierStart: number |
|
|
380
|
+
let qualifierStart: number | null = null
|
|
381
381
|
|
|
382
382
|
for (let index = 1; index < words.length; index++) {
|
|
383
383
|
const word = words[index]!
|
|
@@ -400,7 +400,7 @@ export function stripLocalityQualifier(locality: string): string {
|
|
|
400
400
|
const suffix = words.at(-1)
|
|
401
401
|
|
|
402
402
|
if (
|
|
403
|
-
qualifierStart ===
|
|
403
|
+
qualifierStart === null &&
|
|
404
404
|
suffix &&
|
|
405
405
|
words.length > 1 &&
|
|
406
406
|
(["S", "N", "E", "W", "V", "Ø", "Sø", "Fyn", "Thy", "Sjælland", "Jylland"].includes(suffix.value) ||
|
|
@@ -409,7 +409,7 @@ export function stripLocalityQualifier(locality: string): string {
|
|
|
409
409
|
qualifierStart = suffix.index
|
|
410
410
|
}
|
|
411
411
|
|
|
412
|
-
if (qualifierStart !==
|
|
412
|
+
if (qualifierStart !== null) {
|
|
413
413
|
s = s.slice(0, qualifierStart).trimEnd()
|
|
414
414
|
}
|
|
415
415
|
|
|
@@ -214,7 +214,7 @@ const STREET_SEGMENT_CLUSTER_ORDER = "street_norm, postcode, min_hn, max_hn, row
|
|
|
214
214
|
*
|
|
215
215
|
* `street_segment` stays a rowid table, because `postcode` is nullable.
|
|
216
216
|
* A `WITHOUT ROWID` primary key forbids a null column.
|
|
217
|
-
*
|
|
217
|
+
* A load in key order gives the same page locality.
|
|
218
218
|
*
|
|
219
219
|
* Run {@link createStreetSegmentIndexes} and `VACUUM` afterwards.
|
|
220
220
|
*/
|
|
@@ -233,7 +233,7 @@ export async function clusterStreetSegments(db: Kysely<StreetSegmentDatabase>):
|
|
|
233
233
|
/**
|
|
234
234
|
* Create the two probe indexes the readers use (postcode-scope, street-scope).
|
|
235
235
|
*
|
|
236
|
-
* Each index
|
|
236
|
+
* Each index holds `max_hn`.
|
|
237
237
|
* SQLite therefore rejects a range ending below the house number from the index entry.
|
|
238
238
|
* The rejected row's table page is never fetched.
|
|
239
239
|
*/
|
package/lib/types.ts
CHANGED
|
@@ -45,69 +45,74 @@ export interface PlaceCandidate {
|
|
|
45
45
|
* The place's depth-1 ancestor id from the ancestors sidecar, absent when the
|
|
46
46
|
* artifact has no sidecar even for a place with a parent.
|
|
47
47
|
*/
|
|
48
|
-
parent_id
|
|
48
|
+
parent_id: number | null
|
|
49
49
|
score: number
|
|
50
|
-
distanceKm
|
|
50
|
+
distanceKm: number | null
|
|
51
51
|
|
|
52
52
|
/**
|
|
53
53
|
* Whether the candidate's name or an alias exactly equals the query, used by a
|
|
54
54
|
* later re-rank to stay within the exact-match tier.
|
|
55
55
|
*/
|
|
56
|
-
exactMatch
|
|
56
|
+
exactMatch: boolean | null
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
59
|
* The population term plus the best proximity-bias term.
|
|
60
60
|
*
|
|
61
61
|
* The exact tier sorts by this value instead of population when the query has `near` or `bias`.
|
|
62
62
|
*/
|
|
63
|
-
prominence
|
|
63
|
+
prominence: number | null
|
|
64
64
|
|
|
65
65
|
/**
|
|
66
66
|
* The WOF `wof:population` value, absent when the population is unknown.
|
|
67
67
|
*/
|
|
68
|
-
population
|
|
68
|
+
population: number | null
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
71
|
* The referential likelihood in [0, 1], derived from {@link PlaceCandidate.population}
|
|
72
72
|
* and absent whenever it is.
|
|
73
73
|
*/
|
|
74
|
-
referential
|
|
74
|
+
referential: number | null
|
|
75
75
|
|
|
76
76
|
/**
|
|
77
77
|
* The encyclopedia-evidence importance in [0, 1], used for display only and present only
|
|
78
78
|
* when the extract's `place_importance` table has the split columns.
|
|
79
79
|
*/
|
|
80
|
-
encyclopedic
|
|
80
|
+
encyclopedic: number | null
|
|
81
81
|
|
|
82
82
|
/**
|
|
83
83
|
* The blended toponym prior in [0, 1] that `rankByImportance` reads for bare toponyms,
|
|
84
84
|
* set only by the candidate-table backend.
|
|
85
85
|
*/
|
|
86
|
-
importance
|
|
86
|
+
importance: number | null
|
|
87
87
|
|
|
88
88
|
/**
|
|
89
89
|
* The bounding box from the WOF `spr` extent columns, omitted when the schema lacks them.
|
|
90
90
|
*/
|
|
91
|
-
bbox
|
|
91
|
+
bbox: LatLonBounds | null
|
|
92
92
|
|
|
93
93
|
/**
|
|
94
94
|
* Set by the postcode path when the chosen locality is far from the postcode's own
|
|
95
95
|
* locality. the candidate is still returned so callers can lower their confidence.
|
|
96
96
|
*/
|
|
97
|
-
mismatch
|
|
97
|
+
mismatch: boolean | null
|
|
98
98
|
|
|
99
99
|
/**
|
|
100
100
|
* Whether the ancestors sidecar places this candidate under the query's
|
|
101
101
|
* {@link FindPlaceQuery.regionQualifier}, with `false` meaning the check ran
|
|
102
102
|
* and an absent value meaning it did not.
|
|
103
103
|
*/
|
|
104
|
-
containedByQualifier
|
|
104
|
+
containedByQualifier: boolean | null
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Set when the candidate lies outside the query's parent scope, so callers can demote it.
|
|
108
|
+
*/
|
|
109
|
+
regionScopeMiss: boolean | null
|
|
105
110
|
|
|
106
111
|
/**
|
|
107
112
|
* Set when the variant exemption spared the candidate from the cross-country
|
|
108
113
|
* alias penalty, by the candidate-table backend only.
|
|
109
114
|
*/
|
|
110
|
-
variantAliasExempted
|
|
115
|
+
variantAliasExempted: true | null
|
|
111
116
|
}
|
|
112
117
|
|
|
113
118
|
/**
|
package/lib/uprn/lookup.ts
CHANGED
|
@@ -150,7 +150,7 @@ export class UPRNLookup implements Disposable {
|
|
|
150
150
|
for (const row of rows) {
|
|
151
151
|
const distanceM = haversineKm(latitude, longitude, row.lat, row.lon) * 1000
|
|
152
152
|
|
|
153
|
-
if (distanceM <= radiusM && (best
|
|
153
|
+
if (distanceM <= radiusM && (!best || distanceM < best.distanceM)) {
|
|
154
154
|
best = { uprn: row.uprn, latitude: row.lat, longitude: row.lon, distanceM }
|
|
155
155
|
}
|
|
156
156
|
}
|
|
@@ -5,14 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { dataRootPath, weightsOverlayPath } from "@mailwoman/core/data-root"
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
readLocalJSONFile,
|
|
11
|
-
readLocalTextFile,
|
|
12
|
-
statPath,
|
|
13
|
-
readLocalBuffer,
|
|
14
|
-
statLink,
|
|
15
|
-
} from "@mailwoman/core/fs/readers"
|
|
8
|
+
import { readLocalJSONFile, readLocalTextFile, readLocalBuffer } from "@mailwoman/core/fs/readers"
|
|
9
|
+
import { pathExists, statPath, statLink } from "@mailwoman/core/fs/readers/stat"
|
|
16
10
|
import {
|
|
17
11
|
createSymbolicLink,
|
|
18
12
|
makeDirectories,
|
|
@@ -140,24 +134,27 @@ export interface PairIndexOverlay {
|
|
|
140
134
|
|
|
141
135
|
/**
|
|
142
136
|
* The source files whose MD5s the build records, in the order that `gazetteer pair-index` records them.
|
|
143
|
-
* The default is the WOF admin database.
|
|
144
137
|
*
|
|
145
138
|
* The freshness check compares each MD5 with the header.
|
|
146
139
|
* An empty list makes the check compare the magnitudes only.
|
|
140
|
+
*
|
|
141
|
+
* @defaultValue the WOF admin database.
|
|
147
142
|
*/
|
|
148
143
|
sources?: PathBuilder[]
|
|
149
144
|
|
|
150
145
|
/**
|
|
151
146
|
* Files that must exist before a build runs.
|
|
152
147
|
*
|
|
153
|
-
* The default is `sources`.
|
|
154
148
|
* A missing file prints a warning and skips the build.
|
|
149
|
+
*
|
|
150
|
+
* @defaultValue `sources`
|
|
155
151
|
*/
|
|
156
152
|
inputs?: PathBuilder[]
|
|
157
153
|
|
|
158
154
|
/**
|
|
159
155
|
* Extra CLI arguments that pass the build's sources.
|
|
160
|
-
*
|
|
156
|
+
*
|
|
157
|
+
* @defaultValue `--borough-db <admin db>`
|
|
161
158
|
*/
|
|
162
159
|
extraArgs?: PathBuilderLike[]
|
|
163
160
|
|
|
@@ -268,10 +265,7 @@ export interface PairIndexCalibration {
|
|
|
268
265
|
*
|
|
269
266
|
* The caller checks the source MD5s because only the caller knows its sources.
|
|
270
267
|
*/
|
|
271
|
-
export function pairIndexStaleReason(
|
|
272
|
-
header: PairIndexHeaderFields,
|
|
273
|
-
expected: PairIndexCalibration
|
|
274
|
-
): string | undefined {
|
|
268
|
+
export function pairIndexStaleReason(header: PairIndexHeaderFields, expected: PairIndexCalibration): string | null {
|
|
275
269
|
if (header.schemaVersion !== REQUIRED_PAIR_INDEX_SCHEMA) {
|
|
276
270
|
return `schemaVersion ${header.schemaVersion} → ${REQUIRED_PAIR_INDEX_SCHEMA}`
|
|
277
271
|
}
|
|
@@ -286,7 +280,7 @@ export function pairIndexStaleReason(
|
|
|
286
280
|
return `parentDelta ${header.parentDelta ?? "(absent)"} → ${expected.parentDelta ?? "(absent)"}`
|
|
287
281
|
}
|
|
288
282
|
|
|
289
|
-
return
|
|
283
|
+
return null
|
|
290
284
|
}
|
|
291
285
|
|
|
292
286
|
/**
|
|
@@ -518,15 +512,15 @@ export interface SoftFeedLink {
|
|
|
518
512
|
export async function committedSoftFeedLinks(): Promise<{
|
|
519
513
|
anchor: SoftFeedLink
|
|
520
514
|
country: SoftFeedLink
|
|
521
|
-
streetType
|
|
515
|
+
streetType: SoftFeedLink | null
|
|
522
516
|
}> {
|
|
523
517
|
const config = await readReleaseConfig()
|
|
524
518
|
const sources = repoCommittedSoftFeedSources(repoRootPath(), config.softFeed ?? {})
|
|
525
519
|
|
|
526
|
-
const link = (name: string, consequenceIfMissing: string): SoftFeedLink |
|
|
520
|
+
const link = (name: string, consequenceIfMissing: string): SoftFeedLink | null => {
|
|
527
521
|
const source = sources.get(name)
|
|
528
522
|
|
|
529
|
-
return source ? { source, name, consequenceIfMissing } :
|
|
523
|
+
return source ? { source, name, consequenceIfMissing } : null
|
|
530
524
|
}
|
|
531
525
|
|
|
532
526
|
const anchor = link("anchor-lexicon-v1.json", "gazetteer channel will resolve OFF in this worktree.")
|
|
@@ -540,7 +534,7 @@ export async function committedSoftFeedLinks(): Promise<{
|
|
|
540
534
|
|
|
541
535
|
const streetType = link("street-type-lexicon-v3.json", "the street_type channel will resolve OFF in this worktree.")
|
|
542
536
|
|
|
543
|
-
return { anchor, country,
|
|
537
|
+
return { anchor, country, streetType }
|
|
544
538
|
}
|
|
545
539
|
|
|
546
540
|
/**
|
|
@@ -631,7 +625,7 @@ export interface DevOverlayManifest {
|
|
|
631
625
|
export interface DevOverlay {
|
|
632
626
|
destDir: PathBuilder
|
|
633
627
|
cli: PathBuilder
|
|
634
|
-
card: WeightsCard |
|
|
628
|
+
card: WeightsCard | null
|
|
635
629
|
}
|
|
636
630
|
|
|
637
631
|
const EVIDENCE_LEXICON_SOURCES: ReadonlyArray<{
|
|
@@ -642,10 +636,23 @@ const EVIDENCE_LEXICON_SOURCES: ReadonlyArray<{
|
|
|
642
636
|
{ channel: "locality_surface", source: (name) => dataRootPath("gazetteer", name) },
|
|
643
637
|
]
|
|
644
638
|
|
|
645
|
-
|
|
639
|
+
/**
|
|
640
|
+
* Whether the locale's workspace package declares `mailwoman.baseWeights`.
|
|
641
|
+
*/
|
|
642
|
+
async function declaresBaseWeights(locale: string): Promise<boolean> {
|
|
643
|
+
const path = workspacePathBuilder(`neural-weights-${locale}`, "package.json")
|
|
644
|
+
|
|
645
|
+
if (!(await pathExists(path))) return false
|
|
646
|
+
|
|
647
|
+
const { mailwoman } = await readLocalJSONFile<{ mailwoman?: { baseWeights?: unknown } }>(path)
|
|
648
|
+
|
|
649
|
+
return typeof mailwoman?.baseWeights === "string" && mailwoman.baseWeights.length > 0
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
async function readWeightsCard(workspace: string): Promise<WeightsCard | null> {
|
|
646
653
|
const path = workspacePathBuilder(workspace, "model-card.json")
|
|
647
654
|
|
|
648
|
-
if (!(await pathExists(path))) return
|
|
655
|
+
if (!(await pathExists(path))) return null
|
|
649
656
|
|
|
650
657
|
return readLocalJSONFile<WeightsCard>(path)
|
|
651
658
|
}
|
|
@@ -680,7 +687,7 @@ async function linkCharModel(destDir: PathBuilder, family: string): Promise<void
|
|
|
680
687
|
await removeIfPresent(destDir("tokenizer.model"))
|
|
681
688
|
}
|
|
682
689
|
|
|
683
|
-
async function linkBaseModelPair(destDir: PathBuilder, digestCard: string |
|
|
690
|
+
async function linkBaseModelPair(destDir: PathBuilder, digestCard: string | null): Promise<void> {
|
|
684
691
|
const recipe = await readReleaseConfig()
|
|
685
692
|
|
|
686
693
|
const dataRoot = dataRootPath()
|
|
@@ -800,11 +807,16 @@ export async function materializeDevOverlay(manifest: DevOverlayManifest): Promi
|
|
|
800
807
|
|
|
801
808
|
await makeDirectories(destDir)
|
|
802
809
|
|
|
803
|
-
|
|
810
|
+
// A package that declares `mailwoman.baseWeights` inherits its graph whatever the manifest says,
|
|
811
|
+
// because `resolveWeights` takes the base's graph over a file in the overlay directory.
|
|
812
|
+
const inherits =
|
|
813
|
+
manifest.model?.kind === "inherit" || (!manifest.model && (await declaresBaseWeights(manifest.locale)))
|
|
814
|
+
|
|
815
|
+
if (inherits) {
|
|
804
816
|
await removeIfPresent(destDir("model.onnx"))
|
|
805
817
|
await removeIfPresent(destDir("tokenizer.model"))
|
|
806
818
|
} else if (manifest.model?.kind === "link") {
|
|
807
|
-
await linkBaseModelPair(destDir, manifest.model.digestCard)
|
|
819
|
+
await linkBaseModelPair(destDir, manifest.model.digestCard ?? null)
|
|
808
820
|
} else if (manifest.model?.kind === "char") {
|
|
809
821
|
await linkCharModel(destDir, manifest.model.family)
|
|
810
822
|
}
|
|
@@ -39,6 +39,7 @@ export declare class AddressPointInterpolator<DB extends AddressPointDatabase =
|
|
|
39
39
|
database?: DatabaseClient<DB>;
|
|
40
40
|
fallback?: StreetInterpolator;
|
|
41
41
|
});
|
|
42
|
+
readonly radiusCalibration: null;
|
|
42
43
|
find(query: InterpolationQuery): InterpolatedHit | null;
|
|
43
44
|
[Symbol.dispose](): void;
|
|
44
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interpolation.d.ts","sourceRoot":"","sources":["../../../lib/address/point/interpolation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAEnE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAEzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AA8B7F,qBAAa,wBAAwB,CACpC,EAAE,SAAS,oBAAoB,GAAG,oBAAoB,CACrD,YAAW,mBAAmB;;IAY/B,YAAY,IAAI,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC;QAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;KAAE,EA2BlG;IAED,IAAI,CAAC,KAAK,EAAE,kBAAkB,GAAG,eAAe,GAAG,IAAI,CAsBtD;IAED,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAEvB;CACD"}
|
|
1
|
+
{"version":3,"file":"interpolation.d.ts","sourceRoot":"","sources":["../../../lib/address/point/interpolation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAEnE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAEzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AA8B7F,qBAAa,wBAAwB,CACpC,EAAE,SAAS,oBAAoB,GAAG,oBAAoB,CACrD,YAAW,mBAAmB;;IAY/B,YAAY,IAAI,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC;QAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;KAAE,EA2BlG;IAED,QAAQ,CAAC,iBAAiB,OAAO;IAEjC,IAAI,CAAC,KAAK,EAAE,kBAAkB,GAAG,eAAe,GAAG,IAAI,CAsBtD;IAED,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAEvB;CACD"}
|
|
@@ -73,6 +73,7 @@ export class AddressPointInterpolator {
|
|
|
73
73
|
}
|
|
74
74
|
this.#resources = resources.move();
|
|
75
75
|
}
|
|
76
|
+
radiusCalibration = null;
|
|
76
77
|
find(query) {
|
|
77
78
|
const numberRaw = query.number.trim();
|
|
78
79
|
if (!/^\d+$/.test(numberRaw))
|
|
@@ -123,8 +124,8 @@ function interpolateFromNeighbors(rows, n) {
|
|
|
123
124
|
const anchors = anchorsByNumber(rows);
|
|
124
125
|
// Nearest known number below and above the query.
|
|
125
126
|
// The rows never contain n itself.
|
|
126
|
-
let below;
|
|
127
|
-
let above;
|
|
127
|
+
let below = null;
|
|
128
|
+
let above = null;
|
|
128
129
|
for (const anchor of anchors) {
|
|
129
130
|
if (anchor.n < n) {
|
|
130
131
|
below = anchor;
|
|
@@ -142,6 +143,7 @@ function interpolateFromNeighbors(rows, n) {
|
|
|
142
143
|
lon: below.lon + (above.lon - below.lon) * t,
|
|
143
144
|
interpolated: true,
|
|
144
145
|
method: "address_point",
|
|
146
|
+
parityMatched: null,
|
|
145
147
|
bracket: "both",
|
|
146
148
|
uncertaintyM: Math.round(spanM / 2),
|
|
147
149
|
source: below.source,
|
|
@@ -166,6 +168,7 @@ function interpolateFromNeighbors(rows, n) {
|
|
|
166
168
|
lon,
|
|
167
169
|
interpolated: true,
|
|
168
170
|
method: "address_point",
|
|
171
|
+
parityMatched: null,
|
|
169
172
|
bracket: "single",
|
|
170
173
|
// Explicitly larger than the both-sided radius: the whole pair span plus the overshoot.
|
|
171
174
|
uncertaintyM: Math.round(pairM + overshootM),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interpolation.js","sourceRoot":"","sources":["../../../lib/address/point/interpolation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAIzD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAoB,MAAM,eAAe,CAAA;AACtE,OAAO,EAAE,oBAAoB,EAAiB,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAC1F;;;;;GAKG;AACH,MAAM,mBAAmB,GAAG,CAAC,CAAA;AAqB7B,MAAM,OAAO,wBAAwB;IAG3B,GAAG,CAAoB;IAChC;;;;;OAKG;IACM,UAAU,CAAiB;IAC3B,SAAS,CAAgC;IACzC,WAAW,CAAyF;IAE7G,YAAY,IAAuF;QAClG,MAAM,SAAS,GAAG,IAAI,eAAe,EAAE,CAAA;QAEvC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAA;QACzB,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACxB,IAAI,CAAC,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,cAAc,CAAK,IAAI,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QAClF,CAAC;aAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAA;QACnF,CAAC;QAED,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAA;QAE9B,qEAAqE;QACrE,+FAA+F;QAC/F,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,EAAE,CAAC;YACzC,IAAI,CAAC,WAAW,GAAG,UAAU,CAC5B,IAAI,CAAC,GAAG,EACR;;;;sCAIkC,CAClC,CAAA;QACF,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC,IAAI,EAAE,CAAA;IACnC,CAAC;
|
|
1
|
+
{"version":3,"file":"interpolation.js","sourceRoot":"","sources":["../../../lib/address/point/interpolation.ts"],"names":[],"mappings":"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"}
|
package/out/address/point.d.ts
CHANGED
|
@@ -25,13 +25,14 @@ export declare class AddressPointSqliteLookup<DB extends AddressPointDatabase =
|
|
|
25
25
|
* @param dbPath Extract path.
|
|
26
26
|
* @param opts.streetLocale The street-normalization locale the extract was built with.
|
|
27
27
|
* A mismatch makes every key miss.
|
|
28
|
-
* It defaults to `"us"`.
|
|
29
28
|
* @param opts.localityKeys Whether the extract's `locality_norm` holds full place names.
|
|
30
29
|
* With `"abbreviated"`, a row's locality can select a row but never rejects one.
|
|
31
30
|
* The US situs extract uses NAD city fields.
|
|
32
31
|
* Some counties abbreviate them (`addi` for Addison).
|
|
33
32
|
* Other counties replace them with the parent town.
|
|
34
|
-
*
|
|
33
|
+
*
|
|
34
|
+
* @defaultValue `"us"`
|
|
35
|
+
* @defaultValue `"abbreviated"` for `"us"` and `"full"` for every other locale.
|
|
35
36
|
*/
|
|
36
37
|
constructor(dbPath: PathBuilderLike, opts?: {
|
|
37
38
|
streetLocale?: StreetLocale;
|
|
@@ -44,12 +45,12 @@ export declare class AddressPointSqliteLookup<DB extends AddressPointDatabase =
|
|
|
44
45
|
locality?: string;
|
|
45
46
|
region?: string;
|
|
46
47
|
subregion?: string;
|
|
47
|
-
bbox
|
|
48
|
+
bbox: {
|
|
48
49
|
minLat: number;
|
|
49
50
|
maxLat: number;
|
|
50
51
|
minLon: number;
|
|
51
52
|
maxLon: number;
|
|
52
|
-
};
|
|
53
|
+
} | null;
|
|
53
54
|
}): AddressPointHit | null;
|
|
54
55
|
[Symbol.dispose](): void;
|
|
55
56
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"point.d.ts","sourceRoot":"","sources":["../../lib/address/point.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAEnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAE9C,OAAO,KAAK,EAAE,oBAAoB,EAAqB,MAAM,uBAAuB,CAAA;AAEpF,OAAO,EASN,KAAK,YAAY,EACjB,MAAM,mBAAmB,CAAA;AAc1B;;;;;;;;;;GAUG;AACH,qBAAa,wBAAwB,CAAC,EAAE,SAAS,oBAAoB,GAAG,oBAAoB,CAC3F,YAAW,kBAAkB,EAAE,UAAU;;IAyBzC
|
|
1
|
+
{"version":3,"file":"point.d.ts","sourceRoot":"","sources":["../../lib/address/point.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAEnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAE9C,OAAO,KAAK,EAAE,oBAAoB,EAAqB,MAAM,uBAAuB,CAAA;AAEpF,OAAO,EASN,KAAK,YAAY,EACjB,MAAM,mBAAmB,CAAA;AAc1B;;;;;;;;;;GAUG;AACH,qBAAa,wBAAwB,CAAC,EAAE,SAAS,oBAAoB,GAAG,oBAAoB,CAC3F,YAAW,kBAAkB,EAAE,UAAU;;IAyBzC;;;;;;;;;;;;OAYG;IACH,YACC,MAAM,EAAE,eAAe,EACvB,IAAI,GAAE;QAAE,YAAY,CAAC,EAAE,YAAY,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,GAAG,aAAa,CAAA;KAAO,EAsCjF;IAED,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,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,IAAI,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAA;KAC/E,GAAG,eAAe,GAAG,IAAI,CAsCzB;IAyID,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAEvB;CACD"}
|
package/out/address/point.js
CHANGED
|
@@ -41,13 +41,14 @@ export class AddressPointSqliteLookup {
|
|
|
41
41
|
* @param dbPath Extract path.
|
|
42
42
|
* @param opts.streetLocale The street-normalization locale the extract was built with.
|
|
43
43
|
* A mismatch makes every key miss.
|
|
44
|
-
* It defaults to `"us"`.
|
|
45
44
|
* @param opts.localityKeys Whether the extract's `locality_norm` holds full place names.
|
|
46
45
|
* With `"abbreviated"`, a row's locality can select a row but never rejects one.
|
|
47
46
|
* The US situs extract uses NAD city fields.
|
|
48
47
|
* Some counties abbreviate them (`addi` for Addison).
|
|
49
48
|
* Other counties replace them with the parent town.
|
|
50
|
-
*
|
|
49
|
+
*
|
|
50
|
+
* @defaultValue `"us"`
|
|
51
|
+
* @defaultValue `"abbreviated"` for `"us"` and `"full"` for every other locale.
|
|
51
52
|
*/
|
|
52
53
|
constructor(dbPath, opts = {}) {
|
|
53
54
|
this.#db = new DatabaseClient(dbPath, { readOnly: true });
|
|
@@ -85,7 +86,7 @@ export class AddressPointSqliteLookup {
|
|
|
85
86
|
// `streetKeyVariants` yields the literal key first.
|
|
86
87
|
// Each variant runs the full number fallback sequence.
|
|
87
88
|
// The first variant with a match wins.
|
|
88
|
-
let row;
|
|
89
|
+
let row = null;
|
|
89
90
|
for (const streetNorm of streetKeyVariants(query.street, streetLocaleForSurface(query.street, this.#locale))) {
|
|
90
91
|
row = this.#findForKey(streetNorm, number, scoped);
|
|
91
92
|
if (row)
|
|
@@ -98,8 +99,8 @@ export class AddressPointSqliteLookup {
|
|
|
98
99
|
lon: row.lon,
|
|
99
100
|
source: row.source,
|
|
100
101
|
release: row.release,
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
localityNorm: row.locality_norm || null,
|
|
103
|
+
postcode: row.postcode || null,
|
|
103
104
|
};
|
|
104
105
|
}
|
|
105
106
|
/**
|
|
@@ -145,16 +146,16 @@ export class AddressPointSqliteLookup {
|
|
|
145
146
|
* Each scope runs only when the previous ones missed.
|
|
146
147
|
*/
|
|
147
148
|
#probe(streetNorm, number, query) {
|
|
148
|
-
let row;
|
|
149
|
+
let row = null;
|
|
149
150
|
if (query.postcode) {
|
|
150
151
|
const postcode = query.postcode.trim();
|
|
151
|
-
const localityKey = query.locality ? this.#localityKey(query.locality) :
|
|
152
|
+
const localityKey = query.locality ? this.#localityKey(query.locality) : null;
|
|
152
153
|
// One postcode can cover several places with the same street and number,
|
|
153
154
|
// so a row whose locality agrees with the query is tried first.
|
|
154
155
|
// The postcode-only row answers only if `#scopeContradicts` accepts it.
|
|
155
|
-
const agreeing = localityKey ? this.#byPostcodeLocality(postcode, localityKey, streetNorm, number) :
|
|
156
|
+
const agreeing = localityKey ? this.#byPostcodeLocality(postcode, localityKey, streetNorm, number) : null;
|
|
156
157
|
const candidate = agreeing ?? this.#byPostcode(postcode, streetNorm, number);
|
|
157
|
-
row = candidate && !this.#scopeContradicts(candidate, query) ? candidate :
|
|
158
|
+
row = candidate && !this.#scopeContradicts(candidate, query) ? candidate : null;
|
|
158
159
|
}
|
|
159
160
|
if (!row && query.locality) {
|
|
160
161
|
row = this.#byLocality(this.#localityKey(query.locality), streetNorm, number);
|
|
@@ -168,7 +169,7 @@ export class AddressPointSqliteLookup {
|
|
|
168
169
|
const b = query.bbox;
|
|
169
170
|
const candidate = this.#byBbox(streetNorm, number, b.minLat, b.maxLat, b.minLon, b.maxLon);
|
|
170
171
|
// A row with its own scope that the scoped probes missed is a different address in the same box.
|
|
171
|
-
row = candidate && !this.#scopeContradicts(candidate, query) ? candidate :
|
|
172
|
+
row = candidate && !this.#scopeContradicts(candidate, query) ? candidate : null;
|
|
172
173
|
}
|
|
173
174
|
return row;
|
|
174
175
|
}
|