Skip to content

Instantly share code, notes, and snippets.

@jineshpaloor
Last active October 11, 2015 10:15
Show Gist options
  • Save jineshpaloor/8337b4f596f77cd1cfec to your computer and use it in GitHub Desktop.
Save jineshpaloor/8337b4f596f77cd1cfec to your computer and use it in GitHub Desktop.
Script to find distance between any two places in globe using google map api
import os
import sys
import json
import math
import urllib
import urllib2
def find_coords(address):
"""
This function extracts coordinates from the json response
given the address.
"""
url = "https://maps.googleapis.com/maps/api/geocode/json?"
data = {'address':address,
'components':'country:IN'}
encode_args = urllib.urlencode(data)
url = url+encode_args
# print 'url', url
coords = None
req = urllib2.Request(url)
response = None
jsonenco = None
try:
response = urllib2.urlopen(req)
if response:
jsonenco = response.read()
else:
return -1
except urllib2.HTTPError as e:
from time import sleep
sleep(1.3)
response = urllib2.urlopen(req)
loc_json = json.loads(jsonenco)
# print "loc_json: %s" %(loc_json)
#print loc_json['results']
if not loc_json['results']:
return (0.00, 0.00)
try:
coords = loc_json['results'][0]['geometry']['location']
except:
pass
# print "coords: %s" %type(coords)
if coords == None:
#print "no single coords found"
coords={}
coordsa = loc_json['results'][0]['geometry']['bounds']['northeast']
coordsb = loc_json['results'][0]['geometry']['bounds']['southwest']
if coordsa['lat']>coordsb['lat']:
coordslat = ((coordsa['lat']-coordsb['lat'])/2)+coordsb['lat']
coordslng = ((coordsb['lng']-coordsb['lng'])/2)+coordsb['lng']
coords = {'lat':coordslat, 'lng':coordslng}
else:
coords = loc_json['results'][0]['geometry']['bounds']['northeast']
# print "coords: %s" %(coords)
return (coords['lat'], coords['lng'])
def distance_on_unit_sphere(lat1, long1, lat2, long2):
# Convert latitude and longitude to
# spherical coordinates in radians.
degrees_to_radians = math.pi/180.0
# phi = 90 - latitude
phi1 = (90.0 - lat1)*degrees_to_radians
phi2 = (90.0 - lat2)*degrees_to_radians
# theta = longitude
theta1 = long1*degrees_to_radians
theta2 = long2*degrees_to_radians
# Compute spherical distance from spherical coordinates.
# For two locations in spherical coordinates
# (1, theta, phi) and (1, theta, phi)
# cosine( arc length ) =
# sin phi sin phi' cos(theta-theta') + cos phi cos phi'
# distance = rho * arc length
cos = (math.sin(phi1)*math.sin(phi2)*math.cos(theta1 - theta2) +
math.cos(phi1)*math.cos(phi2))
arc = math.acos( cos )
# Remember to multiply arc by the radius of the earth
# in your favorite set of units to get length.
return arc
def find_distance(coords1, coords2):
"""
Find the rough distance in kilometres between
coords1 and coords2 using the formula:
"""
try:
lat1, long1 = coords1
lat2, long2 = coords2
# Calculate difference between two sets of lats and longs. Multiply
# by 6373 for distance in kilometres.
distance = 6373 * distance_on_unit_sphere(lat1, long1, lat2, long2)
except TypeError:
distance = -1
return distance
def format_address(address_string):
"""
Format the address to create an allowable string
to feed to Google url.
"""
stop_list = '!@#$%*&><?/' #string within single
#quotes.
#address = '+'.join(address_string.split(" "))
address = address_string
# print '---------', address
address = address.encode('ascii', 'ignore')
address = address.decode('utf-8')
for stop_char in address:
if stop_char in stop_list:
address = ''.join(address.split(stop_char))
# print "Formatted address: %s" %address
return address
def feed_addresses(address1, address2):
"""
Entry point for testing purposes.
"""
address1 = format_address(address1)
address2 = format_address(address2)
coords1 = find_coords(address1)
coords2 = find_coords(address2)
distance = find_distance(coords1, coords2)
return address1, address2, distance
if __name__ == '__main__':
addresses = [("Bangalore", "Delhi"), ("Kochin", "Chennai")]
for address1, address2 in addresses:
print feed_addresses(address1, address2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment