Google Maps API - Midpoint along route

2.9k views Asked by At

I've been playing around with the Google Maps/Google directions API. Does anyone have an inkling on how I might be able to find the mid-point along a route, not the geographic midpoint.

Ideally I'd like to find the lat and long values of this midpoint.

Any thoughts? I'm a bit stumped and hoping I may be able to find a suggestion without going crazy trying to find the answer myself.

2

There are 2 answers

0
thomasdao On

An easiest way is that you can first:

1) Calculate total distance of the path using GMSGeometryDistance, by calculating the distance between every two subsequent points by GMSGeometryDistance function, then summing all the distance.

2) Then you calculate again, and summing in each step. When the sum is about half of the total distance, then you are at the middle point. Sample code is as following:

    func findTotalDistanceOfPath(path: GMSPath) -> Double {

        let numberOfCoords = path.count()

        var totalDistance = 0.0

        if numberOfCoords > 1 {

            var index = 0 as UInt

            while index  < numberOfCoords{

                //1.1 cal the next distance

                var currentCoord = path.coordinateAtIndex(index)

                var nextCoord = path.coordinateAtIndex(index + 1)

                var newDistance = GMSGeometryDistance(currentCoord, nextCoord)

                totalDistance = totalDistance + newDistance

                index = index + 1

             }

        }
return totalDistance

    }

func findMiddlePointInPath(path: GMSPath ,totalDistance distance:Double) -> CLLocationCoordinate2D? {

    let numberOfCoords = path.count()

    let halfDistance = distance/2

    let threadhold = 10 //10 meters

    var midDistance = 0.0

    if numberOfCoords > 1 {

        var index = 0 as UInt

        while index  < numberOfCoords{

            //1.1 cal the next distance

            var currentCoord = path.coordinateAtIndex(index)

            var nextCoord = path.coordinateAtIndex(index + 1)

            var newDistance = GMSGeometryDistance(currentCoord, nextCoord)

            midDistance = midDistance + newDistance

            if fabs(midDistance - halfDistance) < threadhold { //Found the middle point in route

                return nextCoord

            }

            index = index + 1

        }

    }
    return nil //Return nil if we cannot find middle point in path for some reason
}

There is more to optimize the function. I wrote a detail answer in Swift in here

0
agaudin On

You can use the GetPointAtDistance prototype from Gisgraphy. The prototype returns a LatLng for a specified distance along a polyline. The following code:

  1. Define a polyline
  2. Determine the half length of this polyline
  3. Use the prototype to return the midpoint LatLng
  4. Extract Lat and Lng from the midpoint LatLng

var polyline = new google.maps.Polyline({
      path: [ new google.maps.LatLng(..., ...),
              new google.maps.LatLng(..., ...),
              ... ];
    }),                                                                //1.
    midDistanceLength = polyline.getPath().getLength() / 2,            //2.
    midDistanceLatLng = polyline.GetPointAtDistance(midDistanceLength),//3.
    midDistanceLat    = midDistanceLatLng.lat(),                       //4.
    midDistanceLng    = midDistanceLatLng.lng();                       //4.

//The prototype from Gisgraphy:
google.maps.Polygon.prototype.GetPointAtDistance = function(metres) {
  // some awkward special cases
  if (metres == 0) return this.getPath().getAt(0);
  if (metres < 0) return null;
  if (this.getPath().getLength() < 2) return null;
  var dist=0;
  var olddist=0;
  for (var i=1; (i < this.getPath().getLength() && dist < metres); i++) {
    olddist = dist;
    dist += google.maps.geometry.spherical.computeDistanceBetween (
      this.getPath().getAt(i),
      this.getPath().getAt(i-1)
    );
  }
  if (dist < metres) return null;
  var p1= this.getPath().getAt(i-2);
  var p2= this.getPath().getAt(i-1);
  var m = (metres-olddist)/(dist-olddist);
  return new google.maps.LatLng( p1.lat() + (p2.lat()-p1.lat())*m, p1.lng() + (p2.lng()-p1.lng())*m);
}
google.maps.Polyline.prototype.GetPointAtDistance = google.maps.Polygon.prototype.GetPointAtDistance;