Compare commits
No commits in common. "5aafac2025802b898f537e61de75ad81852ea5e5" and "cda2195419d7e28b5dc6336a11b05239040cfb5a" have entirely different histories.
5aafac2025
...
cda2195419
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +0,0 @@
|
|||||||
geoapi.ini
|
|
||||||
.idea/
|
|
@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="PYTHON_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
|
||||||
<exclude-output />
|
|
||||||
<content url="file://$MODULE_DIR$" />
|
|
||||||
<orderEntry type="inheritedJdk" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
@ -1,12 +0,0 @@
|
|||||||
[google]
|
|
||||||
apikey=<<API KEY HERE>>
|
|
||||||
|
|
||||||
[mapquest]
|
|
||||||
apikey=<<CONSUMER KEY HERE>>
|
|
||||||
secret=<<CONSUMER SECRET HERE>>
|
|
||||||
|
|
||||||
[geocodio]
|
|
||||||
apikey=<<API KEY HERE>>
|
|
||||||
|
|
||||||
[locationiq]
|
|
||||||
token=<<TOKEN HERE>>
|
|
77
src/dcalc.py
77
src/dcalc.py
@ -1,77 +0,0 @@
|
|||||||
# DCalc.py: basic test of distance calculation from the Boulder office
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import argparse
|
|
||||||
import json
|
|
||||||
import math
|
|
||||||
import configparser
|
|
||||||
import urllib.parse
|
|
||||||
import urllib.request
|
|
||||||
|
|
||||||
|
|
||||||
class GeocodingError(RuntimeError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def geocode_google(config, address):
|
|
||||||
apikey = config['google']['apikey']
|
|
||||||
if not apikey:
|
|
||||||
raise GeocodingError("Google API key not specified")
|
|
||||||
query = { 'key': apikey, 'address': address, 'region': 'us'}
|
|
||||||
url = 'https://maps.googleapis.com/maps/api/geocode/json?' + \
|
|
||||||
urllib.parse.urlencode(query, quote_via=urllib.parse.quote)
|
|
||||||
with urllib.request.urlopen(url) as response:
|
|
||||||
if response.status == 200:
|
|
||||||
apireturn = json.loads(response.read())
|
|
||||||
stat = apireturn['status']
|
|
||||||
if stat == 'OK':
|
|
||||||
results = apireturn['results']
|
|
||||||
if len(results) > 1:
|
|
||||||
raise GeocodingError(f"Google API returned ambiguous results (total count {len(results)})")
|
|
||||||
coords = results[0]['geometry']['location']
|
|
||||||
return coords['lat'], coords['lng']
|
|
||||||
elif stat == 'ZERO_RESULTS':
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
raise GeocodingError(f"Google API returns status of {stat}")
|
|
||||||
else:
|
|
||||||
raise GeocodingError(f"Google API returns {response.status} HTTP status code")
|
|
||||||
|
|
||||||
|
|
||||||
OFFICE_LOCATION = (40.0187905, -105.2764775) # office location - 1433 Pearl Street, Boulder, CO
|
|
||||||
RADIUS = 6371.0 * 1000.0 # Earth radius in meters
|
|
||||||
METERS_PER_MILE = 1852.0 # number of meters per mile
|
|
||||||
|
|
||||||
|
|
||||||
def distance_miles(point1, point2):
|
|
||||||
Φ1 = math.radians(point1[0])
|
|
||||||
Φ2 = math.radians(point2[0])
|
|
||||||
ΔΦ = math.radians(point2[0] - point1[0])
|
|
||||||
Δλ = math.radians(point2[1] - point1[1])
|
|
||||||
a = math.sin(ΔΦ / 2.0) * math.sin(ΔΦ / 2.0) + math.cos(Φ1) * math.cos(Φ2) * math.sin(Δλ / 2.0) * math.sin(Δλ / 2.0)
|
|
||||||
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1.0 - a))
|
|
||||||
return RADIUS * c / METERS_PER_MILE
|
|
||||||
|
|
||||||
|
|
||||||
cmdline_parser = argparse.ArgumentParser()
|
|
||||||
cmdline_parser.add_argument('address', nargs='+', help='The address to be calculated')
|
|
||||||
cmdline_parser.add_argument('-C', '--config', default='geoapi.ini', help='The geocoding API configuration file')
|
|
||||||
|
|
||||||
|
|
||||||
def main(args):
|
|
||||||
opts = cmdline_parser.parse_args(args)
|
|
||||||
config = configparser.ConfigParser()
|
|
||||||
config.read(opts.config)
|
|
||||||
my_address = ' '.join(opts.address)
|
|
||||||
print(f"Address: '{my_address}'")
|
|
||||||
coords = geocode_google(config, my_address)
|
|
||||||
if coords:
|
|
||||||
print(f"Coordinates: Latitude {coords[0]}, longitude {coords[1]}")
|
|
||||||
dist = distance_miles(OFFICE_LOCATION, coords)
|
|
||||||
print(f"Distance from Boulder office: {dist} miles")
|
|
||||||
else:
|
|
||||||
print("Location was not found.")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.exit(main(sys.argv[1:]))
|
|
124
src/gcoder.py
124
src/gcoder.py
@ -1,124 +0,0 @@
|
|||||||
# GCoder.py: basic geocoding test
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import argparse
|
|
||||||
import json
|
|
||||||
import configparser
|
|
||||||
import urllib.parse
|
|
||||||
import urllib.request
|
|
||||||
|
|
||||||
|
|
||||||
class GeocodingError(RuntimeError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def geocode_google(config, address):
|
|
||||||
apikey = config['google']['apikey']
|
|
||||||
if not apikey:
|
|
||||||
raise GeocodingError("Google API key not specified")
|
|
||||||
query = { 'key': apikey, 'address': address, 'region': 'us'}
|
|
||||||
url = 'https://maps.googleapis.com/maps/api/geocode/json?' + \
|
|
||||||
urllib.parse.urlencode(query, quote_via=urllib.parse.quote)
|
|
||||||
with urllib.request.urlopen(url) as response:
|
|
||||||
if response.status == 200:
|
|
||||||
apireturn = json.loads(response.read())
|
|
||||||
stat = apireturn['status']
|
|
||||||
if stat == 'OK':
|
|
||||||
results = apireturn['results']
|
|
||||||
if len(results) > 1:
|
|
||||||
raise GeocodingError(f"Google API returned ambiguous results (total count {len(results)})")
|
|
||||||
coords = results[0]['geometry']['location']
|
|
||||||
return coords['lat'], coords['lng']
|
|
||||||
elif stat == 'ZERO_RESULTS':
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
raise GeocodingError(f"Google API returns status of {stat}")
|
|
||||||
else:
|
|
||||||
raise GeocodingError(f"Google API returns {response.status} HTTP status code")
|
|
||||||
|
|
||||||
|
|
||||||
def geocode_mapquest(config, address):
|
|
||||||
apikey = config['mapquest']['apikey']
|
|
||||||
if not apikey:
|
|
||||||
raise GeocodingError("MapQuest API key not specified")
|
|
||||||
query = { 'key': apikey, 'inFormat': 'kvp', 'outFormat': 'json', 'location': address,
|
|
||||||
'thumbMaps': 'false', 'maxResults': 1}
|
|
||||||
url = 'https://www.mapquestapi.com/geocoding/v1/address?' + urllib.parse.urlencode(query)
|
|
||||||
with urllib.request.urlopen(url) as response:
|
|
||||||
if response.status == 200:
|
|
||||||
apireturn = json.loads(response.read())
|
|
||||||
stat = apireturn['info']['statuscode']
|
|
||||||
if stat == 0:
|
|
||||||
results = apireturn['results']
|
|
||||||
if len(results) > 1:
|
|
||||||
raise GeocodingError(f"MapQuest API returned ambiguous results (total count {len(results)})")
|
|
||||||
locations = results[0]['locations']
|
|
||||||
if len(locations) > 1:
|
|
||||||
raise GeocodingError(f"MapQuest API returned ambiguous locations (total count {len(locations)})")
|
|
||||||
coords = locations[0]['latLng']
|
|
||||||
return coords['lat'], coords['lng']
|
|
||||||
else:
|
|
||||||
raise GeocodingError(f"MapQuest API returns status of {stat}")
|
|
||||||
else:
|
|
||||||
raise GeocodingError(f"MapQuest API returns {response.status} HTTP status code")
|
|
||||||
|
|
||||||
|
|
||||||
def geocode_geocodio(config, address):
|
|
||||||
apikey = config['geocodio']['apikey']
|
|
||||||
if not apikey:
|
|
||||||
raise GeocodingError("Geocodio API key not specified")
|
|
||||||
query = {'q': address, 'api_key': apikey}
|
|
||||||
url = 'https://api.geocod.io/v1.6/geocode?' + urllib.parse.urlencode(query)
|
|
||||||
with urllib.request.urlopen(url) as response:
|
|
||||||
if response.status == 200:
|
|
||||||
apireturn = json.loads(response.read())
|
|
||||||
coords = apireturn['results'][0]['location']
|
|
||||||
return coords['lat'], coords['lng']
|
|
||||||
else:
|
|
||||||
raise GeocodingError(f"Geocodio API returns {response.status} HTTP status code")
|
|
||||||
|
|
||||||
|
|
||||||
def geocode_locationiq(config, address):
|
|
||||||
apikey = config['locationiq']['token']
|
|
||||||
if not apikey:
|
|
||||||
raise GeocodingError("LocationIQ API key not specified")
|
|
||||||
query = {'q': address, 'key': apikey, 'format': 'json', 'limit': 1}
|
|
||||||
url = 'https://us1.locationiq.com/v1/search.php?' + urllib.parse.urlencode(query, quote_via=urllib.parse.quote)
|
|
||||||
with urllib.request.urlopen(url) as response:
|
|
||||||
if response.status == 200:
|
|
||||||
apireturn = json.loads(response.read())
|
|
||||||
place = apireturn[0]
|
|
||||||
return place['lat'], place['lon']
|
|
||||||
else:
|
|
||||||
raise GeocodingError(f"LocationIQ API returns {response.status} HTTP status code")
|
|
||||||
|
|
||||||
|
|
||||||
geocoding_procs = {
|
|
||||||
'google': geocode_google,
|
|
||||||
'mapquest': geocode_mapquest,
|
|
||||||
'geocodio': geocode_geocodio,
|
|
||||||
'locationiq': geocode_locationiq
|
|
||||||
}
|
|
||||||
|
|
||||||
cmdline_parser = argparse.ArgumentParser()
|
|
||||||
cmdline_parser.add_argument('address', nargs='+', help='The address to be geocoded')
|
|
||||||
cmdline_parser.add_argument('-C', '--config', default='geoapi.ini', help='The geocoding API configuration file')
|
|
||||||
cmdline_parser.add_argument('-g', '--geocoder', default='google', choices=geocoding_procs.keys(),
|
|
||||||
help='Geocoding processor to use to get coordinates (default: google)')
|
|
||||||
|
|
||||||
|
|
||||||
def main(args):
|
|
||||||
opts = cmdline_parser.parse_args(args)
|
|
||||||
config = configparser.ConfigParser()
|
|
||||||
config.read(opts.config)
|
|
||||||
my_address = ' '.join(opts.address)
|
|
||||||
print(f"Address: '{my_address}'")
|
|
||||||
coords = geocoding_procs[opts.geocoder](config, my_address)
|
|
||||||
if coords:
|
|
||||||
print(f"Coordinates: Latitude {coords[0]}, longitude {coords[1]}")
|
|
||||||
else:
|
|
||||||
print("Location was not found.")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.exit(main(sys.argv[1:]))
|
|
Loading…
x
Reference in New Issue
Block a user