I want to simulate a movement on a real world map (spherical) and represent the actual position on (google|openStreet)maps.
I have an initial lat/long pair e.g. (51.506314, -0.088455) and want to move to e.g. (51.509359, -0.087221) on a certain speed by getting interpolated coordinates periodically.
Pseudocode for clarification:
loc_init = (51.509359, -0.087221)
loc_target = (51.509359, -0.087221)
move_path = Something.path(loc_init, loc_target, speed=50)
for loc in move_path.get_current_loc():
map.move_to(loc)
device.notify_new_loc(loc)
...
time.sleep(1)
Retrieving the current interpolated position can happen in different ways e.g. calculating with a fixed refresh time (1 sec) or maybe running in a thread holding and calculating continuously new positions.
Unfortunately I never worked with geo data before and can't find something useful on the internet. Maybe there is already a module or an implementation doing that?
Solved my problem:
Found a C++ library geographiclib which was ported to Python doing exactly what I was looking for. Example code to calculate a inverse geodesic line and get positions for a specific distance:
from geographiclib.geodesic import Geodesic
import math
# define the WGS84 ellipsoid
geod = Geodesic.WGS84
loc_init = (51.501218, -0.093773)
loc_target = (51.511020, -0.086563)
g = geod.Inverse(loc_init[0], loc_init[1], loc_target[0], loc_target[1])
l = geod.InverseLine(loc_init[0], loc_init[1], loc_target[0], loc_target[1])
print ("The distance is {:.3f} m.".format(g['s12']))
# interval in m for interpolated line between locations
interval = 500
step = int(math.ceil(l.s13 / interval))
for i in range(step + 1):
if i == 0:
print ("distance latitude longitude azimuth")
s = min(interval * i, l.s13)
loc = l.Position(s, Geodesic.STANDARD | Geodesic.LONG_UNROLL)
print ("{:.0f} {:.5f} {:.5f} {:.5f}".format(
loc['s12'], loc['lat2'], loc['lon2'], loc['azi2']))
Gives:
The distance is 1199.958 m.
distance latitude longitude azimuth
0 51.50122 -0.09377 24.65388
500 51.50530 -0.09077 24.65623
1000 51.50939 -0.08776 24.65858
1200 51.51102 -0.08656 24.65953