Search code examples
javascriptarraysgoogle-mapsgoogle-maps-api-3polygons

Attaching different infowindows to group of polygons google maps


Right now my code looks like this:

   // create a LatLng array out of given coordinates string
  for (var i = 0; i < coordinateString.length; i++) {
    var polygonCoords = new Array();
    var j = 0;
    var z = j + 1;
    while (z < coordinate.length) 
    {
      if ((j%2) === 0) 
      {
        var coord1 = parseFloat(coord[z]);
        var coord2 = parseFloat(coord[j]);
        var newLatLng = new google.maps.LatLng(coord1,coord2);
        polygonCoords.push(newLatLng);
        } else 
        {
            var coord1 = parseFloat(coord[j]);
            var coord2 = parseFloat(coord[z]);
            var newLatLng = new google.maps.LatLng(coord1,coord2);
            polygonCoords.push(newLatLng);
        }
    z++;
    j++;
    }

    /** Adds the polygon to a polygon array
    * and maps it onto the map
    */

         var newPoly = new google.maps.Polygon(
          {
            paths: polygonCoords,
            strokeColor: objArray[i].borderColor,
            strokeOpacity: 0.8,
            strokeWeight: 2,
            fillColor: objArray[i].fillColor,
            fillOpacity: 0.35
            })
          newPoly.setMap(map);
          newPoly.set("eventNum",objArray[i].eventID)
          newPoly.set("offTime", objArray[i].offTime)

           function attachInfoWindow(event) 
            {
              var infowindowPoly = new google.maps.InfoWindow();
              var eventNo = newPoly.get("eventNum");
              var outTime = newPoly.get("offTime");
              var resTime = objArray[i].restoreTime;
              var contentString = "Event Number: " + eventNo + "<br> Outage Time: " + outTime + "<br> Estimated Restoration Time: " + resTime;
              infowindowPoly.setContent(contentString);
              infowindowPoly.setPosition(event.latLng);
              infowindowPoly.open(map);
              google.maps.event.addListener(map, 'click', function() 
                {
                  infowindowPoly.close();
                });
            }
          google.maps.event.addListener(newPoly, 'click', attachInfoWindow); 
         }
       }

Which creates an array of polygons in different positions (its looping, so everytime a new polygon is created and set to the map) and when clicked an infowindow pops up and displays some content, except it is the same content. However I want to display different infowindows for each polygon. I've read all the other similar questions and answers and have modified my code.

Note that, I've stored objects holding the content I want into an array and am using indexes and other ways to grab properties of the object and then display it as my infowindow content.


Solution

  • Create a function to return the click listener function. Pass the index and the polygon into that function so you get function closure on them to keep them associated:

    function attachInfoWindow(newPoly, i) {
        return function (event) {
            var eventNo = newPoly.get("eventNum");
            var outTime = newPoly.get("offTime");
            var resTime = objArray[i].restoreTime;
            var contentString = "Event Number: " + eventNo + "<br> Outage Time: " + outTime + "<br> Estimated Restoration Time: " + resTime;
            infowindowPoly.setContent(contentString);
            infowindowPoly.setPosition(event.latLng);
            infowindowPoly.open(map);
            google.maps.event.addListener(map, 'click', function () {
                infowindowPoly.close();
            });
        };
    }
    

    Call the function like this:

    for (var i = 0; i < numOfPolygons; i++) {
        var newPoly = new google.maps.Polygon({
            paths: polygons[i],
            strokeColor: objArray[i].borderCol,
            strokeOpacity: 0.8,
            strokeWeight: 2,
            fillColor: objArray[i].fill,
            fillOpacity: 0.35
        });
        newPoly.setMap(map);
        newPoly.set("eventNum", objArray[i].eventID);
        newPoly.set("offTime", objArray[i].offTime);
    
        google.maps.event.addListener(newPoly, 'click', attachInfoWindow(newPoly, i));
    }
    

    proof of concept fiddle

    code snippet:

    function attachInfoWindow(newPoly, i) {
      return function(event) {
        var eventNo = newPoly.get("eventNum");
        var outTime = newPoly.get("offTime");
        var resTime = objArray[i].restoreTime;
        var contentString = "Event Number: " + eventNo + "<br> Outage Time: " + outTime + "<br> Estimated Restoration Time: " + resTime;
        infowindowPoly.setContent(contentString);
        infowindowPoly.setPosition(event.latLng);
        infowindowPoly.open(map);
        google.maps.event.addListener(map, 'click', function() {
          infowindowPoly.close();
        });
      };
    }
    
    function initialize() {
      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
        });
      var bounds = new google.maps.LatLngBounds();
      var polygons = [];
    
      for (var j = 0; j < coordinateStrings.length; j++) {
        var coordinates = coordinateStrings[j].split(" ");
        var polygonCoords = [];
        for (var i = 0; i < coordinates.length; i++) {
          var point = coordinates[i].split(",");
          var latlng = new google.maps.LatLng(parseFloat(point[1]), parseFloat(point[0]));
          bounds.extend(latlng);
          polygonCoords.push(latlng);
        }
        polygons.push(polygonCoords);
      }
    
      /** Adds the polygon to a polygon array
       * and maps it onto the map
       */
      var numOfPolygons = objArray.length;
    
      for (var i = 0; i < numOfPolygons; i++) {
        var newPoly = new google.maps.Polygon({
          paths: polygons[i],
          strokeColor: objArray[i].borderCol,
          strokeOpacity: 0.8,
          strokeWeight: 2,
          fillColor: objArray[i].fill,
          fillOpacity: 0.35
        });
        newPoly.setMap(map);
        newPoly.set("eventNum", objArray[i].eventID);
        newPoly.set("offTime", objArray[i].offTime);
    
    
        google.maps.event.addListener(newPoly, 'click', attachInfoWindow(newPoly, i));
      }
      map.fitBounds(bounds);
    }
    
    google.maps.event.addDomListener(window, "load", initialize);
    var geocoder;
    var map;
    var infowindowPoly = new google.maps.InfoWindow();
    var objArray = [{
      borderCol: "#FF0000",
      fill: "#FF0000",
      eventID: 1,
      offTime: "12:10"
    }, {
      borderCol: "#0000FF",
      fill: "#0000FF",
      eventID: 2,
      offTime: "12:00"
    }, {
      borderCol: "#00FF00",
      fill: "#00FF00",
      eventID: 3,
      offTime: "12:20"
    }];
    var coordinateStrings = ["-82.4908447265625,42.99058552185121,0 -82.52174377441406,43.013182961445914,0 -82.42286682128906,43.02573350308799,0 -82.38578796386719,42.98958099829517,0 -82.452392578125,42.96596996868038,0 -82.45857238769531,42.99359899401497,0",
      "-82.33840942382812,42.96094517567432,0 -82.33016967773438,43.014689161895184,0 -82.23129272460938,43.04079076668198,0 -82.23197937011719,42.954412331213284,0",
      "-82.4139404296875,43.062868070571454,0 -82.38372802734375,43.014689161895184,0 -82.22442626953125,43.06387139555526,0 -82.276611328125,43.15209968803547,0 -82.37411499023438,43.141078106345844,0"
    ];
    html,
    body,
    #map_canvas {
      height: 500px;
      width: 500px;
      margin: 0px;
      padding: 0px
    }
    <script src="https://maps.googleapis.com/maps/api/js"></script>
    <div id="map_canvas" style="border: 2px solid #3872ac;"></div>