Search code examples
google-mapsgoogle-maps-api-3google-polyline

Getting Polyline ID Clicked


I'm using Google Maps v3 and have a map placed on my page. The user selects a bunch of data from some lists and then my map is updated with data from my db and provides the user with a map with a polyline of the selected data. The data is retrieved from the db using jquery and returned as json. My code parses the json and draws the polyline. My json contains a data ID, lat, lng. Works fine.

Now I want the user to be able to click on one of the polyline points and I will get additional data for that data ID from my database, but I'm having trouble identifying which ID they clicked. Does anyone have a quick solution to identifying which id was clicked on the line?

This is my listener for the polyline click event. It can get it to react just fine but I don't know how to identify "what" point was clicked so that I can go get my additional data. The example below gives me the ID of the first element in my polyline so I know I'm accessing the array and the event is firing. Just need to be able to locate the specific point I clicked. I get my json. My test set has 8,349 points that looks like this.

{
            "id": 1590065,
            "lat": 37.07318,
            "lng": -88.563132}
,{
            "id": 1590066,
            "lat": 37.07307,
            "lng": -88.563002}
,{
            "id": 1590067,
            "lat": 37.072967,
            "lng": -88.562875}
,{
            "id": 1590068,
            "lat": 37.07287,
            "lng": -88.56275}
,{
            "id": 1590069,
            "lat": 37.072779,
            "lng": -88.56263}
,....

Then I parse the data and assign it to my coordinates.

vesselPathCoordinates = JSON.parse("[" + data + "]");

Then I build my polyline.

vesselPath = new google.maps.Polyline({
    path: vesselPathCoordinates,
    strokeColor: ''#FF0000'',
    strokeOpacity: 1.0,
    strokeWeight: 1.5
});



google.maps.event.addListener(vesselPath, 'click', function( event ){
      console.log( vesselPathCoordinates[0].id ); 
        });

When the user click a specific point on the line I want to know what ID from the JSON that they clicked. In other words, what lat and lng point on the line triggered the event.


Solution

  • You can fine the closest point in the line to the clicked point, look up the id of that vertex in the input data and return it.

    google.maps.event.addListener(vesselPath, 'click', function( event ){
      console.log(event);
      var minDist = Number.MAX_VALUE;
      for (var i=0; i<this.getPath().getLength(); i++){
        var distance = google.maps.geometry.spherical.computeDistanceBetween(event.latLng, this.getPath().getAt(i));
        if (distance < minDist) {
          minDist = distance;
          index = i;
        }
      }
      infowindow.setContent("id="+vesselPathCoordinates[index].id);
      infowindow.setPosition(this.getPath().getAt(index));
      infowindow.open(map);
      console.log( vesselPathCoordinates[0].id ); 
    });
    

    code snippet:

    function initialize() {
      var infowindow = new google.maps.InfoWindow();
      var map = new google.maps.Map(
        document.getElementById("map_canvas"), {
          center: new google.maps.LatLng(37.4419, -122.1419),
          zoom: 13,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        });
      vesselPath = new google.maps.Polyline({
        path: vesselPathCoordinates,
        strokeColor: '#FF0000',
        strokeOpacity: 1.0,
        strokeWeight: 1.5,
        map: map
      });
      var bounds = new google.maps.LatLngBounds();
      for (var i = 0; i < vesselPath.getPath().getLength(); i++) {
        bounds.extend(vesselPath.getPath().getAt(i));
      }
      map.fitBounds(bounds);
      google.maps.event.addListener(vesselPath, 'click', function(event) {
        console.log(event);
        var minDist = Number.MAX_VALUE;
        for (var i = 0; i < this.getPath().getLength(); i++) {
          var distance = google.maps.geometry.spherical.computeDistanceBetween(event.latLng, this.getPath().getAt(i));
          if (distance < minDist) {
            minDist = distance;
            index = i;
          }
        }
        infowindow.setContent("id=" + vesselPathCoordinates[index].id);
        infowindow.setPosition(this.getPath().getAt(index));
        infowindow.open(map);
        console.log(vesselPathCoordinates[index].id);
      });
    }
    google.maps.event.addDomListener(window, "load", initialize);
    
    var vesselPathCoordinates = [{
      "id": 1590065,
      "lat": 37.07318,
      "lng": -88.563132
    }, {
      "id": 1590066,
      "lat": 37.07307,
      "lng": -88.563002
    }, {
      "id": 1590067,
      "lat": 37.072967,
      "lng": -88.562875
    }, {
      "id": 1590068,
      "lat": 37.07287,
      "lng": -88.56275
    }, {
      "id": 1590069,
      "lat": 37.072779,
      "lng": -88.56263
    }]
    html,
    body,
    #map_canvas {
      height: 100%;
      width: 100%;
      margin: 0px;
      padding: 0px
    }
    <script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
    <div id="map_canvas"></div>