Y's note

Web技術・プロダクトマネジメント・そして経営について

本ブログの更新を停止しており、今後は下記Noteに記載していきます。
https://note.com/yutakikuchi/

日本全国避難所データと現在地周辺の避難所地図を公開しました

避難所

防災情報 全国避難所ガイド | ホーム はてなブックマーク - 防災情報 全国避難所ガイド | ホーム
避難所マップ - Yahoo!天気・災害 はてなブックマーク - 避難所マップ - Yahoo!天気・災害

@yutakikuchi_です。オープンデータへの貢献という大義名分っぽい事を掲げ、避難所データを構造化テキストで作成し、更にはポイントを地図上へのマッピングします。避難所というと1st MediaのアプリやYahoo!避難所マップに情報が掲載されていますが、それ以外の避難所野良Web等は避難所データが整理されていません。Yahoo!避難所マップも都道府県毎に公開/非公開があるようでこちらもデータとしては不十分です。今回僕がデータ作成と簡単な地図マッピングを行うので、これを参考に良いアプリケーションが出てくる事に期待しています。

作成した避難所データと地図

作成した避難所データはgithub、それをマッピングした地図をGAEで公開します。地図はGeoLocationAPIを利用して現在地付近の避難所のみを取得します。※利用は全て自己責任でお願いいたします。

公開地図

避難所マップ はてなブックマーク - 避難所マップ

避難所データソース

都道府県避難施設一覧 - 内閣官房 国民保護ポータルサイト はてなブックマーク - 都道府県避難施設一覧 - 内閣官房 国民保護ポータルサイト
1st Mediaの避難所データ はてなブックマーク -
内閣官房 国民保護ポータルサイトのデータを利用します。注意として「平成22年4月1日現在のデータを参考として掲載しております。」とあるようにデータが最新の物では無いです。上のサイトに掲載されているpdfからtextを抽出し、構造化テキストに変換します。代替のデータソースとしては1st MediaのWebPageに掲載されているデータを引っ張ってくる方法もいいかと思いますが、取り扱いには注意してください。

避難所構造化テキスト作成

pdftotextを利用した避難所YAMLファイルの生成

まずはpdfからtextに変換する為のツールであるpdftotextをCentOS6.4へinstallします。install後に国民保護ポータルサイトからpdfファイルをdownloadして、pdftotextコマンドを実行してみます。pdftotextにより標準出力されたデータを見てみるとちゃんと変換されていることが分かりますが、pdf中の表に入力された改行がそのまま改行として出力されています。改行が1つであれルール化できそうですが、2つ以上ある箇所は改行がメイン行の前後に出力されるので、そのようなデータを拾う事はここでは諦めました。拾いたい場合は人の目で判断する必要があると思います。
pythonにはpdfをtext変換するpyPdf はてなブックマーク - pyPdfライブラリもあるので、そちらを使っても良いと思います。

$ sudo yum install  poppler-utils -y
$ wget http://www.kokuminhogo.go.jp/pdf/hinan_hokkaido.pdf
$ pdftotext -enc UTF-8 -layout -nopgbrk hinan_hokkaido.pdf - 
 46    円山公園                     札幌市     円山西町8丁目 
                                        宮の森1214丁目他
 47    旭山記念公園                   札幌市     中央区界川4丁目
                                        中央区中島公園
 48    中島公園                     札幌市     南14条西5丁目
                                        南15条西4丁目

YOLP(地図):Yahoo!ジオコーダAPI - Yahoo!デベロッパーネットワーク はてなブックマーク - YOLP(地図):Yahoo!ジオコーダAPI - Yahoo!デベロッパーネットワーク
Google Geocoding API - Google Maps API ウェブ サービス ― Google Developers はてなブックマーク - Google Geocoding API - Google Maps API ウェブ サービス ― Google Developers

次に以下のPythonコードを実行して、各都道府県の避難所データをYAMLに変換します。生成するYAMLデータ形式都道府県 - 市区町村 - 番地名 - ( 緯度経度 / 場所名[配列] )の4階層になっています。 緯度経度のデータを取得にはYahoo!のジオコーダーAPIを利用しました。Googleのジオコーダーを利用したかったのですが、APIへのリクエスト数上限に引っかかり、OVER_QUERY_LIMITというエラーが頻発するのでYahoo!を使いました。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 避難所データの構造化テキスト作成
# shelter.pyとして保存する
import os,sys,time,re,urllib,urllib2,yaml,json,unicodedata,time
url = 'http://www.kokuminhogo.go.jp/hinan/index.html'
opener = urllib2.build_opener()
ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.51.22 (KHTML, like Gecko) Version/5.1.1 Safari/    534.51.22'
referer = 'http://www.kokuminhogo.go.jp/'
opener.addheaders = [('User-Agent', ua),('Referer', referer)]
appid = 'Yahoo!' # yahooapiのappidをここに定義
try:
   html = unicode(opener.open(url).read(), 'cp932') 
   if re.compile(r'<area shape="rect".*?href="(.*?)" alt="(.*?)"', re.M).search(html) is not None:
      data = re.compile(r'<area shape="rect".*?href="(.*?)" alt="(.*?)"', re.M).findall(html) 
      # pdf download
      for line in data:
         dict = {}
         os.system('wget http://www.kokuminhogo.go.jp' + line[0].replace('..', ''))
         # pdftotext
         textfile = line[0].replace('../pdf/', '').replace('.pdf', '.txt')
         os.system("pdftotext -enc UTF-8 -layout -nopgbrk %s - | sed '/^$/d' | sed 's/^ \+//g' | sed 's/ \{2,\}/\t/g' | sed 's/ //g' | grep '^[0-9]\+'$'\t' | cut -f 2,3,4 | awk '{ print $2%s$3%s$1}' > %s" % (line[0].replace('../pdf/', ''), '"\t"', '"\t"', textfile))
         f = open(textfile, 'r')
         for node in f.readlines():
            (mun,adr,name) = node.rstrip().split("\t")
            if mun == '' or adr == '' or name == '' or name == '/':
               continue
            mun = unicodedata.normalize('NFKC', unicode(mun, 'utf-8'))
            adr = unicodedata.normalize('NFKC', unicode(adr, 'utf-8'))
            name = unicodedata.normalize('NFKC', unicode(name, 'utf-8'))
            dict.setdefault(line[1], {}).setdefault(mun, {}).setdefault(adr, {}).setdefault('name', [] )
            # geoencoding
            #url = "http://maps.googleapis.com/maps/api/geocode/json?address=%s&sensor=false" %(urllib.quote_plus(mun.encode('utf-8') + adr.encode('utf-8')))
            latlng = ''
            try:
               time.sleep(0.2)
               url = 'http://geo.search.olp.yahooapis.jp/OpenLocalPlatform/V1/geoCoder?appid=%s&query=%s&output=%s' % (appid, urllib.quote_plus(mun.encode('utf-8') + adr.encode('utf-8')), 'json')
               res = json.loads(opener.open(url).read())
               if (res['ResultInfo']['Status'] == 200 and res['ResultInfo']['Count'] > 0 ):
                  (lng,lat) = res['Feature'][0]['Geometry']['Coordinates'].split(',')
                  latlng = lat + ',' + lng
               dict[line[1]][mun][adr]['latlng'] = latlng
               dict[line[1]][mun][adr]['name'].append(name)
            except urllib2.URLError:
               dict[line[1]][mun][adr]['latlng'] = latlng
               dict[line[1]][mun][adr]['name'].append(name)
               continue
         f.close()
         # yaml generator
         savefile = open(textfile.replace('.txt', '').replace('hinan_', '') + '_shelter.yaml', 'w')
         yaml.safe_dump(dict, savefile, default_flow_style=False, encoding='utf8', allow_unicode=True)
except Exception, e:
    exc_type, exc_obj, exc_tb = sys.exc_info()
    fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
    print(exc_type, fname, exc_tb.tb_lineno) 
# 都道府県名:
  # 市区町村名:
     # 番地名:
        # latlng:
        # name:
        # - 場所名
        # - 場所名

東京:
  あきる野市:
    上代継190:
      latlng: 35.72992747,139.27797845
      name:
      - あきる野市立西中学校校庭
      - あきる野市立西中学校体育館

その他のオープンデータ

以下は過去に様々なサイトからデータを抽出した個人のオープンデータになります。
こちらも利用される場合は全て自己責任でお願いいたします。
業種別企業の平均年齢と年収の辞書データを公開しました - Yuta.Kikuchiの日記 はてなブックマーク - 業種別企業の平均年齢と年収の辞書データを公開しました - Yuta.Kikuchiの日記
業種別企業名辞書データを公開しました - Yuta.Kikuchiの日記 はてなブックマーク - 業種別企業名辞書データを公開しました - Yuta.Kikuchiの日記
地域データの構造化テキストを公開しました。 - Yuta.Kikuchiの日記 はてなブックマーク - 地域データの構造化テキストを公開しました。 - Yuta.Kikuchiの日記