modified GCoder to detect "not found" cases, added DCalc
This commit is contained in:
parent
70a33ff00d
commit
5aafac2025
77
src/dcalc.py
Executable file
77
src/dcalc.py
Executable file
|
@ -0,0 +1,77 @@
|
||||||
|
# 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:]))
|
|
@ -29,6 +29,8 @@ def geocode_google(config, address):
|
||||||
raise GeocodingError(f"Google API returned ambiguous results (total count {len(results)})")
|
raise GeocodingError(f"Google API returned ambiguous results (total count {len(results)})")
|
||||||
coords = results[0]['geometry']['location']
|
coords = results[0]['geometry']['location']
|
||||||
return coords['lat'], coords['lng']
|
return coords['lat'], coords['lng']
|
||||||
|
elif stat == 'ZERO_RESULTS':
|
||||||
|
return None
|
||||||
else:
|
else:
|
||||||
raise GeocodingError(f"Google API returns status of {stat}")
|
raise GeocodingError(f"Google API returns status of {stat}")
|
||||||
else:
|
else:
|
||||||
|
@ -112,7 +114,10 @@ def main(args):
|
||||||
my_address = ' '.join(opts.address)
|
my_address = ' '.join(opts.address)
|
||||||
print(f"Address: '{my_address}'")
|
print(f"Address: '{my_address}'")
|
||||||
coords = geocoding_procs[opts.geocoder](config, my_address)
|
coords = geocoding_procs[opts.geocoder](config, my_address)
|
||||||
print(f"Coordinates: Latitude {coords[0]}, longitude {coords[1]}")
|
if coords:
|
||||||
|
print(f"Coordinates: Latitude {coords[0]}, longitude {coords[1]}")
|
||||||
|
else:
|
||||||
|
print("Location was not found.")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
Loading…
Reference in New Issue
Block a user