@mailwoman/resolver-wof-sqlite 9.0.0 → 9.1.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/build-candidate.ts +97 -4
- package/candidate-importance.ts +227 -0
- package/candidate-lookup.ts +144 -7
- package/candidate-schema.ts +29 -0
- package/fst-autocomplete.ts +22 -11
- package/fst-builder.ts +25 -35
- package/fst-deserialize-web.ts +43 -7
- package/fst-serialize.ts +68 -12
- package/fst-types.ts +35 -1
- package/fts.ts +12 -0
- package/index.ts +8 -0
- package/lookup.ts +44 -5
- package/out/build-candidate.d.ts +33 -0
- package/out/build-candidate.d.ts.map +1 -1
- package/out/build-candidate.js +37 -4
- package/out/build-candidate.js.map +1 -1
- package/out/candidate-importance.d.ts +132 -0
- package/out/candidate-importance.d.ts.map +1 -0
- package/out/candidate-importance.js +174 -0
- package/out/candidate-importance.js.map +1 -0
- package/out/candidate-lookup.d.ts +9 -1
- package/out/candidate-lookup.d.ts.map +1 -1
- package/out/candidate-lookup.js +115 -6
- package/out/candidate-lookup.js.map +1 -1
- package/out/candidate-schema.d.ts +25 -1
- package/out/candidate-schema.d.ts.map +1 -1
- package/out/candidate-schema.js +5 -0
- package/out/candidate-schema.js.map +1 -1
- package/out/fst-autocomplete.d.ts +13 -3
- package/out/fst-autocomplete.d.ts.map +1 -1
- package/out/fst-autocomplete.js +10 -9
- package/out/fst-autocomplete.js.map +1 -1
- package/out/fst-builder.d.ts.map +1 -1
- package/out/fst-builder.js +21 -28
- package/out/fst-builder.js.map +1 -1
- package/out/fst-deserialize-web.d.ts.map +1 -1
- package/out/fst-deserialize-web.js +36 -7
- package/out/fst-deserialize-web.js.map +1 -1
- package/out/fst-serialize.d.ts +14 -4
- package/out/fst-serialize.d.ts.map +1 -1
- package/out/fst-serialize.js +60 -12
- package/out/fst-serialize.js.map +1 -1
- package/out/fst-types.d.ts +35 -1
- package/out/fst-types.d.ts.map +1 -1
- package/out/fts.d.ts +11 -0
- package/out/fts.d.ts.map +1 -1
- package/out/fts.js +11 -0
- package/out/fts.js.map +1 -1
- package/out/index.d.ts +1 -0
- package/out/index.d.ts.map +1 -1
- package/out/index.js +1 -0
- package/out/index.js.map +1 -1
- package/out/lookup.d.ts.map +1 -1
- package/out/lookup.js +37 -5
- package/out/lookup.js.map +1 -1
- package/out/place-importance-schema.d.ts +189 -0
- package/out/place-importance-schema.d.ts.map +1 -0
- package/out/place-importance-schema.js +242 -0
- package/out/place-importance-schema.js.map +1 -0
- package/out/sqlite-utils.d.ts +12 -0
- package/out/sqlite-utils.d.ts.map +1 -1
- package/out/sqlite-utils.js +20 -0
- package/out/sqlite-utils.js.map +1 -1
- package/out/street-morphology-fst-builder.d.ts.map +1 -1
- package/out/street-morphology-fst-builder.js +5 -4
- package/out/street-morphology-fst-builder.js.map +1 -1
- package/out/street-normalize.d.ts +2 -1
- package/out/street-normalize.d.ts.map +1 -1
- package/out/street-normalize.js +2 -1
- package/out/street-normalize.js.map +1 -1
- package/out/types.d.ts +39 -0
- package/out/types.d.ts.map +1 -1
- package/package.json +14 -6
- package/place-importance-schema.ts +353 -0
- package/sqlite-utils.ts +21 -0
- package/street-morphology-fst-builder.ts +5 -4
- package/street-normalize.ts +3 -2
- package/types.ts +39 -0
package/lookup.ts
CHANGED
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
} from "./fts.ts"
|
|
40
40
|
import { bboxAround, haversineKm } from "./geo.ts"
|
|
41
41
|
import { cfNormalize, softNameScore, trigramJaccard } from "./name-score.ts"
|
|
42
|
+
import { compareReferential, encyclopedicClauses, referentialFromPopulation } from "./place-importance-schema.ts"
|
|
42
43
|
import type { WOFPostalCityAliasLookup } from "./postal-city-alias-lookup.ts"
|
|
43
44
|
import { DEFAULT_WEIGHTS, type RankingWeights } from "./ranking-weights.ts"
|
|
44
45
|
import type { WOFDatabase } from "./schema.ts"
|
|
@@ -137,6 +138,11 @@ interface RawSearchRow {
|
|
|
137
138
|
min_longitude: number | null
|
|
138
139
|
max_longitude: number | null
|
|
139
140
|
population: number | null // from the place_population aux table; null when missing
|
|
141
|
+
/**
|
|
142
|
+
* From `place_importance.encyclopedic` when the shard's table carries the two-score split columns. NULL means the
|
|
143
|
+
* place has no Wikipedia article, or the shard predates the split — absence either way, and never 0 (ROAD_TO_V9 §2).
|
|
144
|
+
*/
|
|
145
|
+
encyclopedic: number | null
|
|
140
146
|
}
|
|
141
147
|
|
|
142
148
|
/**
|
|
@@ -179,6 +185,12 @@ export class WOFSqlitePlaceLookup implements PlaceLookup, Disposable {
|
|
|
179
185
|
* population boost is 0 for every row — preserves compatibility with DBs built before this feature shipped.
|
|
180
186
|
*/
|
|
181
187
|
readonly #hasPopulationIndex: Map<string, boolean>
|
|
188
|
+
/**
|
|
189
|
+
* Per-shard SELECT term + LEFT JOIN for the two-score split's `encyclopedic` carry (ROAD_TO_V9 §2 R1), probed and
|
|
190
|
+
* built once at construction. Degrades to `NULL AS encyclopedic` with no join on a pre-split shard — every shipped
|
|
191
|
+
* shard today. See {@link encyclopedicClauses} for why the probe is a column and not a table.
|
|
192
|
+
*/
|
|
193
|
+
readonly #encyclopedicClauses: Map<string, { select: string; join: string }>
|
|
182
194
|
/**
|
|
183
195
|
* Per-shard probe for the `postcode_locality` table (the coordinate-first candidate table, built by
|
|
184
196
|
* scripts/build-postcode-locality.ts). Cached at construction; null'd out when absent so the coord-first path
|
|
@@ -273,10 +285,12 @@ export class WOFSqlitePlaceLookup implements PlaceLookup, Disposable {
|
|
|
273
285
|
// sqlite_master. Cached at construction so findPlace doesn't query sqlite_master per call.
|
|
274
286
|
this.#hasBboxIndex = new Map()
|
|
275
287
|
this.#hasPopulationIndex = new Map()
|
|
288
|
+
this.#encyclopedicClauses = new Map()
|
|
276
289
|
|
|
277
290
|
for (const s of this.#shards) {
|
|
278
291
|
this.#hasBboxIndex.set(s.schemaName, this.#shardHasTable(s.schemaName, PLACE_BBOX_TABLE))
|
|
279
292
|
this.#hasPopulationIndex.set(s.schemaName, this.#shardHasTable(s.schemaName, PLACE_POPULATION_TABLE))
|
|
293
|
+
this.#encyclopedicClauses.set(s.schemaName, encyclopedicClauses(this.#db, s.schemaName))
|
|
280
294
|
}
|
|
281
295
|
|
|
282
296
|
// #920 country-aware shard routing: probe each NON-MAIN shard's country set once at
|
|
@@ -666,6 +680,11 @@ export class WOFSqlitePlaceLookup implements PlaceLookup, Disposable {
|
|
|
666
680
|
? `LEFT JOIN ${sch}.${PLACE_POPULATION_TABLE} ON ${PLACE_POPULATION_TABLE}.id = spr.id`
|
|
667
681
|
: ""
|
|
668
682
|
|
|
683
|
+
// The encyclopedic score is CARRIED, never ranked on (ROAD_TO_V9 §2, ratified 2026-08-06) — it
|
|
684
|
+
// appears in the SELECT and in no ORDER BY, here or in the companion fetch below. Gated on the
|
|
685
|
+
// split column, so a pre-split shard emits a literal NULL and builds no join at all.
|
|
686
|
+
const { select: encyclopedicSelect, join: encyclopedicJoin } = this.#encyclopedicClauses.get(sch)!
|
|
687
|
+
|
|
669
688
|
// Push the population boost into the ORDER BY when the index is available, so famous places
|
|
670
689
|
// (whose long alt-name lists hurt BM25) actually make it into the over-fetch window. The TS
|
|
671
690
|
// post-scoring will still compute the same boost for the final score; this just ensures the
|
|
@@ -697,10 +716,12 @@ export class WOFSqlitePlaceLookup implements PlaceLookup, Disposable {
|
|
|
697
716
|
spr.latitude AS lat,
|
|
698
717
|
spr.longitude AS lon,
|
|
699
718
|
spr.min_latitude, spr.max_latitude, spr.min_longitude, spr.max_longitude,
|
|
700
|
-
${populationSelect}
|
|
719
|
+
${populationSelect},
|
|
720
|
+
${encyclopedicSelect}
|
|
701
721
|
FROM ${sch}.place_search
|
|
702
722
|
${joinClause}
|
|
703
723
|
${populationJoin}
|
|
724
|
+
${encyclopedicJoin}
|
|
704
725
|
WHERE ${where.join(" AND ")}
|
|
705
726
|
ORDER BY ${orderByExpr} ASC
|
|
706
727
|
LIMIT ?
|
|
@@ -732,10 +753,12 @@ export class WOFSqlitePlaceLookup implements PlaceLookup, Disposable {
|
|
|
732
753
|
spr.latitude AS lat,
|
|
733
754
|
spr.longitude AS lon,
|
|
734
755
|
spr.min_latitude, spr.max_latitude, spr.min_longitude, spr.max_longitude,
|
|
735
|
-
${populationSelect}
|
|
756
|
+
${populationSelect},
|
|
757
|
+
${encyclopedicSelect}
|
|
736
758
|
FROM ${sch}.place_search
|
|
737
759
|
${joinClause}
|
|
738
760
|
${populationJoin}
|
|
761
|
+
${encyclopedicJoin}
|
|
739
762
|
WHERE ${where.join(" AND ")}
|
|
740
763
|
ORDER BY COALESCE(${PLACE_POPULATION_TABLE}.population, 0) DESC
|
|
741
764
|
LIMIT ?
|
|
@@ -848,6 +871,14 @@ export class WOFSqlitePlaceLookup implements PlaceLookup, Disposable {
|
|
|
848
871
|
|
|
849
872
|
if (row.population !== null && row.population > 0) {
|
|
850
873
|
candidate.population = row.population
|
|
874
|
+
// The named ranking key (ROAD_TO_V9 §2). DERIVED, not stored — a pure function of the
|
|
875
|
+
// population already on this row, so it cannot drift from what the ordering uses.
|
|
876
|
+
candidate.referential = referentialFromPopulation(row.population)
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
// Carried for consumers (annotations / API surfaces). No ranking site reads it.
|
|
880
|
+
if (row.encyclopedic !== null) {
|
|
881
|
+
candidate.encyclopedic = row.encyclopedic
|
|
851
882
|
}
|
|
852
883
|
|
|
853
884
|
// Candidate bbox — parity with the WASM lookup (resolver-wof-wasm/lookup.ts), whose
|
|
@@ -936,8 +967,16 @@ export class WOFSqlitePlaceLookup implements PlaceLookup, Disposable {
|
|
|
936
967
|
|
|
937
968
|
// With proximity hints (near/bias), prominence (population + nearness, same units)
|
|
938
969
|
// replaces raw population as the within-tier key — the 48026 rule: the map view or
|
|
939
|
-
// the user's location breaks a cross-country postcode tie. Without hints,
|
|
940
|
-
// ordering
|
|
970
|
+
// the user's location breaks a cross-country postcode tie. Without hints, REFERENTIAL
|
|
971
|
+
// ordering decides.
|
|
972
|
+
//
|
|
973
|
+
// ROAD_TO_V9 §2: this is the site that "orders namesakes", so it is the site that has to
|
|
974
|
+
// say what it orders by. `compareReferential` is referential DESC with raw population as
|
|
975
|
+
// the tiebreak, which is provably the SAME ORDER as the `(b.population ?? 0) - (a.population ?? 0)`
|
|
976
|
+
// it replaces — referential is strictly increasing in population below saturation and
|
|
977
|
+
// constant above it, and the tiebreak restores the order in the saturated tail. Measured
|
|
978
|
+
// zero-delta, not assumed: see `place-importance-schema.test.ts` and `resolver-referential-ranking.test.ts`.
|
|
979
|
+
// Encyclopedic importance is not, and must not become, an input here.
|
|
941
980
|
const hasHints = !!query.near || (query.bias?.length ?? 0) > 0
|
|
942
981
|
|
|
943
982
|
candidates.sort((a, b) => {
|
|
@@ -949,7 +988,7 @@ export class WOFSqlitePlaceLookup implements PlaceLookup, Disposable {
|
|
|
949
988
|
if (ax >= 1) {
|
|
950
989
|
if (hasHints) return (b.prominence ?? 0) - (a.prominence ?? 0) || b.score - a.score
|
|
951
990
|
|
|
952
|
-
return (
|
|
991
|
+
return compareReferential(a, b) || b.score - a.score
|
|
953
992
|
}
|
|
954
993
|
|
|
955
994
|
return b.score - a.score
|
package/out/build-candidate.d.ts
CHANGED
|
@@ -26,6 +26,12 @@
|
|
|
26
26
|
*
|
|
27
27
|
* Measured (2026-06-20, vs the 2.6 GB full-DB FTS): ~5 M rows; ~12 range fetches per 8-query
|
|
28
28
|
* session (the full DB needs 243); US locality 96.8% (region bbox), EU coord parity 88.6%.
|
|
29
|
+
*
|
|
30
|
+
* #28 adds one more denormalized field, `importance` — the toponym-fame prior that decides a BARE
|
|
31
|
+
* city name, joined in from a separate score source by name rather than by id (see
|
|
32
|
+
* `candidate-importance.ts`, which owns that join and explains why the id would be wrong). It is
|
|
33
|
+
* optional: without {@link BuildCandidateOptions.importance} the column is NULL on every row, which
|
|
34
|
+
* the consumer reads as unmeasured and ignores.
|
|
29
35
|
*/
|
|
30
36
|
export interface BuildCandidateOptions {
|
|
31
37
|
/**
|
|
@@ -45,6 +51,18 @@ export interface BuildCandidateOptions {
|
|
|
45
51
|
* ("Brooklyn" for 11201), and they were previously reachable only through FTS.
|
|
46
52
|
*/
|
|
47
53
|
postcodes?: string[];
|
|
54
|
+
/**
|
|
55
|
+
* Optional WOF admin database carrying a `place_importance` table — the source of the `importance` column (#28), the
|
|
56
|
+
* toponym-fame prior that decides the bare-city-name class. Joined by `(name_key, country, placetype)` + nearest
|
|
57
|
+
* centroid, NOT by id; see `candidate-importance.ts` for why the id join silently drops the foreign homonyms the
|
|
58
|
+
* prior exists to demote.
|
|
59
|
+
*
|
|
60
|
+
* Omit it and every row's `importance` is NULL — unmeasured, which is what the consumer's positive-evidence-only rule
|
|
61
|
+
* already treats as "do not participate", so the artifact is byte-identical to a pre-#28 build except for the empty
|
|
62
|
+
* column. That is the honest degradation and it is the DEFAULT: a caller with no score source must not get a
|
|
63
|
+
* population-derived stand-in written into a column that means fame.
|
|
64
|
+
*/
|
|
65
|
+
importance?: string;
|
|
48
66
|
/**
|
|
49
67
|
* Optional progress callback for CLI / test introspection.
|
|
50
68
|
*/
|
|
@@ -63,6 +81,21 @@ export interface BuildCandidateResult {
|
|
|
63
81
|
* through `onProgress`.
|
|
64
82
|
*/
|
|
65
83
|
postcodeAliases: number;
|
|
84
|
+
/**
|
|
85
|
+
* Places that took an `importance` score from the join (#28).
|
|
86
|
+
*
|
|
87
|
+
* `undefined` and `0` mean different things. `undefined` is "the pass did not run" — no score source was given. A `0`
|
|
88
|
+
* would be the source matching NOTHING, which is a finding. Never collapse the two.
|
|
89
|
+
*/
|
|
90
|
+
importanceScored?: number;
|
|
91
|
+
/**
|
|
92
|
+
* Places whose `(name_key, country, placetype)` matched a scored group but whose nearest scored centroid was outside
|
|
93
|
+
* {@link IMPORTANCE_JOIN_GATE_KM} — a different town wearing the same name, refused rather than scored.
|
|
94
|
+
*
|
|
95
|
+
* Worth watching across rebuilds: a jump here means the score source and the admin source have drifted apart, and the
|
|
96
|
+
* join is being asked to guess.
|
|
97
|
+
*/
|
|
98
|
+
importanceGated?: number;
|
|
66
99
|
}
|
|
67
100
|
export declare function buildCandidateTable(opts: BuildCandidateOptions): Promise<BuildCandidateResult>;
|
|
68
101
|
//# sourceMappingURL=build-candidate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-candidate.d.ts","sourceRoot":"","sources":["../build-candidate.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"build-candidate.d.ts","sourceRoot":"","sources":["../build-candidate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAsBH,MAAM,WAAW,qBAAqB;IACrC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CACrD;AAED,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,eAAe,EAAE,MAAM,CAAA;IACvB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;CACxB;AAwBD,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA8apG"}
|
package/out/build-candidate.js
CHANGED
|
@@ -26,11 +26,18 @@
|
|
|
26
26
|
*
|
|
27
27
|
* Measured (2026-06-20, vs the 2.6 GB full-DB FTS): ~5 M rows; ~12 range fetches per 8-query
|
|
28
28
|
* session (the full DB needs 243); US locality 96.8% (region bbox), EU coord parity 88.6%.
|
|
29
|
+
*
|
|
30
|
+
* #28 adds one more denormalized field, `importance` — the toponym-fame prior that decides a BARE
|
|
31
|
+
* city name, joined in from a separate score source by name rather than by id (see
|
|
32
|
+
* `candidate-importance.ts`, which owns that join and explains why the id would be wrong). It is
|
|
33
|
+
* optional: without {@link BuildCandidateOptions.importance} the column is NULL on every row, which
|
|
34
|
+
* the consumer reads as unmeasured and ignores.
|
|
29
35
|
*/
|
|
30
36
|
import { existsSync, rmSync } from "node:fs";
|
|
31
37
|
import { DatabaseSync } from "node:sqlite";
|
|
32
38
|
import { DatabaseClient } from "@mailwoman/core/kysley/client";
|
|
33
39
|
import { createCandidateFTS } from "./candidate-fts.js";
|
|
40
|
+
import { IMPORTANCE_JOIN_GATE_KM, loadImportanceIndex } from "./candidate-importance.js";
|
|
34
41
|
import { CANDIDATE_COLUMNS, createCandidateStagingTables, createCandidateTable, } from "./candidate-schema.js";
|
|
35
42
|
import { normalizeLocalityForKey } from "./street-normalize.js";
|
|
36
43
|
/**
|
|
@@ -71,6 +78,20 @@ export async function buildCandidateTable(opts) {
|
|
|
71
78
|
}
|
|
72
79
|
return id;
|
|
73
80
|
};
|
|
81
|
+
// --- importance source (#28): loaded BEFORE pass 1, which is the only pass that sees a place's
|
|
82
|
+
// name/country/placetype/centroid together. Absent → every row's `importance` stays NULL. ---
|
|
83
|
+
let importance;
|
|
84
|
+
if (opts.importance) {
|
|
85
|
+
progress("importance", `loading place_importance from ${opts.importance}`);
|
|
86
|
+
importance = loadImportanceIndex(opts.importance);
|
|
87
|
+
progress("importance", `${importance.stats.places.toLocaleString()} scored places in ${importance.stats.keys.toLocaleString()} (name, country, placetype) groups` +
|
|
88
|
+
(importance.stats.unkeyable ? `; ${importance.stats.unkeyable.toLocaleString()} unkeyable names skipped` : ""));
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
// Never a silent column of nulls: a build without a score source produces one, and the reason has
|
|
92
|
+
// to be visible in the log rather than inferred from the artifact.
|
|
93
|
+
progress("importance", "no score source given — `importance` will be NULL on every row");
|
|
94
|
+
}
|
|
74
95
|
// --- region_id per place (its region-tier ancestor) for same-name disambiguation ---
|
|
75
96
|
progress("region", "loading region ancestry");
|
|
76
97
|
const regionOf = new Map();
|
|
@@ -118,13 +139,15 @@ export async function buildCandidateTable(opts) {
|
|
|
118
139
|
const neg = -Math.log10(pop + 1);
|
|
119
140
|
const name = String(r.name ?? "");
|
|
120
141
|
const pkey = normalizeLocalityForKey(name);
|
|
142
|
+
const lat = r.lat;
|
|
143
|
+
const lon = r.lon;
|
|
121
144
|
const a = {
|
|
122
145
|
cid,
|
|
123
146
|
rid,
|
|
124
147
|
ptid,
|
|
125
148
|
name,
|
|
126
|
-
lat
|
|
127
|
-
lon
|
|
149
|
+
lat,
|
|
150
|
+
lon,
|
|
128
151
|
mnLat: r.mnlat,
|
|
129
152
|
mnLon: r.mnlon,
|
|
130
153
|
mxLat: r.mxlat,
|
|
@@ -132,17 +155,22 @@ export async function buildCandidateTable(opts) {
|
|
|
132
155
|
pop,
|
|
133
156
|
neg,
|
|
134
157
|
pkey,
|
|
158
|
+
imp: importance?.find(name, r.country, r.placetype, lat, lon) ?? null,
|
|
135
159
|
};
|
|
136
160
|
attrs.set(sid, a);
|
|
137
161
|
if (pkey) {
|
|
138
|
-
insStage.run(pkey, cid, rid, ptid, neg, sid, name, a.lat, a.lon, a.mnLat, a.mnLon, a.mxLat, a.mxLon, pop, 1);
|
|
162
|
+
insStage.run(pkey, cid, rid, ptid, neg, sid, name, a.lat, a.lon, a.mnLat, a.mnLon, a.mxLat, a.mxLon, pop, 1, a.imp);
|
|
139
163
|
nPrim++;
|
|
140
164
|
}
|
|
141
165
|
}
|
|
142
166
|
out.exec("COMMIT");
|
|
143
167
|
progress("primaries", `${nPrim.toLocaleString()} primaries; ${attrs.size.toLocaleString()} places`);
|
|
168
|
+
if (importance) {
|
|
169
|
+
progress("importance", `${importance.matched.toLocaleString()} places scored; ` +
|
|
170
|
+
`${importance.gated.toLocaleString()} refused (nearest same-name place > ${IMPORTANCE_JOIN_GATE_KM} km away)`);
|
|
171
|
+
}
|
|
144
172
|
const stageRow = (k, a, sid, isPrimary) => {
|
|
145
|
-
insStage.run(k, a.cid, a.rid, a.ptid, a.neg, sid, a.name, a.lat, a.lon, a.mnLat, a.mnLon, a.mxLat, a.mxLon, a.pop, isPrimary);
|
|
173
|
+
insStage.run(k, a.cid, a.rid, a.ptid, a.neg, sid, a.name, a.lat, a.lon, a.mnLat, a.mnLon, a.mxLat, a.mxLon, a.pop, isPrimary, a.imp);
|
|
146
174
|
};
|
|
147
175
|
// --- pass 2: distinct normalized aliases from place_search.alt_names ---
|
|
148
176
|
progress("aliases", "exploding alias bags");
|
|
@@ -225,6 +253,10 @@ export async function buildCandidateTable(opts) {
|
|
|
225
253
|
pop: 0,
|
|
226
254
|
neg: 0,
|
|
227
255
|
pkey: key,
|
|
256
|
+
// A postcode has no toponym fame — nobody writes an encyclopedia article about SW1A 2AA — and
|
|
257
|
+
// the score source carries no `postalcode` rows to join against anyway. NULL is the truthful
|
|
258
|
+
// value: unmeasured, so the ranking key leaves postcode rows exactly where they were.
|
|
259
|
+
imp: null,
|
|
228
260
|
};
|
|
229
261
|
pcAttrs.set(Number(r.id), a);
|
|
230
262
|
stageRow(key, a, Number(r.id), 1);
|
|
@@ -330,6 +362,7 @@ export async function buildCandidateTable(opts) {
|
|
|
330
362
|
abbrevs: nAbbr,
|
|
331
363
|
postcodes: nPostcode,
|
|
332
364
|
postcodeAliases: nPostcodeAlias,
|
|
365
|
+
...(importance ? { importanceScored: importance.matched, importanceGated: importance.gated } : {}),
|
|
333
366
|
};
|
|
334
367
|
}
|
|
335
368
|
//# sourceMappingURL=build-candidate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-candidate.js","sourceRoot":"","sources":["../build-candidate.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"build-candidate.js","sourceRoot":"","sources":["../build-candidate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* The score side of the candidate build (#28) — load a WOF admin database's `place_importance` into
|
|
7
|
+
* a lookup the candidate builder can probe per place, so every candidate row can carry the
|
|
8
|
+
* toponym-fame prior a bare city name is decided on.
|
|
9
|
+
*
|
|
10
|
+
* ## Why this joins on the NAME and not on the id
|
|
11
|
+
*
|
|
12
|
+
* The obvious join is `candidate.spr_id = place_importance.id`, and it is wrong here. The score
|
|
13
|
+
* source (`admin-global-priority-importance.db`) and the candidate build's admin source are
|
|
14
|
+
* DIFFERENT SNAPSHOTS, and they disagree about ids for exactly the rows that matter: Whitby,
|
|
15
|
+
* Ontario is `8143502164401` in the shipped `candidate.db` and `8000001156384` in the score source
|
|
16
|
+
* — the Overture-sourced rows were re-keyed between the two. An id join silently drops every one of
|
|
17
|
+
* them, which means it drops precisely the FOREIGN HOMONYMS the fame prior exists to demote, and it
|
|
18
|
+
* drops them invisibly: the build succeeds, the column is populated, and the ranking is inert on
|
|
19
|
+
* the queries it was built for.
|
|
20
|
+
*
|
|
21
|
+
* So the join key is `(name_key, country, placetype)` — the same {@link normalizeLocalityForKey} the
|
|
22
|
+
* candidate build uses for its probe key, so the two sides fold identically by construction.
|
|
23
|
+
*
|
|
24
|
+
* ## Why the key alone is not enough
|
|
25
|
+
*
|
|
26
|
+
* `(warwick, US, locality)` names ELEVEN different places. Taking the group's max would give every
|
|
27
|
+
* Warwick in America the fame of Warwick, Rhode Island, which is the fan-out defect
|
|
28
|
+
* `importance-fanout.ts` documents one layer up, re-introduced at the join. So the group is
|
|
29
|
+
* disambiguated GEOGRAPHICALLY: the nearest centroid wins, and only within
|
|
30
|
+
* {@link IMPORTANCE_JOIN_GATE_KM}. Two artifacts describing the same settlement put its centroid in
|
|
31
|
+
* almost the same place; two same-named towns in one country do not.
|
|
32
|
+
*
|
|
33
|
+
* ## What lands in the column
|
|
34
|
+
*
|
|
35
|
+
* `place_importance.importance` VERBATIM — the pre-split conflation (encyclopedia-derived where
|
|
36
|
+
* the concordance matched, a population-derived proxy everywhere else). See
|
|
37
|
+
* {@link CandidateTable.importance} for why the split `encyclopedic` channel is deliberately NOT
|
|
38
|
+
* what is written here, with the measurement that settled it.
|
|
39
|
+
*
|
|
40
|
+
* A place with no match gets NULL. NULL is UNMEASURED, never zero — the consumer
|
|
41
|
+
* (`resolver/toponym-prior.ts`) leaves an unmeasured candidate exactly where population put it.
|
|
42
|
+
*/
|
|
43
|
+
/**
|
|
44
|
+
* How far apart two artifacts may put the same place's centroid and still be read as the same place.
|
|
45
|
+
*
|
|
46
|
+
* MEASURED, not guessed (2026-08-10, `admin-global-priority.db` × `admin-global-priority-importance.db`; 4,476,245
|
|
47
|
+
* current locality-tier places against 676,790 scored ones, 1,020,099 of which matched a scored group by `(name_key,
|
|
48
|
+
* country, placetype)`). The nearest-centroid distance is **exactly 0.00 km for 577,080 of them (56.6%)** — the two
|
|
49
|
+
* snapshots agree to the bit — and 656,755 (64.4%) are inside 500 m.
|
|
50
|
+
*
|
|
51
|
+
* What sets the gate is where that mode ENDS, and the per-kilometre density says so plainly. It falls from 1,076
|
|
52
|
+
* places/km over 3–5 km to a trough of **441 places/km over 7–10 km**, then climbs back and flattens onto a plateau of
|
|
53
|
+
* 760–780 places/km from 30 km out to 100 km and beyond. That plateau is the background rate of two DIFFERENT towns
|
|
54
|
+
* wearing one name in one country, and it does not decay with distance because there is no reason it should. 10 km is
|
|
55
|
+
* the floor between the two populations. Admitting it scores 679,163 places (66.6% of the matched set); pushing the
|
|
56
|
+
* gate to 25 km buys 8,722 more, and by then better than half of each additional kilometre is the wrong town.
|
|
57
|
+
*
|
|
58
|
+
* The four-row bare-GB board is insensitive across this whole range — 5 km and 25 km were both measured and select
|
|
59
|
+
* identical rows — so the value is chosen by what the join MEANS, not by what it scores. The gate is the definition of
|
|
60
|
+
* "this is the same place"; widening it past the floor starts handing one town's fame to another.
|
|
61
|
+
*/
|
|
62
|
+
export declare const IMPORTANCE_JOIN_GATE_KM = 10;
|
|
63
|
+
/**
|
|
64
|
+
* One scored place from the source: where it is, and what it scored.
|
|
65
|
+
*/
|
|
66
|
+
interface ScoredPlace {
|
|
67
|
+
lat: number;
|
|
68
|
+
lon: number;
|
|
69
|
+
importance: number;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* What {@link loadImportanceIndex} measured while reading the source. Reported by the builder so a run says how much of
|
|
73
|
+
* the gazetteer it actually scored, rather than leaving the caller to infer it from a column full of nulls.
|
|
74
|
+
*/
|
|
75
|
+
export interface ImportanceIndexStats {
|
|
76
|
+
/**
|
|
77
|
+
* Scored places read out of the source.
|
|
78
|
+
*/
|
|
79
|
+
places: number;
|
|
80
|
+
/**
|
|
81
|
+
* Distinct `(name_key, country, placetype)` groups they fall into.
|
|
82
|
+
*/
|
|
83
|
+
keys: number;
|
|
84
|
+
/**
|
|
85
|
+
* Places whose name folded to the empty key and could never be joined (non-Latin punctuation-only names, blanks).
|
|
86
|
+
*/
|
|
87
|
+
unkeyable: number;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* A loaded `place_importance`, probed by name + country + placetype + position.
|
|
91
|
+
*/
|
|
92
|
+
export declare class ImportanceIndex {
|
|
93
|
+
#private;
|
|
94
|
+
readonly stats: ImportanceIndexStats;
|
|
95
|
+
/**
|
|
96
|
+
* Places {@link find} matched inside the gate.
|
|
97
|
+
*/
|
|
98
|
+
matched: number;
|
|
99
|
+
/**
|
|
100
|
+
* Places {@link find} REFUSED — the key matched a scored group, but the nearest member of it was outside the gate, so
|
|
101
|
+
* it is a different place wearing the same name.
|
|
102
|
+
*
|
|
103
|
+
* This is the number worth watching across rebuilds. A jump means the score source and the admin source have drifted
|
|
104
|
+
* apart and the join is being asked to guess; it does not mean the gate is too tight.
|
|
105
|
+
*/
|
|
106
|
+
gated: number;
|
|
107
|
+
constructor(groups: Map<string, ScoredPlace[]>, stats: ImportanceIndexStats);
|
|
108
|
+
/**
|
|
109
|
+
* The importance of the scored place nearest `(lat, lon)` sharing `name`'s folded key, `country` and `placetype`, or
|
|
110
|
+
* null when there is no such place within {@link IMPORTANCE_JOIN_GATE_KM}.
|
|
111
|
+
*
|
|
112
|
+
* Null is UNMEASURED. Never substitute a zero, and never fall back to a population-derived value here — the source
|
|
113
|
+
* column already carries that fallback where it has one, and inventing a second one would make an absence
|
|
114
|
+
* indistinguishable from a measurement.
|
|
115
|
+
*/
|
|
116
|
+
find(name: string, country: string | null, placetype: string | null, lat: number, lon: number): number | null;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Read `place_importance` (joined to `spr` for the name/country/placetype/centroid) out of a WOF admin database into an
|
|
120
|
+
* {@link ImportanceIndex}.
|
|
121
|
+
*
|
|
122
|
+
* Only CURRENT, non-deprecated places are indexed — a superseded row's score belongs to a place the gazetteer no longer
|
|
123
|
+
* carries, and letting it win the nearest-centroid contest would hand a live place a dead one's fame.
|
|
124
|
+
*
|
|
125
|
+
* The whole table is held in memory on purpose. The 2026-08-10 source holds 676,790 scored places in 544,823 groups,
|
|
126
|
+
* and the build probes it once for every one of its ~4.8 M places; the alternative is a prepared statement per place
|
|
127
|
+
* against a 3.7 GB database. Measured end to end, loading the index plus probing all 4.48 M locality-tier places takes
|
|
128
|
+
* 25 s.
|
|
129
|
+
*/
|
|
130
|
+
export declare function loadImportanceIndex(databasePath: string): ImportanceIndex;
|
|
131
|
+
export {};
|
|
132
|
+
//# sourceMappingURL=candidate-importance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"candidate-importance.d.ts","sourceRoot":"","sources":["../candidate-importance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAOH;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAA;AAEzC;;GAEG;AACH,UAAU,WAAW;IACpB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,UAAU,EAAE,MAAM,CAAA;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACpC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;CACjB;AAUD;;GAEG;AACH,qBAAa,eAAe;;IAE3B,QAAQ,CAAC,KAAK,EAAE,oBAAoB,CAAA;IACpC;;OAEG;IACH,OAAO,SAAI;IACX;;;;;;OAMG;IACH,KAAK,SAAI;gBAEG,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,EAAE,KAAK,EAAE,oBAAoB;IAK3E;;;;;;;OAOG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CA+B7G;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,eAAe,CA4CzE"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* The score side of the candidate build (#28) — load a WOF admin database's `place_importance` into
|
|
7
|
+
* a lookup the candidate builder can probe per place, so every candidate row can carry the
|
|
8
|
+
* toponym-fame prior a bare city name is decided on.
|
|
9
|
+
*
|
|
10
|
+
* ## Why this joins on the NAME and not on the id
|
|
11
|
+
*
|
|
12
|
+
* The obvious join is `candidate.spr_id = place_importance.id`, and it is wrong here. The score
|
|
13
|
+
* source (`admin-global-priority-importance.db`) and the candidate build's admin source are
|
|
14
|
+
* DIFFERENT SNAPSHOTS, and they disagree about ids for exactly the rows that matter: Whitby,
|
|
15
|
+
* Ontario is `8143502164401` in the shipped `candidate.db` and `8000001156384` in the score source
|
|
16
|
+
* — the Overture-sourced rows were re-keyed between the two. An id join silently drops every one of
|
|
17
|
+
* them, which means it drops precisely the FOREIGN HOMONYMS the fame prior exists to demote, and it
|
|
18
|
+
* drops them invisibly: the build succeeds, the column is populated, and the ranking is inert on
|
|
19
|
+
* the queries it was built for.
|
|
20
|
+
*
|
|
21
|
+
* So the join key is `(name_key, country, placetype)` — the same {@link normalizeLocalityForKey} the
|
|
22
|
+
* candidate build uses for its probe key, so the two sides fold identically by construction.
|
|
23
|
+
*
|
|
24
|
+
* ## Why the key alone is not enough
|
|
25
|
+
*
|
|
26
|
+
* `(warwick, US, locality)` names ELEVEN different places. Taking the group's max would give every
|
|
27
|
+
* Warwick in America the fame of Warwick, Rhode Island, which is the fan-out defect
|
|
28
|
+
* `importance-fanout.ts` documents one layer up, re-introduced at the join. So the group is
|
|
29
|
+
* disambiguated GEOGRAPHICALLY: the nearest centroid wins, and only within
|
|
30
|
+
* {@link IMPORTANCE_JOIN_GATE_KM}. Two artifacts describing the same settlement put its centroid in
|
|
31
|
+
* almost the same place; two same-named towns in one country do not.
|
|
32
|
+
*
|
|
33
|
+
* ## What lands in the column
|
|
34
|
+
*
|
|
35
|
+
* `place_importance.importance` VERBATIM — the pre-split conflation (encyclopedia-derived where
|
|
36
|
+
* the concordance matched, a population-derived proxy everywhere else). See
|
|
37
|
+
* {@link CandidateTable.importance} for why the split `encyclopedic` channel is deliberately NOT
|
|
38
|
+
* what is written here, with the measurement that settled it.
|
|
39
|
+
*
|
|
40
|
+
* A place with no match gets NULL. NULL is UNMEASURED, never zero — the consumer
|
|
41
|
+
* (`resolver/toponym-prior.ts`) leaves an unmeasured candidate exactly where population put it.
|
|
42
|
+
*/
|
|
43
|
+
import { DatabaseSync } from "node:sqlite";
|
|
44
|
+
import { haversineKm } from "./geo.js";
|
|
45
|
+
import { normalizeLocalityForKey } from "./street-normalize.js";
|
|
46
|
+
/**
|
|
47
|
+
* How far apart two artifacts may put the same place's centroid and still be read as the same place.
|
|
48
|
+
*
|
|
49
|
+
* MEASURED, not guessed (2026-08-10, `admin-global-priority.db` × `admin-global-priority-importance.db`; 4,476,245
|
|
50
|
+
* current locality-tier places against 676,790 scored ones, 1,020,099 of which matched a scored group by `(name_key,
|
|
51
|
+
* country, placetype)`). The nearest-centroid distance is **exactly 0.00 km for 577,080 of them (56.6%)** — the two
|
|
52
|
+
* snapshots agree to the bit — and 656,755 (64.4%) are inside 500 m.
|
|
53
|
+
*
|
|
54
|
+
* What sets the gate is where that mode ENDS, and the per-kilometre density says so plainly. It falls from 1,076
|
|
55
|
+
* places/km over 3–5 km to a trough of **441 places/km over 7–10 km**, then climbs back and flattens onto a plateau of
|
|
56
|
+
* 760–780 places/km from 30 km out to 100 km and beyond. That plateau is the background rate of two DIFFERENT towns
|
|
57
|
+
* wearing one name in one country, and it does not decay with distance because there is no reason it should. 10 km is
|
|
58
|
+
* the floor between the two populations. Admitting it scores 679,163 places (66.6% of the matched set); pushing the
|
|
59
|
+
* gate to 25 km buys 8,722 more, and by then better than half of each additional kilometre is the wrong town.
|
|
60
|
+
*
|
|
61
|
+
* The four-row bare-GB board is insensitive across this whole range — 5 km and 25 km were both measured and select
|
|
62
|
+
* identical rows — so the value is chosen by what the join MEANS, not by what it scores. The gate is the definition of
|
|
63
|
+
* "this is the same place"; widening it past the floor starts handing one town's fame to another.
|
|
64
|
+
*/
|
|
65
|
+
export const IMPORTANCE_JOIN_GATE_KM = 10;
|
|
66
|
+
/**
|
|
67
|
+
* `(name_key, country, placetype)` → the scored places under it. The separator is U+0000, which no WOF name carries and
|
|
68
|
+
* no fold can produce, so the three fields can't smear into one another.
|
|
69
|
+
*/
|
|
70
|
+
function groupKey(nameKey, country, placetype) {
|
|
71
|
+
return `${nameKey}\u0000${(country ?? "").toUpperCase()}\u0000${placetype ?? ""}`;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* A loaded `place_importance`, probed by name + country + placetype + position.
|
|
75
|
+
*/
|
|
76
|
+
export class ImportanceIndex {
|
|
77
|
+
#groups;
|
|
78
|
+
stats;
|
|
79
|
+
/**
|
|
80
|
+
* Places {@link find} matched inside the gate.
|
|
81
|
+
*/
|
|
82
|
+
matched = 0;
|
|
83
|
+
/**
|
|
84
|
+
* Places {@link find} REFUSED — the key matched a scored group, but the nearest member of it was outside the gate, so
|
|
85
|
+
* it is a different place wearing the same name.
|
|
86
|
+
*
|
|
87
|
+
* This is the number worth watching across rebuilds. A jump means the score source and the admin source have drifted
|
|
88
|
+
* apart and the join is being asked to guess; it does not mean the gate is too tight.
|
|
89
|
+
*/
|
|
90
|
+
gated = 0;
|
|
91
|
+
constructor(groups, stats) {
|
|
92
|
+
this.#groups = groups;
|
|
93
|
+
this.stats = stats;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* The importance of the scored place nearest `(lat, lon)` sharing `name`'s folded key, `country` and `placetype`, or
|
|
97
|
+
* null when there is no such place within {@link IMPORTANCE_JOIN_GATE_KM}.
|
|
98
|
+
*
|
|
99
|
+
* Null is UNMEASURED. Never substitute a zero, and never fall back to a population-derived value here — the source
|
|
100
|
+
* column already carries that fallback where it has one, and inventing a second one would make an absence
|
|
101
|
+
* indistinguishable from a measurement.
|
|
102
|
+
*/
|
|
103
|
+
find(name, country, placetype, lat, lon) {
|
|
104
|
+
const nameKey = normalizeLocalityForKey(name);
|
|
105
|
+
if (!nameKey)
|
|
106
|
+
return null;
|
|
107
|
+
const group = this.#groups.get(groupKey(nameKey, country, placetype));
|
|
108
|
+
if (!group)
|
|
109
|
+
return null;
|
|
110
|
+
let best;
|
|
111
|
+
let bestKm = Infinity;
|
|
112
|
+
for (const place of group) {
|
|
113
|
+
const km = haversineKm(lat, lon, place.lat, place.lon);
|
|
114
|
+
if (km < bestKm) {
|
|
115
|
+
bestKm = km;
|
|
116
|
+
best = place;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (!best || bestKm > IMPORTANCE_JOIN_GATE_KM) {
|
|
120
|
+
this.gated++;
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
this.matched++;
|
|
124
|
+
return best.importance;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Read `place_importance` (joined to `spr` for the name/country/placetype/centroid) out of a WOF admin database into an
|
|
129
|
+
* {@link ImportanceIndex}.
|
|
130
|
+
*
|
|
131
|
+
* Only CURRENT, non-deprecated places are indexed — a superseded row's score belongs to a place the gazetteer no longer
|
|
132
|
+
* carries, and letting it win the nearest-centroid contest would hand a live place a dead one's fame.
|
|
133
|
+
*
|
|
134
|
+
* The whole table is held in memory on purpose. The 2026-08-10 source holds 676,790 scored places in 544,823 groups,
|
|
135
|
+
* and the build probes it once for every one of its ~4.8 M places; the alternative is a prepared statement per place
|
|
136
|
+
* against a 3.7 GB database. Measured end to end, loading the index plus probing all 4.48 M locality-tier places takes
|
|
137
|
+
* 25 s.
|
|
138
|
+
*/
|
|
139
|
+
export function loadImportanceIndex(databasePath) {
|
|
140
|
+
const db = new DatabaseSync(databasePath, { readOnly: true });
|
|
141
|
+
try {
|
|
142
|
+
const groups = new Map();
|
|
143
|
+
let places = 0;
|
|
144
|
+
let unkeyable = 0;
|
|
145
|
+
for (const row of db
|
|
146
|
+
.prepare(`SELECT s.name AS name, s.country AS country, s.placetype AS placetype,
|
|
147
|
+
s.latitude AS latitude, s.longitude AS longitude, i.importance AS importance
|
|
148
|
+
FROM place_importance i JOIN spr s ON s.id = i.id
|
|
149
|
+
WHERE s.is_current != 0 AND s.is_deprecated = 0`)
|
|
150
|
+
.iterate()) {
|
|
151
|
+
const importance = Number(row.importance);
|
|
152
|
+
if (!Number.isFinite(importance))
|
|
153
|
+
continue;
|
|
154
|
+
const nameKey = normalizeLocalityForKey(String(row.name ?? ""));
|
|
155
|
+
if (!nameKey) {
|
|
156
|
+
unkeyable++;
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
const key = groupKey(nameKey, row.country, row.placetype);
|
|
160
|
+
let group = groups.get(key);
|
|
161
|
+
if (!group) {
|
|
162
|
+
group = [];
|
|
163
|
+
groups.set(key, group);
|
|
164
|
+
}
|
|
165
|
+
group.push({ lat: Number(row.latitude), lon: Number(row.longitude), importance });
|
|
166
|
+
places++;
|
|
167
|
+
}
|
|
168
|
+
return new ImportanceIndex(groups, { places, keys: groups.size, unkeyable });
|
|
169
|
+
}
|
|
170
|
+
finally {
|
|
171
|
+
db.close();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=candidate-importance.js.map
|