さて、本日はZmap-TOWNⅡから住所データ(地番戸番)を抜き出してみようと思います。大変便利なZmap-TOWNⅡですが、これの住所一覧が欲しいなぁと思ってもゼンリンさんはそんなデータは用意してくれていませんね。なら自分で作ってしまいましょう!
Zmap-TOWNⅡをファイルジオデータベースに変換
まず、Zmap-TOWNⅡは独自の形式なのでファイルジオデータベースに変換します。
変換ツールの使用
以下のようにESRIから変換ツールをダウンロードします。
Zmap-TOWNII、Zmap-AREAII 変換ツールが更新!洗練された地図表現に : ESRIジャパン ArcGISブログ
ArcMapにこのようなツールを追加することができました。
これで変換ですね。
無事変換を終えたのですが、なんとレイヤ構成がZmap-TOWNⅡと違ってるじゃん!どうなってるのさ?!こんな感じなのですが、明らかにレイヤ構成がおかしい。
ということでESRIに問い合わせた結果、変換したファイルジオデータベースは通常のレイヤ追加ではなく、変換ツールからレイヤを追加しなくてはいけないとのこと。
実行した結果、そうそうこれ。これですよ!ESRIさんありがとうございますm(_ _)m
データの内容
今回一番欲しい建物のデータ定義はこんな感じになっています。
中身はこんな感じですね。大字や字丁目などがコードで入っているので、別テーブルと結合して名称を取得する必要がありますね。
サンプルコード
各テーブルやフィーチャクラスをPandasのデータフレームに格納してCSVに吐き出します。そのCSVをDB(SQLSERVER)に突っ込み、住所データ(地番戸番)を取得したいと思います。本当はCSVに出力ではなく、そのままDBに格納したかったのですが、どうしてもうまくいかなかったです・・・なので、それは今後の課題として、今回はCSV出力を行いたいと思います。
# -*- coding: utf-8 -*- import arcpy import pandas as pd import numpy as np #カラム名と属性を返す関数 def GetAttribute(fc): field_list = [] for field in arcpy.ListFields(fc): field_list.append(field.name) cur = arcpy.SearchCursor(fc) vallist2 = [] for row in cur: vallist = [] for field in field_list: vallist.append(row.getValue(field)) vallist2.append(vallist) arr = np.array(vallist2) del row,cur return arr,field_list #GDBに変換したZmapを指定 arcpy.env.workspace = ur"D:\python\zenrin\ZmapTown.gdb" table = arcpy.ListTables() table.sort() jCode = "" #テーブルから属性を取得 for tb in table: if tb == "ZmapTOWN_ZMAP_PST": data,olist = GetAttribute(tb) pst = pd.DataFrame(data) pst.columns = olist #一行だけでいいのでフィルターかける(もじかしたらここは市町村によっては変える必要ありかも) pstOneRow = pd.DataFrame(pst[pst.OID == "1"]) jCode = pstOneRow["JCODE"].values[0] if tb == "ZmapTOWN_ZMAP_TATEMONO_NAME": data,olist = GetAttribute(tb) tatemono = pd.DataFrame(data) tatemono.columns = olist #重複データとCHIBAN、NAMEが空のデータは削除 tatemonoValue = pd.DataFrame(tatemono[tatemono.CHIBAN <> ""]) tatemonoValue = pd.DataFrame(tatemonoValue[tatemonoValue.NAME <> ""]) #ここはキャストしない tatemonoValue = pd.DataFrame(tatemonoValue[tatemonoValue.JCODE == jCode]) tatemonoValue = pd.DataFrame(tatemonoValue.drop_duplicates(['ACODE','CCODE','GCODE','CHIBAN','TPOLYCD'])) #GDBに変換したZmapのZmapTOWNフィーチャデータセットを指定 arcpy.env.workspace = ur"D:\python\zenrin\ZmapTown.gdb\ZmapTOWN" # フィーチャクラスから属性を取得 for fc in arcpy.ListFeatureClasses(): if fc == "ZmapTOWN_ZMAP_OOAZA": data,olist = GetAttribute(fc) ooaza = pd.DataFrame(data) ooaza.columns = olist #重複データとNAMEが空のデータは削除 ooazaValue = pd.DataFrame(ooaza[ooaza.NAME.notnull()]) ooazaValue = pd.DataFrame(ooazaValue[ooazaValue.JCODE == int(jCode)]) ooazaValue = pd.DataFrame(ooazaValue.drop_duplicates(['NAME'])) elif fc == "ZmapTOWN_ZMAP_AZA": data,olist = GetAttribute(fc) aza = pd.DataFrame(data) aza.columns = olist #重複データとNAMEが空のデータは削除 azaValue = pd.DataFrame(aza[aza.NAME.notnull()]) azaValue = pd.DataFrame(azaValue[azaValue.JCODE == int(jCode)]) azaValue = pd.DataFrame(azaValue.drop_duplicates(['ACODE','CCODE','NAME'])) elif fc == "ZmapTOWN_ZMAP_GAIKU": data,olist = GetAttribute(fc) gaiku = pd.DataFrame(data) gaiku.columns = olist #重複データとNAMEが空のデータは削除 gaikuValue = pd.DataFrame(gaiku[gaiku.NAME.notnull()]) gaikuValue = pd.DataFrame(gaikuValue[gaikuValue.JCODE == int(jCode)]) gaikuValue = pd.DataFrame(gaikuValue.drop_duplicates(['ACODE','CCODE','GCODE','NAME'])) #データフレームをCSV出力 gaikuValue.to_csv("D:\python\zenrin\gaiku.csv",encoding = "utf-8") azaValue.to_csv(r"D:\python\zenrin\aza.csv",encoding = "utf-8") ooazaValue.to_csv("D:\python\zenrin\ooaza.csv",encoding = "utf-8") tatemonoValue.to_csv(r"D:\python\zenrin\tatemono.csv",encoding = "utf-8")
出力したCSVはBULK INSERTなりなんなりでDBに突っ込んでください。←雑ですみません
テーブル定義はZmap-TOWNⅡの各テーブル、フィーチャクラスと同じにしました。
■大字
■字丁目
■街区
■建物
どのテーブルもコードばかりでわけがわかりませんね。定義書を見た感じ以下を考慮したSQLを作ればいいのではないかと思います。
・JCODE(拡張市町村コード)
・ACODE(大字コード)
・CCODE(字丁目コード)
・GCODE(街区コード)
select d.NAME 大字, c.NAME 字, b.NAME 街区, a.CHIBAN 地番戸番, a.NAME 名称 from tatemono a left outer join gaiku_zenrin b on (a.ACODE = b.ACODE and a.CCODE = b.CCODE and a.GCODE = b.GCODE) left outer join aza c on (a.ACODE = c.ACODE and a.CCODE = c.CCODE) left outer join ooaza d on a.ACODE = d.ACODE order by d.NAME, c.NAME, b.NAME, a.CHIBAN, a.NAME
結果を見るとこんな感じですね。けっこうあっさりできました。あとはこれをテーブルに突っ込んだり、EXCELに出力したりして利用することができますね!
全然記事の趣旨からはそれるのですが、今回の変換したZmap-TOWNⅡやデータコレクションなどを見ていると、明らかに動きが早いと感じています←やはりこれがESRIさんの実力なのか?!
フィーチャの数は結構多いのに、動きがかなり軽くて驚きですね。今度はどうしてこんなに動きを早くすることができるのか、その辺の分析を行ってみたいと思います。
以上、本日は「【PythonとSQL】Zmap-TOWNⅡをファイルジオデータベースに変換して住所データ(地番戸番)を抜き出す方法 ~やっぱり便利なPandas~」でした。