Hermes Wiki

Geocoding and Reverse Geocoding

Concept

Geocoding converts a human-entered address or place name into geographic coordinates (latitude/longitude); reverse geocoding does the inverse, turning a coordinate — typically one read straight off a device's GPS — into a human-readable address or place description. Together they're the required translation layer sitting between what users actually type or a device actually reports, and what every downstream geospatial operation (proximity search, geohashing, distance calculation) needs as input: a coordinate.

The detail that matters most and is easiest to skip past is that a returned coordinate is not a single quality level — geocoders return results at varying accuracy tiers, and a naive integration that just reads lat/lng off the response and moves on is throwing away exactly the information that says how much to trust that number. Common tiers, roughly ordered from most to least precise:

  • Rooftop — a point on or near the actual building footprint, the highest precision tier.
  • Parcel centroid — a point somewhere within the correct land parcel, but not pinned to the building itself.
  • Street-interpolated — no exact match found, so the geocoder estimates a position along a street segment based on the address range (e.g. "123 Main St" placed proportionally between the segment's known low and high house numbers).
  • Postal/locality centroid — the coarsest fallback, a point representing an entire ZIP code or city when nothing more specific could be matched.

For a representative set of well-covered US addresses, a commonly cited real-world split is roughly 80% rooftop, 15% interpolated, and 5% coarser fallback types — meaning even a "good" address dataset routinely returns a meaningful fraction of results that are city-block accurate at best, not building-accurate.

Tradeoffs

Provider approach Data source Accuracy Cost / limits Best fit
Google Maps Geocoding API Proprietary, Google-maintained High, frequently rooftop in well-mapped regions Per-request pricing (most expensive at volume); ToS caps caching raw lat/lng to 30 days, though the Place ID (a stable identifier) can be cached indefinitely Apps needing broad global coverage and willing to pay for it
Mapbox Geocoding API Blend of proprietary and open data High, tuned for real-time lookups Competitive pricing, supports batch requests High-volume or real-time use cases (logistics, dispatch) where batch throughput matters
OpenStreetMap-derived (Nominatim, LocationIQ, OpenCage) Community-maintained OSM data Variable — strong in well-mapped urban areas, thinner in sparsely-mapped regions Free tiers or self-hostable; generally cheaper at volume Cost-sensitive apps, self-hosting requirements, or use cases that can tolerate uneven regional coverage

The real axis of choice isn't just "which is cheapest" — it's coverage-quality-for-the-regions-that-matter versus cost versus how each provider's terms let you cache results, since caching is what determines whether the same address costs money to resolve once or on every single query.

When to use / when not to

  • Geocode once, at write time — when a user or provider enters an address — and persist the resulting coordinate alongside the record, rather than re-geocoding the same address on every search or page load. This is both a cost control (each call is billed) and, for providers like Google, a terms-of-service requirement — raw coordinates typically can't be cached indefinitely, so store what the provider actually permits (e.g. a stable place identifier) and re-resolve sparingly if the coordinate itself can't be kept past its allowed window.
  • Use reverse geocoding specifically for display purposes — turning a device's GPS reading or a pin drop into a readable address shown to a user — not as a substitute for forward geocoding an address a user actually typed.
  • Always read and act on the accuracy/match-type field the provider returns, not just the presence of a coordinate — a rooftop match and a postal-centroid match should not be treated as equally trustworthy inputs to a distance or proximity calculation.
  • Don't treat a geocoded coordinate as ground truth for anything requiring meter-level precision (e.g. verifying a delivery arrived at the correct address) without a secondary verification step — the coordinate is an estimate whose error bound depends entirely on which accuracy tier produced it.
  • Don't build a system that assumes every address will resolve cleanly — ambiguous, incomplete, or malformed addresses are common enough in real user input that a fallback path (manual pin placement, address confirmation UI) is necessary, not optional.

Common pitfall

Silently accepting a low-confidence match as if it were precise. Many geocoders will still return some coordinate for an ambiguous or partially-wrong address — falling back to a postal-code or city centroid rather than failing outright — and a caller that only checks "did I get a lat/lng back" instead of inspecting the match-type/confidence field will treat a result that's accurate to within a few kilometers exactly the same as one accurate to within a few meters. Downstream, that shows up as a pin placed on the wrong side of a city, a proximity search that misses or wrongly includes results, or a "distance to nearest provider" figure that's wrong by an order of magnitude — and because the API call itself succeeded, nothing about the failure is visible without explicitly checking the precision field.

Engineering Lens

This is the input-quality problem underneath every geospatial index built on top of it: a geohash prefix, an H3 cell, or a quadtree node is only as trustworthy as the coordinate that was encoded into it in the first place, so a coarse-fallback geocode silently degrades every downstream spatial query without the index itself doing anything wrong. The general habit this reinforces: when a system chains a fuzzy, best-effort translation step (address-to-coordinate) into a precise, structured one (spatial indexing, distance math), the correctness of the whole pipeline is capped by the fuzziest step — and that step's uncertainty needs to be surfaced and acted on explicitly, not silently swallowed at the boundary where it happened.

Sources

Hermes Wiki