web/lib/django/contrib/gis/geos/io.py
changeset 29 cc9b7e14412b
parent 0 0d40e90630ef
equal deleted inserted replaced
28:b758351d191f 29:cc9b7e14412b
     1 """
     1 """
     2 Module that holds classes for performing I/O operations on GEOS geometry
     2 Module that holds classes for performing I/O operations on GEOS geometry
     3 objects.  Specifically, this has Python implementations of WKB/WKT
     3 objects.  Specifically, this has Python implementations of WKB/WKT
     4 reader and writer classes.
     4 reader and writer classes.
     5 """
     5 """
     6 from ctypes import byref, c_size_t
       
     7 from django.contrib.gis.geos.base import GEOSBase
       
     8 from django.contrib.gis.geos.error import GEOSException
       
     9 from django.contrib.gis.geos.geometry import GEOSGeometry
     6 from django.contrib.gis.geos.geometry import GEOSGeometry
    10 from django.contrib.gis.geos.libgeos import GEOM_PTR
     7 from django.contrib.gis.geos.prototypes.io import _WKTReader, _WKBReader, WKBWriter, WKTWriter
    11 from django.contrib.gis.geos.prototypes import io as capi
       
    12 
     8 
    13 class IOBase(GEOSBase):
     9 # Public classes for (WKB|WKT)Reader, which return GEOSGeometry
    14     "Base class for GEOS I/O objects."
    10 class WKBReader(_WKBReader):
    15     def __init__(self):
    11     def read(self, wkb):
    16         # Getting the pointer with the constructor.
    12         "Returns a GEOSGeometry for the given WKB buffer."
    17         self.ptr = self.constructor()
    13         return GEOSGeometry(super(WKBReader, self).read(wkb))
    18 
       
    19     def __del__(self):
       
    20         # Cleaning up with the appropriate destructor.
       
    21         if self._ptr: self.destructor(self._ptr)
       
    22 
       
    23 ### WKT Reading and Writing objects ###
       
    24 
       
    25 # Non-public class for internal use because its `read` method returns
       
    26 # _pointers_ instead of a GEOSGeometry object.
       
    27 class _WKTReader(IOBase):
       
    28     constructor = capi.wkt_reader_create
       
    29     destructor = capi.wkt_reader_destroy
       
    30     ptr_type = capi.WKT_READ_PTR
       
    31 
       
    32     def read(self, wkt):
       
    33         if not isinstance(wkt, basestring): raise TypeError
       
    34         return capi.wkt_reader_read(self.ptr, wkt)
       
    35 
    14 
    36 class WKTReader(_WKTReader):
    15 class WKTReader(_WKTReader):
    37     def read(self, wkt):
    16     def read(self, wkt):
    38         "Returns a GEOSGeometry for the given WKT string."
    17         "Returns a GEOSGeometry for the given WKT string."
    39         return GEOSGeometry(super(WKTReader, self).read(wkt))
    18         return GEOSGeometry(super(WKTReader, self).read(wkt))
    40 
    19 
    41 class WKTWriter(IOBase):
       
    42     constructor = capi.wkt_writer_create
       
    43     destructor = capi.wkt_writer_destroy
       
    44     ptr_type = capi.WKT_WRITE_PTR
       
    45 
    20 
    46     def write(self, geom):
       
    47         "Returns the WKT representation of the given geometry."
       
    48         return capi.wkt_writer_write(self.ptr, geom.ptr)
       
    49 
       
    50 ### WKB Reading and Writing objects ###
       
    51 
       
    52 # Non-public class for the same reason as _WKTReader above.
       
    53 class _WKBReader(IOBase):
       
    54     constructor = capi.wkb_reader_create
       
    55     destructor = capi.wkb_reader_destroy
       
    56     ptr_type = capi.WKB_READ_PTR
       
    57 
       
    58     def read(self, wkb):
       
    59         "Returns a _pointer_ to C GEOS Geometry object from the given WKB."
       
    60         if isinstance(wkb, buffer):
       
    61             wkb_s = str(wkb)
       
    62             return capi.wkb_reader_read(self.ptr, wkb_s, len(wkb_s))
       
    63         elif isinstance(wkb, basestring):
       
    64             return capi.wkb_reader_read_hex(self.ptr, wkb, len(wkb))
       
    65         else:
       
    66             raise TypeError
       
    67 
       
    68 class WKBReader(_WKBReader):
       
    69     def read(self, wkb):
       
    70         "Returns a GEOSGeometry for the given WKB buffer."
       
    71         return GEOSGeometry(super(WKBReader, self).read(wkb))
       
    72 
       
    73 class WKBWriter(IOBase):
       
    74     constructor = capi.wkb_writer_create
       
    75     destructor = capi.wkb_writer_destroy
       
    76     ptr_type = capi.WKB_WRITE_PTR
       
    77 
       
    78     def write(self, geom):
       
    79         "Returns the WKB representation of the given geometry."
       
    80         return buffer(capi.wkb_writer_write(self.ptr, geom.ptr, byref(c_size_t())))
       
    81 
       
    82     def write_hex(self, geom):
       
    83         "Returns the HEXEWKB representation of the given geometry."
       
    84         return capi.wkb_writer_write_hex(self.ptr, geom.ptr, byref(c_size_t()))
       
    85 
       
    86     ### WKBWriter Properties ###
       
    87 
       
    88     # Property for getting/setting the byteorder.
       
    89     def _get_byteorder(self):
       
    90         return capi.wkb_writer_get_byteorder(self.ptr)
       
    91 
       
    92     def _set_byteorder(self, order):
       
    93         if not order in (0, 1): raise ValueError('Byte order parameter must be 0 (Big Endian) or 1 (Little Endian).')
       
    94         capi.wkb_writer_set_byteorder(self.ptr, order)
       
    95 
       
    96     byteorder = property(_get_byteorder, _set_byteorder)
       
    97 
       
    98     # Property for getting/setting the output dimension.
       
    99     def _get_outdim(self):
       
   100         return capi.wkb_writer_get_outdim(self.ptr)
       
   101 
       
   102     def _set_outdim(self, new_dim):
       
   103         if not new_dim in (2, 3): raise ValueError('WKB output dimension must be 2 or 3')
       
   104         capi.wkb_writer_set_outdim(self.ptr, new_dim)
       
   105 
       
   106     outdim = property(_get_outdim, _set_outdim)
       
   107 
       
   108     # Property for getting/setting the include srid flag.
       
   109     def _get_include_srid(self):
       
   110         return bool(ord(capi.wkb_writer_get_include_srid(self.ptr)))
       
   111 
       
   112     def _set_include_srid(self, include):
       
   113         if bool(include): flag = chr(1)
       
   114         else: flag = chr(0)
       
   115         capi.wkb_writer_set_include_srid(self.ptr, flag)
       
   116 
       
   117     srid = property(_get_include_srid, _set_include_srid)
       
   118 
       
   119 # Instances of the WKT and WKB reader/writer objects.
       
   120 wkt_r = _WKTReader()
       
   121 wkt_w = WKTWriter()
       
   122 wkb_r = _WKBReader()
       
   123 wkb_w = WKBWriter()