Geocoding and Reverse Geocoding: Turning Text into Coordinates

Geocoding and Reverse Geocoding: Turning Text into Coordinates

E
By Etzal Earth
13 min read

An address is a human instruction. It tells a person how to reach a place using shared local knowledge: which town, which street, roughly how far along, which door. A coordinate is a machine instruction. It names a point and nothing else. Geocoding is the translation between those two, and it is considerably less reliable than the clean interfaces around it suggest.

The core difficulty is that a geocoder almost always returns something. Send it a malformed string, a building that was demolished, or a village name that exists in six countries, and most services will hand back a latitude and longitude with six decimal places. The coordinate is real. Whether it corresponds to the place named in the string is a completely separate question, and answering that question honestly is the entire job.

Everything downstream inherits the answer without seeing the doubt. A risk score, a delivery route, a catchment map, a density heatmap: each of them consumes a point that arrived stripped of the uncertainty that produced it.

What a geocoder actually does

The interface is one string in, one point out. The machinery behind it has four distinct stages, and knowing which stage failed tells you far more than the final score does.

Parsing comes first. The input string is broken into components: house number, street name, unit, locality, administrative area, postcode, country. This is harder than it sounds because the components are not delimited reliably and their order changes by country. A parser has to decide whether a leading number is a house number, a block number, or part of a street name.

Normalisation follows. Abbreviations are expanded or contracted to a canonical form, accents and casing are folded, and street type words are standardised. Every reference dataset stores names one particular way, and matching only works if the query is bent into the same shape.

Candidate retrieval then searches one or more reference datasets: an address point file where individual properties are recorded, a parcel or building layer, a street centreline network with number ranges on each segment, a gazetteer of place names, and administrative and postal boundaries. Each covers a different fraction of the world at a different quality.

Scoring and selection is the last stage. Candidates are ranked on how completely they matched, how many components agreed, how far the candidates are from each other, and whether anything in the query was ignored. The winner is returned. Whether the runner-up was almost as good is information the caller usually never receives.

Why addresses resist being parsed

Addressing is not a standard. It is thousands of local conventions that happen to share a name.

Large parts of the world use informal addressing, where the written address describes a route rather than a position. Directions relative to a landmark, a block and neighbourhood unit rather than a street and number, a compound with a shared entrance, or an address that only functions if the reader already knows the district. These are perfectly good instructions for a human courier and close to unparseable for software expecting street and number.

Ambiguity is the second problem. Place names repeat, within a country and across countries, and street names repeat within a city. A query missing an administrative qualifier may match dozens of real places, all correct answers to an underspecified question. The geocoder is not choosing the right one, it is choosing the most popular one, and popularity is a proxy for correctness that fails exactly where data is thinnest.

Multiple valid forms are the third. The same property can be written with the unit before or after the street, with the building name instead of the number, with an old street name that locals still use, or with a district name that has no official status. All of these are the same door. None of them are the same string.

Then there are the structural mismatches. A single building can carry many addresses, one per entrance or unit, and a single address can cover many buildings, as with a campus or an industrial estate. New developments exist physically for months before they exist in any reference file, and demolished buildings persist in reference files long after they stop existing.

The precision ladder matters more than the coordinate

Every geocoded result sits at a level of precision, and the level is a category, not a distance in metres. Four levels cover most of what services return.

  • Rooftop or address point. The reference data holds a recorded position for this specific property. This is the only level where the coordinate genuinely refers to the thing named.
  • Parcel or building. The result is the centroid of a parcel or footprint the address belongs to. Good for most purposes, but the centroid of an irregular parcel can fall on an unbuilt corner, and the centroid of a concave footprint can fall outside the building entirely.
  • Street interpolation. There is no record of this property, only a street segment with a number range. The position is estimated by proportion along the segment.
  • Centroid fallback. Nothing below the level of a locality, postcode, or administrative area matched. The result is the centre of that area, which is not a location so much as a label.

The precision level is more important than the coordinate because it determines which questions the coordinate can answer. A locality centroid is perfectly adequate for aggregating sales by city. It is worthless for deciding whether a property sits inside a flood extent. The same coordinate, used for two purposes, is fine in one and dangerous in the other, and nothing in the number itself tells the difference.

This is why a response without a precision field is an incomplete response. If a service returns only coordinates, every consumer treats every result as equally trustworthy, which guarantees that the weakest results set the real accuracy of the system.

Interpolation and the house that is not there

Street interpolation deserves its own treatment because it is the level most people mistake for a real match.

The mechanism is simple. A street segment carries a number range, say the even numbers from 2 to 40 on one side. A query for number 20 is placed roughly halfway along the segment, then offset a few metres to the correct side of the centreline. The result looks exactly like a rooftop match.

The assumptions built into that estimate fail routinely. Lot widths are not uniform, so a segment with three large plots and twenty narrow ones will place almost everything wrongly. Numbers are often not allocated evenly, with gaps where a plot was consolidated or blocks reserved and never used. Long rural segments stretch for kilometres, so a proportional estimate can be hundreds of metres from the driveway. Infill developments insert numbers the recorded range does not contain, and the geocoder either clamps them to the end of the range or refuses.

None of this makes interpolation useless. It makes it an estimate, with an error that scales with segment length and lot irregularity, and it should be carried through the system labelled as one.

Reverse geocoding asks a question with several right answers

Reverse geocoding takes a point and returns a description of it. The ambiguity here is worse than in the forward direction, because the question itself is underspecified.

A point has a nearest address point, a parcel it falls within, a building it falls within or beside, a street it is closest to, a neighbourhood, a postcode area, a municipality, and a country. All of those are true descriptions of the point. Which one is the answer depends entirely on what the caller intended, and the caller usually did not say.

The concrete failures follow from that. A point in the middle of a car park has no address, so the service returns the nearest one, which is a shop that happens to back onto it. A point inside a large hospital campus returns whichever of forty buildings has the closest recorded position. A point a few metres from an administrative boundary returns whichever side won, with no indication that the decision was marginal.

Positional error compounds this. Consumer positioning is accurate to some tens of metres in the open and much worse in dense urban areas where signals reflect off buildings. Feeding a point with that much uncertainty into a nearest-address lookup produces an address with none of it. The uncertainty does not disappear, it is discarded at the moment of lookup.

An honest reverse geocoder returns the containing features at several levels, states which level it is confident about, and where a nearest-feature answer is used, says so and gives the distance. Four metres and four hundred metres are not the same answer, and returning both as a plain address string erases the difference.

Match confidence, and the case for refusing

Most services return a confidence score. Treating it as a probability is a mistake. Scores are provider specific, uncalibrated, and frequently not comparable even between regions of the same service. The same score in a country with good address data and in one with thin coverage describes very different situations.

More useful than a single number is structured match metadata: which components of the query matched, which were ignored, which were inferred, how many alternative candidates scored close to the winner, and what precision level the result sits at. That is enough to decide whether to accept a result without guessing what a scalar means.

The more important design point is that a geocoder should be willing to return nothing. Returning a low-confidence guess is worse than returning a failure, because a failure is visible and a bad guess is not. A failed match gets queued for review or dropped from the analysis with a known count. A bad match enters the dataset and is indistinguishable from a good one forever after.

The threshold should be set by the asymmetry of the costs. If a wrong location produces a mildly wrong marketing map, a loose threshold is fine. If a wrong location produces an insurance quote, a routing decision, or a hazard exposure assessment, the threshold should be tight enough that most ambiguous inputs are refused and sent to a human. Systems that never refuse have not eliminated the ambiguity, they have moved it somewhere nobody is looking.

Batch geocoding is not single geocoding in a loop

Geocoding one address interactively and geocoding a million in a job have different failure characteristics, and the difference is not throughput.

The interactive case has a human in the loop. If the result is obviously wrong, someone notices. The batch case has nobody, so failures accumulate silently and the aggregate quality is set by the worst records rather than the typical ones.

The specific things that go wrong in batch:

  • Failures cluster. Bad matches are not randomly distributed. They concentrate in the regions with the weakest reference data, which are usually the poorer or more rural parts of the coverage. A batch that is ninety percent accurate overall can be almost entirely wrong in one province, and the overall figure hides it.
  • Centroid fallbacks pile up. Every record that fell back to a locality centroid lands on the exact same coordinate. In any density analysis those stacks become false hotspots, sitting precisely on town centres.
  • Results drift between runs. Reference data changes. Re-running the same input file months later produces different coordinates for some records, and without recording which reference version produced which result, the difference is unattributable.
  • Rate limits and partial failures interact badly. A job that retries on error and skips on repeated failure will quietly produce an output file shorter than its input, and the difference is rarely checked.

The practical discipline: normalise and deduplicate before geocoding rather than after, keep the original input string alongside every result, record the precision level and reference data version per record, and verify a sample stratified by region and precision level rather than a sample of the whole, which will be dominated by the easy cases.

The licence sits on the output, not just the input

Geocoding carries a legal constraint that most other data operations do not, and it catches teams late.

Many commercial geocoding services permit use of the returned coordinates only in conjunction with their own maps, or only for a limited caching period, or prohibit persistent storage of the results altogether. The coordinates are treated as a licensed product, not as a fact derived from a query. That means a database column full of geocoded points can be a licensing problem even though the addresses in the next column are entirely yours.

Open reference data has the mirror problem. Geocoding against a share-alike dataset and merging the results back into a proprietary table can pull that table into the share-alike obligation, depending on how the merge is structured and what is being distributed. The obligation attaches to distribution, not to internal use, which is why this typically surfaces at the moment a product is launched rather than while it is being built.

Two rules keep this manageable. Decide before implementation whether the coordinates need to be persisted at all, because a design that geocodes on demand has far fewer constraints than one building a permanent table. And record provenance per column, because a table with one restricted column and the rest open cannot be exported as a whole, and without provenance nobody can work out which part is the problem.

The failure that gets shipped

The failure is not a wrong coordinate. It is a low-confidence centroid match treated as an exact location by a system that never saw the confidence.

The shape of it is consistent. A batch of several hundred thousand addresses is geocoded. Most match well. A minority, concentrated in the regions with the thinnest reference data, fall back to locality or postcode centroids. The precision field either was not returned or was dropped during the load into the analytics table. Every record now looks identical: an address and a pair of coordinates.

Downstream, a density map shows striking concentrations at the centre of certain towns, which is the fallback pile rather than a real pattern. A hazard exposure model checks each point against a flood extent, and centroid-located properties are assessed on the flood status of the town centre rather than their own.

Nothing errors. The output is plausible, internally consistent, and confidently wrong in a specific and predictable way. The one control that prevents all of it is structural rather than statistical: the precision level travels with the coordinate through every stage of the pipeline, and any consumer that cannot read the precision level does not get the coordinate.