Search code examples
javamapslatitude-longitude

How to advance X distance (meters) between two points of latitude and longitude?


I'm simulating a polyline with different stops in Java, I have the distance in meters between these two points, the problem is, that I have to go from point A to point B at a speed of 1 to 3 meters per second, and I will need to take the current coordinates I am every 15 min more or less, how can I do that?

The way between the points are straight lines, and all of this is simulated, not happening in a map or something, I just need to print this info every X time, any help?

Example:

I have the coordinates:

LAT: 51.504870000000004 LNG: -0.21533000000000002

and I have to go at that speed to:

LAT: 51.50475 LNG: -0.21571

So, I have to simulate that I go from A to B at 3 meters second, and I need to know my position (lat/lng) while I'm moving between this two points

There's another question that is more or less the same, the difference is that I can't do this with android, is a Java application.


Solution

  • So you know latA, lngA, latB, lngB. From your question, I assume that you know the speed, it's constant, v = 3 m/s. You can get the start time LocalDateTime tA = LocalDateTime.now(); You want to know your coordinates at some moment of time tX.

    In order to do this, I would introduce coefLat and coefLng coefficients for transforming coordinates into meters and back. They use mean radius of Earth and translate degrees into radians:

    double coefLat = 180 / Math.PI / 6371000;
    double coefLng = coefLat / Math.cos(Math.PI * (latA + latB) / 360);
    

    Then calculate distances by Lat and Lng axis and full distance in meters:

    double distLat = (latB - latA) / coefLat;
    double distLng = (lngB - lngA) / coefLng;
    double dist = Math.sqrt(distLat * distLat + distLng * distLng);
    

    enter image description here

    double fullTime = dist / v; // Full time needed to pass from A to B in seconds
    

    After some time of moving, find duration and get current coordinates:

    LocalDateTime tX = LocalDateTime.now(); // get current time
    long dT = Duration.between(tA, tX).getSeconds(); // in seconds
    double ratio = dT / fullTime;
    
    double latX = latA + coefLat * ratio * distLat;
    double lngX = lngA + coefLng * ratio * distLng;
    

    Please also see this answer

    The full code:

    public class GetCurrentCoords {
    
        public static void main(String[] args) {
    
            LocalDateTime tA = LocalDateTime.now();
            double latA = 51.504870000000004;
            double lngA = -0.21533000000000002;
            double latB = 51.50475;
            double lngB = -0.21571;
    
            double coefLat = 180 / Math.PI / 6371000;
            double coefLng = coefLat / Math.cos(Math.PI * (latA + latB) / 360);
    
            double distLat = (latB - latA) / coefLat; // meters
            double distLng = (lngB - lngA) / coefLng; // meters
    
            double dist = Math.sqrt(distLat * distLat + distLng * distLng);
            System.out.println("distLat = " + distLat + "m; distLng = " + distLng + "m; full dist from A to B = " + dist + "m");
            double v = 3;
    
            double fullTime = dist / v; // seconds
            System.out.println("full time from A to B = " + fullTime + "s");
    
            // let's move for 4 seconds
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException ex) {
                Logger.getLogger(GetCurrentCoords.class.getName()).log(Level.SEVERE, null, ex);
            }
    
            LocalDateTime tX = LocalDateTime.now(); 
            long dT = Duration.between(tA, tX).getSeconds();
            double ratio = dT / fullTime;
    
            double latX = latA + coefLat * ratio * distLat;
            double lngX = lngA + coefLng * ratio * distLng;
    
            System.out.println("Moving " + dT + " seconds; latX = " + latX + "; lngX = " + lngX);
         }
    }