@mailwoman/resolver-wof-sqlite 9.1.0 → 9.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -20
- package/lib/address/index.ts +9 -0
- package/{address-point-interpolation.ts → lib/address/point-interpolation.ts} +40 -28
- package/{address-point-schema.ts → lib/address/point-schema.ts} +34 -8
- package/lib/address/point.ts +280 -0
- package/{ancestry-backfill.ts → lib/ancestry/backfill.ts} +14 -19
- package/{ancestry.ts → lib/ancestry/index.ts} +13 -8
- package/{build-candidate.ts → lib/build-candidate.ts} +243 -199
- package/{build-slim.ts → lib/build-slim.ts} +153 -168
- package/lib/candidate/alias-bags.ts +56 -0
- package/lib/candidate/ancestors-sidecar.ts +204 -0
- package/lib/candidate/country-display-names.ts +79 -0
- package/lib/candidate/extract-fold.ts +138 -0
- package/lib/candidate/name-roles.ts +238 -0
- package/lib/candidate/own-name.ts +146 -0
- package/lib/candidate/place-attrs.ts +44 -0
- package/lib/candidate-ancestors-schema.ts +195 -0
- package/{candidate-fts.ts → lib/candidate-fts.ts} +7 -5
- package/{candidate-importance.ts → lib/candidate-importance.ts} +54 -57
- package/lib/candidate-lookup.ts +976 -0
- package/{candidate-schema.ts → lib/candidate-schema.ts} +34 -6
- package/lib/candidate-scoring.ts +261 -0
- package/lib/capital-schema.ts +89 -0
- package/lib/capitals.ts +148 -0
- package/{coincident-roles.ts → lib/coincident-roles.ts} +75 -19
- package/{convention.ts → lib/convention/index.ts} +5 -5
- package/lib/convention/schema.ts +72 -0
- package/{coverage-manifest-schema.ts → lib/coverage-manifest-schema.ts} +15 -16
- package/lib/currency-backfill.ts +334 -0
- package/lib/env.ts +50 -0
- package/lib/exact-match.ts +113 -0
- package/{sharding.ts → lib/extracts.ts} +63 -60
- package/lib/fst/autocomplete.ts +176 -0
- package/{fst-builder.ts → lib/fst/builder.ts} +30 -27
- package/{fst-deserialize-web.ts → lib/fst/deserialize-web.ts} +27 -87
- package/lib/fst/format.ts +106 -0
- package/{fst-freshness.ts → lib/fst/freshness.ts} +42 -75
- package/lib/fst/index.ts +14 -0
- package/{fst-matcher.ts → lib/fst/matcher.ts} +1 -1
- package/{fst-serialize.ts → lib/fst/serialize.ts} +37 -115
- package/{fst-types.ts → lib/fst/types.ts} +4 -2
- package/{fts.ts → lib/fts/index.ts} +28 -23
- package/{fts-query.ts → lib/fts/query.ts} +2 -2
- package/{geonames-aliases.ts → lib/geonames/aliases.ts} +13 -13
- package/lib/geonames/index.ts +8 -0
- package/{geonames-postal.ts → lib/geonames/postal.ts} +16 -15
- package/{index.ts → lib/index.ts} +52 -48
- package/{interpolation.ts → lib/interpolation.ts} +137 -41
- package/lib/lookup.ts +861 -0
- package/{name-score.ts → lib/name-score.ts} +6 -4
- package/lib/nsul/index.ts +8 -0
- package/lib/nsul/lookup.ts +144 -0
- package/lib/nsul/schema.ts +130 -0
- package/{place-importance-schema.ts → lib/place-importance-schema.ts} +70 -22
- package/lib/poi/index.ts +8 -0
- package/{poi-lookup.ts → lib/poi/lookup.ts} +32 -39
- package/{poi-schema.ts → lib/poi/schema.ts} +10 -6
- package/lib/polygon-schema.ts +47 -0
- package/{postal-city-alias-lookup.ts → lib/postal/city-alias-lookup.ts} +15 -21
- package/{postal-city-candidate-schema.ts → lib/postal/city-candidate-schema.ts} +4 -2
- package/lib/postal/index.ts +9 -0
- package/{postcode-point-lookup.ts → lib/postcode-point-lookup.ts} +17 -15
- package/lib/primary-preference.ts +226 -0
- package/lib/proximity-rerank.ts +120 -0
- package/{ranking-weights.ts → lib/ranking-weights.ts} +30 -4
- package/lib/region-keys.ts +144 -0
- package/{reverse.ts → lib/reverse.ts} +45 -56
- package/{schema.ts → lib/schema.ts} +11 -1
- package/lib/search-fetch.ts +257 -0
- package/{sqlite-convention-source.ts → lib/sqlite-convention-source.ts} +9 -10
- package/lib/sqlite-utils.ts +83 -0
- package/{street-centroid-schema.ts → lib/street/centroid-schema.ts} +12 -6
- package/{street-centroid.ts → lib/street/centroid.ts} +26 -28
- package/lib/street/index.ts +13 -0
- package/{street-morphology-fst-builder.ts → lib/street/morphology-fst-builder.ts} +24 -14
- package/{street-morphology-fst-loader.ts → lib/street/morphology-fst-loader.ts} +14 -12
- package/{street-name-lookup.ts → lib/street/name-lookup.ts} +14 -30
- package/lib/street/normalize.ts +572 -0
- package/{street-segment-schema.ts → lib/street/segment-schema.ts} +13 -8
- package/{types.ts → lib/types.ts} +49 -9
- package/{unified-schema.ts → lib/unified-schema.ts} +21 -25
- package/lib/uprn/existence.ts +84 -0
- package/lib/uprn/index.ts +9 -0
- package/lib/uprn/lookup.ts +206 -0
- package/lib/uprn/schema.ts +124 -0
- package/lib/weights-overlay-linker.ts +878 -0
- package/out/address/index.d.ts +9 -0
- package/out/address/index.d.ts.map +1 -0
- package/out/address/index.js +9 -0
- package/out/address/index.js.map +1 -0
- package/out/{address-point-interpolation.d.ts → address/point-interpolation.d.ts} +11 -10
- package/out/address/point-interpolation.d.ts.map +1 -0
- package/out/{address-point-interpolation.js → address/point-interpolation.js} +29 -23
- package/out/address/point-interpolation.js.map +1 -0
- package/out/{address-point-schema.d.ts → address/point-schema.d.ts} +30 -10
- package/out/address/point-schema.d.ts.map +1 -0
- package/out/{address-point-schema.js → address/point-schema.js} +7 -3
- package/out/address/point-schema.js.map +1 -0
- package/out/{address-point.d.ts → address/point.d.ts} +16 -8
- package/out/address/point.d.ts.map +1 -0
- package/out/address/point.js +191 -0
- package/out/address/point.js.map +1 -0
- package/out/{ancestry-backfill.d.ts → ancestry/backfill.d.ts} +7 -5
- package/out/ancestry/backfill.d.ts.map +1 -0
- package/out/{ancestry-backfill.js → ancestry/backfill.js} +12 -16
- package/out/ancestry/backfill.js.map +1 -0
- package/out/{ancestry.d.ts → ancestry/index.d.ts} +6 -5
- package/out/ancestry/index.d.ts.map +1 -0
- package/out/{ancestry.js → ancestry/index.js} +7 -7
- package/out/ancestry/index.js.map +1 -0
- package/out/build-candidate.d.ts +88 -7
- package/out/build-candidate.d.ts.map +1 -1
- package/out/build-candidate.js +145 -149
- package/out/build-candidate.js.map +1 -1
- package/out/build-slim.d.ts +5 -5
- package/out/build-slim.d.ts.map +1 -1
- package/out/build-slim.js +127 -142
- package/out/build-slim.js.map +1 -1
- package/out/candidate/alias-bags.d.ts +19 -0
- package/out/candidate/alias-bags.d.ts.map +1 -0
- package/out/candidate/alias-bags.js +39 -0
- package/out/candidate/alias-bags.js.map +1 -0
- package/out/candidate/ancestors-sidecar.d.ts +32 -0
- package/out/candidate/ancestors-sidecar.d.ts.map +1 -0
- package/out/candidate/ancestors-sidecar.js +140 -0
- package/out/candidate/ancestors-sidecar.js.map +1 -0
- package/out/candidate/country-display-names.d.ts +35 -0
- package/out/candidate/country-display-names.d.ts.map +1 -0
- package/out/candidate/country-display-names.js +59 -0
- package/out/candidate/country-display-names.js.map +1 -0
- package/out/candidate/extract-fold.d.ts +32 -0
- package/out/candidate/extract-fold.d.ts.map +1 -0
- package/out/candidate/extract-fold.js +104 -0
- package/out/candidate/extract-fold.js.map +1 -0
- package/out/candidate/name-roles.d.ts +57 -0
- package/out/candidate/name-roles.d.ts.map +1 -0
- package/out/candidate/name-roles.js +166 -0
- package/out/candidate/name-roles.js.map +1 -0
- package/out/candidate/own-name.d.ts +50 -0
- package/out/candidate/own-name.d.ts.map +1 -0
- package/out/candidate/own-name.js +132 -0
- package/out/candidate/own-name.js.map +1 -0
- package/out/candidate/place-attrs.d.ts +43 -0
- package/out/candidate/place-attrs.d.ts.map +1 -0
- package/out/candidate/place-attrs.js +15 -0
- package/out/candidate/place-attrs.js.map +1 -0
- package/out/candidate-ancestors-schema.d.ts +150 -0
- package/out/candidate-ancestors-schema.d.ts.map +1 -0
- package/out/candidate-ancestors-schema.js +123 -0
- package/out/candidate-ancestors-schema.js.map +1 -0
- package/out/candidate-fts.d.ts +7 -5
- package/out/candidate-fts.d.ts.map +1 -1
- package/out/candidate-fts.js +5 -3
- package/out/candidate-fts.js.map +1 -1
- package/out/candidate-importance.d.ts +16 -16
- package/out/candidate-importance.d.ts.map +1 -1
- package/out/candidate-importance.js +47 -52
- package/out/candidate-importance.js.map +1 -1
- package/out/candidate-lookup.d.ts +31 -52
- package/out/candidate-lookup.d.ts.map +1 -1
- package/out/candidate-lookup.js +380 -172
- package/out/candidate-lookup.js.map +1 -1
- package/out/candidate-schema.d.ts +31 -7
- package/out/candidate-schema.d.ts.map +1 -1
- package/out/candidate-schema.js +3 -0
- package/out/candidate-schema.js.map +1 -1
- package/out/candidate-scoring.d.ts +34 -0
- package/out/candidate-scoring.d.ts.map +1 -0
- package/out/candidate-scoring.js +196 -0
- package/out/candidate-scoring.js.map +1 -0
- package/out/capital-schema.d.ts +51 -0
- package/out/capital-schema.d.ts.map +1 -0
- package/out/capital-schema.js +63 -0
- package/out/capital-schema.js.map +1 -0
- package/out/capitals.d.ts +69 -0
- package/out/capitals.d.ts.map +1 -0
- package/out/capitals.js +98 -0
- package/out/capitals.js.map +1 -0
- package/out/coincident-roles.d.ts +12 -4
- package/out/coincident-roles.d.ts.map +1 -1
- package/out/coincident-roles.js +43 -11
- package/out/coincident-roles.js.map +1 -1
- package/out/{convention.d.ts → convention/index.d.ts} +5 -5
- package/out/convention/index.d.ts.map +1 -0
- package/out/{convention.js → convention/index.js} +4 -4
- package/out/convention/index.js.map +1 -0
- package/out/convention/schema.d.ts +51 -0
- package/out/convention/schema.d.ts.map +1 -0
- package/out/convention/schema.js +34 -0
- package/out/convention/schema.js.map +1 -0
- package/out/coverage-manifest-schema.d.ts +8 -8
- package/out/coverage-manifest-schema.d.ts.map +1 -1
- package/out/coverage-manifest-schema.js +6 -10
- package/out/coverage-manifest-schema.js.map +1 -1
- package/out/currency-backfill.d.ts +90 -0
- package/out/currency-backfill.d.ts.map +1 -0
- package/out/currency-backfill.js +196 -0
- package/out/currency-backfill.js.map +1 -0
- package/out/env.d.ts +43 -0
- package/out/env.d.ts.map +1 -0
- package/out/env.js +48 -0
- package/out/env.js.map +1 -0
- package/out/exact-match.d.ts +25 -0
- package/out/exact-match.d.ts.map +1 -0
- package/out/exact-match.js +88 -0
- package/out/exact-match.js.map +1 -0
- package/out/extracts.d.ts +114 -0
- package/out/extracts.d.ts.map +1 -0
- package/out/{sharding.js → extracts.js} +38 -38
- package/out/extracts.js.map +1 -0
- package/out/{fst-autocomplete.d.ts → fst/autocomplete.d.ts} +13 -13
- package/out/fst/autocomplete.d.ts.map +1 -0
- package/out/fst/autocomplete.js +113 -0
- package/out/fst/autocomplete.js.map +1 -0
- package/out/{fst-builder.d.ts → fst/builder.d.ts} +5 -5
- package/out/fst/builder.d.ts.map +1 -0
- package/out/{fst-builder.js → fst/builder.js} +24 -24
- package/out/fst/builder.js.map +1 -0
- package/out/{fst-deserialize-web.d.ts → fst/deserialize-web.d.ts} +3 -3
- package/out/fst/deserialize-web.d.ts.map +1 -0
- package/out/{fst-deserialize-web.js → fst/deserialize-web.js} +10 -74
- package/out/fst/deserialize-web.js.map +1 -0
- package/out/fst/format.d.ts +80 -0
- package/out/fst/format.d.ts.map +1 -0
- package/out/fst/format.js +91 -0
- package/out/fst/format.js.map +1 -0
- package/out/{fst-freshness.d.ts → fst/freshness.d.ts} +11 -14
- package/out/fst/freshness.d.ts.map +1 -0
- package/out/{fst-freshness.js → fst/freshness.js} +42 -74
- package/out/fst/freshness.js.map +1 -0
- package/out/fst/index.d.ts +14 -0
- package/out/fst/index.d.ts.map +1 -0
- package/out/fst/index.js +14 -0
- package/out/fst/index.js.map +1 -0
- package/out/{fst-matcher.d.ts → fst/matcher.d.ts} +2 -2
- package/out/fst/matcher.d.ts.map +1 -0
- package/out/{fst-matcher.js → fst/matcher.js} +1 -1
- package/out/fst/matcher.js.map +1 -0
- package/out/{fst-serialize.d.ts → fst/serialize.d.ts} +5 -10
- package/out/fst/serialize.d.ts.map +1 -0
- package/out/{fst-serialize.js → fst/serialize.js} +18 -98
- package/out/fst/serialize.js.map +1 -0
- package/out/{fst-types.d.ts → fst/types.d.ts} +4 -3
- package/out/fst/types.d.ts.map +1 -0
- package/out/{fst-types.js → fst/types.js} +1 -1
- package/out/fst/types.js.map +1 -0
- package/out/{fts.d.ts → fts/index.d.ts} +20 -13
- package/out/fts/index.d.ts.map +1 -0
- package/out/{fts.js → fts/index.js} +20 -15
- package/out/fts/index.js.map +1 -0
- package/out/{fts-query.d.ts → fts/query.d.ts} +2 -2
- package/out/fts/query.d.ts.map +1 -0
- package/out/{fts-query.js → fts/query.js} +2 -2
- package/out/fts/query.js.map +1 -0
- package/out/{geonames-aliases.d.ts → geonames/aliases.d.ts} +8 -6
- package/out/geonames/aliases.d.ts.map +1 -0
- package/out/{geonames-aliases.js → geonames/aliases.js} +7 -7
- package/out/geonames/aliases.js.map +1 -0
- package/out/geonames/index.d.ts +8 -0
- package/out/geonames/index.d.ts.map +1 -0
- package/out/geonames/index.js +8 -0
- package/out/geonames/index.js.map +1 -0
- package/out/{geonames-postal.d.ts → geonames/postal.d.ts} +12 -10
- package/out/geonames/postal.d.ts.map +1 -0
- package/out/{geonames-postal.js → geonames/postal.js} +11 -11
- package/out/geonames/postal.js.map +1 -0
- package/out/index.d.ts +32 -31
- package/out/index.d.ts.map +1 -1
- package/out/index.js +24 -24
- package/out/index.js.map +1 -1
- package/out/interpolation.d.ts +18 -9
- package/out/interpolation.d.ts.map +1 -1
- package/out/interpolation.js +108 -36
- package/out/interpolation.js.map +1 -1
- package/out/lookup.d.ts +25 -25
- package/out/lookup.d.ts.map +1 -1
- package/out/lookup.js +174 -558
- package/out/lookup.js.map +1 -1
- package/out/name-score.d.ts +0 -10
- package/out/name-score.d.ts.map +1 -1
- package/out/name-score.js +6 -4
- package/out/name-score.js.map +1 -1
- package/out/nsul/index.d.ts +8 -0
- package/out/nsul/index.d.ts.map +1 -0
- package/out/nsul/index.js +8 -0
- package/out/nsul/index.js.map +1 -0
- package/out/nsul/lookup.d.ts +83 -0
- package/out/nsul/lookup.d.ts.map +1 -0
- package/out/nsul/lookup.js +80 -0
- package/out/nsul/lookup.js.map +1 -0
- package/out/nsul/schema.d.ts +100 -0
- package/out/nsul/schema.d.ts.map +1 -0
- package/out/nsul/schema.js +78 -0
- package/out/nsul/schema.js.map +1 -0
- package/out/place-importance-schema.d.ts +47 -10
- package/out/place-importance-schema.d.ts.map +1 -1
- package/out/place-importance-schema.js +56 -10
- package/out/place-importance-schema.js.map +1 -1
- package/out/poi/index.d.ts +8 -0
- package/out/poi/index.d.ts.map +1 -0
- package/out/poi/index.js +8 -0
- package/out/poi/index.js.map +1 -0
- package/out/{poi-lookup.d.ts → poi/lookup.d.ts} +8 -10
- package/out/poi/lookup.d.ts.map +1 -0
- package/out/{poi-lookup.js → poi/lookup.js} +24 -29
- package/out/poi/lookup.js.map +1 -0
- package/out/{poi-schema.d.ts → poi/schema.d.ts} +10 -6
- package/out/poi/schema.d.ts.map +1 -0
- package/out/{poi-schema.js → poi/schema.js} +1 -1
- package/out/poi/schema.js.map +1 -0
- package/out/polygon-schema.d.ts +37 -0
- package/out/polygon-schema.d.ts.map +1 -0
- package/out/polygon-schema.js +23 -0
- package/out/polygon-schema.js.map +1 -0
- package/out/{postal-city-alias-lookup.d.ts → postal/city-alias-lookup.d.ts} +7 -6
- package/out/postal/city-alias-lookup.d.ts.map +1 -0
- package/out/{postal-city-alias-lookup.js → postal/city-alias-lookup.js} +12 -16
- package/out/postal/city-alias-lookup.js.map +1 -0
- package/out/{postal-city-alias-schema.d.ts → postal/city-alias-schema.d.ts} +1 -1
- package/out/{postal-city-alias-schema.d.ts.map → postal/city-alias-schema.d.ts.map} +1 -1
- package/out/{postal-city-alias-schema.js → postal/city-alias-schema.js} +1 -1
- package/out/{postal-city-alias-schema.js.map → postal/city-alias-schema.js.map} +1 -1
- package/out/{postal-city-candidate-schema.d.ts → postal/city-candidate-schema.d.ts} +4 -3
- package/out/postal/city-candidate-schema.d.ts.map +1 -0
- package/out/{postal-city-candidate-schema.js → postal/city-candidate-schema.js} +2 -2
- package/out/{postal-city-candidate-schema.js.map → postal/city-candidate-schema.js.map} +1 -1
- package/out/postal/index.d.ts +9 -0
- package/out/postal/index.d.ts.map +1 -0
- package/out/postal/index.js +9 -0
- package/out/postal/index.js.map +1 -0
- package/out/postcode-point-lookup.d.ts +10 -10
- package/out/postcode-point-lookup.d.ts.map +1 -1
- package/out/postcode-point-lookup.js +13 -13
- package/out/postcode-point-lookup.js.map +1 -1
- package/out/primary-preference.d.ts +133 -0
- package/out/primary-preference.d.ts.map +1 -0
- package/out/primary-preference.js +146 -0
- package/out/primary-preference.js.map +1 -0
- package/out/proximity-rerank.d.ts +77 -0
- package/out/proximity-rerank.d.ts.map +1 -0
- package/out/proximity-rerank.js +86 -0
- package/out/proximity-rerank.js.map +1 -0
- package/out/ranking-weights.d.ts +15 -3
- package/out/ranking-weights.d.ts.map +1 -1
- package/out/ranking-weights.js +21 -3
- package/out/ranking-weights.js.map +1 -1
- package/out/region-keys.d.ts +47 -0
- package/out/region-keys.d.ts.map +1 -0
- package/out/region-keys.js +121 -0
- package/out/region-keys.js.map +1 -0
- package/out/reverse.d.ts +6 -6
- package/out/reverse.d.ts.map +1 -1
- package/out/reverse.js +23 -35
- package/out/reverse.js.map +1 -1
- package/out/schema.d.ts +10 -1
- package/out/schema.d.ts.map +1 -1
- package/out/schema.js.map +1 -1
- package/out/search-fetch.d.ts +59 -0
- package/out/search-fetch.d.ts.map +1 -0
- package/out/search-fetch.js +184 -0
- package/out/search-fetch.js.map +1 -0
- package/out/sqlite-convention-source.d.ts +7 -7
- package/out/sqlite-convention-source.d.ts.map +1 -1
- package/out/sqlite-convention-source.js +5 -5
- package/out/sqlite-convention-source.js.map +1 -1
- package/out/sqlite-utils.d.ts +24 -6
- package/out/sqlite-utils.d.ts.map +1 -1
- package/out/sqlite-utils.js +24 -7
- package/out/sqlite-utils.js.map +1 -1
- package/out/{street-centroid-schema.d.ts → street/centroid-schema.d.ts} +12 -7
- package/out/street/centroid-schema.d.ts.map +1 -0
- package/out/{street-centroid-schema.js → street/centroid-schema.js} +5 -5
- package/out/{street-centroid-schema.js.map → street/centroid-schema.js.map} +1 -1
- package/out/{street-centroid.d.ts → street/centroid.d.ts} +6 -6
- package/out/street/centroid.d.ts.map +1 -0
- package/out/{street-centroid.js → street/centroid.js} +18 -24
- package/out/street/centroid.js.map +1 -0
- package/out/street/index.d.ts +13 -0
- package/out/street/index.d.ts.map +1 -0
- package/out/street/index.js +13 -0
- package/out/street/index.js.map +1 -0
- package/out/{street-morphology-fst-builder.d.ts → street/morphology-fst-builder.d.ts} +4 -4
- package/out/street/morphology-fst-builder.d.ts.map +1 -0
- package/out/{street-morphology-fst-builder.js → street/morphology-fst-builder.js} +18 -13
- package/out/street/morphology-fst-builder.js.map +1 -0
- package/out/{street-morphology-fst-loader.d.ts → street/morphology-fst-loader.d.ts} +5 -5
- package/out/street/morphology-fst-loader.d.ts.map +1 -0
- package/out/{street-morphology-fst-loader.js → street/morphology-fst-loader.js} +11 -10
- package/out/street/morphology-fst-loader.js.map +1 -0
- package/out/{street-name-lookup.d.ts → street/name-lookup.d.ts} +4 -7
- package/out/street/name-lookup.d.ts.map +1 -0
- package/out/{street-name-lookup.js → street/name-lookup.js} +9 -23
- package/out/street/name-lookup.js.map +1 -0
- package/out/street/normalize.d.ts +179 -0
- package/out/street/normalize.d.ts.map +1 -0
- package/out/street/normalize.js +457 -0
- package/out/street/normalize.js.map +1 -0
- package/out/{street-segment-schema.d.ts → street/segment-schema.d.ts} +13 -9
- package/out/street/segment-schema.d.ts.map +1 -0
- package/out/{street-segment-schema.js → street/segment-schema.js} +4 -4
- package/out/{street-segment-schema.js.map → street/segment-schema.js.map} +1 -1
- package/out/types.d.ts +49 -9
- package/out/types.d.ts.map +1 -1
- package/out/types.js.map +1 -1
- package/out/unified-schema.d.ts +6 -5
- package/out/unified-schema.d.ts.map +1 -1
- package/out/unified-schema.js +16 -19
- package/out/unified-schema.js.map +1 -1
- package/out/uprn/existence.d.ts +53 -0
- package/out/uprn/existence.d.ts.map +1 -0
- package/out/uprn/existence.js +61 -0
- package/out/uprn/existence.js.map +1 -0
- package/out/uprn/index.d.ts +9 -0
- package/out/uprn/index.d.ts.map +1 -0
- package/out/uprn/index.js +9 -0
- package/out/uprn/index.js.map +1 -0
- package/out/uprn/lookup.d.ts +85 -0
- package/out/uprn/lookup.d.ts.map +1 -0
- package/out/uprn/lookup.js +149 -0
- package/out/uprn/lookup.js.map +1 -0
- package/out/uprn/schema.d.ts +93 -0
- package/out/uprn/schema.d.ts.map +1 -0
- package/out/uprn/schema.js +78 -0
- package/out/uprn/schema.js.map +1 -0
- package/out/weights-overlay-linker.d.ts +299 -0
- package/out/weights-overlay-linker.d.ts.map +1 -0
- package/out/weights-overlay-linker.js +511 -0
- package/out/weights-overlay-linker.js.map +1 -0
- package/package.json +622 -154
- package/address-point.ts +0 -125
- package/candidate-lookup.ts +0 -720
- package/fst-autocomplete.ts +0 -204
- package/geo.ts +0 -121
- package/lookup.ts +0 -1354
- package/out/address-point-interpolation.d.ts.map +0 -1
- package/out/address-point-interpolation.js.map +0 -1
- package/out/address-point-schema.d.ts.map +0 -1
- package/out/address-point-schema.js.map +0 -1
- package/out/address-point.d.ts.map +0 -1
- package/out/address-point.js +0 -84
- package/out/address-point.js.map +0 -1
- package/out/ancestry-backfill.d.ts.map +0 -1
- package/out/ancestry-backfill.js.map +0 -1
- package/out/ancestry.d.ts.map +0 -1
- package/out/ancestry.js.map +0 -1
- package/out/convention.d.ts.map +0 -1
- package/out/convention.js.map +0 -1
- package/out/fst-autocomplete.d.ts.map +0 -1
- package/out/fst-autocomplete.js +0 -130
- package/out/fst-autocomplete.js.map +0 -1
- package/out/fst-builder.d.ts.map +0 -1
- package/out/fst-builder.js.map +0 -1
- package/out/fst-deserialize-web.d.ts.map +0 -1
- package/out/fst-deserialize-web.js.map +0 -1
- package/out/fst-freshness.d.ts.map +0 -1
- package/out/fst-freshness.js.map +0 -1
- package/out/fst-matcher.d.ts.map +0 -1
- package/out/fst-matcher.js.map +0 -1
- package/out/fst-serialize.d.ts.map +0 -1
- package/out/fst-serialize.js.map +0 -1
- package/out/fst-types.d.ts.map +0 -1
- package/out/fst-types.js.map +0 -1
- package/out/fts-query.d.ts.map +0 -1
- package/out/fts-query.js.map +0 -1
- package/out/fts.d.ts.map +0 -1
- package/out/fts.js.map +0 -1
- package/out/geo.d.ts +0 -74
- package/out/geo.d.ts.map +0 -1
- package/out/geo.js +0 -71
- package/out/geo.js.map +0 -1
- package/out/geonames-aliases.d.ts.map +0 -1
- package/out/geonames-aliases.js.map +0 -1
- package/out/geonames-postal.d.ts.map +0 -1
- package/out/geonames-postal.js.map +0 -1
- package/out/poi-lookup.d.ts.map +0 -1
- package/out/poi-lookup.js.map +0 -1
- package/out/poi-schema.d.ts.map +0 -1
- package/out/poi-schema.js.map +0 -1
- package/out/postal-city-alias-lookup.d.ts.map +0 -1
- package/out/postal-city-alias-lookup.js.map +0 -1
- package/out/postal-city-candidate-schema.d.ts.map +0 -1
- package/out/sharding.d.ts +0 -114
- package/out/sharding.d.ts.map +0 -1
- package/out/sharding.js.map +0 -1
- package/out/street-centroid-schema.d.ts.map +0 -1
- package/out/street-centroid.d.ts.map +0 -1
- package/out/street-centroid.js.map +0 -1
- package/out/street-morphology-fst-builder.d.ts.map +0 -1
- package/out/street-morphology-fst-builder.js.map +0 -1
- package/out/street-morphology-fst-loader.d.ts.map +0 -1
- package/out/street-morphology-fst-loader.js.map +0 -1
- package/out/street-name-lookup.d.ts.map +0 -1
- package/out/street-name-lookup.js.map +0 -1
- package/out/street-normalize.d.ts +0 -95
- package/out/street-normalize.d.ts.map +0 -1
- package/out/street-normalize.js +0 -272
- package/out/street-normalize.js.map +0 -1
- package/out/street-segment-schema.d.ts.map +0 -1
- package/sqlite-utils.ts +0 -46
- package/street-normalize.ts +0 -318
- /package/{postal-city-alias-schema.ts → lib/postal/city-alias-schema.ts} +0 -0
package/out/street-normalize.js
DELETED
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @copyright Sister Software
|
|
3
|
-
* @license AGPL-3.0
|
|
4
|
-
* @author Teffen Ellis, et al.
|
|
5
|
-
*
|
|
6
|
-
* THE street normalizer for the address-point tier (#476). One function, used by BOTH the shard
|
|
7
|
-
* builder (`scripts/build-address-point-shard.ts`) and the lookup tier (`address-point.ts`) —
|
|
8
|
-
* never two implementations (the PLACETYPE_ORDER lesson: parallel copies silently corrupt).
|
|
9
|
-
*
|
|
10
|
-
* Normalization contract (deliberately aggressive — both sides apply the same function, so
|
|
11
|
-
* collisions only need to be _consistent_, not linguistically perfect):
|
|
12
|
-
*
|
|
13
|
-
* 1. Lowercase, NFKD-fold diacritics, collapse whitespace, strip punctuation (periods, commas,
|
|
14
|
-
* apostrophes).
|
|
15
|
-
* 2. Expand USPS directional abbreviations at the FIRST and LAST token position (`n` → `north`, `se` →
|
|
16
|
-
* `southeast`) — Overture sources abbreviate inconsistently.
|
|
17
|
-
* 3. Canonicalize a trailing USPS street-type token via the codex suffix table to its canonical full
|
|
18
|
-
* form (`st`/`str`/`street` → `street`).
|
|
19
|
-
*
|
|
20
|
-
* Numbered streets are left as digits (`5th` stays `5th`); a SPELLED ordinal before a street suffix
|
|
21
|
-
* folds to its digit form (`tenth street` → `10th street`, #723) so the grid-city ordinal
|
|
22
|
-
* cross-streets the source data spells with digits become reachable.
|
|
23
|
-
*/
|
|
24
|
-
import { AbbreviationToDirectional, US_STREET_SUFFIX_LOOKUP } from "@mailwoman/codex/us";
|
|
25
|
-
/**
|
|
26
|
-
* Token count a street must exceed before its trailing pair is merged. At or below it the pair IS the whole street
|
|
27
|
-
* name, and merging would leave nothing to match on.
|
|
28
|
-
*/
|
|
29
|
-
const MIN_TOKENS_FOR_TAIL_MERGE = 3;
|
|
30
|
-
/**
|
|
31
|
-
* Spelled ordinal street names → their digit-ordinal form ("tenth" → "10th"), applied ONLY when a street-type suffix
|
|
32
|
-
* follows (#723 admin-tail) — so the ordinal cross-streets common in grid cities ("Tenth Street", "Fifth Avenue") match
|
|
33
|
-
* the shards' digit keys, WITHOUT rewriting ordinal-WORD names where the next token is not a suffix ("First National
|
|
34
|
-
* Bank Rd" stays "first national …"). Digit-source shards are unaffected (a digit token isn't in this map), so the
|
|
35
|
-
* existing keys need no rebuild; a future rebuild folds any spelled-source key the same way (the one-function
|
|
36
|
-
* discipline).
|
|
37
|
-
*/
|
|
38
|
-
const SPELLED_ORDINAL_TO_DIGIT = new Map([
|
|
39
|
-
["first", "1st"],
|
|
40
|
-
["second", "2nd"],
|
|
41
|
-
["third", "3rd"],
|
|
42
|
-
["fourth", "4th"],
|
|
43
|
-
["fifth", "5th"],
|
|
44
|
-
["sixth", "6th"],
|
|
45
|
-
["seventh", "7th"],
|
|
46
|
-
["eighth", "8th"],
|
|
47
|
-
["ninth", "9th"],
|
|
48
|
-
["tenth", "10th"],
|
|
49
|
-
["eleventh", "11th"],
|
|
50
|
-
["twelfth", "12th"],
|
|
51
|
-
["thirteenth", "13th"],
|
|
52
|
-
["fourteenth", "14th"],
|
|
53
|
-
["fifteenth", "15th"],
|
|
54
|
-
["sixteenth", "16th"],
|
|
55
|
-
["seventeenth", "17th"],
|
|
56
|
-
["eighteenth", "18th"],
|
|
57
|
-
["nineteenth", "19th"],
|
|
58
|
-
["twentieth", "20th"],
|
|
59
|
-
["thirtieth", "30th"],
|
|
60
|
-
["fortieth", "40th"],
|
|
61
|
-
["fiftieth", "50th"],
|
|
62
|
-
["sixtieth", "60th"],
|
|
63
|
-
["seventieth", "70th"],
|
|
64
|
-
["eightieth", "80th"],
|
|
65
|
-
["ninetieth", "90th"],
|
|
66
|
-
["hundredth", "100th"],
|
|
67
|
-
]);
|
|
68
|
-
/**
|
|
69
|
-
* Lowercase + diacritic-fold + punctuation strip + whitespace collapse.
|
|
70
|
-
*/
|
|
71
|
-
function fold(input) {
|
|
72
|
-
return input
|
|
73
|
-
.normalize("NFKD")
|
|
74
|
-
.replaceAll(/[̀-ͯ]/g, "")
|
|
75
|
-
.toLowerCase()
|
|
76
|
-
.replaceAll(/[.,'’]/g, "")
|
|
77
|
-
.replaceAll(/\s+/g, " ")
|
|
78
|
-
.trim();
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Normalize a street name for address-point keying. Same function at build time and lookup time — see module docstring
|
|
82
|
-
* for the contract.
|
|
83
|
-
*/
|
|
84
|
-
export function normalizeStreetForKey(street) {
|
|
85
|
-
const tokens = fold(street).split(" ");
|
|
86
|
-
if (!tokens.length)
|
|
87
|
-
return "";
|
|
88
|
-
// Spelled-ordinal street names → digit form when a street suffix follows ("Tenth Street" →
|
|
89
|
-
// "10th street", #723). Gated on the next token being a suffix so ordinal-WORD names are untouched.
|
|
90
|
-
for (let i = 0; i < tokens.length - 1; i++) {
|
|
91
|
-
const digit = SPELLED_ORDINAL_TO_DIGIT.get(tokens[i]);
|
|
92
|
-
if (digit && US_STREET_SUFFIX_LOOKUP.has(tokens[i + 1])) {
|
|
93
|
-
tokens[i] = digit;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
// Directional expansion at the edges only ("N Main St" / "Main St N" — never interior
|
|
97
|
-
// tokens, where "W" may be an initial in a person-named street). The codex expands
|
|
98
|
-
// compounds to two words ("SE" → "SOUTH EAST"); we key on the spaceless form
|
|
99
|
-
// ("southeast"), and also merge an already-written two-token pair ("South East …").
|
|
100
|
-
const edgeDirectional = (raw) => AbbreviationToDirectional.get(raw.toUpperCase())?.toLowerCase().replace(" ", "");
|
|
101
|
-
const mergePair = (a, b) => a && b && /^(north|south)$/.test(a) && /^(east|west)$/.test(b) ? a + b : undefined;
|
|
102
|
-
const leadPair = mergePair(tokens[0], tokens[1]);
|
|
103
|
-
if (leadPair && tokens.length > 2) {
|
|
104
|
-
tokens.splice(0, 2, leadPair);
|
|
105
|
-
}
|
|
106
|
-
const first = edgeDirectional(tokens[0]);
|
|
107
|
-
if (first && tokens.length > 1) {
|
|
108
|
-
tokens[0] = first;
|
|
109
|
-
}
|
|
110
|
-
const tailPair = mergePair(tokens.at(-2), tokens.at(-1));
|
|
111
|
-
if (tailPair && tokens.length > MIN_TOKENS_FOR_TAIL_MERGE) {
|
|
112
|
-
tokens.splice(-2, 2, tailPair);
|
|
113
|
-
}
|
|
114
|
-
if (tokens.length > 2) {
|
|
115
|
-
const last = edgeDirectional(tokens.at(-1));
|
|
116
|
-
if (last) {
|
|
117
|
-
tokens[tokens.length - 1] = last;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
// Street-type canonicalization via the codex table (lowercase keys, UPPER canonical
|
|
121
|
-
// values). The suffix is usually the last token, but sits second-to-last when a trailing
|
|
122
|
-
// directional follows ("Main St N") — check both positions, canonicalize the first hit.
|
|
123
|
-
for (const at of [tokens.length - 1, tokens.length - 2]) {
|
|
124
|
-
if (at < 1)
|
|
125
|
-
continue; // never canonicalize the only/first token ("Street Road" exists)
|
|
126
|
-
const canonical = US_STREET_SUFFIX_LOOKUP.get(tokens[at]);
|
|
127
|
-
if (canonical) {
|
|
128
|
-
tokens[at] = canonical.toLowerCase();
|
|
129
|
-
break;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return tokens.join(" ");
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* French street-type abbreviations → canonical full form, applied per token after {@link fold}. French address types
|
|
136
|
-
* LEAD the name ("Av. de…", "Bd …", "Pl. …") and "St"/"Ste" abbreviate Saint/Sainte inside names ("Rue St-Honoré" →
|
|
137
|
-
* "rue saint honore"). fold() has already stripped the trailing period, so the keys are point-free ("av", "bd").
|
|
138
|
-
*/
|
|
139
|
-
const FR_STREET_ABBREV = new Map([
|
|
140
|
-
["av", "avenue"],
|
|
141
|
-
["ave", "avenue"],
|
|
142
|
-
["bd", "boulevard"],
|
|
143
|
-
["bld", "boulevard"],
|
|
144
|
-
["bvd", "boulevard"],
|
|
145
|
-
["boul", "boulevard"],
|
|
146
|
-
["pl", "place"],
|
|
147
|
-
["imp", "impasse"],
|
|
148
|
-
["all", "allee"],
|
|
149
|
-
["ch", "chemin"],
|
|
150
|
-
["che", "chemin"],
|
|
151
|
-
["sq", "square"],
|
|
152
|
-
["pas", "passage"],
|
|
153
|
-
["fg", "faubourg"],
|
|
154
|
-
["fbg", "faubourg"],
|
|
155
|
-
["rte", "route"],
|
|
156
|
-
["st", "saint"],
|
|
157
|
-
["ste", "sainte"],
|
|
158
|
-
["sts", "saints"],
|
|
159
|
-
]);
|
|
160
|
-
/**
|
|
161
|
-
* Normalize a street name for the address-point key in a non-US locale. Same function build-side and probe-side (the
|
|
162
|
-
* one-function discipline). US delegates to {@link normalizeStreetForKey}.
|
|
163
|
-
*
|
|
164
|
-
* - **en** — the shared English address-key pipeline (directionals + suffix aliases), currently identical to US.
|
|
165
|
-
* - **fr** — fold + expand leading type abbreviations and Saint/Sainte (token map).
|
|
166
|
-
* - **de** — fold + ß→ss + canonicalize the GLUED `-str(.)` suffix to `-strasse` ("Lindenstr." → "lindenstrasse",
|
|
167
|
-
* "Lindenstraße" → "lindenstrasse"); an already-full "-strasse" is left intact.
|
|
168
|
-
* - **nl** — fold + canonicalize the glued `-str` suffix to `-straat` ("Kerkstr." → "kerkstraat").
|
|
169
|
-
*/
|
|
170
|
-
export function normalizeStreetForKeyLocale(street, locale) {
|
|
171
|
-
if (locale === "us" || locale === "en")
|
|
172
|
-
return normalizeStreetForKey(street);
|
|
173
|
-
// Hyphen → space so a compound name keys the same whether the source or the query writes the
|
|
174
|
-
// hyphen ("Champs-Élysées", "St-Honoré") or a space — both sides fold identically, so this is pure
|
|
175
|
-
// robustness. It also splits a hyphenated abbreviation ("St-Honoré" → "st honore") into tokens the
|
|
176
|
-
// per-locale type/Saint map can see.
|
|
177
|
-
const tokens = fold(street).replaceAll("ß", "ss").replaceAll("-", " ").split(/\s+/).filter(Boolean);
|
|
178
|
-
if (!tokens.length)
|
|
179
|
-
return "";
|
|
180
|
-
switch (locale) {
|
|
181
|
-
case "fr":
|
|
182
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
183
|
-
tokens[i] = FR_STREET_ABBREV.get(tokens[i]) ?? tokens[i];
|
|
184
|
-
}
|
|
185
|
-
break;
|
|
186
|
-
case "de":
|
|
187
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
188
|
-
const t = tokens[i];
|
|
189
|
-
if (t.endsWith("str") && !t.endsWith("strasse")) {
|
|
190
|
-
tokens[i] = t.replace(/str$/, "strasse");
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
break;
|
|
194
|
-
case "nl":
|
|
195
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
196
|
-
const t = tokens[i];
|
|
197
|
-
if (t.endsWith("str") && !t.endsWith("straat")) {
|
|
198
|
-
tokens[i] = t.replace(/str$/, "straat");
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
break;
|
|
202
|
-
}
|
|
203
|
-
return tokens.join(" ");
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* Normalize a locality name for address-point keying (fold only — no street semantics).
|
|
207
|
-
*/
|
|
208
|
-
export function normalizeLocalityForKey(locality) {
|
|
209
|
-
return fold(locality);
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* Strip a trailing French arrondissement designator from a FOLDED commune key ("paris 8e arrondissement" → "paris",
|
|
213
|
-
* "lyon 1er arrondissement" → "lyon", "marseille 10e arrondissement" → "marseille"). Paris, Lyon and Marseille are the
|
|
214
|
-
* only French communes subdivided into _arrondissements municipaux_; a national register (BAN) names each row per
|
|
215
|
-
* arrondissement, but a query names the base commune ("Place Bellecour, Lyon", never "…, Lyon 2e"). Applied on BOTH
|
|
216
|
-
* sides of the #1042 street-centroid key — build-side (deriving the `locality_base` column) and query-side (folding the
|
|
217
|
-
* probe commune) — so the two agree by construction (the one-function discipline). Input must already be folded
|
|
218
|
-
* (lower-case, diacritic-stripped); a no-op for every other commune. Returns the input unchanged if the strip would
|
|
219
|
-
* empty it.
|
|
220
|
-
*/
|
|
221
|
-
export function stripArrondissement(localityNorm) {
|
|
222
|
-
const stripped = localityNorm.replace(/\s+\d+(?:er|e)\s+arrondissement$/, "").trim();
|
|
223
|
-
return stripped || localityNorm;
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* Strip a locality QUALIFIER for a query-side fallback — when an OA locality's exact normalized name misses the
|
|
227
|
-
* gazetteer's canonical name, retry with the qualifier removed. OA address data carries disambiguating qualifiers the
|
|
228
|
-
* gazetteer's canonical name omits: Austrian `Kraubath/Mur` and `Hart b.Graz` → `Hart`; Swiss `Lenk im Simmental` →
|
|
229
|
-
* `Lenk`, `Roche VD` → `Roche`; Danish `Odense S`, `Hurup Thy`. A FALLBACK ONLY — the exact name is tried first, and
|
|
230
|
-
* the region-bbox disambiguation resolves any base-name ambiguity downstream. The candidate table is unchanged (this is
|
|
231
|
-
* purely query-side); feed the result back through {@link normalizeLocalityForKey}. Returns "" when nothing was stripped
|
|
232
|
-
* (no point re-probing the identical key).
|
|
233
|
-
*
|
|
234
|
-
* Measured (`scripts/eval/candidate-recall.ts --strip-fallback`, EU OA holdouts): recovers AT 74.1→88.2% (+14.1pp), DK
|
|
235
|
-
* 91.5→96.2%, CH 90.4→92.6%; +1.3pp overall (diluted by the already-100% locales). Conservative by design — only the
|
|
236
|
-
* qualifier forms above; FI/PT/SI misses are untouched.
|
|
237
|
-
*/
|
|
238
|
-
export function stripLocalityQualifier(locality) {
|
|
239
|
-
let s = locality.trim();
|
|
240
|
-
if (s.includes("/")) {
|
|
241
|
-
s = s.split("/")[0].trim();
|
|
242
|
-
}
|
|
243
|
-
// "Kraubath/Mur", "St.Kanzian/Klopeiner See"
|
|
244
|
-
s = s.replace(/\s+[a-zà-ÿ]\.\s*\S.*$/iu, ""); // abbreviated " b.Graz" / " o.Bleiburg" / " a.d. …"
|
|
245
|
-
s = s.replace(/\s+(im|an der|ob|bei|in der|unter|vor)\s+\S.*$/iu, ""); // " im Simmental", " bei Graz"
|
|
246
|
-
s = s.replace(/\s+(S|N|E|W|V|Ø|Sø|Fyn|Thy|Sjælland|Jylland|[A-ZÅÄÖ]{2})$/u, ""); // " S", " VD", " Thy"
|
|
247
|
-
s = s.trim();
|
|
248
|
-
return s === locality.trim() ? "" : s;
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* Fold numbered-route designators to a canonical key, applied AFTER {@link normalizeStreetForKey}. Sources disagree
|
|
252
|
-
* systematically on how they spell a route: TIGER says `State Rte 100` / `US Hwy 5` where E911/Overture say `VT ROUTE
|
|
253
|
-
* 100` / `US ROUTE 5` — the dominant street-name miss class in the #483 interpolation eval (rural addresses live on
|
|
254
|
-
* routes). `us <designator> N…` folds to `us route N…`; `state <designator> N…` and `<2-letter-prefix> <designator> N…`
|
|
255
|
-
* (the state abbreviation form) fold to `state route N…`. Only digit-leading route numbers fold — `State Street` and
|
|
256
|
-
* friends never match.
|
|
257
|
-
*
|
|
258
|
-
* Used by BOTH the segment-shard builder (`scripts/build-interpolation-shard.ts`) and the interpolation lookup — same
|
|
259
|
-
* one-function discipline as {@link normalizeStreetForKey}. The address-point tier (#476) does NOT apply it yet:
|
|
260
|
-
* adopting it there requires a shard rebuild (noted on #483).
|
|
261
|
-
*
|
|
262
|
-
* A same-numbered US and state route stay DISTINCT keys (`us route 5` vs `state route 5`); only the BARE `route N` form
|
|
263
|
-
* is ambiguous (designator unknown) and it stays unfolded — a bare-route query therefore misses rather than guessing a
|
|
264
|
-
* designator.
|
|
265
|
-
*/
|
|
266
|
-
export function canonicalizeRouteKey(streetNorm) {
|
|
267
|
-
const match = /^(us|state|[a-z]{2}) (?:route|rte|rt|highway|hwy) (\d.*)$/.exec(streetNorm);
|
|
268
|
-
if (!match)
|
|
269
|
-
return streetNorm;
|
|
270
|
-
return `${match[1] === "us" ? "us" : "state"} route ${match[2]}`;
|
|
271
|
-
}
|
|
272
|
-
//# sourceMappingURL=street-normalize.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"street-normalize.js","sourceRoot":"","sources":["../street-normalize.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"street-segment-schema.d.ts","sourceRoot":"","sources":["../street-segment-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEpC;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IAClC;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;CACf;AAED;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACpC;;OAEG;IACH,iBAAiB,EAAE,MAAM,CAAA;IACzB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;CACd;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACrC,cAAc,EAAE,kBAAkB,CAAA;IAClC,kBAAkB,EAAE,oBAAoB,CAAA;CACxC;AAED;;;GAGG;AACH,eAAO,MAAM,sBAAsB,8JAczB,CAAA;AAEV;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,EAAE,EAAE,MAAM,CAAC,qBAAqB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB/F;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC3C,EAAE,EAAE,MAAM,CAAC,qBAAqB,CAAC,EACjC,GAAG,EAAE,oBAAoB,GACvB,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;GAEG;AACH,wBAAsB,0BAA0B,CAAC,EAAE,EAAE,MAAM,CAAC,qBAAqB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAQjG"}
|
package/sqlite-utils.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @copyright Sister Software
|
|
3
|
-
* @license AGPL-3.0
|
|
4
|
-
* @author Teffen Ellis, et al.
|
|
5
|
-
*
|
|
6
|
-
* Small shared helpers for the SQLite-backed lookups.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import type { DatabaseSync } from "node:sqlite"
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* True when `name` is a table in the open database. The street-level lookups use this to degrade gracefully on an
|
|
13
|
-
* empty/tableless shard — an interrupted `build-*-shard.ts`, or a stray 0-byte file (e.g. `sqlite3 <missing>.db "…"`
|
|
14
|
-
* CREATES one) — rather than throwing `no such table` at construction and taking down a whole state's geocode (#568). A
|
|
15
|
-
* missing table makes the lookup a no-op miss.
|
|
16
|
-
*/
|
|
17
|
-
export function hasTable(db: DatabaseSync, name: string): boolean {
|
|
18
|
-
try {
|
|
19
|
-
const row = db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ? LIMIT 1").get(name)
|
|
20
|
-
|
|
21
|
-
return row !== undefined
|
|
22
|
-
} catch {
|
|
23
|
-
return false
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* True when `table` exists in the open database AND carries `column`.
|
|
29
|
-
*
|
|
30
|
-
* The column-level sibling of {@link hasTable}, and it exists for the same reason one layer down: an artifact built
|
|
31
|
-
* before a column was added is still a VALID artifact, and a reader that unconditionally names the new column in its
|
|
32
|
-
* `SELECT` turns "this gazetteer is a build behind" into `no such column` at the first keystroke. Probe once at
|
|
33
|
-
* construction and shape the query — `table_info` is a PRAGMA, so it must not sit on a per-query path.
|
|
34
|
-
*
|
|
35
|
-
* Note the interpolation: PRAGMA does not take bound parameters, so `table` is spliced. Every caller passes a
|
|
36
|
-
* module-level constant; never pass user input.
|
|
37
|
-
*/
|
|
38
|
-
export function hasColumn(db: DatabaseSync, table: string, column: string): boolean {
|
|
39
|
-
try {
|
|
40
|
-
const rows = db.prepare(`PRAGMA table_info(${table})`).all() as unknown as Array<{ name: string }>
|
|
41
|
-
|
|
42
|
-
return rows.some((r) => String(r.name) === column)
|
|
43
|
-
} catch {
|
|
44
|
-
return false
|
|
45
|
-
}
|
|
46
|
-
}
|
package/street-normalize.ts
DELETED
|
@@ -1,318 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @copyright Sister Software
|
|
3
|
-
* @license AGPL-3.0
|
|
4
|
-
* @author Teffen Ellis, et al.
|
|
5
|
-
*
|
|
6
|
-
* THE street normalizer for the address-point tier (#476). One function, used by BOTH the shard
|
|
7
|
-
* builder (`scripts/build-address-point-shard.ts`) and the lookup tier (`address-point.ts`) —
|
|
8
|
-
* never two implementations (the PLACETYPE_ORDER lesson: parallel copies silently corrupt).
|
|
9
|
-
*
|
|
10
|
-
* Normalization contract (deliberately aggressive — both sides apply the same function, so
|
|
11
|
-
* collisions only need to be _consistent_, not linguistically perfect):
|
|
12
|
-
*
|
|
13
|
-
* 1. Lowercase, NFKD-fold diacritics, collapse whitespace, strip punctuation (periods, commas,
|
|
14
|
-
* apostrophes).
|
|
15
|
-
* 2. Expand USPS directional abbreviations at the FIRST and LAST token position (`n` → `north`, `se` →
|
|
16
|
-
* `southeast`) — Overture sources abbreviate inconsistently.
|
|
17
|
-
* 3. Canonicalize a trailing USPS street-type token via the codex suffix table to its canonical full
|
|
18
|
-
* form (`st`/`str`/`street` → `street`).
|
|
19
|
-
*
|
|
20
|
-
* Numbered streets are left as digits (`5th` stays `5th`); a SPELLED ordinal before a street suffix
|
|
21
|
-
* folds to its digit form (`tenth street` → `10th street`, #723) so the grid-city ordinal
|
|
22
|
-
* cross-streets the source data spells with digits become reachable.
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
import { AbbreviationToDirectional, US_STREET_SUFFIX_LOOKUP } from "@mailwoman/codex/us"
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Token count a street must exceed before its trailing pair is merged. At or below it the pair IS the whole street
|
|
29
|
-
* name, and merging would leave nothing to match on.
|
|
30
|
-
*/
|
|
31
|
-
const MIN_TOKENS_FOR_TAIL_MERGE = 3
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Spelled ordinal street names → their digit-ordinal form ("tenth" → "10th"), applied ONLY when a street-type suffix
|
|
35
|
-
* follows (#723 admin-tail) — so the ordinal cross-streets common in grid cities ("Tenth Street", "Fifth Avenue") match
|
|
36
|
-
* the shards' digit keys, WITHOUT rewriting ordinal-WORD names where the next token is not a suffix ("First National
|
|
37
|
-
* Bank Rd" stays "first national …"). Digit-source shards are unaffected (a digit token isn't in this map), so the
|
|
38
|
-
* existing keys need no rebuild; a future rebuild folds any spelled-source key the same way (the one-function
|
|
39
|
-
* discipline).
|
|
40
|
-
*/
|
|
41
|
-
const SPELLED_ORDINAL_TO_DIGIT = new Map<string, string>([
|
|
42
|
-
["first", "1st"],
|
|
43
|
-
["second", "2nd"],
|
|
44
|
-
["third", "3rd"],
|
|
45
|
-
["fourth", "4th"],
|
|
46
|
-
["fifth", "5th"],
|
|
47
|
-
["sixth", "6th"],
|
|
48
|
-
["seventh", "7th"],
|
|
49
|
-
["eighth", "8th"],
|
|
50
|
-
["ninth", "9th"],
|
|
51
|
-
["tenth", "10th"],
|
|
52
|
-
["eleventh", "11th"],
|
|
53
|
-
["twelfth", "12th"],
|
|
54
|
-
["thirteenth", "13th"],
|
|
55
|
-
["fourteenth", "14th"],
|
|
56
|
-
["fifteenth", "15th"],
|
|
57
|
-
["sixteenth", "16th"],
|
|
58
|
-
["seventeenth", "17th"],
|
|
59
|
-
["eighteenth", "18th"],
|
|
60
|
-
["nineteenth", "19th"],
|
|
61
|
-
["twentieth", "20th"],
|
|
62
|
-
["thirtieth", "30th"],
|
|
63
|
-
["fortieth", "40th"],
|
|
64
|
-
["fiftieth", "50th"],
|
|
65
|
-
["sixtieth", "60th"],
|
|
66
|
-
["seventieth", "70th"],
|
|
67
|
-
["eightieth", "80th"],
|
|
68
|
-
["ninetieth", "90th"],
|
|
69
|
-
["hundredth", "100th"],
|
|
70
|
-
])
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Lowercase + diacritic-fold + punctuation strip + whitespace collapse.
|
|
74
|
-
*/
|
|
75
|
-
function fold(input: string): string {
|
|
76
|
-
return input
|
|
77
|
-
.normalize("NFKD")
|
|
78
|
-
.replaceAll(/[̀-ͯ]/g, "")
|
|
79
|
-
.toLowerCase()
|
|
80
|
-
.replaceAll(/[.,'’]/g, "")
|
|
81
|
-
.replaceAll(/\s+/g, " ")
|
|
82
|
-
.trim()
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Normalize a street name for address-point keying. Same function at build time and lookup time — see module docstring
|
|
87
|
-
* for the contract.
|
|
88
|
-
*/
|
|
89
|
-
export function normalizeStreetForKey(street: string): string {
|
|
90
|
-
const tokens = fold(street).split(" ")
|
|
91
|
-
|
|
92
|
-
if (!tokens.length) return ""
|
|
93
|
-
|
|
94
|
-
// Spelled-ordinal street names → digit form when a street suffix follows ("Tenth Street" →
|
|
95
|
-
// "10th street", #723). Gated on the next token being a suffix so ordinal-WORD names are untouched.
|
|
96
|
-
for (let i = 0; i < tokens.length - 1; i++) {
|
|
97
|
-
const digit = SPELLED_ORDINAL_TO_DIGIT.get(tokens[i]!)
|
|
98
|
-
|
|
99
|
-
if (digit && US_STREET_SUFFIX_LOOKUP.has(tokens[i + 1]!)) {
|
|
100
|
-
tokens[i] = digit
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Directional expansion at the edges only ("N Main St" / "Main St N" — never interior
|
|
105
|
-
// tokens, where "W" may be an initial in a person-named street). The codex expands
|
|
106
|
-
// compounds to two words ("SE" → "SOUTH EAST"); we key on the spaceless form
|
|
107
|
-
// ("southeast"), and also merge an already-written two-token pair ("South East …").
|
|
108
|
-
const edgeDirectional = (raw: string) =>
|
|
109
|
-
AbbreviationToDirectional.get(raw.toUpperCase())?.toLowerCase().replace(" ", "")
|
|
110
|
-
|
|
111
|
-
const mergePair = (a?: string, b?: string) =>
|
|
112
|
-
a && b && /^(north|south)$/.test(a) && /^(east|west)$/.test(b) ? a + b : undefined
|
|
113
|
-
|
|
114
|
-
const leadPair = mergePair(tokens[0], tokens[1])
|
|
115
|
-
|
|
116
|
-
if (leadPair && tokens.length > 2) {
|
|
117
|
-
tokens.splice(0, 2, leadPair)
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const first = edgeDirectional(tokens[0]!)
|
|
121
|
-
|
|
122
|
-
if (first && tokens.length > 1) {
|
|
123
|
-
tokens[0] = first
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const tailPair = mergePair(tokens.at(-2), tokens.at(-1))
|
|
127
|
-
|
|
128
|
-
if (tailPair && tokens.length > MIN_TOKENS_FOR_TAIL_MERGE) {
|
|
129
|
-
tokens.splice(-2, 2, tailPair)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (tokens.length > 2) {
|
|
133
|
-
const last = edgeDirectional(tokens.at(-1)!)
|
|
134
|
-
|
|
135
|
-
if (last) {
|
|
136
|
-
tokens[tokens.length - 1] = last
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Street-type canonicalization via the codex table (lowercase keys, UPPER canonical
|
|
141
|
-
// values). The suffix is usually the last token, but sits second-to-last when a trailing
|
|
142
|
-
// directional follows ("Main St N") — check both positions, canonicalize the first hit.
|
|
143
|
-
for (const at of [tokens.length - 1, tokens.length - 2]) {
|
|
144
|
-
if (at < 1) continue // never canonicalize the only/first token ("Street Road" exists)
|
|
145
|
-
const canonical = US_STREET_SUFFIX_LOOKUP.get(tokens[at]!)
|
|
146
|
-
|
|
147
|
-
if (canonical) {
|
|
148
|
-
tokens[at] = canonical.toLowerCase()
|
|
149
|
-
|
|
150
|
-
break
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return tokens.join(" ")
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Street-name locale for the address-point key. The US path is the full USPS pipeline ({@link normalizeStreetForKey});
|
|
159
|
-
* the international paths fold + apply a SMALL, consistent per-locale type-token canonicalization. Same discipline as
|
|
160
|
-
* the US normalizer: build side and probe side call the identical function, so the key only needs to be CONSISTENT, not
|
|
161
|
-
* linguistically perfect — a folded "rue du chevaleret" keys the same on both sides whether or not we reorder the
|
|
162
|
-
* article, so no salient-token / multi-key index is built yet (deferred until probing shows the normalizer can't absorb
|
|
163
|
-
* the false-negatives).
|
|
164
|
-
*/
|
|
165
|
-
export type StreetLocale = "us" | "en" | "fr" | "de" | "nl"
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* French street-type abbreviations → canonical full form, applied per token after {@link fold}. French address types
|
|
169
|
-
* LEAD the name ("Av. de…", "Bd …", "Pl. …") and "St"/"Ste" abbreviate Saint/Sainte inside names ("Rue St-Honoré" →
|
|
170
|
-
* "rue saint honore"). fold() has already stripped the trailing period, so the keys are point-free ("av", "bd").
|
|
171
|
-
*/
|
|
172
|
-
const FR_STREET_ABBREV = new Map<string, string>([
|
|
173
|
-
["av", "avenue"],
|
|
174
|
-
["ave", "avenue"],
|
|
175
|
-
["bd", "boulevard"],
|
|
176
|
-
["bld", "boulevard"],
|
|
177
|
-
["bvd", "boulevard"],
|
|
178
|
-
["boul", "boulevard"],
|
|
179
|
-
["pl", "place"],
|
|
180
|
-
["imp", "impasse"],
|
|
181
|
-
["all", "allee"],
|
|
182
|
-
["ch", "chemin"],
|
|
183
|
-
["che", "chemin"],
|
|
184
|
-
["sq", "square"],
|
|
185
|
-
["pas", "passage"],
|
|
186
|
-
["fg", "faubourg"],
|
|
187
|
-
["fbg", "faubourg"],
|
|
188
|
-
["rte", "route"],
|
|
189
|
-
["st", "saint"],
|
|
190
|
-
["ste", "sainte"],
|
|
191
|
-
["sts", "saints"],
|
|
192
|
-
])
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Normalize a street name for the address-point key in a non-US locale. Same function build-side and probe-side (the
|
|
196
|
-
* one-function discipline). US delegates to {@link normalizeStreetForKey}.
|
|
197
|
-
*
|
|
198
|
-
* - **en** — the shared English address-key pipeline (directionals + suffix aliases), currently identical to US.
|
|
199
|
-
* - **fr** — fold + expand leading type abbreviations and Saint/Sainte (token map).
|
|
200
|
-
* - **de** — fold + ß→ss + canonicalize the GLUED `-str(.)` suffix to `-strasse` ("Lindenstr." → "lindenstrasse",
|
|
201
|
-
* "Lindenstraße" → "lindenstrasse"); an already-full "-strasse" is left intact.
|
|
202
|
-
* - **nl** — fold + canonicalize the glued `-str` suffix to `-straat` ("Kerkstr." → "kerkstraat").
|
|
203
|
-
*/
|
|
204
|
-
export function normalizeStreetForKeyLocale(street: string, locale: StreetLocale): string {
|
|
205
|
-
if (locale === "us" || locale === "en") return normalizeStreetForKey(street)
|
|
206
|
-
|
|
207
|
-
// Hyphen → space so a compound name keys the same whether the source or the query writes the
|
|
208
|
-
// hyphen ("Champs-Élysées", "St-Honoré") or a space — both sides fold identically, so this is pure
|
|
209
|
-
// robustness. It also splits a hyphenated abbreviation ("St-Honoré" → "st honore") into tokens the
|
|
210
|
-
// per-locale type/Saint map can see.
|
|
211
|
-
const tokens = fold(street).replaceAll("ß", "ss").replaceAll("-", " ").split(/\s+/).filter(Boolean)
|
|
212
|
-
|
|
213
|
-
if (!tokens.length) return ""
|
|
214
|
-
|
|
215
|
-
switch (locale) {
|
|
216
|
-
case "fr":
|
|
217
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
218
|
-
tokens[i] = FR_STREET_ABBREV.get(tokens[i]!) ?? tokens[i]!
|
|
219
|
-
}
|
|
220
|
-
break
|
|
221
|
-
case "de":
|
|
222
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
223
|
-
const t = tokens[i]!
|
|
224
|
-
|
|
225
|
-
if (t.endsWith("str") && !t.endsWith("strasse")) {
|
|
226
|
-
tokens[i] = t.replace(/str$/, "strasse")
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
break
|
|
230
|
-
case "nl":
|
|
231
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
232
|
-
const t = tokens[i]!
|
|
233
|
-
|
|
234
|
-
if (t.endsWith("str") && !t.endsWith("straat")) {
|
|
235
|
-
tokens[i] = t.replace(/str$/, "straat")
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
break
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
return tokens.join(" ")
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Normalize a locality name for address-point keying (fold only — no street semantics).
|
|
246
|
-
*/
|
|
247
|
-
export function normalizeLocalityForKey(locality: string): string {
|
|
248
|
-
return fold(locality)
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Strip a trailing French arrondissement designator from a FOLDED commune key ("paris 8e arrondissement" → "paris",
|
|
253
|
-
* "lyon 1er arrondissement" → "lyon", "marseille 10e arrondissement" → "marseille"). Paris, Lyon and Marseille are the
|
|
254
|
-
* only French communes subdivided into _arrondissements municipaux_; a national register (BAN) names each row per
|
|
255
|
-
* arrondissement, but a query names the base commune ("Place Bellecour, Lyon", never "…, Lyon 2e"). Applied on BOTH
|
|
256
|
-
* sides of the #1042 street-centroid key — build-side (deriving the `locality_base` column) and query-side (folding the
|
|
257
|
-
* probe commune) — so the two agree by construction (the one-function discipline). Input must already be folded
|
|
258
|
-
* (lower-case, diacritic-stripped); a no-op for every other commune. Returns the input unchanged if the strip would
|
|
259
|
-
* empty it.
|
|
260
|
-
*/
|
|
261
|
-
export function stripArrondissement(localityNorm: string): string {
|
|
262
|
-
const stripped = localityNorm.replace(/\s+\d+(?:er|e)\s+arrondissement$/, "").trim()
|
|
263
|
-
|
|
264
|
-
return stripped || localityNorm
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* Strip a locality QUALIFIER for a query-side fallback — when an OA locality's exact normalized name misses the
|
|
269
|
-
* gazetteer's canonical name, retry with the qualifier removed. OA address data carries disambiguating qualifiers the
|
|
270
|
-
* gazetteer's canonical name omits: Austrian `Kraubath/Mur` and `Hart b.Graz` → `Hart`; Swiss `Lenk im Simmental` →
|
|
271
|
-
* `Lenk`, `Roche VD` → `Roche`; Danish `Odense S`, `Hurup Thy`. A FALLBACK ONLY — the exact name is tried first, and
|
|
272
|
-
* the region-bbox disambiguation resolves any base-name ambiguity downstream. The candidate table is unchanged (this is
|
|
273
|
-
* purely query-side); feed the result back through {@link normalizeLocalityForKey}. Returns "" when nothing was stripped
|
|
274
|
-
* (no point re-probing the identical key).
|
|
275
|
-
*
|
|
276
|
-
* Measured (`scripts/eval/candidate-recall.ts --strip-fallback`, EU OA holdouts): recovers AT 74.1→88.2% (+14.1pp), DK
|
|
277
|
-
* 91.5→96.2%, CH 90.4→92.6%; +1.3pp overall (diluted by the already-100% locales). Conservative by design — only the
|
|
278
|
-
* qualifier forms above; FI/PT/SI misses are untouched.
|
|
279
|
-
*/
|
|
280
|
-
export function stripLocalityQualifier(locality: string): string {
|
|
281
|
-
let s = locality.trim()
|
|
282
|
-
|
|
283
|
-
if (s.includes("/")) {
|
|
284
|
-
s = s.split("/")[0]!.trim()
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// "Kraubath/Mur", "St.Kanzian/Klopeiner See"
|
|
288
|
-
s = s.replace(/\s+[a-zà-ÿ]\.\s*\S.*$/iu, "") // abbreviated " b.Graz" / " o.Bleiburg" / " a.d. …"
|
|
289
|
-
s = s.replace(/\s+(im|an der|ob|bei|in der|unter|vor)\s+\S.*$/iu, "") // " im Simmental", " bei Graz"
|
|
290
|
-
s = s.replace(/\s+(S|N|E|W|V|Ø|Sø|Fyn|Thy|Sjælland|Jylland|[A-ZÅÄÖ]{2})$/u, "") // " S", " VD", " Thy"
|
|
291
|
-
s = s.trim()
|
|
292
|
-
|
|
293
|
-
return s === locality.trim() ? "" : s
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
/**
|
|
297
|
-
* Fold numbered-route designators to a canonical key, applied AFTER {@link normalizeStreetForKey}. Sources disagree
|
|
298
|
-
* systematically on how they spell a route: TIGER says `State Rte 100` / `US Hwy 5` where E911/Overture say `VT ROUTE
|
|
299
|
-
* 100` / `US ROUTE 5` — the dominant street-name miss class in the #483 interpolation eval (rural addresses live on
|
|
300
|
-
* routes). `us <designator> N…` folds to `us route N…`; `state <designator> N…` and `<2-letter-prefix> <designator> N…`
|
|
301
|
-
* (the state abbreviation form) fold to `state route N…`. Only digit-leading route numbers fold — `State Street` and
|
|
302
|
-
* friends never match.
|
|
303
|
-
*
|
|
304
|
-
* Used by BOTH the segment-shard builder (`scripts/build-interpolation-shard.ts`) and the interpolation lookup — same
|
|
305
|
-
* one-function discipline as {@link normalizeStreetForKey}. The address-point tier (#476) does NOT apply it yet:
|
|
306
|
-
* adopting it there requires a shard rebuild (noted on #483).
|
|
307
|
-
*
|
|
308
|
-
* A same-numbered US and state route stay DISTINCT keys (`us route 5` vs `state route 5`); only the BARE `route N` form
|
|
309
|
-
* is ambiguous (designator unknown) and it stays unfolded — a bare-route query therefore misses rather than guessing a
|
|
310
|
-
* designator.
|
|
311
|
-
*/
|
|
312
|
-
export function canonicalizeRouteKey(streetNorm: string): string {
|
|
313
|
-
const match = /^(us|state|[a-z]{2}) (?:route|rte|rt|highway|hwy) (\d.*)$/.exec(streetNorm)
|
|
314
|
-
|
|
315
|
-
if (!match) return streetNorm
|
|
316
|
-
|
|
317
|
-
return `${match[1] === "us" ? "us" : "state"} route ${match[2]}`
|
|
318
|
-
}
|
|
File without changes
|