I wrote this script to load a shapefile (which only contained PolygonZ’s) into blender. Turns out I might not actually want to be using shapefile files … so I’m unlikely to take this script any further.
As such I thought I’d post it here in case someone else has a need to load shapefile as it might save them a few hours.
It should be reasonably easy to extend to cover other shapefile types; hope its of use to someone
Rich
import struct
import StringIO
import string
class ShapeFile_Point:
def __init__( self, itr ):
self.x = 0.0
self.y = 0.0
self.x, self.y = struct.unpack( "<dd", itr.read( 16 ) )
self.x = float( self.x )
self.y = float( self.y )
class ShapeFile_PolygonZ:
def __init__( self, itr ):
self.box = []
self.parts = []
self.points = []
self.zMin = 0.0
self.zMax = 0.0
self.zArray = []
self.mMin = 0.0
self.mMax = 0.0
self.mArray = []
self.box = struct.unpack( "<dddd", itr.read( 32 ) )
numParts, numPoints = struct.unpack( "<ii", itr.read( 8 ) )
for i in xrange( 0, numParts ):
self.parts.append( struct.unpack( "<i", itr.read( 4 ) )[ 0 ] )
for i in xrange( 0, numPoints ):
self.points.append( ShapeFile_Point( itr ) )
self.zMin = struct.unpack( "<d", itr.read( 8 ) )[ 0 ]
self.zMax = struct.unpack( "<d", itr.read( 8 ) )[ 0 ]
for i in xrange( 0, numPoints ):
self.zArray.append( struct.unpack( "<d", itr.read( 8 ) )[ 0 ] )
data = itr.read( 8 )
if len( data ) != 0:
self.mMin = struct.unpack( "<d", data )[ 0 ]
self.mMax = struct.unpack( "<d", itr.read( 8 ) )[ 0 ]
for i in xrange( 0, numPoints ):
self.mArray.append( struct.unpack( "<d", itr.read( 8 ) )[ 0 ] )
retVal = " box: %s
" % ( str( self.box ) )
retVal += " noParts: %i
" % ( len( self.parts ) )
retVal += " noPoints: %i
" % ( len( self.points ) )
retVal += " zMin: %s
" % ( self.zMin )
retVal += " zMax: %s
" % ( self.zMax )
retVal += " mMin: %s
" % ( self.mMin )
retVal += " mMax: %s
" % ( self.mMax )
print retVal
def __str__( self ):
retVal = " box: %s
" % ( str( self.box ) )
retVal += " noParts: %i
" % ( len( self.parts ) )
retVal += " noPoints: %i
" % ( len( self.points ) )
retVal += " zMin: %s
" % ( self.zMin )
retVal += " zMax: %s
" % ( self.zMax )
retVal += " mMin: %s
" % ( self.mMin )
retVal += " mMax: %s
" % ( self.mMax )
return retVal
class ShapeFile_Record:
def __init__( self, itr ):
self.shapeType = 0
self.data = None
self.shapeType = struct.unpack( "<i", itr.read( 4 ) )[ 0 ]
retVal = " shapeType: %s
" % ( self.shapeType )
print retVal
if int( self.shapeType ) == 15:
self.data = ShapeFile_PolygonZ( itr )
def __str__( self ):
retVal = " shapeType: %s
" % ( self.shapeType )
retVal += str( self.data )
return retVal
class ShapeFile:
def __init__( self, fname ):
self.version = 0
self.shapeType = 0
self.boundingBox = []
self.records = []
f = open( fname, "rb" )
self._parseFileHeader( f )
while True:
data = f.read( 8 )
if len( data ) == 0:
break
rh = struct.unpack( ">ii", data )
itr = StringIO.StringIO( f.read( int( rh[ 1 ] ) * 2 ) ) # value is size in in16's
self.records.append( ShapeFile_Record( itr ) )
def _parseFileHeader( self, f ):
self.fileCode = struct.unpack( ">i", f.read( 4 ) )[ 0 ]
unused1 = struct.unpack( ">iiiii", f.read( 20 ) )
self.fileLength = struct.unpack( ">i", f.read( 4 ) )[ 0 ]
self.version, self.shapeType = struct.unpack( "<ii", f.read( 8 ) )
self.boundingBox = struct.unpack( "<dddddddd", f.read( 64 ) )
retVal = " version: %s
" % ( self.version )
retVal += " shapeType: %s
" % ( self.shapeType )
retVal += " boundingBox: %s
" % ( str( self.boundingBox ) )
print retVal
def __str__( self ):
retVal = " version: %s
" % ( self.version )
retVal += " shapeType: %s
" % ( self.shapeType )
retVal += " boundingBox: %s
" % ( str( self.boundingBox ) )
for r in self.records:
retVal += str( r )
return retVal
s = ShapeFile( "e000n52e.shp" )
print s
import bpy
from Blender import Curve, Object, Scene
from Blender import *
for rec in s.recordsa:
loop = bpy.data.meshes.new()
for pt in rec.data.points:
loop.verts.extend( [ ( pt.x, pt.y, 0.0 ) ] )
# #for i in xrange( 0, len( rec.data.parts ) ):
# # print "--------------------"
# # for j in xrange( rec.data.parts[ i - 1 ] + 1, rec.data.parts[ i ] ):
# # print j
# # loop.edges.extend( ( loop.verts[ j - 1 ], loop.verts[ j ] ) )
bpy.data.scenes.active.objects.new( loop )