Take Your Time

仕事や研究、コンピューターとの付き合い方

国土数値情報 福祉施設データのxmlをcsv化する

久々に長いコードを書いたので。

概要

国土地理院の国土数値情報は豊富な位置情報があって楽しい。しかし、GISとか詳しくないと超使いづらいのでcsvファイルにしてしまいたい。 試行錯誤したが、名前空間とかめんどくさいのでエンジニアリング力低めの人間にはxmlモジュールのElementTreeでxmlを適当に解析してしまうのが一番楽なように思われる。

手順

  • まず、国土数値情報の福祉施設データを全県分ダウンロード。エンジニアリング力ないのでもちろん手作業ですよ!
  • 次にxmlファイルを一つ一つparseして、root→子→孫と要素を展開してタグの名前で場合分けしてそれぞれリストにぶち込む。
  • 位置情報(pos)は'緯度 経度'と一括されているので(wktとかいうやつ)、強引にsplitする。
  • 最後に、dataframe型にしてcsvにする。
  • なお、埼玉県だけなぜか文字化け的なトラップがあるので、目視で一つ一つ処理しないとparseできないので注意(必要があればコメントしてくれればお教えします)。
  • まあ、こんな方法取らなくてもすごい人なら3行くらいでかけそう。

コード

import xml.etree.ElementTree as ET
import pandas as pd
for i in range(1,48):
    if i != 27:
        number = '{0:02d}'.format(i)
        path = 'hogehoge/P14-15_' + number +'.xml'
        xml = ET.parse(path)
        root = xml.getroot()
        pos = [] # position用のリスト
        name = [] # 施設名用のリスト
        smallclass = [] # 小分類用のリスト
        minimumclass = [] # 細目分類用のリスト
        prefectureName = [] #都道府県名のリスト
        cityName = [] #市区町村名のリスト
        address = [] #住所のリスト
        latitude = []
        longitude = []
        
        for child in root:
            for element in child:
                if element.tag == '{http://www.opengis.net/gml/3.2}pos':
                    pos.append(element.text) 
                if element.tag == '{http://nlftp.mlit.go.jp/ksj/schemas/ksj-app}name':
                    name.append(element.text) 
                if element.tag == '{http://nlftp.mlit.go.jp/ksj/schemas/ksj-app}publicFacilitySmallClassification':
                    smallclass.append(element.text) 
                if element.tag == '{http://nlftp.mlit.go.jp/ksj/schemas/ksj-app}publicFacilityMinimumClassification':
                    minimumclass.append(element.text) 
                if element.tag == '{http://nlftp.mlit.go.jp/ksj/schemas/ksj-app}prefectureName':
                    prefectureName.append(element.text) 
                if element.tag == '{http://nlftp.mlit.go.jp/ksj/schemas/ksj-app}cityName':
                    cityName.append(element.text) 
                if element.tag == '{http://nlftp.mlit.go.jp/ksj/schemas/ksj-app}address':
                    address.append(element.text) 
       # latitudeとlongitudeを分割
        for point in pos:
            latitude.append(point.split()[0])
            longitude.append(point.split()[1])
            
            #保存
        df = pd.DataFrame({'latitude':latitude,'longitude':longitude, 'smallclass':smallclass, 'minimumclass':minimumclass, 
                           'prefectureName':prefectureName, 'cityName':cityName, 'address':address}, index = name)
#            print(df)
        csv_path = 'fukushi' + str(i) + '.csv'
        df.to_csv(csv_path)