Reputation: 1
Given 2 start and stop gps coordinates (ie. point#1: 39.5210981,-76.6194347, point#2: 39.6206699,-76.554627), I have all gps coordinate points for the shortest route between those 2 start and stop gps coordinates using the OpenStreetMap.
The question is how can I iterate a new set of gps coordinates with a speed (ie 30 mph or 45 km/h) per 1 second interval from the given route?
I have tried to calculate the distance between two point using this codes given by another stackoverflow user:
def midpoint(lat1, long1, lat2, long2, per):
return lat1 + (lat2 - lat1) * per, long1 + (long2 - long1) * per
But it looks quite off mark for some of the points, furthermore, if some the points are very close, then I am also off the mark.
Upvotes: 0
Views: 315
Reputation: 16184
I'd suggest using an external library for this, it's pretty difficult to get the maths right if you care about doing this accurately over large distances. I've used pyproj
before and it exposes a Geod.inv
method that says:
Returns forward and back azimuths, plus distances between initial points (specified by lons1, lats1) and terminus points (specified by lons2, lats2).
the "azimuth" is the angle you'd have head to get to the point, and the distance is in meters.
it also exposes Geod.fwd
for getting back to coordinates:
Returns longitudes, latitudes and back azimuths of terminus points given longitudes (lons) and latitudes (lats) of initial points, plus forward azimuths (az) and distances (dist).
I think how you'd want to put these together is like this:
import pyproj
# WGS-84 is the coordinate system used by GPS
wgs84_geod = pyproj.CRS('WGS 84').get_geod()
# I think I'm pulling these apart in the right order, but you'd want to check
src_lat, src_lon = 39.5210981,-76.6194347
dst_lat, dst_lon = 39.6206699,-76.554627
# how many meters between each point
delta = 45 * 1000 / 3600
# keep track of where we currently are
lat, lon = src_lat, src_lon
result = []
while True:
# figure out which direction to go and how far away we are
az, _, dist = wgs84_geod.inv(lon, lat, dst_lon, dst_lat)
# are we done yet?
if dist < delta:
break
result.append((lon, lat))
# move at our speed towards our target
lon, lat, _ = wgs84_geod.fwd(lon, lat, az, delta)
this gives a mostly straight line over short distances, but the curve will be obvious over longer distances
Upvotes: 0