1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

国道走破ゲームを作るために、国道の位置データが欲しい

Last updated at Posted at 2024-08-07

まえがき

qiita含めた、技術ブログ的なものは初投稿です。なにか問題点あれば教えてください。よろしく

動機

  • 国道を走破するゲームを作りたい
    • たぶんまだないし、ニッチな需要がありそう(自分も欲しい)
      image.png
    • youtubeやブログなどのコンテンツとしては存在し、結構人気ある
    • この世界には、確実に国道マニアが存在している
  • どうやって作るか
    • 位置情報からどの道を走っているかを判定することはできる
    • 国道の走破率を計算する必要がある
    • 各国道の位置情報(点の集合)を用意しておいて、現在地と照らし合わせることで走破率を計算できそう
      • ここで問題になるのが、どうやって国道の位置データを取得するか
    • 具体的な実装b(今回の記事には関係なし)
      • 準備
        • 各国道の位置情報を配列としてサーバーに保存しておく
          • 国道1号[始点, ..., 終点]
          • 国道2号[始点, ..., 終点]
            ...
      • 走破率の判定
        1. 現在地を定期的に取得する
        2. 現在地に最も近い国道を求める
        3. 最も近い国道の位置情報配列の中から、最も近い点を探す
        4. 最も近い点との距離が一定値以下ならその点をチェックする
        5. 各国道におけるチェック率を計算する
        • 逐一このプロセスを繰り返すのは微妙なので、バッチ処理したほうがいいかも

ChatGPTにきいてみた

日本の主要な国道の位置情報を取得するためには、国道ごとの経路を示す緯度・経度データのリストが必要です。以下の手順で進めることができます。

  1. オープンデータの利用:
    国土交通省や地理院地図のウェブサイトでは、国道の位置情報が公開されている可能性があります。オープンデータとして提供されているデータセットをダウンロードし、解析することができます。
  2. Google Maps API などの利用:
    Google Maps API を使用して、国道ごとの経路情報を取得できます。国道番号を指定してリクエストを行い、経路を取得し、位置情報を配列として保存することができます。
  3. OpenStreetMap (OSM) データの利用:
    >OSM では道路データがオープンな形で提供されています。OSM の API や Overpass API を利用して、特定の国道の経路データをクエリして取得することが可能です。

ちょっと調べた

  • オープンデータ
  • Google Maps API
    • ちょっと調べた感じ指定した道路を取得するクエリは用意されてなさそう
    • 使いすぎるとお金がかかる
  • OpenStreetMap(以下OSM)
    • 完全無料!
    • Overpass APIでOSMの各種データにアクセスできる
      • 指定した道路のベクターデータも取得できるらしい!
    • これや!

Overpass APIを使ってみる ~失敗~

  • Overpass APIのススメ - Qiita
  • overpass turbo
    • 好きなOverpass APIクエリを投げて、結果を地図上に表示してくれる優れもの
    • 返ってきたjsonデータも見れる
  • Overpass QLというクエリ言語が独特の形式で難しく、ChatGPTにクエリを生成させた
    gptが生成した国道1号を取得するクエリ
    [out:json];
    area["name"="Japan"]->.japan;
    (
      way["highway"="primary"]["ref"="1"](area.japan);
    );
    out body;
    >;
    out skel qt;
    
    レスポンス
    {
      "version": 0.6,
      "generator": "Overpass API 0.7.62.1 084b4234",
      "osm3s": {
        "timestamp_osm_base": "2024-08-07T06:52:30Z",
        "timestamp_areas_base": "2024-08-07T03:37:45Z",
        "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL."
      },
      "elements": [
    
    
    
      ]
    }
    
    • 全然うまくいってない
    • 本来はelementsのところにデータがいろいろ入っているんだろうなあ

ちゃんと調べる

OSMについて

  • これだけで別の記事になってしまうのでなるべく簡潔に
  • そもそも、OSMとは様々な地理情報を自由に追加できる、その名の通りオープンな地図サービスである

OpenStreetMap は地上の物理的な地物(例えば道路や建物)を、基本的なデータ構造(ノード、ウェイ、リレーション)にタグを付与して表現します。各タグで特定のノード、ウェイ、リレーションで表された地物の地理的な属性を記述します。

OSMにおける地理情報のデータ構造

  • Node
    • 地図の基本要素である、緯度経度の座標を持つ単一の点
      • 標識の位置
      • 公衆トイレの位置
  • Way
    • 複数のNodeを順に結んだもの
    • 始点$\neq$終点なら、道路や川のような線状?線形?のデータ
    • 始点$=$終点なら、建物の輪郭や、領域を示すポリゴンデータ
  • Relation
    • 複数のNodeWay、またRelation自体も組み合わせて、より複雑な地物データを表す
      • バスのルート
      • 鉄道路線
      • 大学などの建物群
  • Tag
    • 前述した基本データに対する地理的な属性をタグとして付与
    • key=valueの形
        • highway=residential: 住宅街の道路
        • amenity=school: 学校
        • natural=tree: 木
    • 日本における道路のタグ
      • ここによると、国道を表すタグは、highway=trunkで、その中でもref=numberによって任意の番号の国道を指定できる!

Overpass APIを使ってみる ~成功?~

国道8号線を取得するクエリ
[out:json];
area["name"="日本"]->.searchArea;
(
  way["highway"="trunk"]["ref"="8"](area.searchArea);
);
out body;
>;
out skel qt;
レスポンス
{
  "version": 0.6,
  "generator": "Overpass API 0.7.62.1 084b4234",
  "osm3s": {
    "timestamp_osm_base": "2024-08-07T08:25:00Z",
    "timestamp_areas_base": "2024-08-07T03:37:45Z",
    "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL."
  },
  "elements": [

{
  "type": "way",
  "id": 23634545,
  "nodes": [
    256034652,
    529442479,
    256034651,
    529442478,
    529442477,
    256034648,
    529442476,
    256034647,
    529442475,
    529442474,
    279674072,
    531646732,
    256034646,
    529442463,
    256034645,
    529442460,
    529442459,
    256034644,
    529442461,
    256034643
  ],
  "tags": {
    "highway": "trunk",
    "lanes": "2",
    "layer": "1",
    "name": "国道8号",
    "name:en": "National Highway Route 8",
    "name:ja": "国道8号",
    "ref": "8",
    "source": "YahooJapan/ALPSMAP;GSImaps/std",
    "surface": "paved"
  }
},
//以下"way"が大量に続く
}

なぜgptの生成したクエリではうまくいかなかったか

結果と課題

重複していない国道は取得することができたが、重複区間を取得できなかった。そのため該当区間がどのようなタグを持っているか調べてクエリを改良する必要がある。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?