-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathgeonames.py
64 lines (56 loc) · 2.59 KB
/
geonames.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# coding=utf-8
from __future__ import division, absolute_import, print_function, unicode_literals
from time import sleep
import requests
import lxml.etree
class GeoNamesGeocoder(object):
ENDPOINT = 'http://api.geonames.org'
USERNAME = 'russss'
def __init__(self):
self.session = requests.Session()
def geocode(self, latitude, longitude):
data = self.find_nearby(latitude, longitude)
if data is None:
return None, None
if data.find('ocean') is not None:
# We're over an ocean
return "over the", data.find('ocean/name').text
elif data.find('country') is not None:
# No populated places nearby, but we have a country
country_name = data.find('countryName').text
elif data.find('address') is not None and data.find('address/countryName') is not None:
country_name = data.find('address/countryName').text
elif data.find('address') is not None and data.find('address/adminName1') is not None:
country_name = data.find('address/adminName1').text
elif len(data.findall('geoname')) > 0:
continent_node = data.findall('geoname')[1]
country_name = continent_node.find('name').text
return "over", country_name
def find_nearby(self, latitude, longitude, radius=10):
params = {'lat': latitude, 'lng': longitude,
'cities': 'cities15000', 'username': self.USERNAME}
if radius is not None:
params['range'] = radius
result = self.session.get('%s/extendedFindNearby' % self.ENDPOINT, params=params, timeout=10).content
data = lxml.etree.fromstring(result)
error = data.find('status')
if error is not None:
value = error.get('value')
if value == '24' and radius > 1:
# In some areas of the world, geonames restricts our radius, so try without.
return self.find_nearby(latitude, longitude, radius=None)
elif value == '15':
return None
elif value == '19':
print("Hourly rate limit exceeded. Sleeping for 5mins.")
sleep(300)
return self.find_nearby(latitude, longitude, radius=radius)
elif value == '18':
raise Exception("Daily rate limit exceeded!")
elif value == '12':
print("Unknown Geonames error, sleeping for 10 seconds")
sleep(10)
return None
else:
raise Exception("Unhandled Geonames error: %s" % value)
return data