3

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.

duncan
  • 31,401
  • 13
  • 78
  • 99
ScottM
  • 43
  • 1
  • 8

2 Answers2

0

You can declare a function for adding the listenr to you polyline passing the date you need in event

var addListenersOnPolyline = function(polyline, myJsonData) {
    google.maps.event.addListener(polyline, 'click', function (event) {
        window.open(myJsonData.myData);

    });  

and when you nedd you can set the event by the function this way

addListenersOnPolyline(myActPolyline, myActJsonData );

If you have

jsonData = JSON.parse(yourJson);
jsonData.id // should contain 1590065
ScaisEdge
  • 131,976
  • 10
  • 91
  • 107
  • So you're suggesting adding a listener for each point? My datasets can contain anywhere from 1 to [x], i.e. thousands, points. – ScottM Mar 25 '16 at 17:33
  • I use this technique even with 50,000 polygons simultaneously visible on the map and they work fine. For what i know is the normal technique per object event management in google maps .. – ScaisEdge Mar 25 '16 at 17:36
  • I suggest you an event for polyline ... why you are thinking to point? – ScaisEdge Mar 25 '16 at 17:36
  • Ok. This stuff is all pretty new to me, but it just doesn't seem that efficient, but I will give it a go. – ScottM Mar 25 '16 at 17:38
  • I very very efficient .. is javascript – ScaisEdge Mar 25 '16 at 17:38
  • I'm missing something. Used your code above and replaced window.open with console.log(myJsonDate). When I click a point on my line I get the entire json returned in the console and not the specific point I clicked. How do I get the single point that I clicked? – ScottM Mar 25 '16 at 18:13
  • In my sample MyJsonData is not all the Json file but only the data portion for the specific polyline – ScaisEdge Mar 25 '16 at 18:47
  • I have json like this. { "id": 1590065, "lat": 37.07318, "lng": -88.563132} ,{ "id": 1590066, "lat": 37.07307, "lng": -88.563002} and my line is drawn. Listener is google.maps.event.addListener(vesselPath, ''click'', addListenersOnPolyline(vesselPath, vesselPathCoordinates )); Function is var addListenersOnPolyline = function(polyline, myJsonData) { google.maps.event.addListener(polyline, ''click'', function (event) { console.log(myJsonData); })}; How do I get the ID of the point I click? – ScottM Mar 25 '16 at 18:49
  • I'm missing the bit of how to attach a listener to each point. – ScottM Mar 25 '16 at 18:52
  • What do you mean whit each point? a polyline or each single coord of the polyline .. and way do you refer to point and not to the polyline? – ScaisEdge Mar 25 '16 at 18:56
  • Yes, that gets me the id of the first point. What if I click point 2,127? How do I get the ID of that point? – ScottM Mar 25 '16 at 18:58
  • If you can update your original question with a bit of code where you retrieve the Json, create the polyline and add the listener so i can see hat are you doing.. – ScaisEdge Mar 25 '16 at 19:00
  • Updated the question with a bit more as you requested. – ScottM Mar 25 '16 at 19:09
  • But vesselPath is polyline and then you have only one listener for the object polyline .. if you want manage event click fo every singlle point/coord of the polyline you must add a marker for each point and for each marker add specific listener .so when you click the specific marker you get the point you need (and if you preserve a proper id you get the segment of polyline) . otherwise you can't control the single point click event because you have not the proper "listener" – ScaisEdge Mar 25 '16 at 19:26
  • Ok, I think that was the answer I was looking for! I'll have to do some work to get that in place and will let you know the outcome. Thanks. – ScottM Mar 25 '16 at 19:32
0

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>
geocodezip
  • 158,664
  • 13
  • 220
  • 245