Johnnie
Johnnie

Reputation: 89

Putting latitudes and longitudes into a distance matrix, google map API in python

I have a pandas dataframe in the following format:dataframe. enter image description here

Now I want to put all the pairs of Start Latitude and Start Longitude into origins and the put all the pairs of End Latitude and End Longitude into destinations.I want to get the distance and duration by each row like following. Expected Output:

    Rental Id | Distance | Duration | Status
0   51649420    0          0          OK
1   51649421    959        214        OK
2  
...
15

I tried following tow methods but both of them gave me timeout errors.

Method 1:

import googlemaps
from pandas.io.json import json_normalize
gmaps = googlemaps.Client(key='my API key')
for i in range (0,15):
origins = (journeydf['Start Latitude'][i], journeydf['Start Longitude'][i])
destinations = (journeydf['End Latitude'][i], journeydf['End Longitude'][i])
matrix = gmaps.distance_matrix(origins, destinations, mode="bicycling")
matrixdf = json_normalize(matrix,['rows','elements'])
matrixdf['Rental Id']=journeydf['Rental Id']

Method 2:

import urllib, json, time
import pandas as pd

def google(lato, lono, latd, lond):

url = """http://maps.googleapis.com/maps/api/distancematrix/json?origins=%s,%s"""%(lato, lono)+  \
"""&destinations=%s,%s&mode=driving&language=en-EN&sensor=false"""% (latd, lond)

#CHANGE THIS FOR PYTHON 3.X TO urllib.request.urlopen(url)...
response = urllib.urlopen(url).read().decode('utf8')

#Wait a second so you don't overwhelm the API if doing lots of calls
time.sleep(1)

obj = json.loads(response)
try:
    minutes =   obj['rows'][0]['elements'][0]['duration']['value']/60
    miles = (obj['rows'][0]['elements'][0]['distance']['value']/100)*.62137 #kilometers per mile
    return minutes, miles
except IndexError:
    #something went wrong, the result was not found
    print (url)
    #return the error code
    return obj['Status'], obj['Status']

def ApplyGoogle(row):
lato, lono = row['Start Latitude'], row['Start Longitude']
latd, lond = row['End Latitude'], row['End Longitude']
return google(lato, lono, latd, lond)

journeydf['Minutes'], journeydf['Miles'] = zip(*journeydf.apply(ApplyGoogle, axis = 1))

Is there anyway to solve this problem? Thanks in advance.

Upvotes: 7

Views: 13163

Answers (2)

vikaschablani
vikaschablani

Reputation: 11

16 * 16 = 256 > 100, so probably try with smaller matrix viz 10 X 10 and then it should work.

Upvotes: 0

AlexM
AlexM

Reputation: 1183

I'm surprised that you're getting a timeout error with Method 1. Can you confirm the output?

Have you created a Google Maps API key? It's free for standard use (2,500 distance calculations per day, limit 100 per query and limit 100 per 10 sec) https://developers.google.com/maps/documentation/distance-matrix/get-api-key That key needs to be written where your code has 'my API key'

There may also be an issue with your indentation on the for loop, and assignment to orgins and destinations. Try this out:

# make sure you can connect to Google's server
import requests
try:
  response = requests.get('http://www.google.com')
except:
  print 'Can\'t connect to Google\'s server'
  raw_input('Press any key to exit.')
  quit()

# use the Google Maps API
import googlemaps
gmaps = googlemaps.Client(key='YOUR KEY')
origins = []
destinations = []
for i in range (0,15):
  origins.append(str(journeydf['Start Latitude'][i]) + ' ' + str(journeydf['Start Longitude'][i]))
  destinations.append(str(journeydf['End Latitude'][i]) + ' ' + str(journeydf['End Longitude'][i]))
matrix = gmaps.distance_matrix(origins, destinations, mode="bicycling")
print matrix

Upvotes: 1

Related Questions