2
Module that holds classes for performing I/O operations on GEOS geometry
3
objects. Specifically, this has Python implementations of WKB/WKT
4
reader and writer classes.
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
10
from django.contrib.gis.geos.libgeos import GEOM_PTR
11
from django.contrib.gis.geos.prototypes import io as capi
13
class IOBase(GEOSBase):
14
"Base class for GEOS I/O objects."
16
# Getting the pointer with the constructor.
17
self.ptr = self.constructor()
20
# Cleaning up with the appropriate destructor.
21
if self._ptr: self.destructor(self._ptr)
23
### WKT Reading and Writing objects ###
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
33
if not isinstance(wkt, basestring): raise TypeError
34
return capi.wkt_reader_read(self.ptr, wkt)
36
class WKTReader(_WKTReader):
38
"Returns a GEOSGeometry for the given WKT string."
39
return GEOSGeometry(super(WKTReader, self).read(wkt))
41
class WKTWriter(IOBase):
42
constructor = capi.wkt_writer_create
43
destructor = capi.wkt_writer_destroy
44
ptr_type = capi.WKT_WRITE_PTR
46
def write(self, geom):
47
"Returns the WKT representation of the given geometry."
48
return capi.wkt_writer_write(self.ptr, geom.ptr)
50
### WKB Reading and Writing objects ###
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
59
"Returns a _pointer_ to C GEOS Geometry object from the given WKB."
60
if isinstance(wkb, buffer):
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))
68
class WKBReader(_WKBReader):
70
"Returns a GEOSGeometry for the given WKB buffer."
71
return GEOSGeometry(super(WKBReader, self).read(wkb))
73
class WKBWriter(IOBase):
74
constructor = capi.wkb_writer_create
75
destructor = capi.wkb_writer_destroy
76
ptr_type = capi.WKB_WRITE_PTR
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())))
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()))
86
### WKBWriter Properties ###
88
# Property for getting/setting the byteorder.
89
def _get_byteorder(self):
90
return capi.wkb_writer_get_byteorder(self.ptr)
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)
96
byteorder = property(_get_byteorder, _set_byteorder)
98
# Property for getting/setting the output dimension.
99
def _get_outdim(self):
100
return capi.wkb_writer_get_outdim(self.ptr)
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)
106
outdim = property(_get_outdim, _set_outdim)
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)))
112
def _set_include_srid(self, include):
113
if bool(include): flag = chr(1)
115
capi.wkb_writer_set_include_srid(self.ptr, flag)
117
srid = property(_get_include_srid, _set_include_srid)
119
# Instances of the WKT and WKB reader/writer objects.