iOSシミュレータで使えるGPXファイルジェネレータ

出発地と目的地の住所を指定すると、その間のルートをGPXファイルとして書き出すスクリプトを書きました。GPXファイル、使いだすと便利なんだけど、準備するのがちょっと面倒。そんなときに便利です。

実行方法

こんな感じで使えます。

$ python drive.py "東京タワー" "東京スカイツリー" > sample.gpx

作ったファイルはプロジェクトに追加することで、ロケーションシミュレーションのポップアップに表示されますので、選択することで有効になります。


寄り道指定

途中寄り道したいときは、出発地と目的地の間に入れることで指定できます。

$ python drive.py "東京タワー" "湯島天神" "柴又帝釈天" "東京スカイツリー" > sample.gpx

速度の指定が出来ないなどの突っ込みどころはいろいろありますが、位置情報アプリ作っている方は結構便利に使えます。ご意見お聞かせくださいませ。

関連記事: http://d.hatena.ne.jp/basuke/20120903/1346706236

ソースコード

https://gist.github.com/3605355

#
# python drive.py "origin" ["waypoint" ... ] "destination"
#
# i.e. python drive.py "Union Square, San Francisco" "Ferry Building, San Francisco" 'Bay Bridge' SFO

import sys, json, urllib2
from urllib import quote_plus
from xml.sax.saxutils import escape

argv = sys.argv[1:]

origin = argv[0]
destination = argv[-1]

url = "http://maps.googleapis.com/maps/api/directions/json?origin=%s&destination=%s&sensor=false"
url = url % (quote_plus(origin), quote_plus(destination))

if len(argv) > 2:
	url += '&waypoints=' + quote_plus('|'.join(argv[1:-1]))

fp = urllib2.urlopen(url)
data = json.load(fp)

if data.get('status') != 'OK':
	error('Bad data')

route = data['routes'][0]
legs = route['legs']

def namedWaypoint(coordinate, name):
	print '\t<wpt lat="%(lat).6f" lon="%(lng).6f">' % coordinate
	print '\t\t<name>%s</name>' % escape(name.encode('utf-8'))
	print '\t</wpt>'

def waypoint(coordinate):
	print '\t<wpt lat="%(lat).6f" lon="%(lng).6f"/>' % coordinate

def decodePoly(pts):
	step1 = [ord(x) - 63 for x in pts]

	step2, vals = [], []
	for val in step1:
		vals.insert(0, val & 0x1f)
		if val < 0x20:
			val = 0
			for n in vals:
				val = (val << 5) + n
			if val % 2: val = ~(val - 1)
			val /= 2.0
			val /= 100000.0

			step2.append(val)
			vals = []

	step3 = []
	for lat, lng in zip(step2[0::2], step2[1::2]):
		if len(step3) > 0:
			lat += step3[-1]['lat']
			lng += step3[-1]['lng']
		step3.append({'lat':lat, 'lng':lng})

	return step3

def printGPX(legs):
	print '<?xml version="1.0"?>'
	print '<gpx version="1.1" creator="drive.py coded by basuke">'

	namedWaypoint(legs[0]['start_location'], legs[0]['start_address'])

	for leg in legs:
		for step in leg['steps']:
			start = step['start_location']
			end = step['end_location']

			decodePoly(step['polyline']['points'])
			waypoint(start)
			for pt in decodePoly(step['polyline']['points']):
				waypoint(pt)
			waypoint(end)

		namedWaypoint(leg['end_location'], leg['end_address'])

	print '</gpx>'

printGPX(legs)