先日、ちょっと札幌に行ってきました。
少し時間があったので、嫁が行きたいと言ってた西松屋に行くことにしました。
しかし、札幌の地理がよくわからないので、西松屋店舗案内をみても、どこが近いのかよくわからないのです。
じゃぁ、グーグルマップにマーカーたてちゃおう!
もちろんpythonから。
1.データの準備
lxml・・・ほどのものはないので、ブラウザからコピペして、名前、住所、他を抽出します。
[text]
旭川永山店 旭川市永山二条4丁目1-20 (0166)46-2832 AM10:00~PM8:00
…
[/text]
こんなのが沢山ある感じ。
これを適当にsplitして住所を触れるようにする。
2.google maps api
次に、google maps api web serviceを使って緯度経度を取得する。
こんな感じでアクセスするとjsonで位置情報を返してくれる。
[text]
http://maps.googleapis.com/maps/api/geocode/json?address=%E5%8C%97%E6%B5%B7%E9%81%93&sensor=false&language=ja
[/text]
[text]
{
"results" : [
{
"address_components" : [
{
"long_name" : "北海道",
"short_name" : "北海道",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "日本",
"short_name" : "JP",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "日本, 北海道",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 45.52302160,
"lng" : 146.36840770
},
"southwest" : {
"lat" : 41.35212590,
"lng" : 139.33429950
}
},
"location" : {
"lat" : 43.06461470000001,
"lng" : 141.34680740
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 45.11592539999999,
"lng" : 145.44470790
},
"southwest" : {
"lat" : 40.94229570,
"lng" : 137.24890690
}
}
},
"types" : [ "administrative_area_level_1", "political" ]
}
],
"status" : "OK"
}
[/text]
というわけで、これを使って1のデータの住所から緯度経度を取得しまくる。
3.HTML出力。テンプレートを使ってみる jinja2
Flaskなどで使われているテンプレートエンジン jinja2 を使って、2で取得した緯度経度を出力します。
tmpl.html
[html]
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3&sensor=false"></script>
<script type="text/javascript">
var map;
var g_infowindow = null;
var markers = new Array(
{% for item in items %}
{ name: "{{item.name}}",
latlng: new google.maps.LatLng({{item.lat}}, {{item.lng}}),
content: "{{item.content}}"
}{{ "," if not loop.last }}
{% endfor %}
);
function initialize() {
if (markers.length == 0){
return false;
}
var myOptions = {
zoom: 10,
center: markers[0]["latlng"],
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
for (i=0; i<markers.length; i++){
make_marker(map,
markers[i]["name"],
markers[i]["latlng"],
markers[i]["content"]
);
}
}
function make_marker(map, name, latlng, content){
var marker = new google.maps.Marker({
position:latlng,
map:map,
title:name,
draggable:false
});
var infowindow = new google.maps.InfoWindow({
content: content
});
google.maps.event.addListener(marker, ‘click’, function(event){
if (g_infowindow) g_infowindow.close()
infowindow.open(map, marker);
g_infowindow = infowindow;
});
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width:100%; height:100%"></div>
</body>
</html>
[/html]
このhtmlファイルのテンプレートの部分はmarkersの宣言だけです・・・。
テンプレート使う意味はほぼありませんが、Flaskなしでjinja2を使ってみたかったんです。
このテンプレートを使う処理は以下のような感じです。
[python]
from jinja2 import Template
# data にデータのリストがあるとする。
# テンプレートを読み込む
with open("tmpl.html", "r") as f:
template = Template(f.read().decode(‘utf-8’))
# テンプレート変数を使って描画
html = template.render(items=data)
# できあがったhtmlを書き込み。
with open("output.html", "w") as f:
f.write(html.encode(‘utf-8’))
[/python]
別のgoogle maps apiを使う方法
google maps api web serviceを使わなくても、google.maps.Geocoderを使えばjavascriptで住所から緯度経度を取得できます。
[javascript]
geocoder = new google.maps.Geocoder();
geocoder.geocode({address: "住所"}, callback_function);
[/javascript]
geocodeに渡す住所のリストを回して、geocodeを呼んで、コールバックでマーカー作ってもOKです。
こっちの方だとpythonでやることはほとんどない。
(まぁ、そもそも最初からpythonを使う必要なんてなかったけど。)
できあがったのはこんな感じ
最終的に東店が近かったので行ってきました。
目当ての物はなかったみたいですけどね!
参考
- Template Designer Documentation — Jinja2 2.7-dev documentation(jinja2 for)
- 店舗案内|西松屋チェーン
- Google Maps JavaScript API V3 のイベント – Google Maps JavaScript API V3 – Google Code
- Maps API V3 サービス – Google Maps API Version3 日本語ドキュメント(非公式)
- The Google Geocoding API – Google Maps API Web Services – Google Code
- Geekなぺーじ:住所を使って緯度経度を取得する