Turn on geocoding without turning it into a project
You need to turn an address into a coordinate. That's the whole ask. The problem is that the two ways to get there both start as a project.
Mailwoman Blog
You need to turn an address into a coordinate. That's the whole ask. The problem is that the two ways to get there both start as a project.
I taught the address parser three new countries overnight. Two of them landed. The third tripped a guard I trusted, and the reason was quietly alarming: the new addresses never named their own country, and the model was learning to stop naming it at all.
Most sequence labelers throw away the parts of an address they don't understand, and the output format is built to hide it. We made ours hand every dropped character back, then aggregated them into a ranked list. The top of the list turned out to be the Polish alphabet.
Type 'Vienna, Austria' into our geocoder and it confidently returned a town of ten thousand people in Appalachia. The obvious fix was a retrain. We ran the diagnostic first, and the obvious fix turned out to be the wrong one.
Mailwoman couldn't find Tirana, or Yerevan, or 145 other capitals — not a wrong coordinate, silence. We were going to fix the parser. A ten-minute probe killed that plan, and a stale symlink nearly talked us into a GPU retrain to fix a model that was already fine. Two evals, two silent confounds, and the one dull habit that caught both.
You can point a Nominatim client at Mailwoman now — no PostgreSQL, no planet import, a geocoder from a SQLite file. We did, and the US worked beautifully while the rest of the world resolved to its American namesake. The bug was one line: we'd told it the answer was always America. Here's the line, the four cities that still won't move once you delete it, and the ranking database we forgot to…
You've got a hundred thousand addresses to reconcile. Two databases, the same clinics and providers scattered across both, each one spelled a dozen ways none.
We ran our 30 MB browser geocoder against the incumbents — Nominatim and Pelias — on real European addresses, scored the honest way. We'd just won the US; Europe opened with a double-digit loss. The cause was silence: on messy addresses we returned nothing at all. Here's what the silence was made of, the three fixes that took us clear of both incumbents in Europe, and the one place — Australia —…
Our parser scores 28% on Spanish addresses by the metric that grades its labels. By the metric that grades where the address lands on Earth, it's within a couple of kilometers. Same model, same addresses. Only one of those numbers is measuring the thing we ship.
Open the demo, type an address in Kabul, and watch nothing happen. Not a wrong pin a few streets off. Not a city-center fallback. Nothing — the gazetteer has never heard of the place. Try Hong Kong. Try Tirana, or Chişinău, or anywhere in the Democratic Republic of the Congo. Same silence. We had been calling this gazetteer "world coverage" for weeks, and it covered 97 of the world's ~195…
The whole geocoder runs in your browser. You type an address, you get a rooftop coordinate, and no server ever sees your query — the gazetteer it resolves against is a SQLite database sitting on a CDN, and the page reads it with HTTP range requests, a few kilobytes at a time. It's a lovely trick. We were proud of it. Then we counted the requests it took to find a single city, and the number was…
Overnight I taught the geocoder Canada. Or I thought I did. I pulled 843,000 Canadian postcodes, computed a centroid for every one, spot-checked the result — M5H 2N2, downtown Toronto, 43.652, −79.382, dead on — and validated the database every way I could read it: every postcode present, every coordinate right, nothing else disturbed. Green, top to bottom. This morning, before flipping it live, I…
Open the demo, open your browser's network tab, and type an address. You'll watch it resolve to a rooftop coordinate — 1600 Pennsylvania Ave lands on the actual building, within about ten metres — and then you'll notice what's missing from the network tab: a request carrying your address. There isn't one. The parser ran in the page. The gazetteer it resolved against is a file on a CDN that the…
Every geocoder turns an address into a coordinate. Almost none of them will tell you where that coordinate came from. You get a latitude, a longitude, and a vague confidence enum, and when it's wrong you have no thread to pull — no way to know whether the point came from a federal data release, a county GIS office, or a straight line drawn down the middle of a street. Mailwoman keeps the source on…
Three public datasets land on your desk. The national provider registry — NPPES, every NPI in the country. A federal telecom-funding file from the FCC's Rural Health Care program, one slice of the Universal Service Fund. A state list of licensed nursing facilities from Texas HHSC. You want to know which records describe the same provider, and not one of the three shares an identifier with the…
You have a pile of records and no key to join them on. A clinic shows up in the federal provider registry, again in a state licensing export, a third time in a funding-program spreadsheet somebody keyed by hand. None of those files share an identifier. The provider number is internal to one publisher, the facility ID to another. So the join you actually want — which of these are the same place —…
We're trained to be suspicious of a score that looks too good. The scores that say you failed get a free pass — and this week three of them were lying, including one that had us reporting kilometers for a product that lands in meters.
We taught our parser the hardest street cases it gets wrong, the aggregate score climbed, and we almost shipped it. Then a held-out probe caught it forgetting what a town is.
Mailwoman ships two address parsers in the same box.
Our failure taxonomy finally has a line at the very top: of everything wrong with the parser,