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