Search code examples
javascriptmathgeolocationgeometrygeo

How do I check if a point is behind another point relative to its location and course?


I am working on an app which highly depends on geolocation and calculations based upon it. One of the views is a list view which gives a list of moving POI's behind the users location.

+---------------------------+
+------  .            ------+
+-----    .            -----+
+----      .  [POI1]    ----+
+---        .     /      ---+
+--          .   /        --+
+-            . /          -+
+           [ME]            +
+-              .          -+
+--              .        --+
+---              .      ---+
+----  [POI2]      .    ----+
+-----              .  -----+
+------              .------+
+---------------------------+
/ = user course
..= perpendicular line
[POI1] = in front
[POI2] = Behind

So far I have worked out the following steps:

  1. Get user location
  2. Retrieve POI's in 5km radius
  3. Filter all POI's at higher speed and same course (+/- 45 degrees of own course)

The next step is to determine which POI's are in front of the user and which are behind. The methodology I've figured is to create an infinite line (vector) perpendicular to the users course. (e.g. at a course of 45 degrees, NorthEast, the line would be NorthWest-SouthEast). I then need to figure out if the Lat-Lon of every poi is in front or behind this line in order to know whether it is in front of the user or behind.

All this is done with latitude and longitude in javascript. So I probably need a formula or function of some kind that will compare two latlng points to each other, relative to the course of the first point.

Google hasn't been very helpful so far, so I really hope someone can figure this out! In the mean time I will be in my bubble of shame for not paying enough attention in math class.


Solution

  • I've had a couple of very good and interesting approaches to this problem. The most simple and effective one was to use a library for calculating a bearing between 2 LatLon points.

    I used GeoDesy's latlon-spherical.js and its .bearing() method to get the bearing from my to my POI relative to true north.

    1. Get bearing to POI relative to true north
    2. Subtract my own bearing to get bearing relative to me
    3. Normalize bearing (e.g. add 360 to negative values)
    4. Check if bearing is between 90 and 270 (this means going backwards)
    

    In my code it looks like this:

    function filterShipFromBehind(ship)
    {
        // Get our and the ships latlon
        var shipLatLon = new LatLon(ship.location.latitude, ship.location.longitude);
        var myLatLon = new LatLon(myShip.location.latitude, myShip.location.longitude);
    
        // Calculate the bearing from us to the ship (relative to true north)
        var bearing = myLatLon.bearingTo(shipLatLon);
    
        // Calculate the relative bearing by subtracting our own bearing
        var difference = Ships.normalizeAngle(bearing - myShip.courseOverGround);
    
        // Finally check if the relative bearing is between 90 and 270 degrees
        // indicating it is behind us
        if(difference > 90 && difference < 270)
        {
            filterShipNearing(ship);
        }
    }
    

    I hope this helps the next one looking to tackle this problem!