Search code examples
javaandroidalgorithmgpsinterpolation

Interpolate between 2 GPS locations based on walking speed


Problem:


Given two locations:

L1 = (latitude1, longitude1, timestamp1), L2 = (latitude2, longitude2, timestamp2),

and a configurable, but constant, movement speed:

v = 1.39 meters per second (for instance).

How can we interpolate between these two locations to estimate a users location as he travels from L1 to L2?


I have been searching for solutions to this problem and so far I have found, that for small distances (away from the poles) linear interpolation can be used. So, I looked up linear interpolation on Wikipedia and found this:

// Imprecise method which does not guarantee v = v1 when t = 1,
// due to floating-point arithmetic error.
float lerp(float v0, float v1, float t) {
    return v0 + t*(v1-v0);
}

So I am thinking of using this lerp function to interpolate latitude and longitude between L1 and L2. That was the easy part. How do I calculate t? I'm guessing I have to calculate some time deltas, but how do I factor in the movement speed?


Edit:

I'm testing various methods for collecting GPS-locations. For this purpose, I am recording waypoint-locations throughout a walk. I need to interpolate between these waypoints, using the movement speed, to estimate my position along the walk. Then I can compare my results to the estimates to see how well they are faring.

Example:

map


Solution

  • I'm guessing I have to calculate some time deltas, but how do I factor in the movement speed?

    At linear interpolation, in your casem you iterate between two time points, using the iteration variable t which runs from start time t1 to end time t2, with a predefined step. Asume step = 1 second, which is quite usable for your application.

    long t1 = location1.getTimeStamp(); // in milliseconds;
    long t2 = location2.getTimeStamp();
    double deltaLat = location2.latitude - location1.latitude;
    doule deltaLon =  location2.longitude- location1.longtude;
    // remove this line if you don't have measured speed:
    double deltaSpeed =  location2.speed - location1.speed;
    
    long step = 1 * 1000; // 1 second in millis 
    for (long t = t1; t1 < t2; t+= step) {
    
       // t0_1 shall run from 0.0 to (nearly) 1.0 in that loop
      double t0_1 = (t - t1) / (t2 - t1);
      double latInter = lat1 + deltaLat  * t0_1;
      double lonInter = lon1 + deltaLon  * t0_1;
      // remove the line below if you dont have speed
      double speedInter = speed1 + deltaSpeed  * t0_1;
      Location interPolLocation = new Location(latInter, lonInter, speedInter);
      // add interPolLocation to list or plot.
    }