bep
bep

Reputation: 752

How to find the overlap of polylines in order to draw the common segment as shaded on google maps

I am working on a small project to show inefficiency of routes based on overlap of route segments.

So for example, I put together a JSFIDDLE here showing a pink and blue line overlapping between D and E. How can I determine that this stretch of road has an overlap in their routes?

Routes would be drawn by a user manually, this example just provides an example of an overlap I am trying to detect:

var map;
var directionsService;


function loadRoute1() {
var request = {
    origin: new google.maps.LatLng(30.244517, -97.892271),
    destination: new google.maps.LatLng(30.244517, -97.892271),
    waypoints: [
        { location: new google.maps.LatLng(30.241532, -97.894202) },
        { location: new google.maps.LatLng(30.239549, -97.894567) }
    ],
    travelMode: google.maps.TravelMode.DRIVING
};

directionsService.route(request, function (result, status) {
    if (status == google.maps.DirectionsStatus.OK) {
        result.draggable = true;
        var renderer = new google.maps.DirectionsRenderer({
            draggable: true,
            polylineOptions: { strokeColor: "#DD71D8" },
            map: map
        });
        renderer.setDirections(result);

    }
});
}

function loadRoute2() {
var request = {
    origin: new google.maps.LatLng(30.244220, -97.890426),
    destination: new google.maps.LatLng(30.244220, -97.890426),
    waypoints: [
        { location: new google.maps.LatLng(30.243312, -97.890877) },
        { location: new google.maps.LatLng(30.242431, -97.891601 ) },
        { location: new google.maps.LatLng(30.243145, -97.893156) },
        { location: new google.maps.LatLng(30.242357, -97.893811) },
        { location: new google.maps.LatLng(30.241671, -97.891783) }
    ],
    travelMode: google.maps.TravelMode.DRIVING
};


directionsService.route(request, function (result, status) {
    if (status == google.maps.DirectionsStatus.OK) {
        result.draggable = true;
        var renderer = new google.maps.DirectionsRenderer({
            draggable: true,
            polylineOptions: { strokeColor: "#0000ff" },
            map: map
        });
        renderer.setDirections(result);
    }
});
}

function initialize() {

var mapOptions = {
    zoom: 16,
    draggable: true,
    center: { lat: 30.241532, lng: -97.894202 } 
};

map = new google.maps.Map(document.getElementById('map'), mapOptions);
directionsService = new google.maps.DirectionsService();

loadRoute1();
loadRoute2();

}

initialize();

Just as a display, a separate polyline should be created with striping of the colors for the routes that overlap.

<html> 
    <body> 
        <div id="map" style="height:500px;width:500px"></div> 
    </body>
</html>

I would like to display the overlapping segments of the routes as striped similar to how this map is doing it.

Upvotes: 2

Views: 3047

Answers (1)

geocodezip
geocodezip

Reputation: 161384

To determine the points in common:

  1. get all the points from the directions result returned
  2. process through both polylines looking for common points

proof of concept fiddle

updated proof of concept with multiple overlaps

picture showing result

code snippet:

var map;
var directionsService;
var bounds = new google.maps.LatLngBounds();

var polyline1 = new google.maps.Polyline({
  path: [],
  strokeColor: "#DD71D8",
  strokeWeight: 1
});
var polyline2 = new google.maps.Polyline({
  path: [],
  strokeColor: "#0000ff",
  strokeWeight: 1
});
var polyline3 = new google.maps.Polyline({
  path: [],
  strokeColor: "#ff0000",
  strokeWeight: 8
});


function loadRoute1() {
  var request = {
    origin: new google.maps.LatLng(30.244517, -97.892271),
    destination: new google.maps.LatLng(30.244517, -97.892271),
    waypoints: [{
      location: new google.maps.LatLng(30.241532, -97.894202)
    }, {
      location: new google.maps.LatLng(30.240374, -97.891633)
    }, {
      location: new google.maps.LatLng(30.244220, -97.890442)
    }],
    travelMode: google.maps.TravelMode.DRIVING
  };

  directionsService.route(request, function(result, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      result.draggable = true;
      var renderer = new google.maps.DirectionsRenderer({
        draggable: false, // true,
        polylineOptions: {
          strokeColor: "#DD71D8",
          strokeWeight: 1
        },
        map: map
      });
      var path = result.routes[0].overview_path;
      var legs = result.routes[0].legs;
      for (i = 0; i < legs.length; i++) {
        var steps = legs[i].steps;
        for (j = 0; j < steps.length; j++) {
          var nextSegment = steps[j].path;
          for (k = 0; k < nextSegment.length; k++) {
            polyline1.getPath().push(nextSegment[k]);
            bounds.extend(nextSegment[k]);
          }
        }
      }
      // polyline1.setMap(map);
      if (polyline2.getPath().getLength() > 1) {
        getPolylineIntersection();
      }
      renderer.setDirections(result);
    }
  });
}

function loadRoute2() {
  var request = {
    origin: new google.maps.LatLng(30.244220, -97.890426),
    destination: new google.maps.LatLng(30.244220, -97.890426),
    waypoints: [{
      location: new google.maps.LatLng(30.243312, -97.890877)
    }, {
      location: new google.maps.LatLng(30.242431, -97.891601)
    }, {
      location: new google.maps.LatLng(30.243145, -97.893156)
    }, {
      location: new google.maps.LatLng(30.242357, -97.893811)
    }, {
      location: new google.maps.LatLng(30.241671, -97.891783)
    }],
    travelMode: google.maps.TravelMode.DRIVING
  };


  directionsService.route(request, function(result, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      result.draggable = true;
      var renderer = new google.maps.DirectionsRenderer({
        draggable: false, // true,
        polylineOptions: {
          strokeColor: "#0000ff",
          strokeWeight: 1
        },
        map: map
      });
      var path = result.routes[0].overview_path;
      var legs = result.routes[0].legs;
      for (i = 0; i < legs.length; i++) {
        var steps = legs[i].steps;
        for (j = 0; j < steps.length; j++) {
          var nextSegment = steps[j].path;
          for (k = 0; k < nextSegment.length; k++) {
            polyline2.getPath().push(nextSegment[k]);
            bounds.extend(nextSegment[k]);
          }
        }
      }
      // polyline2.setMap(map);
      if (polyline1.getPath().getLength() > 1) {
        getPolylineIntersection();
      }
      renderer.setDirections(result);
    }
  });
}

function getPolylineIntersection() {
  var commonPts = [];
  for (var i = 0; i < polyline1.getPath().getLength(); i++) {
    for (var j = 0; j < polyline2.getPath().getLength(); j++) {
      if (polyline1.getPath().getAt(i).equals(polyline2.getPath().getAt(j))) {
        commonPts.push({
          lat: polyline1.getPath().getAt(i).lat(),
          lng: polyline1.getPath().getAt(i).lng(),
          route1idx: i
        });
      }
    }
  }
  var path = [];
  var prevIdx = commonPts[0].route1idx;
  for (var i = 0; i < commonPts.length; i++) {
    if (commonPts[i].route1idx <= prevIdx + 1) {
      path.push(commonPts[i]);
      prevIdx = commonPts[i].route1idx;
    } else {
      var polyline = new google.maps.Polyline({
        map: map,
        path: path,
        strokeWeight: 8,
        strokeColor: "#ff0000"
      });
      path = [];
      prevIdx = commonPts[i].route1idx;
    }
  }
  var polyline = new google.maps.Polyline({
    map: map,
    path: path,
    strokeWeight: 8,
    strokeColor: "#ff0000"
  });

}

function initialize() {

  var mapOptions = {
    zoom: 16,
    draggable: true,
    center: {
      lat: 30.241532,
      lng: -97.894202
    }
  };

  map = new google.maps.Map(document.getElementById('map'), mapOptions);
  directionsService = new google.maps.DirectionsService();

  loadRoute1();
  loadRoute2();

}

initialize();
#map {
  width: 500px;
  height: 500px;
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map"></div>

Upvotes: 6

Related Questions