Last active
November 15, 2017 21:06
-
-
Save dannguyen/8c0e4c3c720d6da25f49 to your computer and use it in GitHub Desktop.
Quick command-line script in Python 3 to geocode a location using Google Maps Geocoding API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# | |
# A Python 3.x script designed for command-line operation: | |
# Given a location string, passes it to Google's Geocoding API and prints to stdout: lat, lng, | |
# level of accuracy, and formatted address, as a single delimited line and, optionally, the raw JSON | |
# This is one in a series of mundane programming examples: | |
# - srccon.org/sessions/#proposal-106215 | |
# - https://docs.google.com/spreadsheets/d/1oaUNiWOyuTmxr0hVgx32vr5XN8E4MEb_2FD56BE6mZA/edit?usp=drive_web | |
# | |
# Documentation of Google Maps API | |
# https://developers.google.com/maps/documentation/geocoding/ | |
# | |
# Usage: | |
# | |
# $ script.py "100 Broadway New York, NY" | |
# | |
# Response: | |
# | |
# 40.70791579999999 -74.01107309999999 ROOFTOP 100 Broadway, New York, NY 10006, USA | |
# | |
# | |
# usage: script.py [-h] [--copy] [--delimiter DELIMITER] [--json] addr | |
# positional arguments: | |
# addr Enter an address, preferably quoted | |
# optional arguments: | |
# -h, --help show this help message and exit | |
# --copy, -c Copy JSON response to file at current directory | |
# --delimiter DELIMITER, -d DELIMITER | |
# Use specified delimiter between values; default is `\t` | |
# --json, -j Instead of the tab-delimited values, print the JSON | |
# response to stdout | |
######################################## | |
import argparse | |
import csv | |
import requests | |
from io import StringIO | |
from urllib.parse import quote_plus | |
GOOGLE_MAPS_URL = "https://maps.googleapis.com/maps/api/geocode/json" | |
parser = argparse.ArgumentParser() | |
# Configure the parser | |
parser.add_argument("addr", | |
nargs = 1, | |
help = "Enter an address, preferably quoted") | |
parser.add_argument('--copy', '-c', | |
action = 'store_true', | |
help = 'Copy JSON response to file at current directory') | |
parser.add_argument('--delimiter', '-d', | |
default = "\t", | |
help = 'Use specified delimiter between values; default is `\\t`') | |
parser.add_argument('--json', '-j', | |
action = 'store_true', | |
help = 'Instead of the tab-delimited values, print the JSON response to stdout') | |
# Begin the command-line operation | |
args = parser.parse_args() | |
addr = args.addr[0] | |
resp = requests.get(GOOGLE_MAPS_URL, params = {'address': addr}) | |
results = resp.json()['results'] | |
if results: | |
if args.json: | |
# Print the raw JSON response | |
print(resp.text) | |
else: | |
# We use the csv library to deal with any edge cases involving delimiters and escape-sequences | |
outs = StringIO() | |
c = csv.writer(outs, delimiter = args.delimiter, quoting = csv.QUOTE_MINIMAL) | |
r = results[0] | |
c.writerow([ | |
r['geometry']['location']['lat'], | |
r['geometry']['location']['lng'], | |
r['geometry']['location_type'], | |
r['formatted_address'] | |
]) | |
# csv.writerow() adds a newline character that needs to be stripped | |
print(outs.getvalue().strip()) | |
# Save to file with --copy | |
# "100 Broadway New York, NY" | |
# is saved to: | |
# ./100+Broadway+New+York%2C+NY.json | |
if args.copy: | |
fpath = quote_plus(addr) + '.json' | |
with open(fpath, 'w') as f: | |
f.write(resp.text) | |
# For now, no error-handling...if results list is empty, nothing is printed |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"results" : [ | |
{ | |
"address_components" : [ | |
{ | |
"long_name" : "100", | |
"short_name" : "100", | |
"types" : [ "street_number" ] | |
}, | |
{ | |
"long_name" : "Broadway", | |
"short_name" : "Broadway", | |
"types" : [ "route" ] | |
}, | |
{ | |
"long_name" : "Lower Manhattan", | |
"short_name" : "Lower Manhattan", | |
"types" : [ "neighborhood", "political" ] | |
}, | |
{ | |
"long_name" : "Manhattan", | |
"short_name" : "Manhattan", | |
"types" : [ "sublocality_level_1", "sublocality", "political" ] | |
}, | |
{ | |
"long_name" : "New York", | |
"short_name" : "NY", | |
"types" : [ "locality", "political" ] | |
}, | |
{ | |
"long_name" : "New York County", | |
"short_name" : "New York County", | |
"types" : [ "administrative_area_level_2", "political" ] | |
}, | |
{ | |
"long_name" : "New York", | |
"short_name" : "NY", | |
"types" : [ "administrative_area_level_1", "political" ] | |
}, | |
{ | |
"long_name" : "United States", | |
"short_name" : "US", | |
"types" : [ "country", "political" ] | |
}, | |
{ | |
"long_name" : "10006", | |
"short_name" : "10006", | |
"types" : [ "postal_code" ] | |
} | |
], | |
"formatted_address" : "100 Broadway, New York, NY 10006, USA", | |
"geometry" : { | |
"location" : { | |
"lat" : 40.70791579999999, | |
"lng" : -74.01107309999999 | |
}, | |
"location_type" : "ROOFTOP", | |
"viewport" : { | |
"northeast" : { | |
"lat" : 40.70926478029149, | |
"lng" : -74.00972411970849 | |
}, | |
"southwest" : { | |
"lat" : 40.7065668197085, | |
"lng" : -74.0124220802915 | |
} | |
} | |
}, | |
"place_id" : "ChIJywL_PBdawokR4bOmKjJY3QE", | |
"types" : [ "street_address" ] | |
} | |
], | |
"status" : "OK" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment