国土数値情報 ダウンロードサービスの利用

行政区域データを読む(xml)

 国土数値情報ダウンロードサービスの行政区域のデーターで、東京都です。

 国土地理院のデーターのように使用にあたり申請をするといった手間が無いので大変使いやすい特徴があります。行政区域だけでなく、他にも色々な種類のデーターがあります。

 国土数値情報ダウンロードサービスのデーターをダウンロードすると、xmlファイルとシェープファイルの2種類が入っています。

 このページでは、BlenderのPythonでxmlファイルをアクセスする場合の例を記述します。

 例といっても、xmlの座標データーをとりあえずBlenderのカーブオブジェクトにするのが目的です。まだ平面や立体図形は登場しません。お急ぎの方は他のコンテンツにお回りください。

 xmlファイルでは、自治体の名称やコードなども定義されていますが、今回は登場しません。ひたすら、レコードが持っている座標をポリラインのカーブオブジェクトにするだけです。エラー処理も入っていません。

 とりあえずBlender上に線が出るのが目的ですから、特にこれといった使い道もありませんが、xmlを読む基本形になります。また、生データのダンプにもなります。ただ、レコード数が多い北海道や、長崎、鹿児島などは非常に時間がかかるので、実験には適していません。

 配信データーはネームスペースを使ったxmlなので、一般的なxmlアクセスに比べるとややリストが見づらいです。

 リストにある、XmlName という変数に、xmlのファイル名を指定します。ワイルドカードも使えますが、処理の中で1つのxmlだけを対象にしています。

 緯度と経度の値をそのまま座標として書き込んでいるため、小さな範囲に図形が集中することになります。小さくて探すのは大変です。何かの図形を選択してからビュー上で、テンキーの小数点を押すと該当位置が表示されます。

 処理を追いかけやすいよう、べた書きで一気に記述します。

#!BPY
import bpy
from xml.etree.ElementTree import ElementTree
import glob
#
# 行政区域のレコード全部をBlenderのポリラインにする(xml)
#
XmlName = "N03-*.xml"   # 収録されているxmlファイルを指定
#
# namespace
ns = {'ksj': 'http://nlftp.mlit.go.jp/ksj/schemas/ksj-app',
                'gml': 'http://www.opengis.net/gml/3.2',
                'xlink': 'http://www.w3.org/1999/xlink'}
#
print( '\nStart Script' )
#
# 既存カーブとメッシュの削除
for item in bpy.context.scene.objects:
        if item.type == 'CURVE' or item.type == 'MESH':
                bpy.context.scene.objects.unlink(item)
for item in bpy.data.objects:
        if item.type == 'CURVE' or item.type == 'MESH':
                bpy.data.objects.remove(item)
for item in bpy.data.curves:
        bpy.data.curves.remove(item)
for item in bpy.data.meshes:
        bpy.data.meshes.remove(item)
#
files = glob.glob( XmlName )
if files:
        file = files[ 0 ]       # きりがないので処理は1ファイルに限る
        tree = ElementTree()
        tree.parse( file )
        #
        xpath = ".//gml:Curve"
        for Curve in tree.findall( xpath, ns ):
                # 座標データーを一度配列に溜める
                xpath = ".//gml:posList"
                posList = Curve.find( xpath, ns )
                LineData = posList.text.split( "\n" )
                MapPoint = []
                for temp in LineData:
                        if temp:
                                NowText = temp.lstrip( " \t" )
                                if NowText:
                                        xyStr = NowText.split( " " )
                                        posY = float( xyStr[ 0 ] )
                                        posX = float( xyStr[ 1 ] )
                                        XY = []
                                        XY.append( posX )
                                        XY.append( posY )
                                        MapPoint.append( XY )
                # カーブオブジェクトを作る
                id = Curve.get( "{http://www.opengis.net/gml/3.2}id" )
                curvedata = bpy.data.curves.new( name=id, type="CURVE" )
                curvedata.dimensions = "2D"
                objectdata = bpy.data.objects.new( id, curvedata )
                objectdata.location = ( 0, 0, 0 )
                bpy.context.scene.objects.link( objectdata )
                polyline = curvedata.splines.new( "POLY" )
                # 各座標点を設定
                Count = len( MapPoint )
                polyline.points.add( Count - 1 )
                for ptr in range( 0, Count ):
                        XY = MapPoint[ ptr ]
                        posX = XY[ 0 ]
                        posY = XY[ 1 ]
                        polyline.points[ ptr ].co = ( posX, posY, 0, 0 )
        tree = None     # どうせ終わるので無くてもよい
#
print( '\nEnd Script' )

 実は正規の仕様だとラインの部分は複数記述を合成するようにする必要がありますが、面倒なのでやっていません。そこまでやりだすとPythonのような遅い言語では無理です。古い年度のデーターはこれが理由で正しく変換できません。最新年度のデーターでお使いください。

<トップページに戻る>


Copyright© Shizuka-Toikanbetsu.
inserted by FC2 system