ポリゴンの中に小さい枠を描画する

ポリゴン内に小さい枠を描画する方法を紹介します。プログラムは3つのステップで構成されています。

  1. ポリゴンのパスを取得して、ポリゴン全体を含む領域を算出する
  2. 上記で得られた領域から、小さい枠を描画する領域を計算する
  3. 小さい枠がポリゴン内に収まるかどうかを判定して、収まる場合は描画する

(1)ポリゴンのパスを取得して、ポリゴン全体を含む領域を算出する

描画されたポリゴンからパスを取得するには、Polygon.getPath()を使います。
getPath()メソッドは、LatLng()クラスの配列(MVCArray)を返すので、その全てをLatLngBounds()に追加することで全体を含む領域を得ることができます。

bounds = new google.maps.LatLngBounds();
paths = polygon.getPath();
paths.forEach(function(latlng, i){
  bounds.extend(latlng);
});


(2)小さい枠を描画する領域を計算する

(1)で得られた領域(bounds)を分割して、小さい枠のサイズを計算します。

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);


(3)小さい枠がポリゴン内に収まるかどうかを判定して、収まる場合は描画する

(2)で得られた小さい枠を描画します。このときポリゴン内に収まるかどうかの判定には、google.maps.geometry.poly.containsLocation()を使用します。
google.maps.geometry.poly.containsLocationを使用するためには、geometryライブラリを読み込むように指定します。

<script src="http://maps.googleapis.com/maps/api/js?sensor=false&libraries=geometry"></script>

小さい枠の四隅の緯度経度を計算し、containsLocation()を使って全て収まる場合のみ描画すると、最終的にポリゴン内に収まる小さい枠のみが描画されます。

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);
  }
}


Code

<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(41.796868, 140.756794),
    mapTypeId : google.maps.MapTypeId.SATELLITE,
    zoom : 16
  });
  
  
  //エンコード化されたパス
  var encodedPath = "uyb~FupbzYqAoK|H{@~FaFjCxInFdGkBlEn@|FeEPmA|EaGsDiIUr@_L";
  var points = google.maps.geometry.encoding.decodePath(encodedPath);
  
  //ポリゴンの描画
  var polygonOpts = {
    paths: points,
    strokeWeight : 6,
    strokeColor : "#FF0000",
    strokeOpacity : 1,
    fillColor: "blue",
    fillOpacity: 0.3,
    map : mapCanvas,
    editable : true
  };
  var poly = new google.maps.Polygon(polygonOpts);
  
  onPolygonComplete(poly);
  
  var proc = function() {
    onPolygonComplete(poly);
  };
  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 onPolygonComplete(polygon) {
  var bounds, paths, sw, ne, ystep, xstep,
      boxH, boxW, posArry, flag, pos,
      x, y, i, box, maxBoxCnt;
  
  //古いboxを削除
  boxes.forEach(function(box, i) {
    box.setMap(null);
    delete box;
  });
  
  //ポリゴンを含む領域を計算する
  bounds = new google.maps.LatLngBounds();
  paths = polygon.getPath();
  paths.forEach(function(latlng, i){
    bounds.extend(latlng);
  });
  
  /*
   * デバッグ用
  new google.maps.Rectangle({
    bounds : bounds,
    map : mapCanvas,
          strokeColor: '#ffff00',
          strokeOpacity: 0.5,
          strokeWeight: 5
  });
  */
  
  //小さい枠のサイズを計算する
  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++) {
      //小さい枠がポリゴン内に収まるかどうかを調べる
      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);
        }
      }
      
      //小さい枠を描画する
      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);
      }
    }
  }
}


google.maps.event.addDomListener(window, "load", initialize);
    </script>

サイト内検索
Google Maps APIプログラミング入門 第2版
Google Maps APIプログラミング入門 第2版
全520ページ。Google Maps API version3を中心に公式ドキュメントより詳しく解説しています。
詳しくはこちら
Google Maps APIプログラミングガイド

Google Maps API Expert 4人が共著で執筆。中級者向けに実用に役立つサンプルを中心に紹介! スマートフォン時代に合わせたGoogle Maps APIの使い方も掲載。
詳しくはこちら