use geopy lib and use Nominatum as default geocoder
This commit is contained in:
parent
42b1f4ecd4
commit
d2ecd0ed3d
|
@ -1,4 +1,5 @@
|
||||||
[Geolocation]
|
[Geolocation]
|
||||||
|
; geocoder: Nominatim or MapQuest
|
||||||
geocoder=Nominatim
|
geocoder=Nominatim
|
||||||
mapquest_key=m5aGo8xGe4LLhxeKZYpHr2MPXGN2aDhe
|
mapquest_key=None
|
||||||
prefer_english_names=False
|
prefer_english_names=False
|
||||||
|
|
|
@ -12,6 +12,8 @@ import requests
|
||||||
import urllib.request
|
import urllib.request
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import urllib.error
|
import urllib.error
|
||||||
|
import geopy
|
||||||
|
from geopy.geocoders import Nominatim
|
||||||
|
|
||||||
from elodie.config import load_config
|
from elodie.config import load_config
|
||||||
from elodie import constants
|
from elodie import constants
|
||||||
|
@ -34,7 +36,17 @@ def coordinates_by_name(name):
|
||||||
}
|
}
|
||||||
|
|
||||||
# If the name is not cached then we go ahead with an API lookup
|
# If the name is not cached then we go ahead with an API lookup
|
||||||
geolocation_info = lookup(location=name)
|
geocoder = get_geocoder()
|
||||||
|
if geocoder == 'Nominatim':
|
||||||
|
locator = Nominatim(user_agent='myGeocoder')
|
||||||
|
geolocation_info = locator.geocode(name)
|
||||||
|
if geolocation_info is not None:
|
||||||
|
return {
|
||||||
|
'latitude': geolocation_info.latitude,
|
||||||
|
'longitude': geolocation_info.longitude
|
||||||
|
}
|
||||||
|
elif geocoder == 'MapQuest':
|
||||||
|
geolocation_info = lookup_mapquest(location=name)
|
||||||
|
|
||||||
if(geolocation_info is not None):
|
if(geolocation_info is not None):
|
||||||
if(
|
if(
|
||||||
|
@ -66,6 +78,9 @@ def coordinates_by_name(name):
|
||||||
'longitude': use_location['lng']
|
'longitude': use_location['lng']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,6 +114,17 @@ def dms_string(decimal, type='latitude'):
|
||||||
return '{} deg {}\' {}" {}'.format(dms[0], dms[1], dms[2], direction)
|
return '{} deg {}\' {}" {}'.format(dms[0], dms[1], dms[2], direction)
|
||||||
|
|
||||||
|
|
||||||
|
def get_geocoder():
|
||||||
|
config = load_config(constants.CONFIG_FILE)
|
||||||
|
try:
|
||||||
|
geocoder = config['Geolocation']['geocoder']
|
||||||
|
except KeyError as e:
|
||||||
|
log.error(e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
return geocoder
|
||||||
|
|
||||||
|
|
||||||
def get_key():
|
def get_key():
|
||||||
global __KEY__
|
global __KEY__
|
||||||
if __KEY__ is not None:
|
if __KEY__ is not None:
|
||||||
|
@ -148,12 +174,19 @@ def place_name(lat, lon):
|
||||||
return cached_place_name
|
return cached_place_name
|
||||||
|
|
||||||
lookup_place_name = {}
|
lookup_place_name = {}
|
||||||
geolocation_info = lookup(lat=lat, lon=lon)
|
geocoder = get_geocoder()
|
||||||
|
if geocoder == 'Nominatim':
|
||||||
|
geolocation_info = lookup_osm(lat, lon)
|
||||||
|
elif geocoder == 'MapQuest':
|
||||||
|
geolocation_info = lookup_mapquest(lat=lat, lon=lon)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
if(geolocation_info is not None and 'address' in geolocation_info):
|
if(geolocation_info is not None and 'address' in geolocation_info):
|
||||||
address = geolocation_info['address']
|
address = geolocation_info['address']
|
||||||
# gh-386 adds support for town
|
# gh-386 adds support for town
|
||||||
# taking precedence after city for backwards compatability
|
# taking precedence after city for backwards compatability
|
||||||
for loc in ['city', 'town', 'state', 'country']:
|
for loc in ['city', 'town', 'village', 'state', 'country']:
|
||||||
if(loc in address):
|
if(loc in address):
|
||||||
lookup_place_name[loc] = address[loc]
|
lookup_place_name[loc] = address[loc]
|
||||||
# In many cases the desired key is not available so we
|
# In many cases the desired key is not available so we
|
||||||
|
@ -171,8 +204,27 @@ def place_name(lat, lon):
|
||||||
|
|
||||||
return lookup_place_name
|
return lookup_place_name
|
||||||
|
|
||||||
|
def lookup_osm(lat, lon):
|
||||||
|
|
||||||
def lookup(**kwargs):
|
prefer_english_names = get_prefer_english_names()
|
||||||
|
from geopy.geocoders import Nominatim
|
||||||
|
try:
|
||||||
|
locator = Nominatim(user_agent='myGeocoder')
|
||||||
|
coords = (lat, lon)
|
||||||
|
if(prefer_english_names):
|
||||||
|
lang='en'
|
||||||
|
else:
|
||||||
|
lang='local'
|
||||||
|
return locator.reverse(coords, language=lang).raw
|
||||||
|
except geopy.exc.GeocoderUnavailable as e:
|
||||||
|
log.error(e)
|
||||||
|
return None
|
||||||
|
except ValueError as e:
|
||||||
|
log.error(e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def lookup_mapquest(**kwargs):
|
||||||
if(
|
if(
|
||||||
'location' not in kwargs and
|
'location' not in kwargs and
|
||||||
'lat' not in kwargs and
|
'lat' not in kwargs and
|
||||||
|
@ -180,14 +232,14 @@ def lookup(**kwargs):
|
||||||
):
|
):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
key = get_key()
|
mapquest_key = get_key()
|
||||||
prefer_english_names = get_prefer_english_names()
|
prefer_english_names = get_prefer_english_names()
|
||||||
|
|
||||||
if(key is None):
|
if(mapquest_key is None):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
params = {'format': 'json', 'key': key}
|
params = {'format': 'json', 'key': mapquest_key}
|
||||||
params.update(kwargs)
|
params.update(kwargs)
|
||||||
path = '/geocoding/v1/address'
|
path = '/geocoding/v1/address'
|
||||||
if('lat' in kwargs and 'lon' in kwargs):
|
if('lat' in kwargs and 'lon' in kwargs):
|
||||||
|
|
|
@ -18,18 +18,18 @@ from elodie.config import load_config, load_plugin_config
|
||||||
def test_load_config_singleton_success():
|
def test_load_config_singleton_success():
|
||||||
with open('%s/config.ini-singleton-success' % gettempdir(), 'w') as f:
|
with open('%s/config.ini-singleton-success' % gettempdir(), 'w') as f:
|
||||||
f.write("""
|
f.write("""
|
||||||
[MapQuest]
|
[Geolocation]
|
||||||
key=your-api-key-goes-here
|
key=your-api-key-goes-here
|
||||||
prefer_english_names=False
|
prefer_english_names=False
|
||||||
""")
|
""")
|
||||||
if hasattr(load_config, 'config'):
|
if hasattr(load_config, 'config'):
|
||||||
del load_config.config
|
del load_config.config
|
||||||
|
|
||||||
config = load_config()
|
config = load_config(constants.CONFIG_FILE)
|
||||||
assert config['MapQuest']['key'] == 'your-api-key-goes-here', config.get('MapQuest', 'key')
|
assert config['Geolocation']['key'] == 'your-api-key-goes-here', config.get('MapQuest', 'key')
|
||||||
config.set('MapQuest', 'key', 'new-value')
|
config.set('MapQuest', 'key', 'new-value')
|
||||||
|
|
||||||
config = load_config()
|
config = load_config(constants.CONFIG_FILE)
|
||||||
|
|
||||||
if hasattr(load_config, 'config'):
|
if hasattr(load_config, 'config'):
|
||||||
del load_config.config
|
del load_config.config
|
||||||
|
@ -41,7 +41,7 @@ def test_load_config_singleton_no_file():
|
||||||
if hasattr(load_config, 'config'):
|
if hasattr(load_config, 'config'):
|
||||||
del load_config.config
|
del load_config.config
|
||||||
|
|
||||||
config = load_config()
|
config = load_config(constants.CONFIG_FILE)
|
||||||
|
|
||||||
if hasattr(load_config, 'config'):
|
if hasattr(load_config, 'config'):
|
||||||
del load_config.config
|
del load_config.config
|
||||||
|
|
|
@ -527,8 +527,8 @@ def test_get_folder_path_with_original_default_unknown_location():
|
||||||
def test_get_folder_path_with_custom_path():
|
def test_get_folder_path_with_custom_path():
|
||||||
with open('%s/config.ini-custom-path' % gettempdir(), 'w') as f:
|
with open('%s/config.ini-custom-path' % gettempdir(), 'w') as f:
|
||||||
f.write("""
|
f.write("""
|
||||||
[MapQuest]
|
[Geolocation]
|
||||||
key=czjNKTtFjLydLteUBwdgKAIC8OAbGLUx
|
mapquest_key=czjNKTtFjLydLteUBwdgKAIC8OAbGLUx
|
||||||
|
|
||||||
[Directory]
|
[Directory]
|
||||||
date=%Y-%m-%d
|
date=%Y-%m-%d
|
||||||
|
@ -569,8 +569,8 @@ full_path=%year/%month/%album|%"No Album Fool"/%month
|
||||||
def test_get_folder_path_with_with_more_than_two_levels():
|
def test_get_folder_path_with_with_more_than_two_levels():
|
||||||
with open('%s/config.ini-location-date' % gettempdir(), 'w') as f:
|
with open('%s/config.ini-location-date' % gettempdir(), 'w') as f:
|
||||||
f.write("""
|
f.write("""
|
||||||
[MapQuest]
|
[Geolocation]
|
||||||
key=czjNKTtFjLydLteUBwdgKAIC8OAbGLUx
|
mapquest_key=czjNKTtFjLydLteUBwdgKAIC8OAbGLUx
|
||||||
|
|
||||||
[Directory]
|
[Directory]
|
||||||
year=%Y
|
year=%Y
|
||||||
|
|
|
@ -80,47 +80,47 @@ def test_dms_string_longitude():
|
||||||
assert str(dms[0]) in dms_string, '%s not in %s' % (dms[0], dms_string)
|
assert str(dms[0]) in dms_string, '%s not in %s' % (dms[0], dms_string)
|
||||||
|
|
||||||
def test_reverse_lookup_with_valid_key():
|
def test_reverse_lookup_with_valid_key():
|
||||||
res = geolocation.lookup(lat=37.368, lon=-122.03)
|
res = geolocation.lookup_osm(lat=37.368, lon=-122.03)
|
||||||
assert res['address']['city'] == 'Sunnyvale', res
|
assert res['address']['city'] == 'Sunnyvale', res
|
||||||
|
|
||||||
def test_reverse_lookup_with_invalid_lat_lon():
|
def test_reverse_lookup_with_invalid_lat_lon():
|
||||||
res = geolocation.lookup(lat=999, lon=999)
|
res = geolocation.lookup_osm(lat=999, lon=999)
|
||||||
assert res is None, res
|
assert res is None, res
|
||||||
|
|
||||||
@mock.patch('elodie.geolocation.__KEY__', 'invalid_key')
|
@mock.patch('elodie.geolocation.__KEY__', 'invalid_key')
|
||||||
def test_reverse_lookup_with_invalid_key():
|
def test_reverse_lookup_with_invalid_key():
|
||||||
res = geolocation.lookup(lat=37.368, lon=-122.03)
|
res = geolocation.lookup_mapquest(lat=37.368, lon=-122.03)
|
||||||
assert res is None, res
|
assert res is None, res
|
||||||
|
|
||||||
def test_lookup_with_valid_key():
|
def test_lookup_with_valid_key():
|
||||||
res = geolocation.lookup(location='Sunnyvale, CA')
|
res = geolocation.lookup_mapquest(location='Sunnyvale, CA')
|
||||||
latLng = res['results'][0]['locations'][0]['latLng']
|
latLng = res['results'][0]['locations'][0]['latLng']
|
||||||
assert latLng['lat'] == 37.36883, latLng
|
assert latLng['lat'] == 37.36883, latLng
|
||||||
assert latLng['lng'] == -122.03635, latLng
|
assert latLng['lng'] == -122.03635, latLng
|
||||||
|
|
||||||
def test_lookup_with_invalid_location():
|
def test_lookup_with_invalid_location():
|
||||||
res = geolocation.lookup(location='foobar dne')
|
res = geolocation.lookup_mapquest(location='foobar dne')
|
||||||
assert res is None, res
|
assert res is None, res
|
||||||
|
|
||||||
def test_lookup_with_invalid_location():
|
def test_lookup_with_invalid_location():
|
||||||
res = geolocation.lookup(location='foobar dne')
|
res = geolocation.lookup_mapquest(location='foobar dne')
|
||||||
assert res is None, res
|
assert res is None, res
|
||||||
|
|
||||||
def test_lookup_with_valid_key():
|
def test_lookup_with_valid_key():
|
||||||
res = geolocation.lookup(location='Sunnyvale, CA')
|
res = geolocation.lookup_mapquest(location='Sunnyvale, CA')
|
||||||
latLng = res['results'][0]['locations'][0]['latLng']
|
latLng = res['results'][0]['locations'][0]['latLng']
|
||||||
assert latLng['lat'] == 37.36883, latLng
|
assert latLng['lat'] == 37.36883, latLng
|
||||||
assert latLng['lng'] == -122.03635, latLng
|
assert latLng['lng'] == -122.03635, latLng
|
||||||
|
|
||||||
@mock.patch('elodie.geolocation.__PREFER_ENGLISH_NAMES__', True)
|
@mock.patch('elodie.geolocation.__PREFER_ENGLISH_NAMES__', True)
|
||||||
def test_lookup_with_prefer_english_names_true():
|
def test_lookup_with_prefer_english_names_true():
|
||||||
res = geolocation.lookup(lat=55.66333, lon=37.61583)
|
res = geolocation.lookup_osm(lat=55.66333, lon=37.61583)
|
||||||
assert res['address']['city'] == 'Nagorny District', res
|
assert res['address']['city'] == 'Moscow', res
|
||||||
|
|
||||||
@mock.patch('elodie.geolocation.__PREFER_ENGLISH_NAMES__', False)
|
@mock.patch('elodie.geolocation.__PREFER_ENGLISH_NAMES__', False)
|
||||||
def test_lookup_with_prefer_english_names_false():
|
def test_lookup_with_prefer_english_names_false():
|
||||||
res = geolocation.lookup(lat=55.66333, lon=37.61583)
|
res = geolocation.lookup_osm(lat=55.66333, lon=37.61583)
|
||||||
assert res['address']['city'] == u'\u041d\u0430\u0433\u043e\u0440\u043d\u044b\u0439 \u0440\u0430\u0439\u043e\u043d', res
|
assert res['address']['city'] == 'Москва', res
|
||||||
|
|
||||||
@mock.patch('elodie.constants.location_db', '%s/location.json-cached' % gettempdir())
|
@mock.patch('elodie.constants.location_db', '%s/location.json-cached' % gettempdir())
|
||||||
def test_place_name_deprecated_string_cached():
|
def test_place_name_deprecated_string_cached():
|
||||||
|
@ -159,12 +159,12 @@ def test_place_name_no_default():
|
||||||
|
|
||||||
@mock.patch('elodie.geolocation.__KEY__', 'invalid_key')
|
@mock.patch('elodie.geolocation.__KEY__', 'invalid_key')
|
||||||
def test_lookup_with_invalid_key():
|
def test_lookup_with_invalid_key():
|
||||||
res = geolocation.lookup(location='Sunnyvale, CA')
|
res = geolocation.lookup_mapquest(location='Sunnyvale, CA')
|
||||||
assert res is None, res
|
assert res is None, res
|
||||||
|
|
||||||
@mock.patch('elodie.geolocation.__KEY__', '')
|
@mock.patch('elodie.geolocation.__KEY__', '')
|
||||||
def test_lookup_with_no_key():
|
def test_lookup_with_no_key():
|
||||||
res = geolocation.lookup(location='Sunnyvale, CA')
|
res = geolocation.lookup_mapquest(location='Sunnyvale, CA')
|
||||||
assert res is None, res
|
assert res is None, res
|
||||||
|
|
||||||
def test_parse_result_with_error():
|
def test_parse_result_with_error():
|
||||||
|
|
Loading…
Reference in New Issue