Search code examples
javascriptgoogle-mapsmathcoordinatesgeospatial

Find if a LatLng Coord is between two other LatLng Coords


Objective

To know if a coordinate point is between two other coordinates.

Background

I am making a google-maps application, and I need to know if a certain Point is between two LatLng points (start and end).

I am looking for a function like the following:

var currentCoord = {lat: 51.8732, lng: -118.6346};
var startCoord = {lat: 61.3434, lng: -118.0046};
var endCoord = {lat: 50.5468, lng: -118.5435};

function isBetween(startCoord, endCoord, currentCoord){
    //calculations here
    return "true if currentCoord is between startCoord and endCoord, or false otherwise";
}

What I tried

To achieve this I read several questions and threads:

Code

No matter what i try, I cannot make it work, but I do have a minimal example with my failed experiments:

"use strict";

/*global google*/

function initialize() {

  let mapOptions = {
    zoom: 3,
    center: new google.maps.LatLng(0, -180),
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };

  let map = new google.maps.Map(document.getElementById('map-canvas'),
    mapOptions);

  let flightPlanCoordinates = [
    new google.maps.LatLng(37.772323, -122.214897),
    new google.maps.LatLng(21.291982, -157.821856),
    new google.maps.LatLng(-18.142599, 178.431),
    new google.maps.LatLng(-27.46758, 153.027892)
  ];

  let flightPath = new google.maps.Polyline({
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: '#FF0000',
    strokeOpacity: 1.0,
    strokeWeight: 2
  });

  flightPath.setMap(map);

  google.maps.event.addListener(flightPath, 'mouseover', function(event) {
    console.log("Marker is over the polyline");
  });

  let marker = new google.maps.Marker({
    position: new google.maps.LatLng(37.772323, -122.214897),
    draggable: true,
    map: map,
    title: 'Drag me!'
  });

  marker.addListener('drag', function(event) {

    let startPoint = {
      lat: 37.772323,
      lng: -122.214897
    };
    let endPoint = {
      lat: 21.291982,
      lng: -157.821856
    };
    let currentPoint = {
      lat: marker.getPosition().lat(),
      lng: marker.getPosition().lng()
    };

    if (checkCoordinate(startPoint, endPoint, currentPoint))
      console.log("in line !");
  });
}

google.maps.event.addDomListener(window, 'load', initialize);

function checkCoordinate(start, end, point) {
  var slope = (end.lng - start.lng) / (end.lat - start.lat);
  var newSlope = (end.lng - point.lng) / (end.lat - point.lat);
  return (point.lat > start.lat && point.lat < end.lat && point.lng > start.lng && point.lng < end.lng && slope == newSlope);
}
html,
body,
#map-canvas {
  height: 100%;
  margin: 0px;
  padding: 0px
}
<!DOCTYPE html>
<html>

<head>
  <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
  <meta charset="utf-8">
  <title>Simple Polylines</title>
  <link rel="stylesheet" type="text/css" href="style.css">
  <script src="https://maps.googleapis.com/maps/api/js?v=3"></script>
  <script src="script.js" type="text/javascript"></script>
</head>

<body>
  <div id="map-canvas"></div>
</body>

</html>

Question

  • How can I find out if a given coordinate is between two coordinates using a mathematical approach?

Solution

  • One option would be to use the google.maps.geometry.poly.isLocationOnEdge method.

    code snippet:

    var map;
    
    function initialize() {
    
      var mapOptions = {
        zoom: 2,
        center: new google.maps.LatLng(0, -180),
        mapTypeId: google.maps.MapTypeId.TERRAIN
      };
    
      map = new google.maps.Map(document.getElementById('map-canvas'),
        mapOptions);
    
      var flightPlanCoordinates = [
        new google.maps.LatLng(37.772323, -122.214897),
        new google.maps.LatLng(21.291982, -157.821856),
        new google.maps.LatLng(-18.142599, 178.431),
        new google.maps.LatLng(-27.46758, 153.027892)
      ];
    
      var flightPath = new google.maps.Polyline({
        path: flightPlanCoordinates,
        geodesic: false,
        strokeColor: '#FF0000',
        strokeOpacity: 1.0,
        strokeWeight: 2
      });
    
      flightPath.setMap(map);
    
      var marker = new google.maps.Marker({
        position: new google.maps.LatLng(37.772323, -122.214897),
        draggable: true,
        map: map,
        title: 'Drag me!'
      });
    
      marker.addListener('dragend', function(event) {
    
        var startPoint = {
          lat: 37.772323,
          lng: -122.214897
        };
        var startMarker = new google.maps.Marker({
          position: startPoint,
          map: map
        });
        var endPoint = {
          lat: 21.291982,
          lng: -157.821856
        };
        var endMarker = new google.maps.Marker({
          position: endPoint,
          map: map
        });
        var currentPoint = {
          lat: marker.getPosition().lat(),
          lng: marker.getPosition().lng()
        };
    
        if (checkCoordinate(startPoint, endPoint, marker.getPosition()))
          console.log("in line !");
      });
    }
    
    google.maps.event.addDomListener(window, 'load', initialize);
    
    function checkCoordinate(start, end, point) {
      return google.maps.geometry.poly.isLocationOnEdge(point, new google.maps.Polyline({
        map: map,
        path: [start, end]
      }), 10e-1);
    }
    html,
    body,
    #map-canvas {
      height: 100%;
      margin: 0px;
      padding: 0px
    }
    <!DOCTYPE html>
    <html>
    
    <head>
      <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
      <meta charset="utf-8">
      <title>Simple Polylines</title>
      <link rel="stylesheet" type="text/css" href="style.css">
      <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
      <script src="script.js" type="text/javascript"></script>
    </head>
    
    <body>
      <div id="map-canvas"></div>
    </body>
    
    </html>