i-Vinci TechBlog
株式会社i-Vinciの技術ブログ

地図に色々書いてみる

やりたいこと

皆さんこんにちは。i-Vinci TFZ部所属の藤田と申します。
会社内では元自衛官エンジニアとして主に力仕事と専守防衛を担当しています。
今回は、地図上に3Dでオブジェクトを描画すること、に挑戦してみたいと思います。

きっかけ

身近なMapサービスであるGoogle Mapを使って何か3Dで描画できると面白いかなっと、ふと思いました。
(実はお客さんが地図を使ったサービスを展開していて、現状2Dで色々と描画しているけどいずれ3Dで何か書きたくなるよね だって人間だもの ふじを と思ったのはここだけの話)

調査

Google Map APIに3D描画用のAPIとかないか調べたところ、、、

「調査の結果、、、何も得られませんでしたぁ!!!(某調査兵団風)」

Google Mapの機能として、主要都市周辺の建物などを3D描画する機能はあるものの、3Dを描画するためのAPIは提供されていないようです。

実装方針

調査の結果、3D描画のAPIは存在しないことが分かりました。しかし、直線や円などをMap上に描画するAPIは提供されていることが分かりました。
描画したい図形の頂点の緯度・経度を指定することにより、Map上に図形を描画することが出来ます。
また、通常地図は真上から見た鳥観図形式のアングルでブラウザ上に表示されますが、MapOptionとして定義されているtilt(画角とでもいうのでしょうか)を変更することにより、0°もしくは45°のどちらかのアングルを設定できるようです。

以上のことを踏まえて以下の2つの実装方針を考えました。

実装方針1(数学的にまじめな方法)

自分の絵心にほれぼれしますね。
少し補足させていただきます。補足に当たり以下のように用語を定義します。

viewPoint: 「め」と書いてある点
vertex: オブジェクトの各頂点
shadow: viewPointとvertexを通る直線と地面の交点
focusPoint: Map表示時に焦点を合わせている点
T: viewPointの高さ ≒ Mapのzoomレベルに応じた高さ
t: vertexの高さ
W: viewPointからshadowまでの水平距離(厳密には曲面である地表に沿った線の長さ。今回は短距離のため直線とみなす)
w: vertex & shadowからshadowまでの水平距離(厳密には曲面である地表に沿った線の長さ。今回は短距離のため直線とみなす)

横から見た位置関係を見てみましょう。

wを求めることにより、既知のfocusPointからのshadowまでの距離を計算し、その値を用いてshadowの緯度・経度を求めることが出来ます。

T : t = W : w
T : t = (T + Δw + w) : w
w = t(T + Δw) / (T - t)

ここから色々と何か計算することによって、shadowの緯度・経度が求まる気がします。

また、上から見た位置関係を見ると、

shadowとなる点については、viewPointとfocusPointを結ぶ線からそれぞれ∠a、∠bでvertex & shadow 1, 2から距離tの点の緯度・経度を求めるとよさそうです。

……でも、これ絶対大変ですね……
数学的な考慮がさらに必要になりそうです。

実装方針2(ざっくりとそれっぽい方法)

今回の期待値としてですが、実装方針1をまじめにやり精度を追い求めるほどのことは期待していません。なんとなくそれっぽく3Dで描ければ良い、といった感じ。

国土交通省のこのサイトの地図の計測機能をいろいろいじってみたところ、大体100mくらい南北、もしくは東西に距離を取ると、どちらも経緯度において5秒程度の差がありました。
その値を参考にして、例えば20mの高さのオブジェクトの上面のある頂点は、1秒ほど緯度を足して地図上に描画する、といった感じでやってみましょう。

準備

今回の実装では、Google Maps PlatformのMaps JavaScript APIを使用しますが、APIを使用するに当たりGCPアカウントと作成したプロジェクトに紐づくAPI Keyが必要になるようです。Get an API Key
Google Maps PlatformにはいくつかAPIが提供されていますが、有料のものも多く存在します。いうまでもありませんが、作成したAPI Keyの取り扱いには注意しましょう。Restrict API Key

また、実装に当たりnode.jsを使用しています。(version 12.18.0)

実装 - まずは平面から

i-Vinciの本社ビルの近くにi-Vinciの文字を「平面的」に書いてみましょう。

まずは実行結果です。

次にコードと使用したpolygonデータ(geojsonを使用していますが、nodeで読み込ませる関係上jsonとして定義しています。本質的には変わりないです。)

import geoData from './data/gsi20201101220423432.json';

let map: google.maps.Map;

function initMap(): void {
map = new google.maps.Map(document.getElementById("map") as HTMLElement, {
zoom: 17,
center: { lat: 35.693173, lng: 139.761801 },
});

map.data.addGeoJson(geoData);
map.data.setStyle({
fillColor: "orange",
fillOpacity: 0.75
});
}
export { initMap };
使用したpolygonデータ

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "_color": "#000000",
        "_opacity": 0.5,
        "_weight": 3,
        "_fillColor": "#ff9900",
        "_fillOpacity": 0.75
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.756533,
              35.695138
            ],
            [
              139.756522,
              35.694859
            ],
            [
              139.756898,
              35.694833
            ],
            [
              139.756898,
              35.695121
            ],
            [
              139.756533,
              35.695138
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_color": "#000000",
        "_opacity": 0.5,
        "_weight": 3,
        "_fillColor": "#ff9900",
        "_fillOpacity": 0.75
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.7665,
              35.693883
            ],
            [
              139.766564,
              35.692646
            ],
            [
              139.767283,
              35.692681
            ],
            [
              139.766876,
              35.69384
            ],
            [
              139.7665,
              35.693883
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_color": "#000000",
        "_opacity": 0.5,
        "_weight": 3,
        "_fillColor": "#ff9900",
        "_fillOpacity": 0.75
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.756533,
              35.694519
            ],
            [
              139.756544,
              35.693029
            ],
            [
              139.756908,
              35.693003
            ],
            [
              139.756844,
              35.694476
            ],
            [
              139.756533,
              35.694519
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_color": "#000000",
        "_opacity": 0.5,
        "_weight": 3,
        "_fillColor": "#ff9900",
        "_fillOpacity": 0.75
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.758378,
              35.695704
            ],
            [
              139.759247,
              35.692925
            ],
            [
              139.759891,
              35.692925
            ],
            [
              139.761286,
              35.696105
            ],
            [
              139.760513,
              35.696079
            ],
            [
              139.759719,
              35.693535
            ],
            [
              139.758786,
              35.695922
            ],
            [
              139.758378,
              35.695704
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_color": "#000000",
        "_opacity": 0.5,
        "_weight": 3,
        "_fillColor": "#ff9900",
        "_fillOpacity": 0.75
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.757445,
              35.694136
            ],
            [
              139.757445,
              35.693761
            ],
            [
              139.758335,
              35.693753
            ],
            [
              139.758282,
              35.694084
            ],
            [
              139.757445,
              35.694136
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_color": "#000000",
        "_opacity": 0.5,
        "_weight": 3,
        "_fillColor": "#ff9900",
        "_fillOpacity": 0.75
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.761479,
              35.694354
            ],
            [
              139.761425,
              35.694136
            ],
            [
              139.761801,
              35.69411
            ],
            [
              139.761844,
              35.694345
            ],
            [
              139.761479,
              35.694354
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_color": "#000000",
        "_opacity": 0.5,
        "_weight": 3,
        "_fillColor": "#ff9900",
        "_fillOpacity": 0.75
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.761254,
              35.693831
            ],
            [
              139.761028,
              35.693012
            ],
            [
              139.761339,
              35.693012
            ],
            [
              139.761608,
              35.693831
            ],
            [
              139.761254,
              35.693831
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_color": "#000000",
        "_opacity": 0.5,
        "_weight": 3,
        "_fillColor": "#ff9900",
        "_fillOpacity": 0.75
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.762831,
              35.694215
            ],
            [
              139.76252,
              35.692977
            ],
            [
              139.763024,
              35.692942
            ],
            [
              139.763153,
              35.693753
            ],
            [
              139.763646,
              35.693709
            ],
            [
              139.763603,
              35.692977
            ],
            [
              139.763957,
              35.692968
            ],
            [
              139.764065,
              35.694093
            ],
            [
              139.76326,
              35.694136
            ],
            [
              139.763153,
              35.693901
            ],
            [
              139.76312,
              35.69418
            ],
            [
              139.762831,
              35.694215
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_color": "#000000",
        "_opacity": 0.5,
        "_weight": 3,
        "_fillColor": "#ff9900",
        "_fillOpacity": 0.75
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.766039,
              35.69404
            ],
            [
              139.764676,
              35.694084
            ],
            [
              139.764515,
              35.693003
            ],
            [
              139.765931,
              35.692794
            ],
            [
              139.765953,
              35.69316
            ],
            [
              139.765019,
              35.693282
            ],
            [
              139.764998,
              35.693779
            ],
            [
              139.765888,
              35.6937
            ],
            [
              139.766039,
              35.69404
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_color": "#000000",
        "_opacity": 0.5,
        "_weight": 3,
        "_fillColor": "#ff9900",
        "_fillOpacity": 0.75
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.766361,
              35.694702
            ],
            [
              139.766436,
              35.694249
            ],
            [
              139.767058,
              35.69431
            ],
            [
              139.766972,
              35.694746
            ],
            [
              139.766361,
              35.694702
            ]
          ]
        ]
      }
    }
  ]
}

非常に少ないコードでMap上にi-Vinciの文字を描画することが出来ました。
因みに今回使用したgeojsonのデータは、国土交通省が公開しているサイトを利用することで非常に簡単に作成することが出来ます。(別の記事で簡単に紹介したいと思います)国土交通省 国土情報ウェブマッピングシステム

実装 - 3D

では次は3Dでの描画に挑戦してみましょう。
今回表示するi-VinciオブジェクトのMap上のオブジェクトとしての高さは、40mとします。実装方針2で、緯度・経度において100mの差は5秒程度の差になることが分かっていますので、40m = 2秒ほどずらしてあげるといい感じに見えるのではないでしょうか。

まずは実行結果です。
初期表示がこちらです。最初の2D表示の時からZoomレベルとMapタイプを変更しています。

zoom outした状態がこちらです。

どうでしょうか?3Dに見えますでしょうか?
神田の地にi-Vinciの3D文字を刻んでやりました(笑)

では、使用したjsのコードとPolygonデータを見てみましょう。

import lowerGeoData from './data/gsi20201101220423432.json';
import upperGeoData from './data/upper_layer.json';

let map: google.maps.Map;

function initMap(): void {
map = new google.maps.Map(document.getElementById("map") as HTMLElement, {
zoom: 17.5,
center: { lat: 35.693173, lng: 139.761801 },
});

map.setMapTypeId(google.maps.MapTypeId.SATELLITE);
map.setTilt(45);

// オブジェクト(i-Vinciの立体文字列)の底面と上面のPolygonをoverlayに追加
map.data.addGeoJson(lowerGeoData);
map.data.addGeoJson(upperGeoData);
map.data.setStyle({
fillColor: "orange",
fillOpacity: 0.75
});

// オブジェクト(i-Vinciの立体文字列)の側面のpolylineを追加
for (let i = 0; i < lowerGeoData.features.length; i++){
for (let j = 0; j < lowerGeoData.features[i].geometry.coordinates[0].length; j++){
let lp = lowerGeoData.features[i].geometry.coordinates[0][j];
let up = upperGeoData.features[i].geometry.coordinates[0][j];
const line = new google.maps.Polyline({
path: [
{lat: lp[1], lng: lp[0]},
{lat: up[1], lng: up[0]}
],
map: map
});
}
}
}
export { initMap };

Polygonデータはオブジェクトの底面と上面のデータで2つに分けました。

オブジェクト底面のデータ

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "_color": "#000000",
        "_opacity": 0.5,
        "_weight": 3,
        "_fillColor": "#ff9900",
        "_fillOpacity": 0.75
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.756533,
              35.695138
            ],
            [
              139.756522,
              35.694859
            ],
            [
              139.756898,
              35.694833
            ],
            [
              139.756898,
              35.695121
            ],
            [
              139.756533,
              35.695138
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_color": "#000000",
        "_opacity": 0.5,
        "_weight": 3,
        "_fillColor": "#ff9900",
        "_fillOpacity": 0.75
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.7665,
              35.693883
            ],
            [
              139.766564,
              35.692646
            ],
            [
              139.767283,
              35.692681
            ],
            [
              139.766876,
              35.69384
            ],
            [
              139.7665,
              35.693883
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_color": "#000000",
        "_opacity": 0.5,
        "_weight": 3,
        "_fillColor": "#ff9900",
        "_fillOpacity": 0.75
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.756533,
              35.694519
            ],
            [
              139.756544,
              35.693029
            ],
            [
              139.756908,
              35.693003
            ],
            [
              139.756844,
              35.694476
            ],
            [
              139.756533,
              35.694519
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_color": "#000000",
        "_opacity": 0.5,
        "_weight": 3,
        "_fillColor": "#ff9900",
        "_fillOpacity": 0.75
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.758378,
              35.695704
            ],
            [
              139.759247,
              35.692925
            ],
            [
              139.759891,
              35.692925
            ],
            [
              139.761286,
              35.696105
            ],
            [
              139.760513,
              35.696079
            ],
            [
              139.759719,
              35.693535
            ],
            [
              139.758786,
              35.695922
            ],
            [
              139.758378,
              35.695704
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_color": "#000000",
        "_opacity": 0.5,
        "_weight": 3,
        "_fillColor": "#ff9900",
        "_fillOpacity": 0.75
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.757445,
              35.694136
            ],
            [
              139.757445,
              35.693761
            ],
            [
              139.758335,
              35.693753
            ],
            [
              139.758282,
              35.694084
            ],
            [
              139.757445,
              35.694136
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_color": "#000000",
        "_opacity": 0.5,
        "_weight": 3,
        "_fillColor": "#ff9900",
        "_fillOpacity": 0.75
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.761479,
              35.694354
            ],
            [
              139.761425,
              35.694136
            ],
            [
              139.761801,
              35.69411
            ],
            [
              139.761844,
              35.694345
            ],
            [
              139.761479,
              35.694354
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_color": "#000000",
        "_opacity": 0.5,
        "_weight": 3,
        "_fillColor": "#ff9900",
        "_fillOpacity": 0.75
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.761254,
              35.693831
            ],
            [
              139.761028,
              35.693012
            ],
            [
              139.761339,
              35.693012
            ],
            [
              139.761608,
              35.693831
            ],
            [
              139.761254,
              35.693831
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_color": "#000000",
        "_opacity": 0.5,
        "_weight": 3,
        "_fillColor": "#ff9900",
        "_fillOpacity": 0.75
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.762831,
              35.694215
            ],
            [
              139.76252,
              35.692977
            ],
            [
              139.763024,
              35.692942
            ],
            [
              139.763153,
              35.693753
            ],
            [
              139.763646,
              35.693709
            ],
            [
              139.763603,
              35.692977
            ],
            [
              139.763957,
              35.692968
            ],
            [
              139.764065,
              35.694093
            ],
            [
              139.76326,
              35.694136
            ],
            [
              139.763153,
              35.693901
            ],
            [
              139.76312,
              35.69418
            ],
            [
              139.762831,
              35.694215
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_color": "#000000",
        "_opacity": 0.5,
        "_weight": 3,
        "_fillColor": "#ff9900",
        "_fillOpacity": 0.75
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.766039,
              35.69404
            ],
            [
              139.764676,
              35.694084
            ],
            [
              139.764515,
              35.693003
            ],
            [
              139.765931,
              35.692794
            ],
            [
              139.765953,
              35.69316
            ],
            [
              139.765019,
              35.693282
            ],
            [
              139.764998,
              35.693779
            ],
            [
              139.765888,
              35.6937
            ],
            [
              139.766039,
              35.69404
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_color": "#000000",
        "_opacity": 0.5,
        "_weight": 3,
        "_fillColor": "#ff9900",
        "_fillOpacity": 0.75
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              139.766361,
              35.694702
            ],
            [
              139.766436,
              35.694249
            ],
            [
              139.767058,
              35.69431
            ],
            [
              139.766972,
              35.694746
            ],
            [
              139.766361,
              35.694702
            ]
          ]
        ]
      }
    }
  ]
}
オブジェクト上面のデータ

{
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "properties": {
                "_color": "#000000",
                "_opacity": 0.5,
                "_weight": 3,
                "_fillColor": "#ff9900",
                "_fillOpacity": 0.75
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            139.756533,
                            35.695338
                        ],
                        [
                            139.756522,
                            35.695059
                        ],
                        [
                            139.756898,
                            35.695033
                        ],
                        [
                            139.756898,
                            35.695321
                        ],
                        [
                            139.756533,
                            35.695338
                        ]
                    ]
                ]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "_color": "#000000",
                "_opacity": 0.5,
                "_weight": 3,
                "_fillColor": "#ff9900",
                "_fillOpacity": 0.75
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            139.7665,
                            35.694083
                        ],
                        [
                            139.766564,
                            35.692846
                        ],
                        [
                            139.767283,
                            35.692881
                        ],
                        [
                            139.766876,
                            35.69404
                        ],
                        [
                            139.7665,
                            35.694083
                        ]
                    ]
                ]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "_color": "#000000",
                "_opacity": 0.5,
                "_weight": 3,
                "_fillColor": "#ff9900",
                "_fillOpacity": 0.75
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            139.756533,
                            35.694719
                        ],
                        [
                            139.756544,
                            35.693229
                        ],
                        [
                            139.756908,
                            35.693203
                        ],
                        [
                            139.756844,
                            35.694676
                        ],
                        [
                            139.756533,
                            35.694719
                        ]
                    ]
                ]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "_color": "#000000",
                "_opacity": 0.5,
                "_weight": 3,
                "_fillColor": "#ff9900",
                "_fillOpacity": 0.75
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            139.758378,
                            35.695904
                        ],
                        [
                            139.759247,
                            35.693125
                        ],
                        [
                            139.759891,
                            35.693125
                        ],
                        [
                            139.761286,
                            35.696305
                        ],
                        [
                            139.760513,
                            35.696279
                        ],
                        [
                            139.759719,
                            35.693735
                        ],
                        [
                            139.758786,
                            35.696122
                        ],
                        [
                            139.758378,
                            35.695904
                        ]
                    ]
                ]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "_color": "#000000",
                "_opacity": 0.5,
                "_weight": 3,
                "_fillColor": "#ff9900",
                "_fillOpacity": 0.75
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            139.757445,
                            35.694336
                        ],
                        [
                            139.757445,
                            35.693961
                        ],
                        [
                            139.758335,
                            35.693953
                        ],
                        [
                            139.758282,
                            35.694284
                        ],
                        [
                            139.757445,
                            35.694336
                        ]
                    ]
                ]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "_color": "#000000",
                "_opacity": 0.5,
                "_weight": 3,
                "_fillColor": "#ff9900",
                "_fillOpacity": 0.75
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            139.761479,
                            35.694554
                        ],
                        [
                            139.761425,
                            35.694336
                        ],
                        [
                            139.761801,
                            35.69431
                        ],
                        [
                            139.761844,
                            35.694545
                        ],
                        [
                            139.761479,
                            35.694554
                        ]
                    ]
                ]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "_color": "#000000",
                "_opacity": 0.5,
                "_weight": 3,
                "_fillColor": "#ff9900",
                "_fillOpacity": 0.75
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            139.761254,
                            35.694031
                        ],
                        [
                            139.761028,
                            35.693212
                        ],
                        [
                            139.761339,
                            35.693212
                        ],
                        [
                            139.761608,
                            35.694031
                        ],
                        [
                            139.761254,
                            35.694031
                        ]
                    ]
                ]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "_color": "#000000",
                "_opacity": 0.5,
                "_weight": 3,
                "_fillColor": "#ff9900",
                "_fillOpacity": 0.75
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            139.762831,
                            35.694415
                        ],
                        [
                            139.76252,
                            35.693177
                        ],
                        [
                            139.763024,
                            35.693142
                        ],
                        [
                            139.763153,
                            35.693953
                        ],
                        [
                            139.763646,
                            35.693909
                        ],
                        [
                            139.763603,
                            35.693177
                        ],
                        [
                            139.763957,
                            35.693168
                        ],
                        [
                            139.764065,
                            35.694293
                        ],
                        [
                            139.76326,
                            35.694336
                        ],
                        [
                            139.763153,
                            35.694101
                        ],
                        [
                            139.76312,
                            35.69438
                        ],
                        [
                            139.762831,
                            35.694415
                        ]
                    ]
                ]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "_color": "#000000",
                "_opacity": 0.5,
                "_weight": 3,
                "_fillColor": "#ff9900",
                "_fillOpacity": 0.75
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            139.766039,
                            35.69424
                        ],
                        [
                            139.764676,
                            35.694284
                        ],
                        [
                            139.764515,
                            35.693203
                        ],
                        [
                            139.765931,
                            35.692994
                        ],
                        [
                            139.765953,
                            35.69336
                        ],
                        [
                            139.765019,
                            35.693482
                        ],
                        [
                            139.764998,
                            35.693979
                        ],
                        [
                            139.765888,
                            35.6939
                        ],
                        [
                            139.766039,
                            35.69424
                        ]
                    ]
                ]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "_color": "#000000",
                "_opacity": 0.5,
                "_weight": 3,
                "_fillColor": "#ff9900",
                "_fillOpacity": 0.75
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            139.766361,
                            35.694902
                        ],
                        [
                            139.766436,
                            35.694449
                        ],
                        [
                            139.767058,
                            35.69441
                        ],
                        [
                            139.766972,
                            35.694946
                        ],
                        [
                            139.766361,
                            35.694902
                        ]
                    ]
                ]
            }
        }
    ]
}

オブジェクトの側面については、底面と上面のデータから側面の辺を形成する点を指定し、Polylineとして描画しています。そのためMap上ではオブジェクトの側面は色なしの透明な面として描画しています。

まとめと今後の課題

Google Maps PlatformのMaps JavaScript APIを使用することで、無事、3D(っぽい)オブジェクトをMap上に描画することが、非常に簡単に出来ました。
今後の課題としては以下のような点があります。
1. 立体としての描画が正確でない
2. 視点(viewPoint)を水平方向や上下方向に移動した場合に、立体の見え方が変化しない≒shadowとなる点が移動しない
3. ZoomOutした場合に、立体の見え方が変化しない≒shadowとなる点が移動しない

上記3点を解決することで、さらに立体に見えるオブジェクトをMap上に描画することが出来るようになるはずです。
今後の課題として取り組みたいと思います。

今回作成したコードはこちら