mirror of
https://github.com/xbgmsharp/postgsail.git
synced 2025-09-17 11:17:46 +00:00
Update reverse_geocode_py_fn, improve location detection, ignore tag road or highway. Recursive over lower zoom level.
This commit is contained in:
@@ -16,7 +16,8 @@ CREATE SCHEMA IF NOT EXISTS public;
|
|||||||
-- https://github.com/CartoDB/labs-postgresql/blob/master/workshop/plpython.md
|
-- https://github.com/CartoDB/labs-postgresql/blob/master/workshop/plpython.md
|
||||||
--
|
--
|
||||||
DROP FUNCTION IF EXISTS reverse_geocode_py_fn;
|
DROP FUNCTION IF EXISTS reverse_geocode_py_fn;
|
||||||
CREATE OR REPLACE FUNCTION reverse_geocode_py_fn(IN geocoder TEXT, IN lon NUMERIC, IN lat NUMERIC,
|
DROP FUNCTION public.reverse_geocode_py_fn;
|
||||||
|
CREATE OR REPLACE FUNCTION reverse_geocode_py_fn(IN geocoder TEXT, IN lon NUMERIC, IN lat numeric,
|
||||||
OUT geo jsonb)
|
OUT geo jsonb)
|
||||||
AS $reverse_geocode_py$
|
AS $reverse_geocode_py$
|
||||||
import requests
|
import requests
|
||||||
@@ -39,47 +40,56 @@ AS $reverse_geocode_py$
|
|||||||
plpy.error('Error missing parameters')
|
plpy.error('Error missing parameters')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Make the request to the geocoder API
|
def georeverse(geocoder, lon, lat, zoom="18"):
|
||||||
# https://operations.osmfoundation.org/policies/nominatim/
|
# Make the request to the geocoder API
|
||||||
payload = {"lon": lon, "lat": lat, "format": "jsonv2", "zoom": 18}
|
# https://operations.osmfoundation.org/policies/nominatim/
|
||||||
# https://nominatim.org/release-docs/latest/api/Reverse/
|
payload = {"lon": lon, "lat": lat, "format": "jsonv2", "zoom": zoom, "accept-language": "en"}
|
||||||
r = requests.get(url, headers = {"Accept-Language": "en-US,en;q=0.5"}, params=payload)
|
# https://nominatim.org/release-docs/latest/api/Reverse/
|
||||||
|
r = requests.get(url, headers = {"Accept-Language": "en-US,en;q=0.5"}, params=payload)
|
||||||
|
|
||||||
# Parse response
|
# Parse response
|
||||||
# Option1: If name is null fallback to address field road,neighbourhood,suburb
|
# If name is null fallback to address field tags: neighbourhood,suburb
|
||||||
# Option2: Return the json for future reference like country
|
# if none repeat with lower zoom level
|
||||||
if r.status_code == 200 and "name" in r.json():
|
if r.status_code == 200 and "name" in r.json():
|
||||||
r_dict = r.json()
|
r_dict = r.json()
|
||||||
#plpy.notice('reverse_geocode_py_fn Parameters [{}] [{}] Response'.format(lon, lat, r_dict))
|
#plpy.notice('reverse_geocode_py_fn Parameters [{}] [{}] Response'.format(lon, lat, r_dict))
|
||||||
output = None
|
output = None
|
||||||
country_code = None
|
country_code = None
|
||||||
if "country_code" in r_dict["address"] and r_dict["address"]["country_code"]:
|
if "country_code" in r_dict["address"] and r_dict["address"]["country_code"]:
|
||||||
country_code = r_dict["address"]["country_code"]
|
country_code = r_dict["address"]["country_code"]
|
||||||
if r_dict["name"]:
|
if r_dict["name"]:
|
||||||
return { "name": r_dict["name"], "country_code": country_code }
|
return { "name": r_dict["name"], "country_code": country_code }
|
||||||
elif "address" in r_dict and r_dict["address"]:
|
elif "address" in r_dict and r_dict["address"]:
|
||||||
if "neighbourhood" in r_dict["address"] and r_dict["address"]["neighbourhood"]:
|
if "neighbourhood" in r_dict["address"] and r_dict["address"]["neighbourhood"]:
|
||||||
return { "name": r_dict["address"]["neighbourhood"], "country_code": country_code }
|
return { "name": r_dict["address"]["neighbourhood"], "country_code": country_code }
|
||||||
elif "road" in r_dict["address"] and r_dict["address"]["road"]:
|
elif "hamlet" in r_dict["address"] and r_dict["address"]["hamlet"]:
|
||||||
return { "name": r_dict["address"]["road"], "country_code": country_code }
|
return { "name": r_dict["address"]["hamlet"], "country_code": country_code }
|
||||||
elif "suburb" in r_dict["address"] and r_dict["address"]["suburb"]:
|
elif "suburb" in r_dict["address"] and r_dict["address"]["suburb"]:
|
||||||
return { "name": r_dict["address"]["suburb"], "country_code": country_code }
|
return { "name": r_dict["address"]["suburb"], "country_code": country_code }
|
||||||
elif "residential" in r_dict["address"] and r_dict["address"]["residential"]:
|
elif "residential" in r_dict["address"] and r_dict["address"]["residential"]:
|
||||||
return { "name": r_dict["address"]["residential"], "country_code": country_code }
|
return { "name": r_dict["address"]["residential"], "country_code": country_code }
|
||||||
elif "village" in r_dict["address"] and r_dict["address"]["village"]:
|
elif "village" in r_dict["address"] and r_dict["address"]["village"]:
|
||||||
return { "name": r_dict["address"]["village"], "country_code": country_code }
|
return { "name": r_dict["address"]["village"], "country_code": country_code }
|
||||||
elif "town" in r_dict["address"] and r_dict["address"]["town"]:
|
elif "town" in r_dict["address"] and r_dict["address"]["town"]:
|
||||||
return { "name": r_dict["address"]["town"], "country_code": country_code }
|
return { "name": r_dict["address"]["town"], "country_code": country_code }
|
||||||
else:
|
elif "amenity" in r_dict["address"] and r_dict["address"]["amenity"]:
|
||||||
return { "name": "n/a", "country_code": country_code }
|
return { "name": r_dict["address"]["amenity"], "country_code": country_code }
|
||||||
else:
|
else:
|
||||||
return { "name": "n/a", "country_code": country_code }
|
if (zoom == 15):
|
||||||
else:
|
plpy.notice('georeverse recursive retry with lower zoom than:[{}], Response [{}]'.format(zoom , r.json()))
|
||||||
plpy.warning('Failed to received a geo full address %s', r.json())
|
return georeverse(geocoder, lon, lat, 14)
|
||||||
#plpy.error('Failed to received a geo full address %s', r.json())
|
else:
|
||||||
return { "name": "unknown", "country_code": "unknown" }
|
plpy.notice('georeverse recursive retry with lower zoom than:[{}], Response [{}]'.format(zoom , r.json()))
|
||||||
|
return georeverse(geocoder, lon, lat, 15)
|
||||||
|
else:
|
||||||
|
return { "name": "n/a", "country_code": country_code }
|
||||||
|
else:
|
||||||
|
plpy.warning('Failed to received a geo full address %s', r.json())
|
||||||
|
#plpy.error('Failed to received a geo full address %s', r.json())
|
||||||
|
return { "name": "unknown", "country_code": "unknown" }
|
||||||
|
|
||||||
|
return georeverse(geocoder, lon, lat)
|
||||||
$reverse_geocode_py$ TRANSFORM FOR TYPE jsonb LANGUAGE plpython3u;
|
$reverse_geocode_py$ TRANSFORM FOR TYPE jsonb LANGUAGE plpython3u;
|
||||||
|
|
||||||
-- Description
|
-- Description
|
||||||
COMMENT ON FUNCTION
|
COMMENT ON FUNCTION
|
||||||
public.reverse_geocode_py_fn
|
public.reverse_geocode_py_fn
|
||||||
|
Reference in New Issue
Block a user