From 0336b83294db725d83bed194ad569bc149b7a4a6 Mon Sep 17 00:00:00 2001 From: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Date: Tue, 30 Apr 2024 15:39:16 -0700 Subject: [PATCH] Update location_utils to use HANA (#518) * Replace geopy location utils with Hana calls * Fix response parsing in location_utils * Add geopy extra dependencies and backwards-compat handling * Revert dependency changes and add TODO for later --------- Co-authored-by: Daniel McKnight --- neon_utils/location_utils.py | 67 +++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/neon_utils/location_utils.py b/neon_utils/location_utils.py index e965051f..96ac6e88 100644 --- a/neon_utils/location_utils.py +++ b/neon_utils/location_utils.py @@ -31,12 +31,11 @@ from datetime import datetime from typing import Optional, Union from dateutil.tz import tzlocal -from geopy.exc import GeocoderServiceError -from geopy.geocoders import Nominatim from timezonefinder import TimezoneFinder from re import sub from ovos_utils.log import LOG +from neon_utils.hana_utils import request_backend # geocode.maps.co nominatim.openstreetmap.org _NOMINATIM_DOMAIN = "nominatim.openstreetmap.org" @@ -63,22 +62,30 @@ def get_full_location(address: Union[str, tuple], None if service is not available """ try: - nominatim = Nominatim(user_agent="neon-ai", domain=_NOMINATIM_DOMAIN, - timeout=10) if isinstance(address, str): - location = nominatim.geocode(address, addressdetails=True, - language=lang) + response = request_backend("proxy/geolocation/geocode", + {"address": address}) + coords = (response.get('lat'), response.get('lon')) else: - location = nominatim.reverse(address, addressdetails=True, - language=lang) + coords = address - dict_location = location.raw + dict_location = request_backend("proxy/geolocation/reverse", + {"lat": coords[0], "lon": coords[1]}) dict_location['address']['country'] = sub(f'[0-9]', '', dict_location['address']. get('country')) + if lang: + try: + # TODO: make this optional with a deprecation notice + from geopy.geocoders import Nominatim + resp = Nominatim(user_agent="neon-ai", domain=_NOMINATIM_DOMAIN, + timeout=10).reverse(coords, language=lang) + return resp.raw + except ImportError: + LOG.error("geopy not installed") + except Exception as e: + LOG.exception(e) return dict_location - except GeocoderServiceError as e: - LOG.error(e) except Exception as e: LOG.exception(e) return None @@ -90,14 +97,14 @@ def get_coordinates(gps_loc: dict) -> (float, float): :param gps_loc: dict of "city", "state", "country" :return: lat, lng float values """ - coordinates = Nominatim(user_agent="neon-ai", domain=_NOMINATIM_DOMAIN, - timeout=10) try: - location = coordinates.geocode(gps_loc) + request_str = ', '.join((x for x in [gps_loc.get('city'), + gps_loc.get('state'), + gps_loc.get('country')] if x)) + location = request_backend("proxy/geolocation/geocode", + {"address": request_str}) LOG.debug(f"{location}") - return location.latitude, location.longitude - except GeocoderServiceError as e: - LOG.error(e) + return float(location.get('lat')), float(location.get('lon')) except Exception as x: LOG.exception(x) return -1, -1 @@ -112,25 +119,21 @@ def get_location(lat, lng) -> (str, str, str, str): :return: city, county, state, country """ try: - address = Nominatim(user_agent="neon-ai", domain=_NOMINATIM_DOMAIN, - timeout=10) - except GeocoderServiceError as e: - LOG.error(e) - return None + location = request_backend("proxy/geolocation/reverse", + {"lat": lat, "lon": lng}) + + dict_location = location.get('address') except Exception as x: LOG.exception(x) return None - location = address.reverse([lat, lng], language="en-US") LOG.debug(f"{location}") - LOG.debug(f"{location.raw}") - LOG.debug(f"{location.raw.get('address')}") - city = location.raw.get('address').get('city') or \ - location.raw.get('address').get('town') or \ - location.raw.get('address').get('village') or \ - location.raw.get('address').get('hamlet') - county = location.raw.get('address').get('county') - state = location.raw.get('address').get('state') - country = location.raw.get('address').get('country') + city = dict_location.get('city') or \ + dict_location.get('town') or \ + dict_location.get('village') or \ + dict_location.get('hamlet') + county = dict_location.get('county') + state = dict_location.get('state') + country = dict_location.get('country') return city, county, state, country