GUNMA GIS GEEK

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

*

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

     - Google Map API, leaflet.js, turf.js

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

道路上のマーカー

そろそろ、世間では「ポケモン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リクエスト)の範囲で収まるように少なめの数で生成しています。

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

 - Google Map API, leaflet.js, turf.js

  関連記事

前橋市 平成22年男女別・年齢別人口構成
前橋市には、男子より女子の方が多く住んでいる。

example 男子の人口を、女子の人口が上回る地域が多数。 概要 前橋市オープ …

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

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

github_geojson_search
GithubからGeoJSONを検索して地図上に表示するページを作ってみました。

example Google Custom Search APIを使って、Git …

turf.js along
[Turf.js]ラインに沿って任意の距離を移動する

example スライダーで選択した距離だけ各ライン上に沿ってマーカーが移動しま …

leaflet css fiter
[leaflet]クライアントサイドでの画像処理を可能にする「tilefilter」プラグイン

Home · humangeo/leaflet-tilefilter Wiki …

ベクトルタイルマップ
[D3+Leaflet]国土地理院さん渾身のベクトルタイルで遊んでみた。

ベクトルタイルの提供実験について|国土地理院 FOSS4G 2014 Hokka …

Google Map上に画像を配置する

example 群馬県警察で公開されている「犯罪発生マップ(画像)」をGoogl …

手書き風地図
Leaflet.jsとD3.jsを使って手書き風の地図を表示する

実用性はありません。あとIEで動きません。 example スライダーを右に移動 …

Delaunay triangulation
【D3.js】ドロネー三角分割図を作成してみた

example ボロノイ図と対になるドロネー図をGoogle Map上に表示して …

Excel2Gmap
「E2D3」を使ってExcel上にGoogle Mapsを表示してみた。

昨日に引き続き「E2D3」を弄ってます。 Google Maps表示してみた 昨 …