ooRexx logo
   1: #!/usr/bin/env rexx
   2: /*------------------------------------------------------------------*/
   3: /* Routine to retrieve an address from a latitude/longitude pair    */          
   4: /* by utilizing the facilities provided by:                         */    
   5: /*                                                                  */
   6: /* https://nominatim.openstreetmap.org                              */
   7: /*                                                                  */
   8: /* @param   latitude  - in decimal degrees                          */
   9: /*                                                                  */
  10: /* @param   longitude - in deicmal degrees                          */
  11: /*                                                                  */
  12: /* @param   language  - in odes like "en", "de", "nl" etc.  see:    */
  13: /*                                                                  */
  14: /* https://wiki.openstreetmap.org/wiki/Nominatim/Country_Codes      */
  15: /*                                                                  */
  16: /* @param   level     - the level of detail of the result:          */
  17: /*                                                                  */
  18: /*                      3  - country                                */
  19: /*                      4  - state                                  */
  20: /*                      8  - county                                 */
  21: /*                      10 - city                                   */
  22: /*                      14 - suburb                                 */
  23: /*                      16 - major streets                          */
  24: /*                      17 - major and minor streets                */
  25: /*                      18 - building                               */
  26: /*                                                                  */
  27: /* @returns address   - such as 1600 Pennsylvania Avenue Washin.... */
  28: /*                                                                  */
  29: /* Can be invoked from the command line:                            */
  30: /*                                                                  */
  31: /*       "nominatim_address_from_latlon.orx" lat lon lvl            */
  32: /*                                                                  */
  33: /* Or as a subroutine or function:                                  */
  34: /*                                                                  */
  35: /*       call nominatim_address_from_latlon lat, lon, lvl           */    
  36: /*                                                                  */
  37: /*       nominatim_address_from_latlon(lat, lon, lvl)               */   
  38: /*                                                                  */
  39: /* The latter two should use a:                                     */
  40: /*                                                                  */
  41: /*   ::requires "nominatim_address_from_latlon.orx"                 */
  42: /*                                                                  */
  43: /* For ooRexx 5.0.0 or later only                                   */
  44: /*                                                                  */
  45: /*------------------------------------------------------------------*/
  46: /*                                                                  */
  47: /* Originally by Ruurd J. Idenburg                                  */
  48: /*                                                                  */
  49: /* No copyright, no licence, no guarantees or warrantees, be it     */
  50: /* explicit, implicit or whatever. Usage is totally and completely  */
  51: /* at the users own risk, the author shall not be liable for any    */ 
  52: /* damages whatsoever, for any reason whatsoever.                   */
  53: /*                                                                  */
  54: /* Please keep this comment block intact when modifying this code   */
  55: /* and add a note with date and a description.                      */
  56: /*                                                                  */
  57: /*------------------------------------------------------------------*/
  58: /*                                                                  */
  59: /* 2021/05/02 - Initial version                                     */
  60: /*                                                                  */
  61: /*------------------------------------------------------------------*/
  62: 
  63: parse source os how me
  64: if how=="COMMAND" then do
  65:   if .sysCArgs[3]==.nil then .sysCArgs[3] = "nl"
  66:   if .sysCArgs[4]==.nil then .sysCArgs[4] = 16
  67:   address = nominatim_address_from_latlon(.sysCArgs[1],-
  68:                                           .sysCArgs[2],-
  69:                                           .sysCArgs[3],-
  70:                                           .sysCArgs[4])
  71:   say address
  72: end
  73: exit
  74: 
  75: ::routine nominatim_address_from_latlon public
  76: use strict arg lat, lon, lng="nl", lvl=16
  77: /*------------------------------------------------------------------*/
  78: /* nominatim appreciates a non standard https-header for User_Agent */
  79: /* I have mine stored as an linux environment variable via .profile */
  80: /* but it can be hardcoded as well of course.                       */
  81: /*------------------------------------------------------------------*/
  82: myAgent = value("USER_AGENT", ,"ENVIRONMENT")
  83: /*------------------------------------------------------------------*/
  84: /* nominatim appreciates an e-mail address in case of frequent and  */
  85: /* multiple requests. I keep mine as a Linux environment variable,  */
  86: /* but it can be hardcoded as well of course.                       */
  87: /*------------------------------------------------------------------*/
  88: myEmail = value("MY_EMAIL", ,"ENVIRONMENT")
  89: /*------------------------------------------------------------------*/
  90: /* nominatim usage guidelines suggest not to issue more than one    */
  91: /* request per second, so we'll wait 1 second before issueing the   */
  92: /* request for the case we do multiple requests in a short period.  */
  93: /*------------------------------------------------------------------*/
  94: call sysSleep(1)
  95: /*------------------------------------------------------------------*/
  96: /* We use the (new in ooRexx 5.0.0) "ADDRESS SYSTEM WITH" keyword   */
  97: /* instruction to issue the request via "CURL" (https://curl.se/)   */
  98: /*------------------------------------------------------------------*/
  99: jsonArray = .array~new
 100: -- Direct output from CURL to an array   
 101: address system with output using (jsonArray)
 102: "curl -s -A "myAgent" 'https://nominatim.openstreetmap.org/reverse?"-
 103:        "format=json&lat="lat"&lon="lon"&zoom="lvl"&addressdetails=1"-
 104:        "&limit=1&accept-language="lng"&email="myEmail"'"
 105: -- Switch output back to normal
 106: address system with output normal
 107: -- Uncomment to see the whole result from CURL
 108: --say jsonArray
 109: -- Create the ooRexx (.directory) equivalent of the JSON
 110: rexx = .json~new()~fromJSON(jsonArray~toString("C"))
 111: address = ""
 112: -- Without error
 113: if \rexx~hasindex("error")then do
 114:   address = rexx["display_name"]
 115: end
 116: -- With error
 117: else do
 118:   address = "ERROR: "
 119:   do e over rexx["error"]
 120:     address ||= rexx["error"][e]" " 
 121:   end
 122: end
 123: if address = "" then address = "UNKNOWN"
 124: return address
 125: 
 126: ::routine addr_from_latlon public
 127: lng = arg(3)
 128: lvl = arg(4)
 129: if lng=="" then lng = "en"
 130: if lvl=="" then lvl = 16
 131: return nominatim_address_from_latlon(arg(1), arg(2), lng, lvl)
 132:   
 133: ::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.