In [5]:
import pandas as pd
import numpy as np
from map_functions import *

df = pd.read_csv('data/locations (no_lat-lng)_2017.csv')
df.tail()


Out[5]:
Name_Orig Lat_Orig Lng_Orig Name_Des Lat_Des Lng_Des
15 Columbus, OH NaN NaN Fort Worth, TX NaN NaN
16 Columbus, OH NaN NaN Cincinnati, OH NaN NaN
17 Columbus, OH NaN NaN Dublin, Ireland NaN NaN
18 Paso Robles, CA NaN NaN Palm Springs, CA NaN NaN
19 Paso Robles, CA NaN NaN Monterey, CA NaN NaN

In [6]:
# Add columns for origin and destination payloads (for Google API) 
payload_pre = 'https://maps.googleapis.com/maps/api/geocode/json?address='
df['Payload_Orig'] = df['Name_Orig'].str.replace(', ','+').str.replace(' ','+')
df['Payload_Des'] = df['Name_Des'].str.replace(', ','+').str.replace(' ','+')
df['Payload_Orig'] = payload_pre + df['Payload_Orig']
df['Payload_Des'] = payload_pre + df['Payload_Des']
df['Distance (nm)'] = 0
df['Distance (mi)'] = 0
df['Distance (km)'] = 0
df.tail()


Out[6]:
Name_Orig Lat_Orig Lng_Orig Name_Des Lat_Des Lng_Des Payload_Orig Payload_Des Distance (nm) Distance (mi) Distance (km)
15 Columbus, OH NaN NaN Fort Worth, TX NaN NaN https://maps.googleapis.com/maps/api/geocode/j... https://maps.googleapis.com/maps/api/geocode/j... 0 0 0
16 Columbus, OH NaN NaN Cincinnati, OH NaN NaN https://maps.googleapis.com/maps/api/geocode/j... https://maps.googleapis.com/maps/api/geocode/j... 0 0 0
17 Columbus, OH NaN NaN Dublin, Ireland NaN NaN https://maps.googleapis.com/maps/api/geocode/j... https://maps.googleapis.com/maps/api/geocode/j... 0 0 0
18 Paso Robles, CA NaN NaN Palm Springs, CA NaN NaN https://maps.googleapis.com/maps/api/geocode/j... https://maps.googleapis.com/maps/api/geocode/j... 0 0 0
19 Paso Robles, CA NaN NaN Monterey, CA NaN NaN https://maps.googleapis.com/maps/api/geocode/j... https://maps.googleapis.com/maps/api/geocode/j... 0 0 0

I round the decimal degrees and distance measurements for readability. Pick what to round decimal degrees to based on the accuracy required. For our purposes, 3 decimal places should suffice.

This table from Wikipedia gives the precision of decimal degrees.

Decimal Degrees Identifiable Distance At Equator
1 country or large region 111.32 km
0.1 large city or district 11.132 km
0.01 town or village 1.1132 km
0.001 neighborhood, street 111.32 m
0.0001 individual street, land parcel 11.132 m
0.00001 individual trees 1.1132 m
0.000001 individual humans 111.32 mm
0.0000001 practical limit of commercial surveying 11.132 mm
0.00000001 specialized surveying (e.g. tectonic plate mapping) 1.1132 mm

In [7]:
# Find latitude and longitude of each location, and distance between
round_coord = 3
round_dist = 1

print('Completed...')
for row in range(0,df.shape[0]):
    try: 
        # Read payloads to pass to Google API
        payload_orig = df.iloc[row,6]
        payload_des = df.iloc[row,7]
        
        # Request and write latitude and longitude
        lat_orig, lng_orig = get_lat_lng(payload_orig)
        lat_des, lng_des = get_lat_lng(payload_des)
        df.ix[row,'Lat_Orig'] = round(lat_orig,round_coord)
        df.ix[row,'Lng_Orig'] = round(lng_orig,round_coord)
        df.ix[row,'Lat_Des'] = round(lat_des,round_coord)
        df.ix[row,'Lng_Des'] = round(lng_des,round_coord)
        
        # Calculate and write distance
        nm, mi, km = get_distance(lat_orig, lng_orig, lat_des, lng_des)
        df.ix[row,'Distance (nm)']  = round(nm,round_dist)
        df.ix[row,'Distance (mi)']  = round(mi,round_dist)
        df.ix[row,'Distance (km)'] = round(km,round_dist)
        
        print(' - '+ str(round(nm,round_dist))+' nm '+df.iloc[row,0]+' to '+df.iloc[row,3])
    
    except:
        print('\tSKIPPING: '+df.iloc[row,0]+' to '+df.iloc[row,3])
        print('\t'+payload_orig)
        print('\t'+payload_des)

df.tail()


Completed...
	SKIPPING: Columbus, OH to Hotel de Rome, Berlin, Germany
	https://maps.googleapis.com/maps/api/geocode/json?address=Columbus+OH
	https://maps.googleapis.com/maps/api/geocode/json?address=Hotel+de+Rome+Berlin+Germany
	SKIPPING: Berlin, Germany to Cathedrale Notre-Dame de Paris, Paris, France
	https://maps.googleapis.com/maps/api/geocode/json?address=Berlin+Germany
	https://maps.googleapis.com/maps/api/geocode/json?address=Cathedrale+Notre-Dame+de+Paris+Paris+France
/Users/mkudija/anaconda/lib/python3.5/site-packages/ipykernel/__main__.py:15: DeprecationWarning: 
.ix is deprecated. Please use
.loc for label based indexing or
.iloc for positional indexing

See the documentation here:
http://pandas.pydata.org/pandas-docs/stable/indexing.html#deprecate_ix
 - 42.3 nm Paris, France to Cathedrale Notre-Dame de Chartres
	SKIPPING: Paris, France to Columbus, OH
	https://maps.googleapis.com/maps/api/geocode/json?address=Paris+France
	https://maps.googleapis.com/maps/api/geocode/json?address=Columbus+OH
 - 1795.9 nm Columbus, OH to Paso Robles, CA
	SKIPPING: Paso Robles, CA to Dallas, TX
	https://maps.googleapis.com/maps/api/geocode/json?address=Paso+Robles+CA
	https://maps.googleapis.com/maps/api/geocode/json?address=Dallas+TX
 - 793.8 nm Dallas, TX to Columbus, OH
 - 927.3 nm Columbus, OH to Austin, TX
 - 1691.7 nm Columbus, OH to Reno, NV
	SKIPPING: Reno, NV to Incline Village, NV
	https://maps.googleapis.com/maps/api/geocode/json?address=Reno+NV
	https://maps.googleapis.com/maps/api/geocode/json?address=Incline+Village+NV
 - 30.1 nm Columbus, OH to Utica, OH
 - 129.9 nm Oakland, CA to Yosemite National Park, California
	SKIPPING: Columbus, OH to South Bend, IN
	https://maps.googleapis.com/maps/api/geocode/json?address=Columbus+OH
	https://maps.googleapis.com/maps/api/geocode/json?address=South+Bend+IN
 - 424.1 nm Columbus, OH to Ossining, NY
 - 70.3 nm Columbus, OH to Wooster, OH
 - 816.3 nm Columbus, OH to Fort Worth, TX
 - 87.1 nm Columbus, OH to Cincinnati, OH
 - 3110.3 nm Columbus, OH to Dublin, Ireland
	SKIPPING: Paso Robles, CA to Palm Springs, CA
	https://maps.googleapis.com/maps/api/geocode/json?address=Paso+Robles+CA
	https://maps.googleapis.com/maps/api/geocode/json?address=Palm+Springs+CA
 - 83.5 nm Paso Robles, CA to Monterey, CA
Out[7]:
Name_Orig Lat_Orig Lng_Orig Name_Des Lat_Des Lng_Des Payload_Orig Payload_Des Distance (nm) Distance (mi) Distance (km)
15 Columbus, OH 39.961 -82.999 Fort Worth, TX 32.755 -97.331 https://maps.googleapis.com/maps/api/geocode/j... https://maps.googleapis.com/maps/api/geocode/j... 816.3 939.3 1511.7
16 Columbus, OH 39.961 -82.999 Cincinnati, OH 39.103 -84.512 https://maps.googleapis.com/maps/api/geocode/j... https://maps.googleapis.com/maps/api/geocode/j... 87.1 100.2 161.2
17 Columbus, OH 39.961 -82.999 Dublin, Ireland 53.350 -6.260 https://maps.googleapis.com/maps/api/geocode/j... https://maps.googleapis.com/maps/api/geocode/j... 3110.3 3579.3 5760.3
18 Paso Robles, CA NaN NaN Palm Springs, CA NaN NaN https://maps.googleapis.com/maps/api/geocode/j... https://maps.googleapis.com/maps/api/geocode/j... 0.0 0.0 0.0
19 Paso Robles, CA 35.637 -120.655 Monterey, CA 36.600 -121.895 https://maps.googleapis.com/maps/api/geocode/j... https://maps.googleapis.com/maps/api/geocode/j... 83.5 96.0 154.6

In [8]:
# Save df to csv
header = ['Name_Orig','Lat_Orig','Lng_Orig','Name_Des','Lat_Des','Lng_Des',
          'Distance (nm)','Distance (mi)','Distance (km)']
df.to_csv('data/locations.csv', columns=header, index=False)

In [ ]: