1

I make polygon drawing on my map.

Here is function for drawingManager

 drawingManager = new google.maps.drawing.DrawingManager({
    drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
    drawingControlOptions: {
        drawingModes: [
            google.maps.drawing.OverlayType.RECTANGLE,
            google.maps.drawing.OverlayType.POLYGON

        ]
    },
    polygonOptions: {
        fillColor: 'green',
        fillOpacity: 0.4,
        strokeWeight: 1,
        clickable: true,
        zIndex: 1,
        editable: false
    }
});

I need to calculate bounds for polygon. I read, that I cannot do it via .getBounds like with square.

So I found here answer

I tried one of answers.

So now my code looks like this.

drawingManager.addListener('polygoncomplete', function (polygon) {
    var bounds = new google.maps.LatLngBounds();

    polygon.forEach(function (feature) {
        if (feature.getGeometry().getType() === 'Polygon') {
            feature.getGeometry().forEachLatLng(function (latlng) {
                bounds.extend(latlng);
            });
        }
    });
    console.dir(bounds);
}); 

and in console I get this error.

Index.js:1673 Uncaught TypeError: polygon.forEach is not a function

at this row polygon.forEach(function (feature) {

Where is problem and how I can solve it?

Balance
  • 167
  • 2
  • 11

2 Answers2

5

See the documentation:

A polygon has a .getPaths() method, which returns a MVCArray of LatLng objects.

drawingManager.addListener('polygoncomplete', function(polygon) {
  var bounds = new google.maps.LatLngBounds();
  polygon.getPaths().forEach(function(path) {
    path.forEach(function(latlng) {
      bounds.extend(latlng);
      map.fitBounds(bounds);
    });
  });
});

proof of concept fiddle

code snippet:

function initialize() {
  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
    });
  var drawingManager = new google.maps.drawing.DrawingManager({
    map: map,
    drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
    drawingControlOptions: {
      drawingModes: [
        google.maps.drawing.OverlayType.RECTANGLE,
        google.maps.drawing.OverlayType.POLYGON

      ]
    },
    polygonOptions: {
      fillColor: 'green',
      fillOpacity: 0.4,
      strokeWeight: 1,
      clickable: true,
      zIndex: 1,
      editable: false
    }
  });
  drawingManager.addListener('polygoncomplete', function(polygon) {
    var bounds = new google.maps.LatLngBounds();


    polygon.getPaths().forEach(function(path) {
      path.forEach(function(latlng) {
        bounds.extend(latlng);
        map.fitBounds(bounds);
      });
    });
  });
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry,drawing&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map_canvas"></div>
geocodezip
  • 158,664
  • 13
  • 220
  • 245
  • I don't think you need to look at all the linear rings, do you? The first ring, which you can retrieve directly with `.getPath()`, defines the outer ring, so you can iterate directly over that one and disregard the rest. Any rings after the first one are holes in the polygon, so they wouldn't affect the outer bounds. – Michael Geary Jan 30 '18 at 12:01
  • Also do you really want to call `map.fitBounds(bounds)` repeatedly like that? I would expect that you'd want to call it only once, after the loop exits and you've accumulated the bounds. – Michael Geary Jan 30 '18 at 12:04
  • @MichaelGeary the first path doesn't **have** to be the outer boundary (although, from the `DrawingManager`, it will be, and there will only be one path, ever, so it isn't particularly relevant) – geocodezip Jan 30 '18 at 14:13
  • _the first path doesn't **have** to be the outer boundary_ Oh, that is interesting and a bit scary. For some reason I assumed it was like [GeoJSON](https://tools.ietf.org/html/rfc7946#section-3.1.6) where the outer ring must be first. Bad assumption on my part, thanks for the correction! It's an interesting comparison that [`Data.Polygon`](https://developers.google.com/maps/documentation/javascript/datalayer) does require the outer ring to be first, but it makes sense since it uses GeoJSON for its data format. – Michael Geary Jan 30 '18 at 22:28
0

While it's not documented here: https://developers.google.com/maps/documentation/javascript/reference/polygon

The Google Maps API for Polygons does have a getBounds() method.

The API documentation should be updated to include:

getBounds()
  Parameters:  None
  Return Value:  LatLngBounds
  Returns the bounds of the Polygon.
\\ define map up here, draw polygons

let bounds = polygon.getBounds();
let rect = new google.maps.Rectangle({
    bounds: bounds,
    map: thisMap
});

the above code produces this

mcmurphy
  • 781
  • 16
  • 30