8

I have a Google Maps V3 polyline. I can detect click events on the entire polyline, but can I do anything more advanced with the click event?

What I'd like to do is detect which section of the polyline has been clicked, and show this in an alert.

 routePath = new google.maps.Polyline({
     path: routeCoordinates,
     strokeColor: "#CC33FF",
     strokeWeight: 3
 });     
 routePath.setMap(map);
 google.maps.event.addListener(routePath, 'click', function() {
     alert(routePath);
     // TODO: display which section of the polyline has been clicked?
 });

Does anyone know how to do this in Google Maps?

thanks!

skaffman
  • 398,947
  • 96
  • 818
  • 769
phil123
  • 195
  • 3
  • 3
  • 8
  • I [can't even get the click event to fire](https://stackoverflow.com/questions/65387148/how-to-determine-when-it-is-safe-to-add-an-event-to-a-newly-created-element), I've trying adding the element like you are as well as directly on the polyline, what am I doing wrong? – Michael Dec 23 '20 at 17:52

3 Answers3

12

On the click event you can receive a LatLng of the coordinate that was clicked. However, since that will probably not be an exact point that is creating the polyline you need to find the closest point. You can use the computeDistanceBetween in the Google Maps library or you can use Pythagoras theorem as it should give you a good enough accuracy in this case.

You can find more information on computeDistanceBetween here: https://developers.google.com/maps/documentation/javascript/reference#spherical

Here is a code example how you could do it with the computeDistanceBetween.

google.maps.event.addListener(routePath, 'click', function(h) {
     var latlng=h.latLng;
     alert(routePath);
     var needle = {
         minDistance: 9999999999, //silly high
         index: -1,
         latlng: null
     };
     routePath.getPath().forEach(function(routePoint, index){
         var dist = google.maps.geometry.spherical.computeDistanceBetween(latlng, routePoint);
         if (dist < needle.minDistance){
            needle.minDistance = dist;
            needle.index = index;
            needle.latlng = routePoint;
         }
     });
     // The closest point in the polyline
     alert("Closest index: " + needle.index);

     // The clicked point on the polyline
     alert(latlng);

 });
BrettJ
  • 6,801
  • 1
  • 23
  • 26
Nils
  • 2,041
  • 1
  • 15
  • 20
4

I ran into the same, issue here is how I dealt with it: when setting up the handler:

google.maps.event.addListener(routePath, 'click', function(e) {
    handlePolyClick(e, this)
});

var handlePolyClick(eventArgs, polyLine) {
    // now you can access the polyLine
    alert(polyLine.strokeColor);
});

Or if you want to access a related object set it by creating a variable on the polyLine:

routePath.car = $.extend({}, cars[1]); // shallow copy of cars[1]

then you can access your car from the event:

alert(this.car.color);
parsley72
  • 8,449
  • 8
  • 65
  • 98
  • this doesn't tell you which section of the polyline was clicked on... does it? – Michael Dec 21 '20 at 02:43
  • This works perfectly when you want to extend the polyline attributes. I was not aware of the use of $.extend is quite neat!. –  Mar 03 '22 at 00:19
1

Finding the closest point by distance analysis will fail in a lot of cases where a path crosses back over or near itself.

You can use it to identify candidates, but you should confirm them by comparing the cross product and/or dot product of the 2 lines created if you use the click point to split 2 consecutive polyline points

jmaculate
  • 2,976
  • 2
  • 17
  • 14