GUNMA GIS GEEK

群馬県の片隅でオープンデータとデータビジュアライゼーションとGIS(地理情報システム)に戯れるエンジニアのブログ。

*

「ポケモンGOみたいなゲーム作って〜」と言われたときのために、巨人(Google)の力をかりて、道路上にランダムにマーカーを設置する。

     - Google Map API, leaflet.js

  • このエントリーをはてなブックマークに追加

道路上のマーカー

そろそろ、世間では「ポケモンGOみたいの作ってー作ってー」という無茶振りと、それに伴うエンジニアの悲鳴が聞こえてくる季節が近づいてきたかと思います。そこで、いつそんな無茶振りが来ても対応できるように、位置情報を用いたゲームを作る際の高いハードル「人が行ける場所にモンスターを配置する」という難問をグーグル様のお力を利用して、とりあえず形だけでもなんとか取り繕ってみたいと思います。

一応言っておきますと……あんまり、実用的ではないですよ。

ランダムに緯度経度を生成する

まず、手始めに日本が収まる範囲に限定してランダムに1000件の緯度経度を生成します。
turf.jsを使用するとランダムなポイントデータをgeojsonとして簡単に生成できます。

生成したgeojsonをマーカーとして地図上に表示したのが以下となります。

ランダムに生成された1000件のマーカー

ランダムに生成されてはいますが、海の上など不要な場所に大量にマーカーが配置されてしまいました。次のフェーズでは、日本列島以外に配置された不要なマーカーを除去します。

日本列島上の位置情報のみ残してほかを消す

不要な緯度経度データをそぎ落とし、 日本列島上に収まるデータだけを取り出してみます。
turf.jsには、ポイントデータが特定のポリゴン内に含まれているかどうかを判別するためのメソッドがあるので、大まかな日本列島のアウトラインをポリゴンとして生成し、そのポリゴン内に含まれているかどうかを条件としてフィルタリングを行います。

・アウトラインポリゴン
日本列島アウトライン | Github Gist
japan_outline 2016-08-05 20-38-44

上記、geojsonを読み込み先ほど生成したマーカー群とのマッチングを行います。

フィルタリング後の緯度経度を地図上にマーカーとして表示すると以下となります。

日本列島上のみに絞り込んだマーカー

道路上の緯度経度のみを選ぶ

さて、ここからが本番です。
海上に配置されていたマーカーは綺麗さっぱり消すことができましたが、今のままでは、山の上だったり川の中だったりと、人の行けないような場所にもたくさんのマーカーが設置されてしまっています。
この中から、道路上に配置されたマーカーのみを残す、あるいは近くの道路までマーカーを移動するにはどうしたらよいでしょうか?

なかなかの難問ですが、Google様の力を利用することで一部解決できます。

キーとなるのは「ストリートビューAPI」

ストリートビューを表示する以外にも、非常に便利な機能が詰まったこのAPIを使って、ランダムに生成された緯度経度から道路上の緯度経度を取得します。

StreetViewServiceクラスが持つ、getPanoramaByLocationメソッドは、特定の緯度経度から指定した半径(下記では100m)以内にストリートビューに対応したポイントがないかを検索し、対応しているポイントがあればその緯度経度を返します。
このメソッドに、残りの緯度経度データを全て突っ込んで、手当たりしだいに検索リクエストを投げます。
getPanoramaByLocationのレスポンスに含まれる緯度経度は、ストリートビューに対応した「人が訪れることができる場所」として別途保存します。

ちなみに、getPanoramaByLocationメソッドは非同期処理になるので、プロミスで包んで最後にまとめて取得しています。

上記の方法でフィルタリングした緯度経度を地図上に表示したのが以下。だいぶ数が減ってしまいましたが、表示されているマーカーは、すべて人が行ける場所(ほとんどが道路上)に配置されています。

道路上にマッピングしたマーカー

マーカーにはクリックすると、その位置へズームするイベントがバインドされていますので、正しく配置されているか確認してみてください。

道路上のマーカー

サンプルコード

更新されるたびにランダムにマーカーを設置します。
APIの制限数を越えると設置されなくなります。
example

まとめ

最初に生成する緯度経度の数を増やせば、最終的に取得できる数も増えるわけですが、その分Streetviewへのリクエストも増えるので注意してください。今回はAPIの無料制限(1日2500リクエスト)の範囲で収まるように少なめの数で生成しています。

 - Google Map API, leaflet.js

  • このエントリーをはてなブックマークに追加

  関連記事

no image
[GMaps API v3] カスタムコントロール内の要素にイベントリスナーを設定できない場合の対応

予想外のところで引っかかったので、とりあえずメモ。 Google Maps AP …

GMPSAPI geojson(ポリゴン)読み込み
Google Map上にGeoJSONデータを表示する

Google、地図アプリのデベロッパー向けJavaScript APIでGeoJ …

leaflet-def
ハイクオリティでちょーかっこいいデータ視覚化地図が作れる「Leaflet-dvf」

「Leaflet-dvf」は、ベース地図にLeaflet.jsを用い、地理情報を …

Proj4js
Google Maps APIで緯度経度を元にプロットしたマーカーの位置がずれる(測地系変換)

某社のAPIから取得した物件データの緯度経度を元にGoogle Map上にプロッ …

重み付けボロノイ図
【D3.js】重み付けボロノイ図

example 重み付けボロノイ図のサンプルを作った。 通常のボロノイ図は母点間 …

Antique shop
Leaflet.jsで画像を表示する

先日の「社寺参詣曼荼羅」が面白い。の記事で、曼荼羅画像をLeaflet.jsを使 …

leaflet エリア選択
Leafletで任意のエリアを選択するUIプラグイン

いわゆる「Bounding Box」とか呼ばれる奴です。 example ホント …

test000009
【D3.js】地図上に四分木を描く

example 以前、地図上にボロノイ図を描いてみましたが、今回は四分木を描いて …

streetview000001
[GMaps API v3] ストリートビューを使う。

ストリートビュー、27市町村も対象に グーグル 群馬 グーグル グッジョブ! ( …

日本の地形地図
日本の典型地形情報をGoogleの地形図の上に重ねてみた。

「日本の典型地形ウェブサイト」をリニューアル ~地理院地図との連携でより分かりや …