在Google地图上绘制区域中的矩形

时间:2012-11-14 15:10:23

标签: javascript jquery google-maps google-maps-api-3

我正在使用Geometry API在Google地图上绘制一个区域。我想知道是否可以在一个动态大小的区域上绘制重复元素?

例如,如果我将我的区域绘制成如下所示:

enter image description here

然后我希望能够点击“下一步”并看到类似这样的东西,在该区域绘制矩形,但前提是它们适合。即,它们必须是“完整的”矩形,而不是部分矩形:

enter image description here

唯一的问题是,我不完全确定如何解决这个问题。我会使用HTML5 <canvas>但不幸的是,这需要尽可能地符合浏览器,但如果它必须是<canvas>那么就这样吧!

2 个答案:

答案 0 :(得分:14)

虽然我没有使用canvas,但这段代码怎么样?

function onPolygonComplete(polygon) {
  var bounds, paths, sw, ne, ystep, xstep,
      boxH, boxW, posArry, flag, pos,
      x, y, i, box, maxBoxCnt;

  //Delete old boxes.
  boxes.forEach(function(box, i) {
    box.setMap(null);
    delete box;
  });

  //Calculate the bounds that contains entire polygon.
  bounds = new google.maps.LatLngBounds();
  paths = polygon.getPath();
  paths.forEach(function(latlng, i){
    bounds.extend(latlng);
  });


  //Calculate the small box size.
  maxBoxCnt = 8;
  sw = bounds.getSouthWest();
  ne = bounds.getNorthEast();
  ystep = Math.abs(sw.lat() - ne.lat()) / maxBoxCnt;
  boxH = Math.abs(sw.lat() - ne.lat()) / (maxBoxCnt + 1);
  xstep = Math.abs(sw.lng() - ne.lng()) / maxBoxCnt;
  boxW = Math.abs(sw.lng() - ne.lng()) / (maxBoxCnt + 1);

  for (y = 0; y < maxBoxCnt; y++) {
    for (x = 0; x < maxBoxCnt; x++) {
      //Detect that polygon is able to contain a small box.
      bounds = new google.maps.LatLngBounds();
      posArry = [];
      posArry.push(new google.maps.LatLng(sw.lat() + ystep * y, sw.lng() + xstep * x));
      posArry.push(new google.maps.LatLng(sw.lat() + ystep * y, sw.lng() + xstep * x + boxW));
      posArry.push(new google.maps.LatLng(sw.lat() + ystep * y + boxH, sw.lng() + xstep * x));
      posArry.push(new google.maps.LatLng(sw.lat() + ystep * y + boxH, sw.lng() + xstep * x + boxW));
      flag = true;
      for (i = 0; i < posArry.length; i++) {
        pos = posArry[i];
        if (flag) {
          flag = google.maps.geometry.poly.containsLocation(pos, polygon);
          bounds.extend(pos);
        }
      }

      //Draw a small box.
      if (flag) {
        box = new google.maps.Rectangle({
          bounds : bounds,
          map : mapCanvas,
          strokeColor: '#00ffff',
          strokeOpacity: 0.5,
          strokeWeight: 1,
          fillColor: '#00ffff',
          fillOpacity : 0.5,
          clickable: false
        });
        boxes.push(box);
      }
    }
  }
}

此代码的工作方式与此图像类似。 enter image description here

我写了一个解释代码的页面。 http://googlemaps.googlermania.com/google_maps_api_v3/en/poly_containsLocation.html

答案 1 :(得分:7)

@Joshua M

抱歉让你久等了。 好的,新代码如下。 您可以在var boxSize = new google.maps.Size(10, 20);

指定小方框尺寸
<!DOCTYPE html>
<html>
  <head>
    <script src="http://maps.googleapis.com/maps/api/js?sensor=false&libraries=geometry"></script>
    <script type='text/javascript'>
      var mapCanvas, boxes = new google.maps.MVCArray();
      function initialize() {
        var mapDiv = document.getElementById("map_canvas");
        mapCanvas = new google.maps.Map(mapDiv, {
          center : new google.maps.LatLng(37.422191,-122.084585),
          mapTypeId : google.maps.MapTypeId.SATELLITE,
          zoom : 19,
          tilt : 0
        });


        //Encoded path
        var encodedPath = "eblcFnuchVv@D@q@P?a@eD]AC~@b@DCz@a@A";
        var points = google.maps.geometry.encoding.decodePath(encodedPath);

        //Draw a polygon
        var polygonOpts = {
          paths : points,
          strokeWeight : 6,
          strokeColor : "#FF0000",
          strokeOpacity : 1,
          //fillColor : "blue",
          fillOpacity : 0,
          map : mapCanvas,
          editable : true
        };
        var poly = new google.maps.Polygon(polygonOpts);


        var proc = function() {
          onPolygonComplete(poly);
        };
        google.maps.event.addListener(mapCanvas, "projection_changed", proc);
        google.maps.event.addListener(poly.getPath(), 'insert_at', proc);
        google.maps.event.addListener(poly.getPath(), 'remove_at', proc);
        google.maps.event.addListener(poly.getPath(), 'set_at', proc);
      }

      function onDrawMgr_complete(polygon) {
        var path = polygon.getPath();
        console.log(google.maps.geometry.encoding.encodePath(path));
      }

      function onPolygonComplete(polygon) {
        var bounds, paths, sw, ne, ystep, xstep, boxH, boxW, posArry, flag, pos, x, y, i, box;

        //Delete old boxes.
        boxes.forEach(function(box, i) {
          box.setMap(null);
          delete box;
        });

        //Calculate the bounds that contains entire polygon.
        bounds = new google.maps.LatLngBounds();
        paths = polygon.getPath();
        paths.forEach(function(latlng, i) {
          bounds.extend(latlng);
        });

        var projection = mapCanvas.getProjection();
        var zoom = mapCanvas.getZoom();
        var powBase = Math.pow(2, zoom);

        //Calculate the small box size.
        sw = bounds.getSouthWest();
        ne = bounds.getNorthEast();
        var swPoint = projection.fromLatLngToPoint(sw);
        var nePoint = projection.fromLatLngToPoint(ne);
        var boxSize = new google.maps.Size(10, 20); //in pixels.
        boxSize.width /= powBase;
        boxSize.height /= powBase;
        var maxX = Math.floor(Math.abs((swPoint.x - nePoint.x)) / boxSize.width);
        var maxY = Math.floor(Math.abs((swPoint.y - nePoint.y)) / boxSize.height);


        for ( y = 0; y < maxY; y++) {
          for (x = 0; x < maxX; x++) {
            //Detect that polygon is able to contain a small box.
            bounds = new google.maps.LatLngBounds();
            posArry = [];
            posArry.push(new google.maps.Point(swPoint.x + boxSize.width * x, swPoint.y - boxSize.height * y));
            posArry.push(new google.maps.Point(swPoint.x + boxSize.width * x, swPoint.y - boxSize.height * (y + 1)));
            posArry.push(new google.maps.Point(swPoint.x + boxSize.width * (x + 1), swPoint.y - boxSize.height * y));
            posArry.push(new google.maps.Point(swPoint.x + boxSize.width * (x + 1), swPoint.y - boxSize.height * (y + 1)));

            var flag = true;
            for (var i = 0; i < posArry.length; i++) {
              pos = projection.fromPointToLatLng(posArry[i]);
              if (flag) {
                flag = google.maps.geometry.poly.containsLocation(pos, polygon);
                bounds.extend(pos);
              }
            }

            if (flag) {
              box = new google.maps.Rectangle({
                bounds : bounds,
                map : mapCanvas,
                strokeColor : 'green',
                strokeOpacity : 1,
                strokeWeight : 1,
                fillColor : 'yellow',
                fillOpacity : 0.5,
                clickable : false
              });
              boxes.push(box);
            }
          }
        }
      }


      google.maps.event.addDomListener(window, "load", initialize);
    </script>
    <style type="text/css">
      window,html,#map_canvas{
        width : 700px;
        height : 500px;
      }
    </style>
  </head>
  <body>

    <div id="map_canvas"/>
  </body>
</html>

enter image description here