Ejemplo n.º 1
0
 def __shapefileHeader(self, fileObj, headerType='shp'):
     """Writes the specified header type to the specified file-like object.
     Several of the shapefile formats are so similar that a single generic
     method to read or write them is warranted."""
     f = self.__getFileObj(fileObj)
     f.seek(0)
     # File code, Unused bytes
     f.write(pack(">6i", 9994, 0, 0, 0, 0, 0))
     # File length (Bytes / 2 = 16-bit words)
     if headerType == 'shp':
         f.write(pack(">i", self.__shpFileLength()))
     elif headerType == 'shx':
         f.write(pack('>i', ((100 + (len(self._shapes) * 8)) // 2)))
     # Version, Shape type
     f.write(pack("<2i", 1000, self.shapeType))
     # The shapefile's bounding box (lower left, upper right)
     if self.shapeType != 0:
         try:
             f.write(pack("<4d", *self.bbox()))
         except error:
             raise ShapefileException(
                 "Failed to write shapefile bounding box. Floats required.")
     else:
         f.write(pack("<4d", 0, 0, 0, 0))
     # Elevation
     z = self.zbox()
     # Measure
     m = self.mbox()
     try:
         f.write(pack("<4d", z[0], z[1], m[0], m[1]))
     except error:
         raise ShapefileException(
             "Failed to write shapefile elevation and measure values. Floats required."
         )
Ejemplo n.º 2
0
 def __init__(self, *args, **kwargs):
     self.shp = None
     self.shx = None
     self.dbf = None
     self.shapeName = "Not specified"
     self._offsets = []
     self.shpLength = None
     self.numRecords = None
     self.fields = []
     self.__dbfHdrLength = 0
     # See if a shapefile name was passed as an argument
     if len(args) > 0:
         if is_string(args[0]):
             self.load(args[0])
             return
     if "shp" in kwargs.keys():
         if hasattr(kwargs["shp"], "read"):
             self.shp = kwargs["shp"]
             if hasattr(self.shp, "seek"):
                 self.shp.seek(0)
         if "shx" in kwargs.keys():
             if hasattr(kwargs["shx"], "read"):
                 self.shx = kwargs["shx"]
                 if hasattr(self.shx, "seek"):
                     self.shx.seek(0)
     if "dbf" in kwargs.keys():
         if hasattr(kwargs["dbf"], "read"):
             self.dbf = kwargs["dbf"]
             if hasattr(self.dbf, "seek"):
                 self.dbf.seek(0)
     if self.shp or self.dbf:
         self.load()
     else:
         raise ShapefileException(
             "Shapefile Reader requires a shapefile or file-like object.")
Ejemplo n.º 3
0
 def __getFileObj(self, f):
     """Safety handler to verify file-like objects"""
     if not f:
         raise ShapefileException("No file-like object available.")
     elif hasattr(f, "write"):
         return f
     else:
         pth = os.path.split(f)[0]
         if pth and not os.path.exists(pth):
             os.makedirs(pth)
         return open(f, "wb")
Ejemplo n.º 4
0
 def __getFileObj(self, f):
     """Checks to see if the requested shapefile file object is
     available. If not a ShapefileException is raised."""
     if not f:
         raise ShapefileException(
             "Shapefile Reader requires a shapefile or file-like object.")
     if self.shp and self.shpLength is None:
         self.load()
     if self.dbf and len(self.fields) == 0:
         self.load()
     return f
Ejemplo n.º 5
0
 def load(self, shapefile=None):
     """Opens a shapefile from a filename or file-like
     object. Normally this method would be called by the
     constructor with the file object or file name as an
     argument."""
     if shapefile:
         shapeName, ext = os.path.splitext(shapefile)
         self.shapeName = shapeName
         try:
             self.shp = open("%s.shp" % shapeName, "rb")
         except IOError:
             raise ShapefileException("Unable to open %s.shp" % shapeName)
         try:
             self.shx = open("%s.shx" % shapeName, "rb")
         except IOError:
             raise ShapefileException("Unable to open %s.shx" % shapeName)
         try:
             self.dbf = open("%s.dbf" % shapeName, "rb")
         except IOError:
             raise ShapefileException("Unable to open %s.dbf" % shapeName)
     if self.shp:
         self.__shpHeader()
     if self.dbf:
         self.__dbfHeader()
Ejemplo n.º 6
0
 def __shpHeader(self):
     """Reads the header information from a .shp or .shx file."""
     if not self.shp:
         raise ShapefileException(
             "Shapefile Reader requires a shapefile or file-like object. (no shp file found"
         )
     shp = self.shp
     # File length (16-bit word * 2 = bytes)
     shp.seek(24)
     self.shpLength = unpack(">i", shp.read(4))[0] * 2
     # Shape type
     shp.seek(32)
     self.shapeType = unpack("<i", shp.read(4))[0]
     # The shapefile's bounding box (lower left, upper right)
     self.bbox = Array('d', unpack("<4d", shp.read(32)))
     # Elevation
     self.elevation = Array('d', unpack("<2d", shp.read(16)))
     # Measure
     self.measure = Array('d', unpack("<2d", shp.read(16)))
Ejemplo n.º 7
0
 def __shpRecords(self):
     """Write the shp records"""
     f = self.__getFileObj(self.shp)
     f.seek(100)
     recNum = 1
     for s in self._shapes:
         self._offsets.append(f.tell())
         # Record number, Content length place holder
         f.write(pack(">2i", recNum, 0))
         recNum += 1
         start = f.tell()
         # Shape Type
         if self.shapeType != 31:
             s.shapeType = self.shapeType
         f.write(pack("<i", s.shapeType))
         # All shape types capable of having a bounding box
         if s.shapeType in (3, 5, 8, 13, 15, 18, 23, 25, 28, 31):
             try:
                 f.write(pack("<4d", *self.__bbox([s])))
             except error:
                 raise ShapefileException(
                     "Falied to write bounding box for record %s. Expected floats."
                     % recNum)
         # Shape types with parts
         if s.shapeType in (3, 5, 13, 15, 23, 25, 31):
             # Number of parts
             f.write(pack("<i", len(s.parts)))
         # Shape types with multiple points per record
         if s.shapeType in (3, 5, 8, 13, 15, 23, 25, 31):
             # Number of points
             f.write(pack("<i", len(s.points)))
         # Write part indexes
         if s.shapeType in (3, 5, 13, 15, 23, 25, 31):
             for p in s.parts:
                 f.write(pack("<i", p))
         # Part types for Multipatch (31)
         if s.shapeType == 31:
             for pt in s.partTypes:
                 f.write(pack("<i", pt))
         # Write points for multiple-point records
         if s.shapeType in (3, 5, 8, 13, 15, 23, 25, 31):
             try:
                 [f.write(pack("<2d", *p[:2])) for p in s.points]
             except error:
                 raise ShapefileException(
                     "Failed to write points for record %s. Expected floats."
                     % recNum)
         # Write z extremes and values
         if s.shapeType in (13, 15, 18, 31):
             try:
                 f.write(pack("<2d", *self.__zbox([s])))
             except error:
                 raise ShapefileException(
                     "Failed to write elevation extremes for record %s. Expected floats."
                     % recNum)
             try:
                 if hasattr(s, "z"):
                     f.write(pack("<%sd" % len(s.z), *s.z))
                 else:
                     [f.write(pack("<d", p[2])) for p in s.points]
             except error:
                 raise ShapefileException(
                     "Failed to write elevation values for record %s. Expected floats."
                     % recNum)
         # Write m extremes and values
         if s.shapeType in (13, 15, 18, 23, 25, 28, 31):
             try:
                 if hasattr(s, "m"):
                     f.write(pack("<%sd" % len(s.m), *s.m))
                 else:
                     f.write(pack("<2d", *self.__mbox([s])))
             except error:
                 raise ShapefileException(
                     "Failed to write measure extremes for record %s. Expected floats"
                     % recNum)
             try:
                 [f.write(pack("<d", p[3])) for p in s.points]
             except error:
                 raise ShapefileException(
                     "Failed to write measure values for record %s. Expected floats"
                     % recNum)
         # Write a single point
         if s.shapeType in (1, 11, 21):
             try:
                 f.write(pack("<2d", s.points[0][0], s.points[0][1]))
             except error:
                 raise ShapefileException(
                     "Failed to write point for record %s. Expected floats."
                     % recNum)
         # Write a single Z value
         if s.shapeType == 11:
             if hasattr(s, "z"):
                 try:
                     if not s.z:
                         s.z = (0, )
                     f.write(pack("<d", s.z[0]))
                 except error:
                     raise ShapefileException(
                         "Failed to write elevation value for record %s. Expected floats."
                         % recNum)
             else:
                 try:
                     if len(s.points[0]) < 3:
                         s.points[0].append(0)
                     f.write(pack("<d", s.points[0][2]))
                 except error:
                     raise ShapefileException(
                         "Failed to write elevation value for record %s. Expected floats."
                         % recNum)
         # Write a single M value
         if s.shapeType in (11, 21):
             if hasattr(s, "m"):
                 try:
                     if not s.m:
                         s.m = (0, )
                     f.write(pack("<1d", s.m[0]))
                 except error:
                     raise ShapefileException(
                         "Failed to write measure value for record %s. Expected floats."
                         % recNum)
             else:
                 try:
                     if len(s.points[0]) < 4:
                         s.points[0].append(0)
                     f.write(pack("<1d", s.points[0][3]))
                 except error:
                     raise ShapefileException(
                         "Failed to write measure value for record %s. Expected floats."
                         % recNum)
         # Finalize record length as 16-bit words
         finish = f.tell()
         length = (finish - start) // 2
         self._lengths.append(length)
         # start - 4 bytes is the content length field
         f.seek(start - 4)
         f.write(pack(">i", length))
         f.seek(finish)
Ejemplo n.º 8
0
 def assertFile(self, attr):
     # attr should be 'shp', 'dbf', or 'shx'
     if not getattr(self, attr, None):
         raise ShapefileException(
             "Shapefile Reader requires a shapefile or file-like object."
             "(no %s file found)" % attr)