7
4

More than 3 years have passed since last update.

MapboxのMap Matching APIでGPSデータを補正するツールを作成しました(Mapbox Map Matching API)

Last updated at Posted at 2020-06-13

目的

MapboxMap Matching APIを用いて、GPSデータを補正するツールを作成してみました。

Map Matching API

  • MapboxのAPIのうち、Navigation serviceに分類されるMap Matching APIを使用しています。
  • Map Matching APIは、誤差が含まれるGPSデータ(緯度、経度)を道路ネットワーク上にスナップし、確からしい位置に補正するAPIになります。

実行環境

  • この記事ではPython3、MapboxのMap Matching APIを使用しています。
  • MapboxのMap Matching APIを使用するには、Access Tokensが必要になります。
  • Mapboxのサイトよりアカウントを登録すると、自動的に Access Tokens が発行されます。
  • このAccess Tokensを使用し、各種APIをコールすることができます。
  • Mapbox は、従量課金になるので詳しい料金体系についてはMapboxの Pricing ページをご確認ください。
  • なお、毎月50,000リクエストまでは無料枠が設定されていますので、大量にリクエストしなければ課金されることはありません。

前提条件

使用データ

  • 使用データは、マラソン大会走行時に手首に装着したGarminウォッチで取得したGPSデータを用います。
  • GPSデータは、適宜、ご用意ください。

実行方法

入力設定

  • 入力CSVファイルにGPSデータ(緯度、経度)を入力してください。

image.png

実行

  • 入力CSVファイル、出力CSVファイル、api_token(Access Tokens)を入力してください。
  • 「Map Matching API URL」は、変更しないでください。
  • Pythonスクリプトを実行してください。
MapboxMapMatchingAPI.py
import os
import csv
import json
import datetime
import time
import configparser
import requests

# 入力CSVファイル指定
input_csvfile = "入力CSVファイルを入力してください。"

# 出力CSVファイル指定
output_csvfile = "出力CSVファイルを入力してください。"

# Map Matching API URL※変更しないでください。
api_url = "https://api.mapbox.com/matching/v5/mapbox/driving/"

# Mapbox Access token
api_token = "Access tokenを入力してください。"

# 作業用リスト
data = []
wklst = []

# 入力CSVファイルを作業用リストへセット
with open(input_csvfile) as f:
    #ヘッダー行をスキップ
    h = next(csv.reader(f))
    for v in csv.reader(f):
        data.append(v)

for i in range(len(data) -1):
    wklst.append([data[i][0],data[i][1],data[i+1][0],data[i+1][1]])

# print(wklst)

# 出力CSVファイルの存在チェック(ヘッダー有無の判断)
if(os.path.exists(output_csvfile)):
    header_flg = 0
else:
    header_flg = 1

# 作業用リストよりMap Matching APIへリクエストし、結果を出力CSVファイルに書き込む
with open(output_csvfile, 'a', encoding='shift_jis') as output_csvfile_fp:

    fieldnames = ['bef_lat','bef_lng','aft_lat','aft_lng']
    csvfile_writer = csv.DictWriter(output_csvfile_fp, fieldnames=fieldnames,lineterminator='\n')

    # 出力CSVファイル新規作成時、ヘッダー出力
    if header_flg == 1:
        csvfile_writer.writeheader()
        header_flg == 0

    print(len(wklst))
    for i in range(len(wklst)):
        # print(wklst[i])
        # Map Matching APIのパラメータ生成
        origins = wklst[i][1] + ','+ wklst[i][0]
        destinations = wklst[i][3] + ','+ wklst[i][2]
        params = {
            'radiuses':'50;50',
            'access_token': api_token
            }
        # Map Matching APIにリクエスト
        raw_response = requests.get(api_url + origins + ';' + destinations, params)
        parsed_response = json.loads(raw_response.text)
        parsed_response_json = json.dumps(parsed_response, indent=4)
        # print(parsed_response_json)
        breakpoint

        # JSONから要素を取り出す
        if parsed_response['code'] == 'Ok':
            lng1 = parsed_response['tracepoints'][0]['location'][0]
            lat1 = parsed_response['tracepoints'][0]['location'][1]
            lng2 = parsed_response['tracepoints'][1]['location'][0]
            lat2 = parsed_response['tracepoints'][1]['location'][1]
        else:
            lng1 = None
            lat1 = None
            lng2 = None
            lat2 = None

        # 出力CSVファイルに書き込み
        csvfile_writer.writerow({
            'bef_lat': wklst[i][0],
            'bef_lng': wklst[i][1],
            'aft_lat': lat1,
            'aft_lng': lng1
            })

        print(wklst[i][0],wklst[i][1],lat1,lng1)

print(u'処理終了')

実行結果

  • 補正前のGPSデータ(緯度、経度)は、1列目と2列目になります。
  • 補正後のGPSデータ(緯度、経度)は、3列目と4列目になります。

image.png

  • 実行結果をQGISで可視化すると以下のようになります。
  • 青いポイントが補正前のGPSデータ(緯度、経度)、赤いポイントが補正後のGPSデータ(緯度、経度)になります。
  • 補正前は道路上から外れていた青いポイントが、補正後は道路上にスナップされ、確からしい位置(赤いポイント)に補正されています。

image.png

※背景地図には、国土地理院の地理院タイル(淡色地図)を使用しています。

留意事項

※無料枠を超えてAPIを使用すると課金されますのでご注意ください(>_<)

7
4
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
7
4