Reputation: 580
I'm trying to come up with a function where...
Input: Geodesic distance in miles or km
Output: The euclidean distance between any two gps points that are the input distance apart
I feel like I have some of the components
import numpy as np
from numpy import linalg as LA
from geopy.distance import geodesic
loc1 = np.array([40.099993, -83.166000])
loc2 = np.array([40.148652, -82.903962])
This is the euclidean distance between those two points
LA.norm(loc1-loc2)
#0.2665175636332336
This is the geodesic distance in miles between those two points
geodesic(loc1,loc2).miles
#14.27909749425243
My brain is running low on juice right now, anyone have any ideas on how I can make a function like:
geodesic_to_euclidean(14.27909749425243)
#0.2665175636332336
Upvotes: 3
Views: 1372
Reputation: 1327
If you're okay with a great-circle distance, as mentioned in the comments, then this should work. It's the haversine distance:
def haversine(origin, destination, units='mi'):
# Radian deltas
origin_lat = radians(float(origin[0]))
origin_lon = radians(float(origin[1]))
destination_lat = radians(float(destination[0]))
destination_lon = radians(float(destination[1]))
lat_delta = destination_lat - origin_lat
lon_delta = destination_lon - origin_lon
# Radius of earth in meters
r = 6378127
# Haversine formula
a = sin(lat_delta / 2) ** 2 + cos(origin_lat) * \
cos(destination_lat) * sin(lon_delta / 2) ** 2
c = 2 * asin(sqrt(a))
meters_traveled = c * r
scaling_factors = {
"m:": 1,
"km": 1 / 1000,
"ft": 3.2808, # meters to feet
"mi:": 0.000621371 # meters to miles
}
return meters_traveled * scaling_factors[units]
If you already have the geodesic (great circle) distance in meters and you want the chord length, then you can do the following
def chord(geodesic_distance):
"""
Chord length
C = 2 * r * sin(theta/2)
Arc length; which is geodesic distance in this case
AL = R * theta
therefore
C = 2 * R * sin(AL/(2*R))
"""
r = 6378127 # Radius of earth in meters
return 2 * r * sin(geodesic_distance / (2 * r))
Upvotes: 2