Last active
October 20, 2019 19:06
-
-
Save Saigesp/1c2f90a47dca6d9f3308c91c0f8fcf51 to your computer and use it in GitHub Desktop.
Python script to get longitude and latitude from google maps API or transform from UTM (provided in file)
This file contains 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
# -*- coding: UTF-8 -*- | |
import csv | |
import os | |
import sys | |
import json | |
import time | |
import pyproj | |
import argparse | |
from urllib import parse, request | |
if sys.version_info[0] < 3: raise Exception("Python 3 required") | |
googleapi = '<YOUR_GOOGLEMAPS_APIKEY_HERE>' | |
_projections = {} | |
def zone(coordinates): | |
# https://gist.github.com/twpayne/4409500 | |
if 56 <= coordinates[1] < 64 and 3 <= coordinates[0] < 12: | |
return 32 | |
if 72 <= coordinates[1] < 84 and 0 <= coordinates[0] < 42: | |
if coordinates[0] < 9: | |
return 31 | |
elif coordinates[0] < 21: | |
return 33 | |
elif coordinates[0] < 33: | |
return 35 | |
return 37 | |
return int((coordinates[0] + 180) / 6) + 1 | |
def letter(coordinates): | |
# https://gist.github.com/twpayne/4409500 | |
return 'CDEFGHJKLMNPQRSTUVWXX'[int((coordinates[1] + 80) / 8)] | |
def project(coordinates): | |
# https://gist.github.com/twpayne/4409500 | |
z = zone(coordinates) | |
l = letter(coordinates) | |
if z not in _projections: | |
_projections[z] = pyproj.Proj(proj='utm', zone=z, ellps='WGS84') | |
x, y = _projections[z](coordinates[0], coordinates[1]) | |
if y < 0: | |
y += 10000000 | |
return z, l, x, y | |
def unproject(z, l, x, y): | |
# https://gist.github.com/twpayne/4409500 | |
if z not in _projections: | |
_projections[z] = pyproj.Proj(proj='utm', zone=z, ellps='WGS84') | |
if l < 'N': | |
y -= 10000000 | |
lng, lat = _projections[z](x, y, inverse=True) | |
return (lng, lat) | |
def get_coordinates_from_address(address, key): | |
debug_msg = False | |
googleGeocodeUrl = 'https://maps.googleapis.com/maps/api/geocode/json?' | |
address = address.encode('utf-8') | |
params = { | |
'address': address, | |
'key': key, | |
} | |
url = googleGeocodeUrl + parse.urlencode(params) | |
json_response = request.urlopen(url) | |
response = json.loads(json_response.read().decode('utf-8')) | |
if response['status'] == 'OK': | |
location = response['results'][0]['geometry']['location'] | |
latitude, longitude = location['lat'], location['lng'] | |
if debug_msg: print (address, latitude, longitude) | |
else: | |
latitude, longitude = None, None | |
if debug_msg: print (address, "<no results>") | |
if debug_msg: print (response) | |
return [response['status'], longitude, latitude] | |
def clean_white_spaces(strtoclean): | |
while strtoclean.startswith(' '): | |
strtoclean = strtoclean[1:] | |
while strtoclean.endswith(' '): | |
strtoclean = strtoclean[:-1] | |
return strtoclean | |
def transform_file(inputfile, outputfile): | |
with open(inputfile, 'r', encoding='utf-8') as csvfile: | |
reader = csv.reader(csvfile, delimiter=",") | |
next(reader) | |
with open(outputfile, 'w') as outfile: | |
writer = csv.writer(outfile) | |
for row in reader: | |
address = f'{clean_white_spaces(row[2])}, {clean_white_spaces(row[4])}, ESPAÑA' | |
while True: | |
time.sleep(0.5) | |
status, lng, lat = get_coordinates_from_address(address, googleapi) | |
if status == 'OK': | |
row.append(lng) | |
row.append(lat) | |
writer.writerow(row) | |
print(status, lng, lat, address) | |
break | |
if status == 'ZERO_RESULTS': | |
lng, lat = unproject(30, 's', row[6], row[5]) | |
row.append(lng) | |
row.append(lat) | |
writer.writerow(row) | |
print(status, lng, lat, address) | |
break | |
if __name__=="__main__": | |
parser = argparse.ArgumentParser() | |
parser.add_argument("-f", help="CSV file to parse") | |
args = parser.parse_args() | |
if not args.f: | |
print('-f argument required') | |
print('Example: python geolocorutm.py -f educapu.csv') | |
sys.exit() | |
if not args.f.endswith('.csv'): | |
print('-f argument must end with ".csv"') | |
print('Example: python geolocorutm.py -f educapu.csv') | |
sys.exit() | |
inputfile = os.path.normpath(args.f) | |
if not os.path.exists(inputfile): | |
print('File not found') | |
sys.exit() | |
outputfile = os.path.normpath(args.f[:-4]+'-output.csv') | |
transform_file(inputfile, outputfile) | |
This file contains 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
CD_CENTRO | ETIQUETA | DIRECCION | CMUNI | MUNICIPIO | UTM_Y | UTM_X | |
---|---|---|---|---|---|---|---|
28000029 | CEIPS San Blas | Calle Víctor Hurtado, s/n | 002 | Ajalvir | 4487835 | 458854 | |
28000042 | CEIP El Álamo | Calle Río Alagón, 14 | 004 | Álamo (El) | 4453715 | 416061 | |
28000054 | CEIP Antonio de Nebrija | Calle San Ignacio de Loyola, 13 | 005 | Alcalá de Henares | 4482313 | 468386 | |
28000066 | CEIP Cardenal Cisneros | Calle San Juan, 2 | 005 | Alcalá de Henares | 4481259 | 468658 | |
28000078 | CEIP Cervantes | Calle Giner de los Ríos, 5 | 005 | Alcalá de Henares | 4481496 | 469552 | |
28000081 | CEIP Daoiz y Velarde | Calle Infantado, 2 | 005 | Alcalá de Henares | 4481956 | 468826 | |
28000111 | CEIP Reyes Católicos | Calle San Vidal, 4 | 005 | Alcalá de Henares | 4480481 | 468204 | |
28000315 | CEIP Emperador Fernando | Calle Ronda Fiscal, 44 | 005 | Alcalá de Henares | 4480180 | 468369 | |
28000339 | CEIP El Juncal | Calle Núñez de Guzmán, 31 | 005 | Alcalá de Henares | 4480671 | 467839 | |
28000364 | IES Complutense | Calle Valladolid, 1 | 005 | Alcalá de Henares | 4481599 | 470510 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage:
python geolocorutm.py -f path/to/file.csv
path/to/file.csv
is the input file.path/to/file-output.csv