0

I need to draw multiple shapes on a map upon initialization and then add event listeners to see if the shapes have been modified or clicked on.

If I draw a single shape, the below code works properly:

// 1
var polygon = new google.maps.Polygon({
    id: '1',
    paths: [
        {lat: 38.56080094343725, lng: -121.74302101135254},
        {lat: 38.56106940317395, lng: -121.76750421524048},
        {lat: 38.57249479108347, lng: -121.76737546920776},
        {lat: 38.57244446296193, lng: -121.75782680511475},
        {lat: 38.57595057110021, lng: -121.75774097442627},
        {lat: 38.57583314441062, lng: -121.74778461456299}
    ],
    strokeColor: '#FF0000',
    strokeOpacity: 0.8,
    strokeWeight: 1,
    fillColor: '#FF0000',
    fillOpacity: 0.1
});
polygon.setMap(map);

google.maps.event.addListener(polygon, 'click', function() {
    console.log(polygon.id);
});

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 shapeCoords = '';
    for (var i =0; i < polygon.getPath().getLength(); i++) {
        var xy = polygon.getPath().getAt(i);
        shapeCoords += '{lat: ' + xy.lat() + ', lng: ' + xy.lng() + '},\n';
    }
    console.log(shapeCoords);
    console.log(polygon.id);
}

When I draw any additional shapes, I have to duplicate all of the click events and change the variable name (e.g. to polygon2).

// 2
var polygon2 = new google.maps.Polygon({
    id: '2',
    paths: [
        {lat: 38.56075060712497, lng: -121.76754713058472},
        {lat: 38.5605157038683, lng: -121.74289226531982},
        {lat: 38.55172305844243, lng: -121.7401671409607},
        {lat: 38.550665854985745, lng: -121.74636840820312},
        {lat: 38.54645366782474, lng: -121.745445728302},
        {lat: 38.54636975720739, lng: -121.74585342407227},
        {lat: 38.546302628643, lng: -121.74879312515259},
        {lat: 38.54655436043634, lng: -121.76778316497803}
    ],
    strokeColor: '#FF0000',
    strokeOpacity: 0.8,
    strokeWeight: 1,
    fillColor: '#FF0000',
    fillOpacity: 0.1
});
polygon2.setMap(map);

google.maps.event.addListener(polygon2, 'click', function() {
    console.log(polygon2.id);
});

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

function getPath2() {
    var shapeCoords = '';
    for (var i =0; i < polygon2.getPath().getLength(); i++) {
        var xy = polygon2.getPath().getAt(i);
        shapeCoords += '{lat: ' + xy.lat() + ', lng: ' + xy.lng() + '},\n';
    }
    console.log(shapeCoords);
    console.log(polygon2.id);
}

Is there any way to use the same getPath function and/or event listeners so I don't need to duplicate the same code for each shape?

user513951
  • 12,445
  • 7
  • 65
  • 82
Lauren
  • 743
  • 3
  • 12
  • 24

1 Answers1

1

One option is to solve the problem the same way that was used in your last question. Create a createPolygon function that takes the path, id, and any other options of the polygon you want configurable. Use that to create the fixed polygons with its own internal version of getPath (so you have one instance of the function local to the polygon creation function, which has access to the closure on polygon, use the same function to create the polygons from the DrawingManager).

function createPolygon(id, poly) {
  var polygon;
  if (!(poly instanceof google.maps.Polygon)) {
    var polygon = new google.maps.Polygon({
      id: id,
      paths: poly,
      strokeColor: '#FF0000',
      strokeOpacity: 0.8,
      strokeWeight: 1,
      fillColor: '#FF0000',
      fillOpacity: 0.1
    });
  } else {
    polygon = poly;
  }
  polygon.setMap(map);

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

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

  function getPathCP() {
    var shapeCoords = '';
    for (var i = 0; i < polygon.getPath().getLength(); i++) {
      var xy = polygon.getPath().getAt(i);
      shapeCoords += '{lat: ' + xy.lat() + ', lng: ' + xy.lng() + '},\n';
    }
    console.log(shapeCoords);
    console.log(polygon.id);
  }
  return polygon;
}

proof of concept fiddle

code snippet:

var geocoder;
var map;

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    center: {
      lat: -34.397,
      lng: 150.644
    },
    zoom: 8
  });
  var bounds = new google.maps.LatLngBounds();
  var shapeID = 1;

  function createPolygon(id, poly) {
      var polygon;
      if (!(poly instanceof google.maps.Polygon)) {
        var polygon = new google.maps.Polygon({
          id: id,
          paths: poly,
          strokeColor: '#FF0000',
          strokeOpacity: 0.8,
          strokeWeight: 1,
          fillColor: '#FF0000',
          fillOpacity: 0.1
        });
      } else {
        polygon = poly;
      }
      for (var i = 0; i < polygon.getPath().getLength(); i++) {
        bounds.extend(polygon.getPath().getAt(i));
      }
      polygon.setMap(map);

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

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

      function getPathCP() {
        var shapeCoords = '';
        for (var i = 0; i < polygon.getPath().getLength(); i++) {
          var xy = polygon.getPath().getAt(i);
          shapeCoords += '{lat: ' + xy.lat() + ', lng: ' + xy.lng() + '},\n';
        }
        console.log(shapeCoords);
        console.log(polygon.id);
      }
      return polygon;
    }
    // 1
  var polygon1 = createPolygon(shapeID++, [{
    lat: 38.56080094343725,
    lng: -121.74302101135254
  }, {
    lat: 38.56106940317395,
    lng: -121.76750421524048
  }, {
    lat: 38.57249479108347,
    lng: -121.76737546920776
  }, {
    lat: 38.57244446296193,
    lng: -121.75782680511475
  }, {
    lat: 38.57595057110021,
    lng: -121.75774097442627
  }, {
    lat: 38.57583314441062,
    lng: -121.74778461456299
  }]);
  // 2
  var polygon2 = createPolygon(shapeID++, [{
    lat: 38.56075060712497,
    lng: -121.76754713058472
  }, {
    lat: 38.5605157038683,
    lng: -121.74289226531982
  }, {
    lat: 38.55172305844243,
    lng: -121.7401671409607
  }, {
    lat: 38.550665854985745,
    lng: -121.74636840820312
  }, {
    lat: 38.54645366782474,
    lng: -121.745445728302
  }, {
    lat: 38.54636975720739,
    lng: -121.74585342407227
  }, {
    lat: 38.546302628643,
    lng: -121.74879312515259
  }, {
    lat: 38.54655436043634,
    lng: -121.76778316497803
  }]);
  map.fitBounds(bounds);
  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);

  google.maps.event.addListener(drawingManager, 'polygoncomplete', function(polygon) {
    drawingManager.setDrawingMode(null);
    polygon.setOptions({
      id: shapeID,
      editable: true,
      draggable: true
    });
    createPolygon(shapeID++, polygon);
    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=drawing&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map"></div>
geocodezip
  • 158,664
  • 13
  • 220
  • 245