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

穴の開いた浮き出し地図を作る(シェープファイル)

 千葉県の鎌ケ谷市です。南に大きな穴、よく見るとその左にも三角形の穴があいています。穴のあけ方は、先のxml版と同じ手法です。

 サブのスクリプトCShpR.pyは前回と全く同じです。メインのスクリプトのみです。ここに生pyファイルがあります。

#!BPY
import bpy
import math
import glob
from CShpR import CShpR
#
# 穴の開いた浮き出し地図を作る(シェープファイル)
#       main004.py
#       2016/11/17 Shizuka-Toikanbetsu
#
ShpName = "N03-??_12_*.shp"     # 収録されているshpファイルを指定
AreaCode = "12224"      # 地方公共団体コードを文字列型で指定
ObjScale = 0.001        # 原寸では大きいので1000分の1
#
# 世界座標の基準緯度と世界座標の目標座標の距離をメートル単位で返す
def     GetLatOffset(pBaseLat, pLat):
        return ( pLat - pBaseLat ) * 40007000.0 / 360.0
#
# 世界座標の基準経度と世界座標の目標座標の距離をメートル単位で返す
def     GetLonOffset(pBaseLon, pLat, pLon):
        return ( pLon - pBaseLon ) * 40075000.0 * math.cos( math.radians( pLat ) ) / 360.0
#
def     MergeRecName():
        Buff = []
        for item in bpy.data.objects:
                if item.type == "MESH":
                        temp = item.name
                        Buff.append( temp[ 0 : 5 ] )
        Buff.sort()
        AreaCode = []
        OldCode = ""
        for temp in Buff:
                if temp != OldCode:
                        AreaCode.append( temp )
                OldCode = temp
        #
        for Code in AreaCode:
                bpy.ops.object.select_all(action='DESELECT')
                flag = True
                for curve in bpy.data.objects:
                        if curve.type == 'MESH':
                                NowName = curve.name
                                NowCode = NowName[:5]
                                if NowCode == Code:
                                        if flag:
                                                RecName = NowName
                                                flag = False
                                        curve.select = True
                                        bpy.context.scene.objects.active = curve
                bpy.ops.object.join()
                bpy.ops.object.select_all(action='DESELECT')
        # 小数点の付く名前は書き換える
        for item in bpy.data.objects:
                if item.type == "MESH":
                        temp = item.name
                        try:
                                item.name = temp[ 0 : temp.index( "." ) ]
                        except ValueError:
                                pass
        #
        bpy.context.scene.objects.active = None
#
def     CreateCurve(pName, pShape, pPart, pInterior):
        temp = pShape.parts[ pPart ]
        top = temp[ 0 ]
        btm = temp[ 1 ]
        Count = btm - top + 1
        CvData = bpy.data.curves.new( name = pName, type="CURVE" )
        CvData.dimensions = "2D"
        ObjData = bpy.data.objects.new( pName, CvData )
        if pInterior:
                ObjData.location = ( 0, 0, 1 )
        else:
                ObjData.location = ( 0, 0, 0 )
        ObjData.scale[0] = ObjScale
        ObjData.scale[1] = ObjScale
        ObjData.scale[2] = ObjScale
        bpy.context.scene.objects.link( ObjData )
        polyline = CvData.splines.new( "POLY" )
        #
        polyline.points.add( Count - 1 )
        ptr = top
        for xyptr in range( 0, Count ):
                posX = pShape.XY[ ptr ][ 0 ]
                posY = pShape.XY[ ptr ][ 1 ]
                ptr = ptr + 1
                posX = GetLonOffset( wx, posY, posX )
                posY = GetLatOffset( wy, posY )
                polyline.points[xyptr].co = ( posX, posY, 0, 0 )
        polyline.use_cyclic_u = True
        ObjData.select = True
        if pInterior:
                bpy.context.scene.objects.active = ObjData
                bpy.ops.object.modifier_add(type='SOLIDIFY')    # 厚み付け
                bpy.context.object.modifiers["Solidify"].thickness = 5.0 / ObjScale
        # カーブをメッシュオブジェクトに変換
        bpy.context.scene.objects.active = ObjData
        bpy.ops.object.convert( target = "MESH" )
        ObjData.select = False
        return ObjData
#
print( '\nStart Script' )
#
# 既存メッシュの削除
for item in bpy.context.scene.objects:
        if item.type == "MESH":
                bpy.context.scene.objects.unlink( item )
for item in bpy.data.objects:
        if item.type == "MESH":
                bpy.data.objects.remove( item )
for item in bpy.data.meshes:
        bpy.data.meshes.remove( item )
#
files = glob.glob( ShpName )
if files:
        file = files[ 0 ]       # きりがないので処理は1ファイルに限る
        shape = CShpR()
        shape.open( file )
        #
        for fldptr in range( 0, shape.DbfFieldCount ):
                temp = shape.DbfField[ fldptr ].name
                if temp == "N03_001":
                        DbfPref = fldptr
                elif temp == "N03_003":
                        DbfCounty = fldptr
                elif temp == "N03_004":
                        DbfCity = fldptr
                elif temp == "N03_007":
                        DbfArea = fldptr
        # 事前にセンターの位置を割り出す
        Xmin = 100000000.0
        Ymin = Xmin
        Xmax = -Xmin
        Ymax = Xmax
        for RecNo in range( 0, shape.DbfRecCount ):
                #
                tempbin = shape.readdbf( RecNo )
                temp = shape.getdbfvalue( tempbin, DbfArea )
                if( temp == AreaCode ):
                        tempbin = shape.readrec( RecNo )
                        shptype = shape.GetBinDword( tempbin[:4] )
                        if shptype == 5:        # polygon is 5
                                lXmin = shape.GetBinDouble( tempbin[4:12] )
                                lYmin = shape.GetBinDouble( tempbin[12:20] )
                                lXmax = shape.GetBinDouble( tempbin[20:28] )
                                lYmax = shape.GetBinDouble( tempbin[28:36] )
                                Xmin = min( lXmin, Xmin )
                                Xmax = max( lXmax, Xmax )
                                Ymin = min( lYmin, Ymin )
                                Ymax = max( lYmax, Ymax )
        wx = ( Xmin + Xmax ) / 2.0
        wy = ( Ymin + Ymax ) / 2.0
        #
        # ここから本番。レコードごとに図形を作る
        for RecNo in range( 0, shape.DbfRecCount ):
                # dbfを1レコード読む
                tempbin = shape.readdbf( RecNo )
                temp = shape.getdbfvalue( tempbin, DbfArea )
                if( temp == AreaCode ):
                        # ↓ オブジェクト名を作る
                        RecName = AreaCode
                        temp = shape.getdbfvalue( tempbin, DbfPref )
                        RecName = RecName + "_" + temp
                        temp = shape.getdbfvalue( tempbin, DbfCounty )
                        if len( temp ):
                                RecName = RecName + "_" + temp
                        temp = shape.getdbfvalue( tempbin, DbfCity )
                        if len( temp ):
                                RecName = RecName + "_" + temp
                        # ↑ オブジェクト名を作る
                        #
                        tempbin = shape.readrec( RecNo )
                        shptype = shape.GetBinDword( tempbin[:4] )
                        if shptype == 5:        # polygon is 5
                                shape.CreateSegVert( tempbin )
                                #
                                objectdata = CreateCurve( RecName, shape, 0, False )
                                #
                                # 穴をあける処理を追加
                                for part in range( 1, len( shape.parts ) ):
                                        objectdata2 = CreateCurve( "temp", shape, part, True )
                                        #
                                        objectdata.select = True
                                        bpy.context.scene.objects.active = objectdata
                                        bpy.ops.object.modifier_add(type='BOOLEAN')
                                        bpy.context.object.modifiers["Boolean"].operation = 'DIFFERENCE'
                                        bpy.context.object.modifiers["Boolean"].object = bpy.data.objects["temp"]
                                        bpy.context.object.modifiers["Boolean"].double_threshold = 0.0
                                        bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Boolean")
                                        objectdata.select = False
                                        objectdata2.select = True
                                        bpy.ops.object.delete(use_global=False)
                                        bpy.context.scene.objects.active = None
        #
        shape.close()
        #
        MergeRecName()  # 複数レコードを1つにまとめたいなら実行
#
print( '\nEnd Script' )

 出来上がった図形をポリゴン数削減で0.1にし、高さを加えると次のようになります。

<トップページに戻る>


Copyright© Shizuka-Toikanbetsu.
inserted by FC2 system