ooRexx logo
#!/usr/bin/env rexx
/*------------------------------------------------------------------*/
/* Routine to retrieve an address from a latitude/longitude pair    */          
/* by utilizing the facilities provided by:                         */    
/*                                                                  */
/* https://nominatim.openstreetmap.org                              */
/*                                                                  */
/* @param   latitude  - in decimal degrees                          */
/*                                                                  */
/* @param   longitude - in deicmal degrees                          */
/*                                                                  */
/* @param   language  - in odes like "en", "de", "nl" etc.  see:    */
/*                                                                  */
/* https://wiki.openstreetmap.org/wiki/Nominatim/Country_Codes      */
/*                                                                  */
/* @param   level     - the level of detail of the result:          */
/*                                                                  */
/*                      3  - country                                */
/*                      4  - state                                  */
/*                      8  - county                                 */
/*                      10 - city                                   */
/*                      14 - suburb                                 */
/*                      16 - major streets                          */
/*                      17 - major and minor streets                */
/*                      18 - building                               */
/*                                                                  */
/* @returns address   - such as 1600 Pennsylvania Avenue Washin.... */
/*                                                                  */
/* Can be invoked from the command line:                            */
/*                                                                  */
/*       "nominatim_address_from_latlon.orx" lat lon lvl            */
/*                                                                  */
/* Or as a subroutine or function:                                  */
/*                                                                  */
/*       call nominatim_address_from_latlon lat, lon, lvl           */    
/*                                                                  */
/*       nominatim_address_from_latlon(lat, lon, lvl)               */  
/*                                                                  */
/* The latter two should use a:                                     */
/*                                                                  */
/*   ::requires "nominatim_address_from_latlon.orx"                 */
/*                                                                  */
/* For ooRexx 5.0.0 or later only                                   */
/*                                                                  */
/*------------------------------------------------------------------*/
/*                                                                  */
/* Originally by Ruurd J. Idenburg                                  */
/*                                                                  */
/* No copyright, no licence, no guarantees or warrantees, be it     */
/* explicit, implicit or whatever. Usage is totally and completely  */
/* at the users own risk, the author shall not be liable for any    */
/* damages whatsoever, for any reason whatsoever.                   */
/*                                                                  */
/* Please keep this comment block intact when modifying this code   */
/* and add a note with date and a description.                      */
/*                                                                  */
/*------------------------------------------------------------------*/
/*                                                                  */
/* 2021/05/02 - Initial version                                     */
/*                                                                  */
/*------------------------------------------------------------------*/

parse source os how me
if how=="COMMAND" then do
  if .sysCArgs[3]==.nil then .sysCArgs[3] = "nl"
  if .sysCArgs[4]==.nil then .sysCArgs[4] = 16
  address = nominatim_address_from_latlon(.sysCArgs[1],-
                                          .sysCArgs[2],-
                                          .sysCArgs[3],-
                                          .sysCArgs[4])
  say address
end
exit

::routine nominatim_address_from_latlon public
use strict arg lat, lon, lng="nl", lvl=16
/*------------------------------------------------------------------*/
/* nominatim appreciates a non standard https-header for User_Agent */
/* I have mine stored as an linux environment variable via .profile */
/* but it can be hardcoded as well of course.                       */
/*------------------------------------------------------------------*/
myAgent = value("USER_AGENT", ,"ENVIRONMENT")
/*------------------------------------------------------------------*/
/* nominatim appreciates an e-mail address in case of frequent and  */
/* multiple requests. I keep mine as a Linux environment variable,  */
/* but it can be hardcoded as well of course.                       */
/*------------------------------------------------------------------*/
myEmail = value("MY_EMAIL", ,"ENVIRONMENT")
/*------------------------------------------------------------------*/
/* nominatim usage guidelines suggest not to issue more than one    */
/* request per second, so we'll wait 1 second before issueing the   */
/* request for the case we do multiple requests in a short period.  */
/*------------------------------------------------------------------*/
call sysSleep(1)
/*------------------------------------------------------------------*/
/* We use the (new in ooRexx 5.0.0) "ADDRESS SYSTEM WITH" keyword   */
/* instruction to issue the request via "CURL" (https://curl.se/)   */
/*------------------------------------------------------------------*/
jsonArray = .array~new
-- Direct output from CURL to an array  
address system with output using (jsonArray)
"curl -s -A "myAgent" 'https://nominatim.openstreetmap.org/reverse?"-
       "format=json&lat="lat"&lon="lon"&zoom="lvl"&addressdetails=1"-
       "&limit=1&accept-language="lng"&email="myEmail"'"
-- Switch output back to normal
address system with output normal
-- Uncomment to see the whole result from CURL
--say jsonArray
-- Create the ooRexx (.directory) equivalent of the JSON
rexx = .json~new()~fromJSON(jsonArray~toString("C"))
address = ""
-- Without error
if \rexx~hasindex("error")then do
  address = rexx["display_name"]
end
-- With error
else do
  address = "ERROR: "
  do e over rexx["error"]
    address ||= rexx["error"][e]" "
  end
end
if address = "" then address = "UNKNOWN"
return address

::routine addr_from_latlon public
lng = arg(3)
lvl = arg(4)
if lng=="" then lng = "en"
if lvl=="" then lvl = 16
return nominatim_address_from_latlon(arg(1), arg(2), lng, lvl)
 
::requires json.cls
 
If you feel inclined to make corrections, suggestions etc., please mail me any.
All content © Ruurd Idenburg, 2007–, except where marked otherwise. All rights reserved. This page is primarily for non-commercial use only. The Idenburg website records no personal information and sets no ‘cookies’. This site is hosted on a VPS(Virtual Private System) rented from Transip.nl, a Dutch company, falling under Dutch (privacy) laws (I think).

This page updated on by Ruurd Idenburg.