Repository navigation
feat(matchers): match by phone number and email address - #850
Merged
Merged
Conversation
Owner
Author
|
The advisories check failed for two reasons:
Generated by Claude Code |
PoiMatcher now also matches when the ATP feature and the OSM candidate share a descriptive phone number or email address, and their main categories are equal or a known pair (src/matchers/contact/ category_pairs.tsv). A brand:wikidata conflict still vetoes the match. Beyond 150 m, a contact match also needs the street address to agree. Restaurants, hotels, schools and fuel stations now get a matcher too, and more categories (cafes, fast food, bars, schools, clinics, doctors, fitness centres, museums, healthcare=*) get a match mask. The phone and email parsers move from pipeline::atp::nondescript to matchers::contact, so both sides are parsed alike. OSM numbers in national format go through the phonenumber crate, in the ATP feature's country. See docs/notes/2026-10-25-phone-and-email-matching.md. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P43kACSyJVwszya8Z3d4qQ
Ignore RUSTSEC-2023-0089 (atomic-polyfill is unmaintained), which phonenumber pulls in through postcard and heapless 0.7, only for targets without native atomics. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P43kACSyJVwszya8Z3d4qQ
parse_osm_phone now calls phones::parse_phone_number directly instead of taking the first item of parse_phone_numbers. With build-mode none, CodeQL resolved that `.next()` to unrelated iterators in tables::graph and reported a cleartext-logging flow that does not exist. Also fill in the planet match count of this change in the note. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P43kACSyJVwszya8Z3d4qQ
brawer
force-pushed
the
contact-matching-main
branch
from
October 25, 2026 13:17
d46bc0c to
0b04ded
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Sascha · project thread
What changes
PoiMatchercan now match features that have nobrand:wikidata, by a shared phone number or email address.src/matchers/contact/category_pairs.tsv, and 0 otherwise. Values in the nondescript sets (feat: compute denylist of ATP switchboard phone numbers #844–feat: compute nondescript email addresses from AllThePlaces #846) never count. Abrand:wikidataconflict still vetoes the match. Beyond 150 m, the OSM street and house number must also appear in the ATP address (src/matchers/address.rs).scripts/infer_contact_category_pairs.pysuggested 61 pairs from a planet run. I removed 18 by hand, mostly shop-in-shop cases like Western Union counters in supermarkets, post offices in convenience stores, and hospital departments. They stay in the file as comments, with the reason.healthcare=*get a match mask.pipeline::atp::nondescripttomatchers::contact, so both sides parse alike. OSM numbers that are not in+form go through thephonenumbercrate, in the ATP feature'saddr:country.docs/notes/2026-10-25-phone-and-email-matching.md.TECHNICAL_DESIGN.mdandscripts/README.mdare updated too.Results
These planet numbers come from the experimental branch
contact-matching:brand:wikidatamatches from 825,901 to 1,233,452. Most of the gain is fast food and fuel stations. For charging stations, the median ATP–OSM distance is 8 m.brand:wikidatafound in 97.1% of about 183k cases. Hand checks of new matches put precision at about 97%.+numbers with the crate costs about 15 CPU-seconds on the planet. In India, Thailand, Romania, Japan and Korea, 15–38% of OSM numbers are in national format.A planet rerun of this PR's own code matched 1,302,469 ATP rows. That is 69,017 more than
brand:wikidatawith the wider categories alone, with none lost and 535 moved. The match step took 38 s. The experimental branch matched about 34k more, all of them from its brand-tag matching, which this PR leaves out.The brand-tag matching from
matching-experimentsis not part of this PR.Tests
cargo fmt,cargo clippy --all-targets -- -D warningscargo test: all unit and integration tests pass. I installed tippecanoe locally for the integration tests.matchers::contact(category factor, OSM phone parsing, nondescript filtering, agreement) andtest_poi_matcher_contact(pair, veto, national-format number, no matcher without evidence).uv run pytest test_infer_contact_category_pairs.pypasses. Thetest-on-hetznertests fail locally with and without this change.cargo deny checkpasses.deny.tomlnow ignores RUSTSEC-2023-0089 (atomic-polyfill is unmaintained).phonenumberpulls it in throughpostcardandheapless0.7, but only for targets without native atomics.Generated by Claude Code