PageRenderTime 184ms CodeModel.GetById 80ms app.highlight 41ms RepoModel.GetById 60ms app.codeStats 0ms

/django/contrib/gis/geos/prototypes/io.py

https://code.google.com/p/mango-py/
Python | 242 lines | 163 code | 49 blank | 30 comment | 23 complexity | 082269179f4c931d33d1c442e3afeb50 MD5 | raw file
  1import threading
  2from ctypes import byref, c_char_p, c_int, c_char, c_size_t, Structure, POINTER
  3from django.contrib.gis.geos.base import GEOSBase
  4from django.contrib.gis.geos.libgeos import GEOM_PTR
  5from django.contrib.gis.geos.prototypes.errcheck import check_geom, check_string, check_sized_string
  6from django.contrib.gis.geos.prototypes.geom import c_uchar_p, geos_char_p
  7from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc
  8
  9### The WKB/WKT Reader/Writer structures and pointers ###
 10class WKTReader_st(Structure): pass
 11class WKTWriter_st(Structure): pass
 12class WKBReader_st(Structure): pass
 13class WKBWriter_st(Structure): pass
 14
 15WKT_READ_PTR  = POINTER(WKTReader_st)
 16WKT_WRITE_PTR = POINTER(WKTWriter_st)
 17WKB_READ_PTR  = POINTER(WKBReader_st)
 18WKB_WRITE_PTR = POINTER(WKBReader_st)
 19
 20### WKTReader routines ###
 21wkt_reader_create = GEOSFunc('GEOSWKTReader_create')
 22wkt_reader_create.restype = WKT_READ_PTR
 23
 24wkt_reader_destroy = GEOSFunc('GEOSWKTReader_destroy')
 25wkt_reader_destroy.argtypes = [WKT_READ_PTR]
 26
 27wkt_reader_read = GEOSFunc('GEOSWKTReader_read')
 28wkt_reader_read.argtypes = [WKT_READ_PTR, c_char_p]
 29wkt_reader_read.restype = GEOM_PTR
 30wkt_reader_read.errcheck = check_geom
 31
 32### WKTWriter routines ###
 33wkt_writer_create = GEOSFunc('GEOSWKTWriter_create')
 34wkt_writer_create.restype = WKT_WRITE_PTR
 35
 36wkt_writer_destroy = GEOSFunc('GEOSWKTWriter_destroy')
 37wkt_writer_destroy.argtypes = [WKT_WRITE_PTR]
 38
 39wkt_writer_write = GEOSFunc('GEOSWKTWriter_write')
 40wkt_writer_write.argtypes = [WKT_WRITE_PTR, GEOM_PTR]
 41wkt_writer_write.restype = geos_char_p
 42wkt_writer_write.errcheck = check_string
 43
 44### WKBReader routines ###
 45wkb_reader_create = GEOSFunc('GEOSWKBReader_create')
 46wkb_reader_create.restype = WKB_READ_PTR
 47
 48wkb_reader_destroy = GEOSFunc('GEOSWKBReader_destroy')
 49wkb_reader_destroy.argtypes = [WKB_READ_PTR]
 50
 51def wkb_read_func(func):
 52    # Although the function definitions take `const unsigned char *`
 53    # as their parameter, we use c_char_p here so the function may
 54    # take Python strings directly as parameters.  Inside Python there
 55    # is not a difference between signed and unsigned characters, so
 56    # it is not a problem.
 57    func.argtypes = [WKB_READ_PTR, c_char_p, c_size_t]
 58    func.restype = GEOM_PTR
 59    func.errcheck = check_geom
 60    return func
 61
 62wkb_reader_read = wkb_read_func(GEOSFunc('GEOSWKBReader_read'))
 63wkb_reader_read_hex = wkb_read_func(GEOSFunc('GEOSWKBReader_readHEX'))
 64
 65### WKBWriter routines ###
 66wkb_writer_create = GEOSFunc('GEOSWKBWriter_create')
 67wkb_writer_create.restype = WKB_WRITE_PTR
 68
 69wkb_writer_destroy = GEOSFunc('GEOSWKBWriter_destroy')
 70wkb_writer_destroy.argtypes = [WKB_WRITE_PTR]
 71
 72# WKB Writing prototypes.
 73def wkb_write_func(func):
 74    func.argtypes = [WKB_WRITE_PTR, GEOM_PTR, POINTER(c_size_t)]
 75    func.restype = c_uchar_p
 76    func.errcheck = check_sized_string
 77    return func
 78
 79wkb_writer_write = wkb_write_func(GEOSFunc('GEOSWKBWriter_write'))
 80wkb_writer_write_hex = wkb_write_func(GEOSFunc('GEOSWKBWriter_writeHEX'))
 81
 82# WKBWriter property getter/setter prototypes.
 83def wkb_writer_get(func, restype=c_int):
 84    func.argtypes = [WKB_WRITE_PTR]
 85    func.restype = restype
 86    return func
 87
 88def wkb_writer_set(func, argtype=c_int):
 89    func.argtypes = [WKB_WRITE_PTR, argtype]
 90    return func
 91
 92wkb_writer_get_byteorder = wkb_writer_get(GEOSFunc('GEOSWKBWriter_getByteOrder'))
 93wkb_writer_set_byteorder = wkb_writer_set(GEOSFunc('GEOSWKBWriter_setByteOrder'))
 94wkb_writer_get_outdim    = wkb_writer_get(GEOSFunc('GEOSWKBWriter_getOutputDimension'))
 95wkb_writer_set_outdim    = wkb_writer_set(GEOSFunc('GEOSWKBWriter_setOutputDimension'))
 96wkb_writer_get_include_srid = wkb_writer_get(GEOSFunc('GEOSWKBWriter_getIncludeSRID'), restype=c_char)
 97wkb_writer_set_include_srid = wkb_writer_set(GEOSFunc('GEOSWKBWriter_setIncludeSRID'), argtype=c_char)
 98
 99### Base I/O Class ###
100class IOBase(GEOSBase):
101    "Base class for GEOS I/O objects."
102    def __init__(self):
103        # Getting the pointer with the constructor.
104        self.ptr = self._constructor()
105
106    def __del__(self):
107        # Cleaning up with the appropriate destructor.
108        if self._ptr: self._destructor(self._ptr)
109
110### Base WKB/WKT Reading and Writing objects ###
111
112# Non-public WKB/WKT reader classes for internal use because
113# their `read` methods return _pointers_ instead of GEOSGeometry
114# objects.
115class _WKTReader(IOBase):
116    _constructor = wkt_reader_create
117    _destructor = wkt_reader_destroy
118    ptr_type = WKT_READ_PTR
119
120    def read(self, wkt):
121        if not isinstance(wkt, basestring): raise TypeError
122        return wkt_reader_read(self.ptr, wkt)
123
124class _WKBReader(IOBase):
125    _constructor = wkb_reader_create
126    _destructor = wkb_reader_destroy
127    ptr_type = WKB_READ_PTR
128
129    def read(self, wkb):
130        "Returns a _pointer_ to C GEOS Geometry object from the given WKB."
131        if isinstance(wkb, buffer):
132            wkb_s = str(wkb)
133            return wkb_reader_read(self.ptr, wkb_s, len(wkb_s))
134        elif isinstance(wkb, basestring):
135            return wkb_reader_read_hex(self.ptr, wkb, len(wkb))
136        else:
137            raise TypeError
138
139### WKB/WKT Writer Classes ###
140class WKTWriter(IOBase):
141    _constructor = wkt_writer_create
142    _destructor = wkt_writer_destroy
143    ptr_type = WKT_WRITE_PTR
144
145    def write(self, geom):
146        "Returns the WKT representation of the given geometry."
147        return wkt_writer_write(self.ptr, geom.ptr)
148
149class WKBWriter(IOBase):
150    _constructor = wkb_writer_create
151    _destructor = wkb_writer_destroy
152    ptr_type = WKB_WRITE_PTR
153
154    def write(self, geom):
155        "Returns the WKB representation of the given geometry."
156        return buffer(wkb_writer_write(self.ptr, geom.ptr, byref(c_size_t())))
157
158    def write_hex(self, geom):
159        "Returns the HEXEWKB representation of the given geometry."
160        return wkb_writer_write_hex(self.ptr, geom.ptr, byref(c_size_t()))
161
162    ### WKBWriter Properties ###
163
164    # Property for getting/setting the byteorder.
165    def _get_byteorder(self):
166        return wkb_writer_get_byteorder(self.ptr)
167
168    def _set_byteorder(self, order):
169        if not order in (0, 1): raise ValueError('Byte order parameter must be 0 (Big Endian) or 1 (Little Endian).')
170        wkb_writer_set_byteorder(self.ptr, order)
171
172    byteorder = property(_get_byteorder, _set_byteorder)
173
174    # Property for getting/setting the output dimension.
175    def _get_outdim(self):
176        return wkb_writer_get_outdim(self.ptr)
177
178    def _set_outdim(self, new_dim):
179        if not new_dim in (2, 3): raise ValueError('WKB output dimension must be 2 or 3')
180        wkb_writer_set_outdim(self.ptr, new_dim)
181
182    outdim = property(_get_outdim, _set_outdim)
183
184    # Property for getting/setting the include srid flag.
185    def _get_include_srid(self):
186        return bool(ord(wkb_writer_get_include_srid(self.ptr)))
187
188    def _set_include_srid(self, include):
189        if bool(include): flag = chr(1)
190        else: flag = chr(0)
191        wkb_writer_set_include_srid(self.ptr, flag)
192
193    srid = property(_get_include_srid, _set_include_srid)
194
195# `ThreadLocalIO` object holds instances of the WKT and WKB reader/writer
196# objects that are local to the thread.  The `GEOSGeometry` internals
197# access these instances by calling the module-level functions, defined
198# below. 
199class ThreadLocalIO(threading.local):
200    wkt_r = None
201    wkt_w = None
202    wkb_r = None
203    wkb_w = None
204    ewkb_w = None
205    ewkb_w3d = None
206
207thread_context = ThreadLocalIO()
208
209# These module-level routines return the I/O object that is local to the
210# the thread.  If the I/O object does not exist yet it will be initialized.
211def wkt_r():
212    if not thread_context.wkt_r:
213        thread_context.wkt_r = _WKTReader()
214    return thread_context.wkt_r
215
216def wkt_w():
217    if not thread_context.wkt_w:
218        thread_context.wkt_w = WKTWriter()
219    return thread_context.wkt_w
220
221def wkb_r():
222    if not thread_context.wkb_r:
223        thread_context.wkb_r = _WKBReader()
224    return thread_context.wkb_r
225
226def wkb_w():
227   if not thread_context.wkb_w:
228       thread_context.wkb_w = WKBWriter()
229   return thread_context.wkb_w
230
231def ewkb_w():
232    if not thread_context.ewkb_w:
233        thread_context.ewkb_w = WKBWriter()
234        thread_context.ewkb_w.srid = True
235    return thread_context.ewkb_w
236
237def ewkb_w3d():
238    if not thread_context.ewkb_w3d:
239        thread_context.ewkb_w3d = WKBWriter()
240        thread_context.ewkb_w3d.srid = True
241        thread_context.ewkb_w3d.outdim = 3
242    return thread_context.ewkb_w3d