@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
package/out/fts.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* FTS5 index lifecycle for the WOF SQLite distribution.
|
|
7
7
|
*
|
|
8
|
-
* Shared by `
|
|
8
|
+
* Shared by `WOFSqlitePlaceLookup` (lazy build via `buildFTS: true`) and the operator-side
|
|
9
9
|
* `mailwoman-wof-build-fts` CLI (ahead-of-time build to avoid first-open latency in production).
|
|
10
10
|
*
|
|
11
11
|
* Upstream WOF SQLite distributions do NOT ship FTS5. The index lives in a `place_search` virtual
|
|
@@ -14,82 +14,76 @@
|
|
|
14
14
|
* bag.
|
|
15
15
|
*/
|
|
16
16
|
/**
|
|
17
|
-
* Name of the FTS5 virtual table this module owns. Centralized so `
|
|
18
|
-
* CLI can't drift apart.
|
|
17
|
+
* Name of the FTS5 virtual table this module owns. Centralized so `WOFSqlitePlaceLookup` and the CLI can't drift apart.
|
|
19
18
|
*/
|
|
20
19
|
export const PLACE_SEARCH_TABLE = "place_search";
|
|
21
20
|
/**
|
|
22
|
-
* Boundary-preserving separator between aliases in the `alt_names` bag (#523): U+E000, the first
|
|
23
|
-
*
|
|
21
|
+
* Boundary-preserving separator between aliases in the `alt_names` bag (#523): U+E000, the first Private Use Area
|
|
22
|
+
* codepoint, written as an escape so the source stays plain ASCII.
|
|
24
23
|
*
|
|
25
|
-
* Why a PUA codepoint and not punctuation: the goal is to stop a phrase query from matching ACROSS
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* sits between the aliases and breaks positional adjacency.
|
|
24
|
+
* Why a PUA codepoint and not punctuation: the goal is to stop a phrase query from matching ACROSS two adjacent
|
|
25
|
+
* aliases' concatenation boundary ("York" + "New City" must not phrase-match `"york new"`). FTS5 assigns token
|
|
26
|
+
* positions to TOKENS only — separator characters never consume a position — so any character the tokenizer treats as a
|
|
27
|
+
* boundary leaves the two aliases' tokens adjacent and the false phrase match intact. The separator must therefore be
|
|
28
|
+
* an INDEXED TOKEN that sits between the aliases and breaks positional adjacency.
|
|
31
29
|
*
|
|
32
|
-
* Empirical probe (node:sqlite, `tokenize = 'unicode61 remove_diacritics 2'` — the exact config
|
|
33
|
-
*
|
|
34
|
-
*
|
|
30
|
+
* Empirical probe (node:sqlite, `tokenize = 'unicode61 remove_diacritics 2'` — the exact config below). Bag = the
|
|
31
|
+
* aliases "York" and "New City" joined by each candidate separator; query = the cross-boundary phrase `MATCH '"york
|
|
32
|
+
* new"'`:
|
|
35
33
|
*
|
|
36
34
|
* - `' '` (the pre-#523 join, no separator) — false HIT
|
|
37
35
|
* - `' ; '` (punctuation) — false HIT
|
|
38
36
|
* - `' \u2016 '` (double vertical line) — false HIT
|
|
39
37
|
* - `' \x1F '` (ASCII unit separator) — false HIT
|
|
40
|
-
* - `' \uE000 '` (PUA, this constant) — NO match, while `'"york"'` and `'"new city"'` still match the
|
|
41
|
-
*
|
|
38
|
+
* - `' \uE000 '` (PUA, this constant) — NO match, while `'"york"'` and `'"new city"'` still match the bag individually
|
|
39
|
+
* under every variant above.
|
|
42
40
|
*
|
|
43
|
-
* U+E000 works because unicode61 classifies it (category Co — neither space nor punctuation) as a
|
|
44
|
-
*
|
|
45
|
-
*
|
|
41
|
+
* U+E000 works because unicode61 classifies it (category Co — neither space nor punctuation) as a token character, so
|
|
42
|
+
* the standalone `\uE000` between aliases is indexed as its own token and the aliases' tokens are no longer
|
|
43
|
+
* positionally adjacent. The remaining requirements also hold:
|
|
46
44
|
*
|
|
47
|
-
* - **Unreachable from queries**: `
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* - **Never in place names**: PUA codepoints are unassigned by definition; real-world WOF names don't
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* - **Survives GROUP_CONCAT**: verified — `GROUP_CONCAT(name, ' ' || char(57344) || ' ')` emits the
|
|
54
|
-
*
|
|
55
|
-
* - **Cost**: one extra token per alias boundary in the FTS document. Marginal BM25 length-norm
|
|
56
|
-
*
|
|
45
|
+
* - **Unreachable from queries**: `sanitizeFTSQuery` (Node + WASM resolvers) strips everything outside `\p{L}\p{N}` from
|
|
46
|
+
* token bodies, and U+E000 is neither — no user query can ever address the separator token. The demo's `sanitizeFTS`
|
|
47
|
+
* strips it explicitly.
|
|
48
|
+
* - **Never in place names**: PUA codepoints are unassigned by definition; real-world WOF names don't carry them.
|
|
49
|
+
* Defensively, the INSERT below also strips any embedded U+E000 from source names so a poisoned row can't forge an
|
|
50
|
+
* alias boundary.
|
|
51
|
+
* - **Survives GROUP_CONCAT**: verified — `GROUP_CONCAT(name, ' ' || char(57344) || ' ')` emits the codepoint intact
|
|
52
|
+
* (`57344` = 0xE000).
|
|
53
|
+
* - **Cost**: one extra token per alias boundary in the FTS document. Marginal BM25 length-norm impact, on a column whose
|
|
54
|
+
* length stats are already the known #189 problem.
|
|
57
55
|
*
|
|
58
|
-
* Interaction with #189 (split `alt_names` into its own FTS table for independent BM25 length
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* fold both into ONE rebuild rather than shipping two FTS schema bumps.
|
|
56
|
+
* Interaction with #189 (split `alt_names` into its own FTS table for independent BM25 length stats): the separator
|
|
57
|
+
* SURVIVES that split as proposed — #189 still GROUP_CONCATs all aliases into one `place_search_alt` row per place, so
|
|
58
|
+
* both the separator and the bag-parsing exact check (`aliasBagExactMatch`) carry over unchanged, just pointed at the
|
|
59
|
+
* new table. Only if #189 were instead built as one-row-per-alias would both become moot (per-alias rows give exact
|
|
60
|
+
* equality and phrase isolation for free). Sequencing: if #189 lands before the next slim-DB artifact rebuild, fold
|
|
61
|
+
* both into ONE rebuild rather than shipping two FTS schema bumps.
|
|
65
62
|
*/
|
|
66
63
|
export const ALIAS_SEPARATOR = "\uE000";
|
|
67
64
|
/** `char()` argument for {@link ALIAS_SEPARATOR} in SQL — keeps the SQL text plain ASCII. */
|
|
68
65
|
const ALIAS_SEPARATOR_CODEPOINT = ALIAS_SEPARATOR.codePointAt(0);
|
|
69
66
|
/**
|
|
70
|
-
* Does any alias in an `alt_names` bag exactly equal the (already-normalized) query? The single
|
|
71
|
-
*
|
|
72
|
-
* resolver
|
|
73
|
-
* bag format and its parsers can't drift.
|
|
67
|
+
* Does any alias in an `alt_names` bag exactly equal the (already-normalized) query? The single shared implementation
|
|
68
|
+
* of the exact-tier alias check for every consumer of the bag — the Node resolver's `#exactMatchIds` fallback, the WASM
|
|
69
|
+
* resolver, and the demo's httpvfs resolver — so the bag format and its parsers can't drift.
|
|
74
70
|
*
|
|
75
71
|
* Two formats exist in the wild:
|
|
76
72
|
*
|
|
77
|
-
* - **Separated bags** (built since #523): aliases joined with {@link ALIAS_SEPARATOR}, plus a
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* the alias "New York City") and cross-boundary fragments ("York New" across "…York" + "New…").
|
|
86
|
-
* Delete this branch once every shipped artifact carries the separator.
|
|
73
|
+
* - **Separated bags** (built since #523): aliases joined with {@link ALIAS_SEPARATOR}, plus a trailing separator so even
|
|
74
|
+
* a single-alias bag self-identifies as separator-formatted. Split + per-alias equality — a true exact-alias check,
|
|
75
|
+
* matching the semantics of the full `names` table (`names.name = ? COLLATE NOCASE`), so it runs UNGATED: an alias
|
|
76
|
+
* match is an exact match whether or not another candidate matched on its canonical name.
|
|
77
|
+
* - **Legacy bags** (pre-#523 artifacts, e.g. an already-deployed slim DB): aliases space-joined, boundaries lost. Falls
|
|
78
|
+
* back to the historical padded-containment check, gated on `anyStrictExact` — ungated containment would
|
|
79
|
+
* false-promote interior fragments ("York" inside the alias "New York City") and cross-boundary fragments ("York New"
|
|
80
|
+
* across "…York" + "New…"). Delete this branch once every shipped artifact carries the separator.
|
|
87
81
|
*
|
|
88
82
|
* @param altNames The `alt_names` bag from `place_search` (null when the row has no aliases).
|
|
89
|
-
* @param normalizedQuery The query, pre-normalized: lowercased, trimmed, internal whitespace
|
|
90
|
-
*
|
|
91
|
-
* @param anyStrictExact Whether ANY candidate in the pool already matched strictly (canonical name
|
|
92
|
-
*
|
|
83
|
+
* @param normalizedQuery The query, pre-normalized: lowercased, trimmed, internal whitespace collapsed (every consumer
|
|
84
|
+
* already normalizes this way).
|
|
85
|
+
* @param anyStrictExact Whether ANY candidate in the pool already matched strictly (canonical name or region
|
|
86
|
+
* abbreviation). Only consulted for legacy bags.
|
|
93
87
|
*/
|
|
94
88
|
export function aliasBagExactMatch(altNames, normalizedQuery, anyStrictExact) {
|
|
95
89
|
if (altNames === null || altNames === "" || !normalizedQuery)
|
|
@@ -103,31 +97,31 @@ export function aliasBagExactMatch(altNames, normalizedQuery, anyStrictExact) {
|
|
|
103
97
|
return ` ${norm(altNames)} `.includes(` ${normalizedQuery} `);
|
|
104
98
|
}
|
|
105
99
|
/**
|
|
106
|
-
* Name of the R*Tree virtual table that indexes WOF places' bounding boxes for proximity / bbox
|
|
107
|
-
*
|
|
108
|
-
*
|
|
100
|
+
* Name of the R*Tree virtual table that indexes WOF places' bounding boxes for proximity / bbox lookups. Built
|
|
101
|
+
* alongside `place_search` by the CLI and `buildFTS: true`. Pure SQLite — no extensions needed, the `rtree`
|
|
102
|
+
* virtual-table module ships with the core library.
|
|
109
103
|
*/
|
|
110
104
|
export const PLACE_BBOX_TABLE = "place_bbox";
|
|
111
105
|
/**
|
|
112
|
-
* Name of the auxiliary table holding `wof:population` per place. Powers the population-weighted
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
106
|
+
* Name of the auxiliary table holding `wof:population` per place. Powers the population-weighted ranking boost. Sparse
|
|
107
|
+
* — WOF only populates this field for ~15% of localities (and mostly larger ones); missing means no boost, never a
|
|
108
|
+
* penalty. Built upstream by `scripts/build-unified-wof.ts` at ingest (and copied through by `build-slim`) — this
|
|
109
|
+
* module consumes it, never builds it.
|
|
116
110
|
*
|
|
117
111
|
* Schema: `(id INTEGER PRIMARY KEY, population INTEGER NOT NULL)`. Plain table, not virtual.
|
|
118
112
|
*/
|
|
119
113
|
export const PLACE_POPULATION_TABLE = "place_population";
|
|
120
114
|
/**
|
|
121
|
-
* Build (or rebuild, with `drop: true`) the `place_search` FTS5 virtual table AND the `place_bbox`
|
|
122
|
-
*
|
|
115
|
+
* Build (or rebuild, with `drop: true`) the `place_search` FTS5 virtual table AND the `place_bbox` R*Tree virtual table
|
|
116
|
+
* from the existing `spr` + `names` tables in a WOF SQLite distribution.
|
|
123
117
|
*
|
|
124
|
-
* The FTS5 index is used for name-based MATCH queries; the R*Tree is used for bbox + proximity
|
|
125
|
-
*
|
|
118
|
+
* The FTS5 index is used for name-based MATCH queries; the R*Tree is used for bbox + proximity filtering. Both are pure
|
|
119
|
+
* SQLite — no extensions required.
|
|
126
120
|
*
|
|
127
|
-
* Returns a `
|
|
128
|
-
*
|
|
121
|
+
* Returns a `BuildPlaceSearchFTSResult` summary. Idempotent when `drop: false` — re-running against an already-indexed
|
|
122
|
+
* DB skips whichever indexes already exist.
|
|
129
123
|
*/
|
|
130
|
-
export function
|
|
124
|
+
export function buildPlaceSearchFTS(db, opts = {}) {
|
|
131
125
|
const start = Date.now();
|
|
132
126
|
const onProgress = opts.onProgress ?? (() => { });
|
|
133
127
|
onProgress("checking");
|
|
@@ -240,10 +234,10 @@ export function buildPlaceSearchFts(db, opts = {}) {
|
|
|
240
234
|
};
|
|
241
235
|
}
|
|
242
236
|
/**
|
|
243
|
-
* Returns true iff the `place_search` table exists in the connected DB. Used by
|
|
244
|
-
*
|
|
237
|
+
* Returns true iff the `place_search` table exists in the connected DB. Used by `WOFSqlitePlaceLookup` for its "FTS
|
|
238
|
+
* missing — pass buildFTS:true or run the CLI" guard.
|
|
245
239
|
*/
|
|
246
|
-
export function
|
|
240
|
+
export function placeSearchFTSExists(db) {
|
|
247
241
|
return tableExists(db, PLACE_SEARCH_TABLE);
|
|
248
242
|
}
|
|
249
243
|
/** Returns true iff the `place_bbox` R*Tree table exists. Used for opt-in proximity lookup checks. */
|
package/out/fts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fts.js","sourceRoot":"","sources":["../fts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH
|
|
1
|
+
{"version":3,"file":"fts.js","sourceRoot":"","sources":["../fts.ts"],"names":[],"mappings":"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"}
|
package/out/geo.d.ts
CHANGED
|
@@ -12,19 +12,18 @@
|
|
|
12
12
|
*
|
|
13
13
|
* The PIP implementation here is the CANONICAL port of the even-odd ray cast that previously lived
|
|
14
14
|
* only in Python (`scripts/eval/pip-containment.py`, with a second copy in
|
|
15
|
-
* `scripts/build-postcode-locality.
|
|
15
|
+
* `scripts/build-postcode-locality.ts`). Keep the three in sync if the algorithm ever changes —
|
|
16
16
|
* the eval-side Python copies grade the same containment truth this one resolves with.
|
|
17
17
|
*
|
|
18
18
|
* The R*Tree index name + schema are centralized in `fts.ts` (alongside the FTS5 build).
|
|
19
19
|
*/
|
|
20
20
|
export { haversineKm } from "@mailwoman/spatial";
|
|
21
21
|
/**
|
|
22
|
-
* Approximate bbox around a point — `radiusKm` in each direction. Used to translate a `near: {lat,
|
|
23
|
-
*
|
|
22
|
+
* Approximate bbox around a point — `radiusKm` in each direction. Used to translate a `near: {lat, lon}` +
|
|
23
|
+
* `maxDistanceKm` filter into an R*Tree bbox query.
|
|
24
24
|
*
|
|
25
|
-
* The math is the spherical-Earth equirectangular approximation: 1° latitude ≈ 111 km globally, 1°
|
|
26
|
-
*
|
|
27
|
-
* haversine post-fetch), and it stays cheap.
|
|
25
|
+
* The math is the spherical-Earth equirectangular approximation: 1° latitude ≈ 111 km globally, 1° longitude ≈ 111 km ×
|
|
26
|
+
* cos(latitude). Accurate enough for filtering (we re-check with exact haversine post-fetch), and it stays cheap.
|
|
28
27
|
*/
|
|
29
28
|
export interface Bbox {
|
|
30
29
|
minLat: number;
|
|
@@ -34,8 +33,8 @@ export interface Bbox {
|
|
|
34
33
|
}
|
|
35
34
|
export declare function bboxAround(lat: number, lon: number, radiusKm: number): Bbox;
|
|
36
35
|
/**
|
|
37
|
-
* A GeoJSON position — `[lon, lat]`, possibly with extra dimensions we ignore. WOF geometries are
|
|
38
|
-
*
|
|
36
|
+
* A GeoJSON position — `[lon, lat]`, possibly with extra dimensions we ignore. WOF geometries are 2-D throughout, but
|
|
37
|
+
* the type stays open so a 3-D source doesn't break parsing.
|
|
39
38
|
*/
|
|
40
39
|
export type GeojsonPosition = [number, number, ...number[]];
|
|
41
40
|
/** The two areal GeoJSON geometry types PIP can test, plus an open fallback (Point etc.). */
|
|
@@ -53,22 +52,22 @@ export type GeojsonGeometry = GeojsonPolygon | GeojsonMultiPolygon | {
|
|
|
53
52
|
coordinates?: unknown;
|
|
54
53
|
};
|
|
55
54
|
/**
|
|
56
|
-
* Ray-cast a point against ONE linear ring. Standard even-odd crossing count: shoot a ray along
|
|
57
|
-
*
|
|
58
|
-
*
|
|
55
|
+
* Ray-cast a point against ONE linear ring. Standard even-odd crossing count: shoot a ray along +lon and toggle on
|
|
56
|
+
* every edge crossing. Points exactly on an edge are implementation-defined (either side is acceptable for geocoding —
|
|
57
|
+
* admin boundaries are DP-simplified anyway).
|
|
59
58
|
*/
|
|
60
59
|
export declare function pointInRing(lon: number, lat: number, ring: readonly GeojsonPosition[]): boolean;
|
|
61
60
|
/**
|
|
62
|
-
* Even-odd containment over a polygon's ring list (`[outer, hole1, …]`) — being inside an odd
|
|
63
|
-
*
|
|
61
|
+
* Even-odd containment over a polygon's ring list (`[outer, hole1, …]`) — being inside an odd number of rings means
|
|
62
|
+
* inside the polygon, which handles holes without ring-orientation rules.
|
|
64
63
|
*/
|
|
65
64
|
export declare function pointInPolygonRings(lon: number, lat: number, rings: readonly GeojsonPosition[][]): boolean;
|
|
66
65
|
/**
|
|
67
66
|
* Does an areal GeoJSON geometry contain the point?
|
|
68
67
|
*
|
|
69
68
|
* - `true` / `false` — a Polygon or MultiPolygon was tested.
|
|
70
|
-
* - `null` — the geometry isn't areal (Point, LineString, …) and CANNOT contain; callers treat this
|
|
71
|
-
*
|
|
69
|
+
* - `null` — the geometry isn't areal (Point, LineString, …) and CANNOT contain; callers treat this the same as "no
|
|
70
|
+
* polygon on record" (the approximate-fallback path), never as a rejection.
|
|
72
71
|
*/
|
|
73
72
|
export declare function geometryContains(geometry: GeojsonGeometry | null | undefined, lon: number, lat: number): boolean | null;
|
|
74
73
|
//# sourceMappingURL=geo.d.ts.map
|
package/out/geo.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geo.d.ts","sourceRoot":"","sources":["../geo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAOhD
|
|
1
|
+
{"version":3,"file":"geo.d.ts","sourceRoot":"","sources":["../geo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAOhD;;;;;;GAMG;AACH,MAAM,WAAW,IAAI;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAY3E;AAED;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAA;AAE3D,6FAA6F;AAC7F,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,SAAS,CAAA;IACf,6EAA6E;IAC7E,WAAW,EAAE,eAAe,EAAE,EAAE,CAAA;CAChC;AAED,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,cAAc,CAAA;IACpB,WAAW,EAAE,eAAe,EAAE,EAAE,EAAE,CAAA;CAClC;AAED,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,mBAAmB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,CAAA;AAE5G;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,eAAe,EAAE,GAAG,OAAO,CAgB/F;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,eAAe,EAAE,EAAE,GAAG,OAAO,CAQ1G;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC/B,QAAQ,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,EAC5C,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,GACT,OAAO,GAAG,IAAI,CAYhB"}
|
package/out/geo.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*
|
|
13
13
|
* The PIP implementation here is the CANONICAL port of the even-odd ray cast that previously lived
|
|
14
14
|
* only in Python (`scripts/eval/pip-containment.py`, with a second copy in
|
|
15
|
-
* `scripts/build-postcode-locality.
|
|
15
|
+
* `scripts/build-postcode-locality.ts`). Keep the three in sync if the algorithm ever changes —
|
|
16
16
|
* the eval-side Python copies grade the same containment truth this one resolves with.
|
|
17
17
|
*
|
|
18
18
|
* The R*Tree index name + schema are centralized in `fts.ts` (alongside the FTS5 build).
|
|
@@ -37,9 +37,9 @@ export function bboxAround(lat, lon, radiusKm) {
|
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
|
-
* Ray-cast a point against ONE linear ring. Standard even-odd crossing count: shoot a ray along
|
|
41
|
-
*
|
|
42
|
-
*
|
|
40
|
+
* Ray-cast a point against ONE linear ring. Standard even-odd crossing count: shoot a ray along +lon and toggle on
|
|
41
|
+
* every edge crossing. Points exactly on an edge are implementation-defined (either side is acceptable for geocoding —
|
|
42
|
+
* admin boundaries are DP-simplified anyway).
|
|
43
43
|
*/
|
|
44
44
|
export function pointInRing(lon, lat, ring) {
|
|
45
45
|
let inside = false;
|
|
@@ -56,8 +56,8 @@ export function pointInRing(lon, lat, ring) {
|
|
|
56
56
|
return inside;
|
|
57
57
|
}
|
|
58
58
|
/**
|
|
59
|
-
* Even-odd containment over a polygon's ring list (`[outer, hole1, …]`) — being inside an odd
|
|
60
|
-
*
|
|
59
|
+
* Even-odd containment over a polygon's ring list (`[outer, hole1, …]`) — being inside an odd number of rings means
|
|
60
|
+
* inside the polygon, which handles holes without ring-orientation rules.
|
|
61
61
|
*/
|
|
62
62
|
export function pointInPolygonRings(lon, lat, rings) {
|
|
63
63
|
let inside = false;
|
|
@@ -71,8 +71,8 @@ export function pointInPolygonRings(lon, lat, rings) {
|
|
|
71
71
|
* Does an areal GeoJSON geometry contain the point?
|
|
72
72
|
*
|
|
73
73
|
* - `true` / `false` — a Polygon or MultiPolygon was tested.
|
|
74
|
-
* - `null` — the geometry isn't areal (Point, LineString, …) and CANNOT contain; callers treat this
|
|
75
|
-
*
|
|
74
|
+
* - `null` — the geometry isn't areal (Point, LineString, …) and CANNOT contain; callers treat this the same as "no
|
|
75
|
+
* polygon on record" (the approximate-fallback path), never as a rejection.
|
|
76
76
|
*/
|
|
77
77
|
export function geometryContains(geometry, lon, lat) {
|
|
78
78
|
if (!geometry)
|
package/out/geo.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geo.js","sourceRoot":"","sources":["../geo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,mGAAmG;AACnG,qGAAqG;AACrG,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAEhD,gCAAgC;AAChC,SAAS,KAAK,CAAC,GAAW;IACzB,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAA;AAC7B,CAAC;
|
|
1
|
+
{"version":3,"file":"geo.js","sourceRoot":"","sources":["../geo.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* For each POPULATED place (feature class `P`) this writes an `spr` row + `names` rows (primary +
|
|
14
14
|
* Latin alt-names) + population into the SAME tables the WOF/Overture paths use — synthetic ids
|
|
15
15
|
* based at {@link GEONAMES_ID_BASE} so the three sources never collide. The caller then rebuilds
|
|
16
|
-
* `place_search` ({@link
|
|
16
|
+
* `place_search` ({@link buildPlaceSearchFTS} with `drop: true`) so the candidate build carries
|
|
17
17
|
* Karjaa↔Karis. Proven (FI hard-resolve 69.5 → 85.8 %, coverage 74.4 → 94.0 %); duplicating a
|
|
18
18
|
* place already held under another source is benign — the rows share name_key+coord and the
|
|
19
19
|
* candidate ranking dedupes by score.
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
*/
|
|
26
26
|
import type { DatabaseSync } from "node:sqlite";
|
|
27
27
|
/**
|
|
28
|
-
* Synthetic id base for GeoNames-sourced rows (#743/#193) — above Overture's 8e12 so the three
|
|
29
|
-
*
|
|
28
|
+
* Synthetic id base for GeoNames-sourced rows (#743/#193) — above Overture's 8e12 so the three sources (WOF real ids,
|
|
29
|
+
* Overture, GeoNames) never collide in a combined DB.
|
|
30
30
|
*/
|
|
31
31
|
export declare const GEONAMES_ID_BASE = 9000000000000;
|
|
32
32
|
/** Per-country progress for the ingest — one event per country dump processed (or skipped). */
|
|
@@ -39,12 +39,21 @@ export interface GeonamesIngestProgress {
|
|
|
39
39
|
skipped: boolean;
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
|
-
* Fold the GeoNames `P`-class places (+ their Latin alt-names) for `countries` into `db`'s `spr` /
|
|
43
|
-
* `
|
|
42
|
+
* Fold the GeoNames `P`-class places (+ their Latin alt-names) for `countries` into `db`'s `spr` / `names` /
|
|
43
|
+
* `place_population` tables. Returns the total places ingested.
|
|
44
44
|
*
|
|
45
|
-
* `onProgress` receives one event per country (default: a stderr line, matching the build scripts'
|
|
46
|
-
*
|
|
47
|
-
*
|
|
45
|
+
* `onProgress` receives one event per country (default: a stderr line, matching the build scripts' legacy output). The
|
|
46
|
+
* caller MUST rebuild `place_search` afterward (`buildPlaceSearchFTS(db, { drop: true })`) for the new names to reach
|
|
47
|
+
* the candidate build's alias pass.
|
|
48
48
|
*/
|
|
49
|
-
export declare function ingestGeonamesAliases(db: DatabaseSync, countries: string[], geonamesDir: string, onProgress?: (event: GeonamesIngestProgress) => void
|
|
49
|
+
export declare function ingestGeonamesAliases(db: DatabaseSync, countries: string[], geonamesDir: string, onProgress?: (event: GeonamesIngestProgress) => void, opts?: {
|
|
50
|
+
/**
|
|
51
|
+
* #267: the countries for which to ALSO fold the GeoNames A-class admin (PCLI country + ADM1 regions) and link each
|
|
52
|
+
* locality's `parent_id` + ancestry chain (locality → region → country). PER-COUNTRY because a country that already
|
|
53
|
+
* carries WOF admin would double up — pass only the ZERO-COVERAGE gap countries (the coverage-expansion targets),
|
|
54
|
+
* never the EU alias set. Without admin, a gap country's localities are orphans (`parent_id=-1`, no ancestors), so
|
|
55
|
+
* `parentID` scoping and adminCoherence can't reach them and "Tbilisi, GE" can't resolve.
|
|
56
|
+
*/
|
|
57
|
+
adminForCountries?: ReadonlySet<string>;
|
|
58
|
+
}): number;
|
|
50
59
|
//# sourceMappingURL=geonames-aliases.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geonames-aliases.d.ts","sourceRoot":"","sources":["../geonames-aliases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE/C;;;GAGG;AACH,eAAO,MAAM,gBAAgB,gBAAoB,CAAA;AAEjD,+FAA+F;AAC/F,MAAM,WAAW,sBAAsB;IACtC,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAA;IACd,+FAA+F;IAC/F,OAAO,EAAE,OAAO,CAAA;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACpC,EAAE,EAAE,YAAY,EAChB,SAAS,EAAE,MAAM,EAAE,EACnB,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,
|
|
1
|
+
{"version":3,"file":"geonames-aliases.d.ts","sourceRoot":"","sources":["../geonames-aliases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE/C;;;GAGG;AACH,eAAO,MAAM,gBAAgB,gBAAoB,CAAA;AAEjD,+FAA+F;AAC/F,MAAM,WAAW,sBAAsB;IACtC,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAA;IACd,+FAA+F;IAC/F,OAAO,EAAE,OAAO,CAAA;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACpC,EAAE,EAAE,YAAY,EAChB,SAAS,EAAE,MAAM,EAAE,EACnB,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,EACpD,IAAI,CAAC,EAAE;IACN;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CACvC,GACC,MAAM,CAkJR"}
|
package/out/geonames-aliases.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* For each POPULATED place (feature class `P`) this writes an `spr` row + `names` rows (primary +
|
|
14
14
|
* Latin alt-names) + population into the SAME tables the WOF/Overture paths use — synthetic ids
|
|
15
15
|
* based at {@link GEONAMES_ID_BASE} so the three sources never collide. The caller then rebuilds
|
|
16
|
-
* `place_search` ({@link
|
|
16
|
+
* `place_search` ({@link buildPlaceSearchFTS} with `drop: true`) so the candidate build carries
|
|
17
17
|
* Karjaa↔Karis. Proven (FI hard-resolve 69.5 → 85.8 %, coverage 74.4 → 94.0 %); duplicating a
|
|
18
18
|
* place already held under another source is benign — the rows share name_key+coord and the
|
|
19
19
|
* candidate ranking dedupes by score.
|
|
@@ -26,19 +26,19 @@
|
|
|
26
26
|
import { existsSync, readFileSync } from "node:fs";
|
|
27
27
|
import { join } from "node:path";
|
|
28
28
|
/**
|
|
29
|
-
* Synthetic id base for GeoNames-sourced rows (#743/#193) — above Overture's 8e12 so the three
|
|
30
|
-
*
|
|
29
|
+
* Synthetic id base for GeoNames-sourced rows (#743/#193) — above Overture's 8e12 so the three sources (WOF real ids,
|
|
30
|
+
* Overture, GeoNames) never collide in a combined DB.
|
|
31
31
|
*/
|
|
32
32
|
export const GEONAMES_ID_BASE = 9_000_000_000_000;
|
|
33
33
|
/**
|
|
34
|
-
* Fold the GeoNames `P`-class places (+ their Latin alt-names) for `countries` into `db`'s `spr` /
|
|
35
|
-
* `
|
|
34
|
+
* Fold the GeoNames `P`-class places (+ their Latin alt-names) for `countries` into `db`'s `spr` / `names` /
|
|
35
|
+
* `place_population` tables. Returns the total places ingested.
|
|
36
36
|
*
|
|
37
|
-
* `onProgress` receives one event per country (default: a stderr line, matching the build scripts'
|
|
38
|
-
*
|
|
39
|
-
*
|
|
37
|
+
* `onProgress` receives one event per country (default: a stderr line, matching the build scripts' legacy output). The
|
|
38
|
+
* caller MUST rebuild `place_search` afterward (`buildPlaceSearchFTS(db, { drop: true })`) for the new names to reach
|
|
39
|
+
* the candidate build's alias pass.
|
|
40
40
|
*/
|
|
41
|
-
export function ingestGeonamesAliases(db, countries, geonamesDir, onProgress) {
|
|
41
|
+
export function ingestGeonamesAliases(db, countries, geonamesDir, onProgress, opts) {
|
|
42
42
|
// Latin-only, no bracket/paren noise GeoNames packs into `alternatenames` ("(( Karis Landskommun ))",
|
|
43
43
|
// airport codes), 2–60 chars, at least one letter (drops bare postcodes/numbers).
|
|
44
44
|
const LATIN_NAME = /^[\p{Script=Latin}\p{M}\s\-'.]{2,60}$/u;
|
|
@@ -49,6 +49,9 @@ export function ingestGeonamesAliases(db, countries, geonamesDir, onProgress) {
|
|
|
49
49
|
const sprInsert = db.prepare(`INSERT OR REPLACE INTO spr (id, parent_id, name, placetype, country, latitude, longitude, min_latitude, min_longitude, max_latitude, max_longitude, is_current, is_deprecated, is_ceased, is_superseded, is_superseding, lastmodified) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
50
50
|
const namesInsert = db.prepare(`INSERT INTO names (id, name, placetype, country, language, lastmodified) VALUES (?, ?, ?, ?, ?, ?)`);
|
|
51
51
|
const populationInsert = db.prepare(`INSERT OR REPLACE INTO place_population (id, population) VALUES (?, ?)`);
|
|
52
|
+
// #267 admin linkage: ancestor rows (locality→region→country) so parentID scoping + adminCoherence reach
|
|
53
|
+
// the gap countries. Only used for a country in opts.adminForCountries.
|
|
54
|
+
const ancestorInsert = db.prepare(`INSERT INTO ancestors (id, ancestor_id, ancestor_placetype, lastmodified) VALUES (?, ?, ?, 0)`);
|
|
52
55
|
const report = (event, missingFile) => {
|
|
53
56
|
if (onProgress) {
|
|
54
57
|
onProgress(event);
|
|
@@ -70,8 +73,53 @@ export function ingestGeonamesAliases(db, countries, geonamesDir, onProgress) {
|
|
|
70
73
|
continue;
|
|
71
74
|
}
|
|
72
75
|
let nc = 0;
|
|
73
|
-
//
|
|
74
|
-
|
|
76
|
+
// #267: add A-class admin + ancestry only for the gap countries this country is in (never the EU set).
|
|
77
|
+
const addAdmin = opts?.adminForCountries?.has(cc) ?? false;
|
|
78
|
+
// GeoNames dump columns (0-indexed): 1 name, 2 asciiname, 3 alternatenames, 4 lat, 5 lon, 6 feature_class,
|
|
79
|
+
// 7 feature_code, 10 admin1 code, 14 pop.
|
|
80
|
+
const lines = readFileSync(file, "utf8").split("\n");
|
|
81
|
+
// #267 admin pre-pass (gap countries): fold the country (PCLI) + regions (ADM1), self+ancestry them, and
|
|
82
|
+
// build the admin1→region map the localities link through. Point bbox (GeoNames gives a centroid only).
|
|
83
|
+
let countryID = -1;
|
|
84
|
+
const adminMap = new Map();
|
|
85
|
+
if (addAdmin) {
|
|
86
|
+
for (const line of lines) {
|
|
87
|
+
const f = line.split("\t");
|
|
88
|
+
if (f[6] !== "A")
|
|
89
|
+
continue;
|
|
90
|
+
const aname = clean(f[2] ?? "") ?? clean(f[1] ?? "");
|
|
91
|
+
if (!aname)
|
|
92
|
+
continue;
|
|
93
|
+
const lat = Number(f[4]) || 0;
|
|
94
|
+
const lon = Number(f[5]) || 0;
|
|
95
|
+
if (f[7]?.startsWith("PCL")) {
|
|
96
|
+
// Any country-level political entity — PCLI (independent), PCLD (dependent territory),
|
|
97
|
+
// PCLF (freely associated), PCLS (special administrative region: HK/MO/PS). All are the
|
|
98
|
+
// country tier; restricting to PCLI left those ~17 territories without a country row.
|
|
99
|
+
if (countryID >= 0)
|
|
100
|
+
continue; // one country row
|
|
101
|
+
countryID = id++;
|
|
102
|
+
sprInsert.run(countryID, -1, aname, "country", cc, lat, lon, lat, lon, lat, lon, 1, 0, 0, 0, 0, 0);
|
|
103
|
+
namesInsert.run(countryID, aname, "country", cc, "", 0);
|
|
104
|
+
ancestorInsert.run(countryID, countryID, "country");
|
|
105
|
+
}
|
|
106
|
+
else if (f[7] === "ADM1" && f[10]) {
|
|
107
|
+
const rid = id++;
|
|
108
|
+
sprInsert.run(rid, -1, aname, "region", cc, lat, lon, lat, lon, lat, lon, 1, 0, 0, 0, 0, 0);
|
|
109
|
+
namesInsert.run(rid, aname, "region", cc, "", 0);
|
|
110
|
+
ancestorInsert.run(rid, rid, "region");
|
|
111
|
+
adminMap.set(f[10], rid);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Re-parent regions + ancestor them to the (now-known) country.
|
|
115
|
+
if (countryID >= 0) {
|
|
116
|
+
for (const rid of adminMap.values()) {
|
|
117
|
+
db.prepare("UPDATE spr SET parent_id = ? WHERE id = ?").run(countryID, rid);
|
|
118
|
+
ancestorInsert.run(rid, countryID, "country");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
for (const line of lines) {
|
|
75
123
|
if (!line)
|
|
76
124
|
continue;
|
|
77
125
|
const f = line.split("\t");
|
|
@@ -85,10 +133,20 @@ export function ingestGeonamesAliases(db, countries, geonamesDir, onProgress) {
|
|
|
85
133
|
if (!name)
|
|
86
134
|
continue;
|
|
87
135
|
const nid = id++;
|
|
136
|
+
// #267: link to the locality's region (else country) for gap countries; -1 (orphan) otherwise.
|
|
137
|
+
const regionID = addAdmin ? (adminMap.get(f[10] ?? "") ?? -1) : -1;
|
|
138
|
+
const parentID = regionID >= 0 ? regionID : addAdmin && countryID >= 0 ? countryID : -1;
|
|
88
139
|
// Point bbox — a GeoNames row is a centroid; the candidate's region-bbox disambiguation just
|
|
89
140
|
// sees it as contained in itself, fine for a locality.
|
|
90
|
-
sprInsert.run(nid,
|
|
141
|
+
sprInsert.run(nid, parentID, name, "locality", cc, lat, lon, lat, lon, lat, lon, 1, 0, 0, 0, 0, 0);
|
|
91
142
|
namesInsert.run(nid, name, "locality", cc, "", 0);
|
|
143
|
+
if (addAdmin) {
|
|
144
|
+
ancestorInsert.run(nid, nid, "locality");
|
|
145
|
+
if (regionID >= 0)
|
|
146
|
+
ancestorInsert.run(nid, regionID, "region");
|
|
147
|
+
if (countryID >= 0)
|
|
148
|
+
ancestorInsert.run(nid, countryID, "country");
|
|
149
|
+
}
|
|
92
150
|
const seen = new Set([name]);
|
|
93
151
|
for (const raw of [f[2] ?? "", ...(f[3] ? f[3].split(",") : [])]) {
|
|
94
152
|
const alt = clean(raw);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geonames-aliases.js","sourceRoot":"","sources":["../geonames-aliases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAGhC;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,iBAAiB,CAAA;AAYjD;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CACpC,EAAgB,EAChB,SAAmB,EACnB,WAAmB,EACnB,UAAoD;
|
|
1
|
+
{"version":3,"file":"geonames-aliases.js","sourceRoot":"","sources":["../geonames-aliases.ts"],"names":[],"mappings":"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"}
|
package/out/index.d.ts
CHANGED
|
@@ -3,25 +3,25 @@
|
|
|
3
3
|
* @license AGPL-3.0
|
|
4
4
|
* @author Teffen Ellis, et al.
|
|
5
5
|
*/
|
|
6
|
-
export type { FindPlaceQuery, GeoBbox, GeoPoint, PlaceCandidate, PlaceLookup,
|
|
7
|
-
export type { AncestorsTable, CoincidentRolesTable, ConcordancesTable, GeojsonTable, NamesTable, PlaceAbbrTable, PlacePopulationTable, PlaceSearchTable, SprTable,
|
|
8
|
-
export {
|
|
9
|
-
export { CANDIDATE_FTS_TABLE,
|
|
10
|
-
export {
|
|
6
|
+
export type { FindPlaceQuery, GeoBbox, GeoPoint, PlaceCandidate, PlaceLookup, WOFPlacetype } from "./types.js";
|
|
7
|
+
export type { AncestorsTable, CoincidentRolesTable, ConcordancesTable, GeojsonTable, NamesTable, PlaceAbbrTable, PlacePopulationTable, PlaceSearchTable, SprTable, WOFDatabase, } from "./schema.js";
|
|
8
|
+
export { WOFSqlitePlaceLookup, type RankingWeights, type WOFSqlitePlaceLookupOpts } from "./lookup.js";
|
|
9
|
+
export { CANDIDATE_FTS_TABLE, createCandidateFTS } from "./candidate-fts.js";
|
|
10
|
+
export { WOFCandidateTableLookup, type WOFCandidateTableLookupOpts } from "./candidate-lookup.js";
|
|
11
11
|
export { GEONAMES_ID_BASE, ingestGeonamesAliases, type GeonamesIngestProgress } from "./geonames-aliases.js";
|
|
12
12
|
export { ADDRESS_POINT_COLUMNS, createAddressPointIndexes, createAddressPointTable } from "./address-point-schema.js";
|
|
13
13
|
export type { AddressPointDatabase, AddressPointTable } from "./address-point-schema.js";
|
|
14
|
-
export {
|
|
14
|
+
export { WOFPostalCityAliasLookup, type PostalCityAlias, type WOFPostalCityAliasLookupOpts, } from "./postal-city-alias-lookup.js";
|
|
15
15
|
export type { PostalCityAliasDatabase, PostalCityAliasTable } from "./postal-city-alias-schema.js";
|
|
16
16
|
export { POSTAL_CITY_CANDIDATE_COLUMNS, POSTAL_CITY_CANDIDATE_TABLE, createPostalCityCandidateTable, } from "./postal-city-candidate-schema.js";
|
|
17
17
|
export type { PostalCityCandidateDatabase, PostalCityCandidateTable } from "./postal-city-candidate-schema.js";
|
|
18
18
|
export { ADDRESS_CONVENTION_TABLE, BUILTIN_STRATEGY_NAMES, SeedConventionSource, WORLD_DEFAULT, mergeConventions, resolveConvention, type Convention, type ConventionSource, type ResolvedConvention, type ScoringWeights, type Strategy, } from "./convention.js";
|
|
19
19
|
export { SqliteConventionSource } from "./sqlite-convention-source.js";
|
|
20
|
-
export {
|
|
21
|
-
export { PLACE_BBOX_TABLE, PLACE_SEARCH_TABLE,
|
|
20
|
+
export { WOFPostcodeLookup, type PostcodePlace } from "./postcode-point-lookup.js";
|
|
21
|
+
export { PLACE_BBOX_TABLE, PLACE_SEARCH_TABLE, buildPlaceSearchFTS, placeBboxExists, placeSearchFTSExists, type BuildPlaceSearchFTSOpts, type BuildPlaceSearchFTSResult, } from "./fts.js";
|
|
22
22
|
export { bboxAround, geometryContains, haversineKm, pointInPolygonRings, pointInRing, type Bbox, type GeojsonGeometry, type GeojsonMultiPolygon, type GeojsonPolygon, type GeojsonPosition, } from "./geo.js";
|
|
23
23
|
export { PLACETYPE_DEPTH, ancestorLineage, placetypeDepth, type AncestorPlaceRow } from "./ancestry.js";
|
|
24
|
-
export {
|
|
24
|
+
export { WOFReverseGeocoder, type ContainmentKind, type ReverseGeocodeOpts, type ReverseGeocodeResult, type WOFReverseGeocoderOpts, } from "./reverse.js";
|
|
25
25
|
export { AddressPointInterpolator } from "./address-point-interpolation.js";
|
|
26
26
|
export { AddressPointSqliteLookup } from "./address-point.js";
|
|
27
27
|
export { StreetInterpolator, type InterpolatedHit, type InterpolationMethod, type InterpolationQuery, } from "./interpolation.js";
|