Search code examples
javascriptgoogle-mapsgoogle-maps-api-3

Google Maps: Applying Event Listeners


I need to keep track of coordinates of drawn shapes while using Google Maps drawing mode. I can add event listeners once a shape is drawn (e.g. polygon) to log the given ID and coordinates in both click and dragend events, but they won't work when editing the shape (e.g. insert_at, remove_at, set_at).

var shapeID = 1;

google.maps.event.addListener(drawingManager, 'polygoncomplete', function(polygon) {
  drawingManager.setDrawingMode(null);

  polygon.setOptions({ id: shapeID, editable:true, draggable:true });

  google.maps.event.addListener(polygon, 'click', function() {
    console.log(this.id+' '+this.getPath().getArray().toString());
  });

  google.maps.event.addListener(polygon, 'dragend', function() {
    console.log(this.id+' '+this.getPath().getArray().toString());
  });

  google.maps.event.addListener(polygon, 'insert_at', function() {
    console.log(this.id+' '+this.getPath().getArray().toString());
  });

  google.maps.event.addListener(polygon, 'remove_at', function() {
    console.log(this.id+' '+this.getPath().getArray().toString());
  });

  google.maps.event.addListener(polygon, 'set_at', function() {
    console.log(this.id+' '+this.getPath().getArray().toString());
  });

  shapeID++;
});

Setting the polygon options works fine; if you click on the polygons their correct shapeID is logged in the console.

My problem is that I want to add an event like this:

google.maps.event.addListener(polygon.getPath(), "insert_at", getPath);
google.maps.event.addListener(polygon.getPath(), "remove_at", getPath);
google.maps.event.addListener(polygon.getPath(), "set_at", getPath);

function getPath() {
  var path = polygon.getPath();
  var len = path.getLength();
  var coordStr = 'id: '+polygon.id+'\n';
  for (var i=0; i<len; i++) {
    coordStr += path.getAt(i).toUrlValue(6)+"\n";
  }
  console.log(coordStr);
}

But I can't access the shapes by their assigned shapeID. Google Maps isn't letting me assign the polygon ID in the string:

google.maps.event.addListener(POLYGON_ID.getPath(), "insert_at", getPath);

I get an error that says "a is not defined".


Solution

  • If you include the getPath function inside (local to) the overlaycomplete event function, it can reference the polygon and its ID.

    var shapeID = 1;
    
    google.maps.event.addListener(drawingManager, 'polygoncomplete', function(polygon) {
      drawingManager.setDrawingMode(null);
    
      polygon.setOptions({
        id: shapeID,
        editable: true,
        draggable: true
      });
    
      google.maps.event.addListener(polygon, 'click', function() {
        console.log(this.id + ' ' + this.getPath().getArray().toString());
      });
    
      google.maps.event.addListener(polygon, 'dragend', function() {
        console.log(this.id + ' ' + this.getPath().getArray().toString());
      });
    
      google.maps.event.addListener(polygon.getPath(), "insert_at", getPath);
      google.maps.event.addListener(polygon.getPath(), "remove_at", getPath);
      google.maps.event.addListener(polygon.getPath(), "set_at", getPath);
    
      function getPath() {
        var path = polygon.getPath();
        var len = path.getLength();
        var coordStr = 'id: ' + polygon.id + '\n';
        for (var i = 0; i < len; i++) {
          coordStr += this.getAt(i).toUrlValue(6) + "\n";
        }
        console.log(coordStr);
      }
    
      shapeID++;
    });
    

    proof of concept fiddle

    code snippet:

    var geocoder;
    var map;
    
    function initMap() {
      var map = new google.maps.Map(document.getElementById('map'), {
        center: {
          lat: -34.397,
          lng: 150.644
        },
        zoom: 8
      });
    
      var drawingManager = new google.maps.drawing.DrawingManager({
        drawingMode: google.maps.drawing.OverlayType.MARKER,
        drawingControl: true,
        drawingControlOptions: {
          position: google.maps.ControlPosition.TOP_CENTER,
          drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
        },
        markerOptions: {
          icon: 'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png'
        },
        circleOptions: {
          fillColor: '#ffff00',
          fillOpacity: 1,
          strokeWeight: 5,
          clickable: false,
          editable: true,
          zIndex: 1
        }
      });
      drawingManager.setMap(map);
    
      var shapeID = 1;
    
      google.maps.event.addListener(drawingManager, 'polygoncomplete', function(polygon) {
        drawingManager.setDrawingMode(null);
    
        polygon.setOptions({
          id: shapeID,
          editable: true,
          draggable: true
        });
    
        google.maps.event.addListener(polygon, 'click', function() {
          console.log(this.id + ' ' + this.getPath().getArray().toString());
        });
    
        google.maps.event.addListener(polygon, 'dragend', function() {
          console.log(this.id + ' ' + this.getPath().getArray().toString());
        });
    
        google.maps.event.addListener(polygon.getPath(), "insert_at", getPath);
        google.maps.event.addListener(polygon.getPath(), "remove_at", getPath);
        google.maps.event.addListener(polygon.getPath(), "set_at", getPath);
    
        function getPath() {
          var path = polygon.getPath();
          var len = path.getLength();
          var coordStr = 'id: ' + polygon.id + '\n';
          for (var i = 0; i < len; i++) {
            coordStr += this.getAt(i).toUrlValue(6) + "\n";
          }
          console.log(coordStr);
        }
    
        shapeID++;
      });
    }
    
    
    google.maps.event.addDomListener(window, "load", initMap);
    /* Always set the map height explicitly to define the size of the div
           * element that contains the map. */
    
    #map {
      height: 100%;
    }
    /* Optional: Makes the sample page fill the window. */
    
    html,
    body {
      height: 100%;
      margin: 0;
      padding: 0;
    }
    <script src="https://maps.googleapis.com/maps/api/js?libraries=geometry,drawing&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
    <div id="map"></div>