Terence Eden’s Blog<p><strong>Reverse Geocoding is Hard</strong></p><p><a href="https://shkspr.mobi/blog/2025/04/reverse-geocoding-is-hard/" rel="nofollow noopener noreferrer" translate="no" target="_blank"><span class="invisible">https://</span><span class="ellipsis">shkspr.mobi/blog/2025/04/rever</span><span class="invisible">se-geocoding-is-hard/</span></a></p><p>My wife and I run <a href="https://openbenches.org/" rel="nofollow noopener noreferrer" target="_blank">OpenBenches</a> - a crowd-sourced database of nearly 40,000 memorial benches. Every bench is geo-tagged with a latitude and longitude. But how do you go from a string of digits to something human readable?</p><p>How do I turn <code>-33.755780,150.603769</code> into "42 Wallaby Way, Sydney, Australia"?</p><p>Luckily, that's a (somewhat) solved problem. Services like <a href="https://opencagedata.com/" rel="nofollow noopener noreferrer" target="_blank">OpenCage</a>, <a href="https://stadiamaps.com/" rel="nofollow noopener noreferrer" target="_blank">StadiaMaps</a>, <a href="https://nominatim.openstreetmap.org" rel="nofollow noopener noreferrer" target="_blank">OpenStreetMap</a>, and <a href="https://geocode.earth/" rel="nofollow noopener noreferrer" target="_blank">Geocode.Earth</a> all provide APIs which transform co-ordinates into addresses. Done! Let's go home.</p><p>Except… Not everywhere <em>has</em> an address. <a href="https://openbenches.org/bench/35905" rel="nofollow noopener noreferrer" target="_blank">Some benches are in parks</a>. They typically don't have a street number, but might have an interesting feature nearby to help with location. For example a statue or prominent landmark.</p><p>And… Not every address is relevant. <a href="https://openbenches.org/bench/26061" rel="nofollow noopener noreferrer" target="_blank">Some benches are on streets</a>. But we probably don't want to imply that the bench is <em>inside</em> or belongs to a specific nearby house.</p><p>Let's step back a bit. <em>Why</em> do we want to display a human-readable address?</p><p>We have two use-cases.</p><p>"As a visitor to the site, I want to:"</p><ol><li>Read a (rough) textual representation of where the bench is.</li><li>Click on a component of the address to see all benches within that area.</li></ol><p>The first is easy to explain:</p><p></p><p>The second is harder. Suppose a bench is in Wellington, New Zealand. We want to create a URl like <a href="https://openbenches.org/location/New%20Zealand/Wellington/" rel="nofollow noopener noreferrer" target="_blank">openbenches.org/location/New Zealand/Wellington/</a>. That way, users can click on the word "Wellington" and find all the benches nearby. A user can also manually edit that URl to increase or decrease precision.</p><p>Both of these are problems of <em>precision</em>.</p><p>Let's take a look at <a href="https://nominatim.openstreetmap.org/reverse?lat=51.476845&lon=-0.295296&format=jsonv2" rel="nofollow noopener noreferrer" target="_blank">how one of the reverse geocoding services</a> deals with transforming <code>51.476845,-0.295296</code> into an address:</p><blockquote><p>Royal Botanic Gardens, Kew, Sandycombe Road, Kew, London Borough of Richmond upon Thames, London, Greater London, England, TW9 2EN, United Kingdom</p></blockquote><p><strong>That is <em>too much</em> address!</strong></p><p>Yes, it is technically accurate. But it contains far too much detail for humans, the postcode is irrelevant, and the weird-subdivisions are nothing that a local person would use.</p><p>Looking at the full API response, we can see:</p><pre><code>{ "place_id": 258770727, "licence": "Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright", "name": "Royal Botanic Gardens, Kew", "display_name": "Royal Botanic Gardens, Kew, Elizabeth Cottages, Kew, London Borough of Richmond upon Thames, London, Greater London, England, TW9 3NJ, United Kingdom", "address": { "leisure": "Royal Botanic Gardens, Kew", "road": "Elizabeth Cottages", "suburb": "Kew", "city_district": "London Borough of Richmond upon Thames", "ISO3166-2-lvl8": "GB-RIC", "city": "London", "state_district": "Greater London", "state": "England", "ISO3166-2-lvl4": "GB-ENG", "postcode": "TW9 3NJ", "country": "United Kingdom", "country_code": "gb" }}</code></pre><p>Aha! Perhaps I can build a better address using just those components!</p><p>Except… Not every country has states. And not all states are used when giving addresses. Not every location is in a city. Some places have villages, prefectures, municipalities, and hamlets.</p><p>New York, New York is a valid address, but <a href="https://blog.opencagedata.com/post/99059889253/good-looking-addresses-solving-the-berlin-berlin" rel="nofollow noopener noreferrer" target="_blank">Berlin, Berlin</a> is not!</p><p>There's an <a href="https://github.com/OpenCageData/address-formatting" rel="nofollow noopener noreferrer" target="_blank">address formatter by OpenCage</a> which is pretty sensible about stripping off irrelevant details. But, to go back to my first point, not every map location on OpenBenches is a street address and - even if it is on a street - it probably shouldn't have a house number.</p><p>Well, there's kind of a solution to that! Most mapping provider have a POI function - we can find nearby things of interest and use them as a location.</p><p>Here's a <a href="https://openbenches.org/bench/36734" rel="nofollow noopener noreferrer" target="_blank">bench in Cook County, Illinois, USA</a>. The POI address is:</p><pre><code>{… "name": "Central Park", "coarse_location": "Des Plaines, IL, USA",…}</code></pre><p>I <em>assume</em> there's only one Central Park in Des Plaines. Do people know that "Il" is Illinois? Would "Cook County" be useful?</p><p>On the subject of localisation, not everywhere speaks English. Do I want to display addresses like "<span>原爆の子の像, 広島, 日本</span>"? How about "原爆の子の像, Hiroshima, Japan"?</p><p>We're an international site, but most benches are in Anglophone countries.</p><p>Of course, just because something is <em>physically</em> near a POI, that doesn't mean it is <em>logically</em> close to it.</p><p>Consider a bench situated <a href="https://www.openstreetmap.org/query?lat=50.580682&lon=-3.467831" rel="nofollow noopener noreferrer" target="_blank">at the edge of this park</a></p><p>The nearest POI is "Gay's Creamery" - across the river. Is that what you'd expect? Is there any way to easily say "if a point is <em>inside</em> an amenity* then use that as the address?</p><p>I don't want the users of our site to have to select from a list of POIs or addresses, this should be as automated as possible.</p><p><strong>The Plan</strong></p><p>For each bench:</p><ol><li>Use StadiaMaps to get the nearest POI.</li><li>Get the data in English.</li><li>Concatenate the name and coarse location.</li><li>Save the "address".</li><li>Wait for complaints?</li></ol><p>Thoughts?</p><p><a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://shkspr.mobi/blog/tag/geolocation/" target="_blank">#geolocation</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://shkspr.mobi/blog/tag/geotagging/" target="_blank">#geotagging</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://shkspr.mobi/blog/tag/openbenches/" target="_blank">#OpenBenches</a></p>