@mailwoman/resolver-wof-sqlite 8.1.0 → 8.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/address-point-interpolation.ts +9 -3
- package/address-point-schema.ts +32 -10
- package/address-point.ts +3 -0
- package/ancestry-backfill.ts +18 -5
- package/ancestry.ts +7 -2
- package/build-candidate.ts +29 -6
- package/build-slim.ts +40 -11
- package/candidate-fts.ts +1 -0
- package/candidate-lookup.ts +36 -14
- package/candidate-schema.ts +35 -11
- package/coincident-roles.ts +28 -6
- package/convention.ts +3 -1
- package/coverage-manifest-schema.ts +49 -16
- package/fst-autocomplete.ts +15 -9
- package/fst-builder.ts +29 -5
- package/fst-deserialize-web.ts +46 -9
- package/fst-matcher.ts +12 -5
- package/fst-serialize.ts +83 -9
- package/fst-types.ts +26 -3
- package/fts-query.ts +84 -0
- package/fts.ts +35 -9
- package/geo.ts +9 -3
- package/geonames-aliases.ts +116 -79
- package/geonames-postal.ts +25 -5
- package/index.ts +10 -0
- package/interpolation.ts +33 -55
- package/lookup.ts +103 -292
- package/name-score.ts +76 -0
- package/out/address-point-interpolation.d.ts.map +1 -1
- package/out/address-point-interpolation.js +4 -2
- package/out/address-point-interpolation.js.map +1 -1
- package/out/address-point-schema.d.ts +30 -10
- package/out/address-point-schema.d.ts.map +1 -1
- package/out/address-point-schema.js +6 -2
- package/out/address-point-schema.js.map +1 -1
- package/out/address-point.d.ts.map +1 -1
- package/out/address-point.js.map +1 -1
- package/out/ancestry-backfill.d.ts +6 -2
- package/out/ancestry-backfill.d.ts.map +1 -1
- package/out/ancestry-backfill.js +7 -3
- package/out/ancestry-backfill.js.map +1 -1
- package/out/ancestry.d.ts +6 -2
- package/out/ancestry.d.ts.map +1 -1
- package/out/ancestry.js +3 -1
- package/out/ancestry.js.map +1 -1
- package/out/build-candidate.d.ts +9 -3
- package/out/build-candidate.d.ts.map +1 -1
- package/out/build-candidate.js +5 -3
- package/out/build-candidate.js.map +1 -1
- package/out/build-slim.d.ts +15 -5
- package/out/build-slim.d.ts.map +1 -1
- package/out/build-slim.js +11 -5
- package/out/build-slim.js.map +1 -1
- package/out/candidate-fts.d.ts.map +1 -1
- package/out/candidate-fts.js.map +1 -1
- package/out/candidate-lookup.d.ts +9 -3
- package/out/candidate-lookup.d.ts.map +1 -1
- package/out/candidate-lookup.js +16 -11
- package/out/candidate-lookup.js.map +1 -1
- package/out/candidate-schema.d.ts +33 -11
- package/out/candidate-schema.d.ts.map +1 -1
- package/out/candidate-schema.js.map +1 -1
- package/out/coincident-roles.d.ts +16 -4
- package/out/coincident-roles.d.ts.map +1 -1
- package/out/coincident-roles.js +9 -3
- package/out/coincident-roles.js.map +1 -1
- package/out/convention.d.ts +3 -1
- package/out/convention.d.ts.map +1 -1
- package/out/convention.js.map +1 -1
- package/out/coverage-manifest-schema.d.ts +45 -14
- package/out/coverage-manifest-schema.d.ts.map +1 -1
- package/out/coverage-manifest-schema.js +14 -5
- package/out/coverage-manifest-schema.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 +11 -9
- package/out/fst-autocomplete.js.map +1 -1
- package/out/fst-builder.d.ts.map +1 -1
- package/out/fst-builder.js +15 -5
- package/out/fst-builder.js.map +1 -1
- package/out/fst-deserialize-web.d.ts.map +1 -1
- package/out/fst-deserialize-web.js +34 -9
- package/out/fst-deserialize-web.js.map +1 -1
- package/out/fst-matcher.d.ts +6 -2
- package/out/fst-matcher.d.ts.map +1 -1
- package/out/fst-matcher.js +9 -5
- package/out/fst-matcher.js.map +1 -1
- package/out/fst-serialize.d.ts.map +1 -1
- package/out/fst-serialize.js +62 -9
- package/out/fst-serialize.js.map +1 -1
- package/out/fst-types.d.ts +26 -3
- package/out/fst-types.d.ts.map +1 -1
- package/out/fts-query.d.ts +41 -0
- package/out/fts-query.d.ts.map +1 -0
- package/out/fts-query.js +75 -0
- package/out/fts-query.js.map +1 -0
- package/out/fts.d.ts +21 -7
- package/out/fts.d.ts.map +1 -1
- package/out/fts.js +10 -4
- package/out/fts.js.map +1 -1
- package/out/geo.d.ts +6 -2
- package/out/geo.d.ts.map +1 -1
- package/out/geo.js +3 -1
- package/out/geo.js.map +1 -1
- package/out/geonames-aliases.d.ts +12 -4
- package/out/geonames-aliases.d.ts.map +1 -1
- package/out/geonames-aliases.js +72 -67
- package/out/geonames-aliases.js.map +1 -1
- package/out/geonames-postal.d.ts +9 -3
- package/out/geonames-postal.d.ts.map +1 -1
- package/out/geonames-postal.js +7 -2
- package/out/geonames-postal.js.map +1 -1
- package/out/index.d.ts.map +1 -1
- package/out/index.js.map +1 -1
- package/out/interpolation.d.ts +18 -6
- package/out/interpolation.d.ts.map +1 -1
- package/out/interpolation.js +11 -40
- package/out/interpolation.js.map +1 -1
- package/out/lookup.d.ts +3 -97
- package/out/lookup.d.ts.map +1 -1
- package/out/lookup.js +52 -184
- package/out/lookup.js.map +1 -1
- package/out/name-score.d.ts +28 -0
- package/out/name-score.d.ts.map +1 -0
- package/out/name-score.js +67 -0
- package/out/name-score.js.map +1 -0
- package/out/poi-lookup.d.ts +24 -8
- package/out/poi-lookup.d.ts.map +1 -1
- package/out/poi-lookup.js +27 -13
- package/out/poi-lookup.js.map +1 -1
- package/out/poi-schema.d.ts +42 -13
- package/out/poi-schema.d.ts.map +1 -1
- package/out/poi-schema.js +12 -3
- package/out/poi-schema.js.map +1 -1
- package/out/postal-city-alias-lookup.d.ts +18 -6
- package/out/postal-city-alias-lookup.d.ts.map +1 -1
- package/out/postal-city-alias-lookup.js.map +1 -1
- package/out/postal-city-alias-schema.d.ts +27 -9
- package/out/postal-city-alias-schema.d.ts.map +1 -1
- package/out/postal-city-alias-schema.js +3 -1
- package/out/postal-city-alias-schema.js.map +1 -1
- package/out/postal-city-candidate-schema.d.ts +15 -5
- package/out/postal-city-candidate-schema.d.ts.map +1 -1
- package/out/postal-city-candidate-schema.js +3 -1
- package/out/postal-city-candidate-schema.js.map +1 -1
- package/out/postcode-point-lookup.d.ts +6 -2
- package/out/postcode-point-lookup.d.ts.map +1 -1
- package/out/postcode-point-lookup.js +6 -2
- package/out/postcode-point-lookup.js.map +1 -1
- package/out/ranking-weights.d.ts +118 -0
- package/out/ranking-weights.d.ts.map +1 -0
- package/out/ranking-weights.js +44 -0
- package/out/ranking-weights.js.map +1 -0
- package/out/reverse.d.ts +9 -3
- package/out/reverse.d.ts.map +1 -1
- package/out/reverse.js +20 -6
- package/out/reverse.js.map +1 -1
- package/out/sharding.d.ts +3 -1
- package/out/sharding.d.ts.map +1 -1
- package/out/sharding.js +7 -5
- package/out/sharding.js.map +1 -1
- package/out/sqlite-convention-source.d.ts.map +1 -1
- package/out/sqlite-convention-source.js +3 -1
- package/out/sqlite-convention-source.js.map +1 -1
- package/out/street-centroid-schema.d.ts +33 -11
- package/out/street-centroid-schema.d.ts.map +1 -1
- package/out/street-centroid-schema.js +3 -1
- package/out/street-centroid-schema.js.map +1 -1
- package/out/street-centroid.d.ts.map +1 -1
- package/out/street-centroid.js +6 -2
- package/out/street-centroid.js.map +1 -1
- package/out/street-morphology-fst-builder.d.ts +6 -2
- package/out/street-morphology-fst-builder.d.ts.map +1 -1
- package/out/street-morphology-fst-builder.js +8 -7
- package/out/street-morphology-fst-builder.js.map +1 -1
- package/out/street-morphology-fst-loader.d.ts +24 -8
- package/out/street-morphology-fst-loader.d.ts.map +1 -1
- package/out/street-morphology-fst-loader.js +11 -5
- package/out/street-morphology-fst-loader.js.map +1 -1
- package/out/street-name-lookup.d.ts +9 -3
- package/out/street-name-lookup.d.ts.map +1 -1
- package/out/street-name-lookup.js +9 -7
- package/out/street-name-lookup.js.map +1 -1
- package/out/street-normalize.d.ts +3 -1
- package/out/street-normalize.d.ts.map +1 -1
- package/out/street-normalize.js +23 -13
- package/out/street-normalize.js.map +1 -1
- package/out/street-segment-schema.d.ts +48 -16
- package/out/street-segment-schema.d.ts.map +1 -1
- package/out/street-segment-schema.js +6 -2
- package/out/street-segment-schema.js.map +1 -1
- package/out/types.d.ts +18 -6
- package/out/types.d.ts.map +1 -1
- package/out/unified-schema.d.ts +1 -1
- package/out/unified-schema.d.ts.map +1 -1
- package/out/unified-schema.js +2 -2
- package/out/unified-schema.js.map +1 -1
- package/package.json +5 -5
- package/poi-lookup.ts +53 -21
- package/poi-schema.ts +43 -13
- package/postal-city-alias-lookup.ts +20 -6
- package/postal-city-alias-schema.ts +28 -9
- package/postal-city-candidate-schema.ts +15 -5
- package/postcode-point-lookup.ts +6 -2
- package/ranking-weights.ts +148 -0
- package/reverse.ts +47 -10
- package/sharding.ts +13 -6
- package/sqlite-convention-source.ts +4 -1
- package/street-centroid-schema.ts +35 -11
- package/street-centroid.ts +10 -3
- package/street-morphology-fst-builder.ts +25 -9
- package/street-morphology-fst-loader.ts +26 -10
- package/street-name-lookup.ts +19 -7
- package/street-normalize.ts +28 -13
- package/street-segment-schema.ts +50 -16
- package/types.ts +18 -6
- package/unified-schema.ts +11 -2
package/interpolation.ts
CHANGED
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
import { DatabaseSync } from "node:sqlite"
|
|
30
30
|
|
|
31
31
|
import type { InterpolationLookup } from "@mailwoman/resolver"
|
|
32
|
+
import { clampFraction, pointAlong } from "@mailwoman/spatial"
|
|
32
33
|
|
|
33
34
|
import { haversineKm } from "./geo.ts"
|
|
34
35
|
import { hasTable } from "./sqlite-utils.ts"
|
|
@@ -44,13 +45,19 @@ import { canonicalizeRouteKey, normalizeStreetForKey } from "./street-normalize.
|
|
|
44
45
|
*/
|
|
45
46
|
export type InterpolationMethod = "address_point" | "tiger_range"
|
|
46
47
|
|
|
47
|
-
/**
|
|
48
|
+
/**
|
|
49
|
+
* One interpolated coordinate estimate. Never an exact situs point — see `uncertaintyM`.
|
|
50
|
+
*/
|
|
48
51
|
export interface InterpolatedHit {
|
|
49
52
|
lat: number
|
|
50
53
|
lon: number
|
|
51
|
-
/**
|
|
54
|
+
/**
|
|
55
|
+
* Always true — the tier's honesty flag, mirrored into `resolution_tier` when wired.
|
|
56
|
+
*/
|
|
52
57
|
interpolated: true
|
|
53
|
-
/**
|
|
58
|
+
/**
|
|
59
|
+
* Which rung answered — see {@link InterpolationMethod}.
|
|
60
|
+
*/
|
|
54
61
|
method: InterpolationMethod
|
|
55
62
|
/**
|
|
56
63
|
* `tiger_range` only. True when the matched segment side's parity agrees with the house number (or the side is
|
|
@@ -67,16 +74,22 @@ export interface InterpolatedHit {
|
|
|
67
74
|
* span (`address_point`/`both`), or the explicitly larger extrapolation penalty (`address_point`/`single`).
|
|
68
75
|
*/
|
|
69
76
|
uncertaintyM: number
|
|
70
|
-
/**
|
|
77
|
+
/**
|
|
78
|
+
* Provenance, e.g. `"tiger:edges"`.
|
|
79
|
+
*/
|
|
71
80
|
source: string
|
|
72
|
-
/**
|
|
81
|
+
/**
|
|
82
|
+
* Pinned data vintage, e.g. `"TIGER2023"`.
|
|
83
|
+
*/
|
|
73
84
|
release: string
|
|
74
85
|
}
|
|
75
86
|
|
|
76
87
|
export interface InterpolationQuery {
|
|
77
88
|
street: string
|
|
78
89
|
number: string
|
|
79
|
-
/**
|
|
90
|
+
/**
|
|
91
|
+
* ZIP scope — strongly preferred; without it common street names abstain (see module doc).
|
|
92
|
+
*/
|
|
80
93
|
postcode?: string
|
|
81
94
|
}
|
|
82
95
|
|
|
@@ -114,10 +127,12 @@ export class StreetInterpolator implements InterpolationLookup {
|
|
|
114
127
|
// `street_segment` table this interpolator is a no-op miss, not a crash that loses the state (#568).
|
|
115
128
|
if (hasTable(this.#db, "street_segment")) {
|
|
116
129
|
const columns = `from_hn, to_hn, min_hn, max_hn, parity, postcode, geometry, source, release`
|
|
130
|
+
|
|
117
131
|
this.#byPostcode = this.#db.prepare(
|
|
118
132
|
`SELECT ${columns} FROM street_segment
|
|
119
133
|
WHERE postcode = ? AND street_norm = ? AND min_hn <= ? AND max_hn >= ?`
|
|
120
134
|
)
|
|
135
|
+
|
|
121
136
|
this.#byStreet = this.#db.prepare(
|
|
122
137
|
`SELECT ${columns} FROM street_segment
|
|
123
138
|
WHERE street_norm = ? AND min_hn <= ? AND max_hn >= ?`
|
|
@@ -133,6 +148,7 @@ export class StreetInterpolator implements InterpolationLookup {
|
|
|
133
148
|
const row = this.#db.prepare("SELECT radius_multiplier FROM interp_calibration LIMIT 1").get() as
|
|
134
149
|
| { radius_multiplier: unknown }
|
|
135
150
|
| undefined
|
|
151
|
+
|
|
136
152
|
const value = row?.radius_multiplier
|
|
137
153
|
|
|
138
154
|
if (typeof value === "number" && Number.isFinite(value) && value > 0) {
|
|
@@ -175,23 +191,29 @@ export class StreetInterpolator implements InterpolationLookup {
|
|
|
175
191
|
if (postcodes.size > 1) return null
|
|
176
192
|
}
|
|
177
193
|
|
|
178
|
-
if (rows.length
|
|
194
|
+
if (!rows.length) return null
|
|
179
195
|
|
|
180
196
|
// Parity preference: exact side first, then 'mixed' (matches either), then the
|
|
181
197
|
// opposite side as a flagged fallback.
|
|
182
198
|
const wantOdd = n % 2 === 1
|
|
183
199
|
const exact = rows.filter((r) => r.parity === (wantOdd ? "odd" : "even"))
|
|
184
200
|
const mixed = rows.filter((r) => r.parity === "mixed")
|
|
185
|
-
const preferred = exact.length
|
|
186
|
-
const pool = preferred.length
|
|
201
|
+
const preferred = exact.length ? exact : mixed
|
|
202
|
+
const pool = preferred.length ? preferred : rows
|
|
187
203
|
const parityMatched = preferred.length > 0
|
|
188
204
|
|
|
189
205
|
// Tightest range wins — the most specific claim about where this number lives.
|
|
190
|
-
|
|
206
|
+
let best = pool[0]!
|
|
207
|
+
|
|
208
|
+
for (const candidate of pool) {
|
|
209
|
+
if (candidate.max_hn - candidate.min_hn < best.max_hn - best.min_hn) {
|
|
210
|
+
best = candidate
|
|
211
|
+
}
|
|
212
|
+
}
|
|
191
213
|
|
|
192
214
|
const polyline = JSON.parse(best.geometry) as [number, number][]
|
|
193
215
|
const span = best.to_hn - best.from_hn
|
|
194
|
-
const t = span === 0 ? 0.5 :
|
|
216
|
+
const t = span === 0 ? 0.5 : clampFraction((n - best.from_hn) / span)
|
|
195
217
|
const [lon, lat, lengthKm] = pointAlong(polyline, t)
|
|
196
218
|
|
|
197
219
|
return {
|
|
@@ -212,47 +234,3 @@ export class StreetInterpolator implements InterpolationLookup {
|
|
|
212
234
|
}
|
|
213
235
|
}
|
|
214
236
|
}
|
|
215
|
-
|
|
216
|
-
function clamp01(t: number): number {
|
|
217
|
-
return t < 0 ? 0 : t > 1 ? 1 : t
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Point at fraction `t` of the polyline's total arc length (haversine), plus the total length in km. `t` is assumed
|
|
222
|
-
* clamped to [0, 1].
|
|
223
|
-
*/
|
|
224
|
-
function pointAlong(polyline: readonly [number, number][], t: number): [lon: number, lat: number, lengthKm: number] {
|
|
225
|
-
const legs: number[] = []
|
|
226
|
-
let total = 0
|
|
227
|
-
|
|
228
|
-
for (let i = 1; i < polyline.length; i++) {
|
|
229
|
-
const [aLon, aLat] = polyline[i - 1]!
|
|
230
|
-
const [bLon, bLat] = polyline[i]!
|
|
231
|
-
const d = haversineKm(aLat, aLon, bLat, bLon)
|
|
232
|
-
legs.push(d)
|
|
233
|
-
total += d
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
if (total === 0) {
|
|
237
|
-
const [lon, lat] = polyline[0]!
|
|
238
|
-
|
|
239
|
-
return [lon, lat, 0]
|
|
240
|
-
}
|
|
241
|
-
let remaining = t * total
|
|
242
|
-
|
|
243
|
-
for (let i = 0; i < legs.length; i++) {
|
|
244
|
-
const leg = legs[i]!
|
|
245
|
-
|
|
246
|
-
if (remaining <= leg || i === legs.length - 1) {
|
|
247
|
-
const f = leg === 0 ? 0 : clamp01(remaining / leg)
|
|
248
|
-
const [aLon, aLat] = polyline[i]!
|
|
249
|
-
const [bLon, bLat] = polyline[i + 1]!
|
|
250
|
-
|
|
251
|
-
return [aLon + (bLon - aLon) * f, aLat + (bLat - aLat) * f, total]
|
|
252
|
-
}
|
|
253
|
-
remaining -= leg
|
|
254
|
-
}
|
|
255
|
-
const [lon, lat] = polyline[polyline.length - 1]!
|
|
256
|
-
|
|
257
|
-
return [lon, lat, total]
|
|
258
|
-
}
|