Google マイマップのデータを画像化して保存する1

Googleマップのマイマップに保存された場所を, 一ヶ所ずつ別の画像ファイルとして保存する. 携帯端末があればこんな面倒なことはいらないが, この地図をPSPなどに入れて持ち歩いたりもできる.

#!/usr/bin/env python

import xml.dom.minidom as minidom
import urllib
import re
import os
import time


def get_text(element):
    return ''.join([node.data for node in element.childNodes 
                    if node.nodeType == node.TEXT_NODE])

def get_element(node, tags):
    if type(tags) is str: tags = [tags]
    else: tags.reverse()

    return __get_element(node, tags)

def __get_element(node, tags):
    tag = tags.pop()
    elements = node.getElementsByTagName(tag)
    if len(elements) != 1: return None
    elif len(tags) == 0: return elements[0]
    else: return __get_element(elements[0], tags)

def adjust_name(name):
    pattern = re.compile('[\s/]')
    return pattern.sub('_', name)

url_template = 'http://maps.google.com/maps/api/staticmap?' \
    + 'center=%(lattitude)s,%(longitude)s&zoom=%(zoom)d' \
    + '&size=%(width)dx%(height)s&sensor=false&cc=jp&format=%(format)s' \
    + '&markers=color:pink|%(lattitude)s,%(longitude)s'

def gmap2image(filenames, dirname='./maps', format='png32'):
    if not os.path.isdir(dirname): os.mkdir(dirname)

    places = {}
    for filename in filenames:
        document = minidom.parse(filename)

        for placemark in  document.getElementsByTagName('Placemark'):
            name_node = get_element(placemark, 'name')
            coordinates_node = get_element(placemark, ['Point', 'coordinates'])
            if name_node is None or coordinates_node is None: continue

            name = adjust_name(get_text(name_node))
            coordinate = get_text(coordinates_node).split(',')
            if len(coordinate) != 3: continue

            places[name] = coordinate

        document.unlink()

    for name1, coordinate1 in places.items():
        parameter \
            = {'lattitude': coordinate1[1], 'longitude': coordinate1[0],
               'zoom': 16, 'width': 640, 'height': 640, 'format': format}

        url = url_template % parameter
        lattitude1, longitude1 = float(coordinate1[1]), float(coordinate1[0])
        for name2, coordinate2 in places.items():
            lattitude2, longitude2 \
                = float(coordinate2[1]), float(coordinate2[0])
            if name1 != name2 and abs(lattitude1 - lattitude2) < 0.0056 \
                    and abs(longitude1 - longitude2) < 0.0069:
                url += '&markers=color:blue|%s,%s' \
                    % (coordinate2[1], coordinate2[0])

        filename = '%s/%s.png' % (dirname, name1)
        if not os.path.isfile(filename):
            print name1, url
            urllib.urlretrieve(url, filename)
            time.sleep(1)


if __name__ == '__main__':
    import sys


    if len(sys.argv) < 2: sys.exit(0)
    else: gmap2image(sys.argv[1: ], format='png32')

Google Static Maps APIを用いた. APIに関しては以下のサイトを参考にした.

http://code.google.com/intl/ja/apis/maps/documentation/staticmaps

やっていることとしてはkmlをパースして得た情報をGoogle Static Maps APIになげて画像化して保存している. 1ファイルごとに'time.sleep(1)'を入れないとおそらくGoogle側で一時的に利用が規制されたような気がする.

使い方としてはこれをgmap2imageなどとして保存し, 実効権限をつけて, 'gmap2image *.kml'などとして使う. Googleマイマップのデータをkmlファイルとして保存する方法は以下の通り.

google earthで表示」を右クリックしてリンクアドレスをコピーして、そのURLの中の「output=nl」を「output=kml」に変更してアクセスするとkmlファイルがダウンロードされます。
Google マイマップのデータをKMLにエクスポートしてCSVに変換する方法
http://d.hatena.ne.jp/tmizu23/20091024/1256298170

このアドレスはstaticみたいだからこれを記憶しておいて毎回wgetするようにした方が良いかもしれない.