LoginSignup
19
26

More than 5 years have passed since last update.

OSSルーティングエンジン「GraphHopper」と戯れてみた

Posted at

モチベーション

位置情報ログの分析・解析用途でルーティングエンジンを活用してみたい!

  • ユーザーの経路検索ログを可視化
  • GPSログの経路マッチング
  • ネットワークベースの到達圏解析
  • etc...

OSSルーティングエンジン

いろいろ調べた結果、結局 OpenStreetMap Wiki にまとめられている情報にたどり着いた。
https://wiki.openstreetmap.org/wiki/Routing

image

気になったプロダクトは以下。

  • pgRouting
  • GraphHopper
  • Open Source Routing Machine
  • Valhalla

その中で、今回は GraphHopper と戯れてみたというお話。

GraphHopper とは

image
https://github.com/graphhopper/graphhopper

  • Java実装のOSSルーティングエンジン
  • OSMデータ(OpenStreetMapデータ)からネットワークデータを生成して動作する
    • 他データ形式もそれ用のインポートツールがあれば対応される
  • 動作要件は「JRE (Java 7+) がインストールされていること」のみ
    • ただしネットワークデータを展開するだけのメモリ領域は必要
    • また起動スクリプトのリモートOSMファイル取得で wget コマンドを利用
  • 「とりあえず動かしてみる」までの敷居が低かったので手始めに触ってみた

Getting Started

ドキュメントのインストラクションに従う。
https://github.com/graphhopper/graphhopper/blob/0.8/docs/core/quickstart-from-source.md

ソースコードの取得と、最新安定版へのチェックアウト。

$ git clone git://github.com/graphhopper/graphhopper.git
$ cd graphhopper; git checkout 0.8

プロジェクトルートにある graphhopper.sh でビルド、OSMデータの取得、OSMデータからネットワークデータの生成、アプリケーションの起動まで面倒みてくれる。

$ ./graphhopper.sh web europe_germany_berlin.pbf

OSMデータがローカルになければリモートから取得してくれる。
ダイアログが表示されるので、そのまま ENTER を押下でOSMデータがダウンロードされる。

## using java 1.8.0_111 (64bit) from 
File not found 'europe_germany_berlin.pbf'. Press ENTER to get it from: http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf
Press CTRL+C if you do not have enough disc space or you don't want to download several MB.

OSMデータのダウンロードが完了するとネットワークデータの生成が始まる。データ量によってそこそこ時間がかかる。
最後にWebアプリケーションの起動ログが出力されればOK(HTTP :8989と起動ポートが表示される)。

:
2016-11-02 19:08:43,186 [main] INFO  com.graphhopper.http.GHServer - Started server at HTTP :8989

http://localhost:8989/ にアクセスするとWebアプリケーションで確認可能。

image

日本のエリアでアプリケーションを動かすには、以下コマンドで。メモリを 2000m (デフォルトだと 1000m )で確保しないと OutOfMemory となったので JAVA_OPTS で指定している。

$ JAVA_OPTS="-Xmx2000m -Xms2000m -server" ./graphhopper.sh web asia_japan.pbf

image

意外とジオコーダーっぽいものも動いている :raised_hands:

Web API

もちろん、 HTML ページではなく Web API のインターフェースも用意されている。ドキュメントは以下。
https://github.com/graphhopper/graphhopper/blob/0.8/docs/web/api-doc.md

image

「田町駅」から「駒場東大前」までのルートレスポンスは以下の通り。
http://localhost:8989/route?point=35.645736,139.747683&point=35.658902,139.683363&points_encoded=false&instructions=false&debug=true

{
  "hints": {
    "visited_nodes.average": "234.0",
    "visited_nodes.sum": "234"
  },
  "paths": [{
    "descend": 0,
    "ascend": 0,
    "distance": 9681.893,
    "bbox": [
      139.682723,
      35.645041,
      139.748104,
      35.665978
    ],
    "weight": 479.639483,
    "time": 479630,
    "points_encoded": false,
    "points": {
      "coordinates": [
        [
          139.747846,
          35.646186
        ],
        [
          139.748058,
          35.646301
        ],
        [
          139.748089,
          35.646341
        ],
        :
        (省略)
        :
        [
          139.683392,
          35.658996
        ]
      ],
      "type": "LineString"
    },
    "snapped_waypoints": {
      "coordinates": [
        [
          139.747846,
          35.646186
        ],
        [
          139.683392,
          35.658996
        ]
      ],
      "type": "LineString"
    }
  }],
  "info": {
    "took": 11,
    "copyrights": [
      "GraphHopper",
      "OpenStreetMap contributors"
    ]
  }
}

WebAPI経由で他プログラムから経路検索

Ruby で Web API を叩いて、結果を GeoJSON 形式で吐き出すプログラムを書いてみた。

to_geojson.rb
require 'net/http'
require 'json'

# INPUT
start_point = "35.645736,139.747683"
end_point = "35.658902,139.683363"

# リクエスト
uri = URI.parse('http://localhost:8989/route')
uri.query = URI.encode_www_form({
  point: [start_point, end_point],
  points_encoded: "false",
  instructions: "false",
  debug: "true",
})
res = Net::HTTP.get_response(uri).body

# GeoJSONに変換
res_json = JSON.parse(res)
coordinates = res_json["paths"][0]["points"]["coordinates"]
geojson = {
  type: "FeatureCollection",
  features: [
    {
      type: "Feature",
      geometry: {
        type: "LineString",
        coordinates: coordinates,
      }, 
      properties: {
        "stroke": "#FF0000",
        "stroke-opacity": 0.8,
        "stroke-width": 5,
      },
    }
  ]
}

# 出力
puts JSON.pretty_generate geojson

以下な感じで実行して結果をファイル出力。

$ ruby to_geojson.rb > route.geojson

この出力した GeoJSON ファイルを GitHub にコミットすればプレビューされる。

image

GraphHopper 所感

  • OSMデータのサイズでダウンロードおよびネットワークデータの展開はそこそこ時間がかかる
  • データ処理時間を除けば「とりあえず触ってみる」の敷居は低いっぽい
  • デフォルトだと車の経路検索となる、歩行者の経路検索を行う設定カスタマイズを確認したい
  • 経路マッチングを行う map-matching なるプロダクトもあり、これも試したい
  • 位置情報ログの分析・解析用途に利用するにはこれでいい感じっぽい :thumbsup:

今後の展開

  • GraphHopperの設定カスタマイズや map-matching などの機能を試して、分析・解析用途の幅を広げたい
  • 他のルーティングエンジンも評価して、それぞれの特徴や強みなどを整理したい
19
26
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
19
26