git-svn-id: http://code.djangoproject.com/svn/django/trunk@11728 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
f3bb5276e0
commit
36fe303e35
|
@ -357,26 +357,42 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
#### Output Routines ####
|
#### Output Routines ####
|
||||||
@property
|
@property
|
||||||
def ewkt(self):
|
def ewkt(self):
|
||||||
"Returns the EWKT (WKT + SRID) of the Geometry."
|
"""
|
||||||
|
Returns the EWKT (WKT + SRID) of the Geometry. Note that Z values
|
||||||
|
are *not* included in this representation because GEOS does not yet
|
||||||
|
support serializing them.
|
||||||
|
"""
|
||||||
if self.get_srid(): return 'SRID=%s;%s' % (self.srid, self.wkt)
|
if self.get_srid(): return 'SRID=%s;%s' % (self.srid, self.wkt)
|
||||||
else: return self.wkt
|
else: return self.wkt
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def wkt(self):
|
def wkt(self):
|
||||||
"Returns the WKT (Well-Known Text) of the Geometry."
|
"Returns the WKT (Well-Known Text) representation of this Geometry."
|
||||||
return wkt_w.write(self)
|
return wkt_w.write(self)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hex(self):
|
def hex(self):
|
||||||
"""
|
"""
|
||||||
Returns the HEX of the Geometry -- please note that the SRID is not
|
Returns the HEX of the Geometry -- please note that the SRID is not
|
||||||
included in this representation, because the GEOS C library uses
|
included in this representation, because it is not a part of the
|
||||||
-1 by default, even if the SRID is set.
|
OGC specification (use the `hexewkb` property instead).
|
||||||
"""
|
"""
|
||||||
# A possible faster, all-python, implementation:
|
# A possible faster, all-python, implementation:
|
||||||
# str(self.wkb).encode('hex')
|
# str(self.wkb).encode('hex')
|
||||||
return wkb_w.write_hex(self)
|
return wkb_w.write_hex(self)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def hexewkb(self):
|
||||||
|
"""
|
||||||
|
Returns the HEXEWKB of this Geometry. This is an extension of the WKB
|
||||||
|
specification that includes SRID and Z values taht are a part of this
|
||||||
|
geometry.
|
||||||
|
"""
|
||||||
|
if self.hasz:
|
||||||
|
return ewkb_w3d.write_hex(self)
|
||||||
|
else:
|
||||||
|
return ewkb_w.write_hex(self)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def json(self):
|
def json(self):
|
||||||
"""
|
"""
|
||||||
|
@ -391,9 +407,25 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def wkb(self):
|
def wkb(self):
|
||||||
"Returns the WKB of the Geometry as a buffer."
|
"""
|
||||||
|
Returns the WKB (Well-Known Binary) representation of this Geometry
|
||||||
|
as a Python buffer. SRID and Z values are not included, use the
|
||||||
|
`ewkb` property instead.
|
||||||
|
"""
|
||||||
return wkb_w.write(self)
|
return wkb_w.write(self)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ewkb(self):
|
||||||
|
"""
|
||||||
|
Return the EWKB representation of this Geometry as a Python buffer.
|
||||||
|
This is an extension of the WKB specification that includes any SRID
|
||||||
|
and Z values that are a part of this geometry.
|
||||||
|
"""
|
||||||
|
if self.hasz:
|
||||||
|
return ewkb_w3d.write(self)
|
||||||
|
else:
|
||||||
|
return ewkb_w.write(self)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def kml(self):
|
def kml(self):
|
||||||
"Returns the KML representation of this Geometry."
|
"Returns the KML representation of this Geometry."
|
||||||
|
@ -617,7 +649,7 @@ GEOS_CLASSES = {0 : Point,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Similarly, import the GEOS I/O instances here to avoid conflicts.
|
# Similarly, import the GEOS I/O instances here to avoid conflicts.
|
||||||
from django.contrib.gis.geos.io import wkt_r, wkt_w, wkb_r, wkb_w
|
from django.contrib.gis.geos.io import wkt_r, wkt_w, wkb_r, wkb_w, ewkb_w, ewkb_w3d
|
||||||
|
|
||||||
# If supported, import the PreparedGeometry class.
|
# If supported, import the PreparedGeometry class.
|
||||||
if GEOS_PREPARE:
|
if GEOS_PREPARE:
|
||||||
|
|
|
@ -14,19 +14,19 @@ class IOBase(GEOSBase):
|
||||||
"Base class for GEOS I/O objects."
|
"Base class for GEOS I/O objects."
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# Getting the pointer with the constructor.
|
# Getting the pointer with the constructor.
|
||||||
self.ptr = self.constructor()
|
self.ptr = self._constructor()
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
# Cleaning up with the appropriate destructor.
|
# Cleaning up with the appropriate destructor.
|
||||||
if self._ptr: self.destructor(self._ptr)
|
if self._ptr: self._destructor(self._ptr)
|
||||||
|
|
||||||
### WKT Reading and Writing objects ###
|
### WKT Reading and Writing objects ###
|
||||||
|
|
||||||
# Non-public class for internal use because its `read` method returns
|
# Non-public class for internal use because its `read` method returns
|
||||||
# _pointers_ instead of a GEOSGeometry object.
|
# _pointers_ instead of a GEOSGeometry object.
|
||||||
class _WKTReader(IOBase):
|
class _WKTReader(IOBase):
|
||||||
constructor = capi.wkt_reader_create
|
_constructor = capi.wkt_reader_create
|
||||||
destructor = capi.wkt_reader_destroy
|
_destructor = capi.wkt_reader_destroy
|
||||||
ptr_type = capi.WKT_READ_PTR
|
ptr_type = capi.WKT_READ_PTR
|
||||||
|
|
||||||
def read(self, wkt):
|
def read(self, wkt):
|
||||||
|
@ -39,8 +39,8 @@ class WKTReader(_WKTReader):
|
||||||
return GEOSGeometry(super(WKTReader, self).read(wkt))
|
return GEOSGeometry(super(WKTReader, self).read(wkt))
|
||||||
|
|
||||||
class WKTWriter(IOBase):
|
class WKTWriter(IOBase):
|
||||||
constructor = capi.wkt_writer_create
|
_constructor = capi.wkt_writer_create
|
||||||
destructor = capi.wkt_writer_destroy
|
_destructor = capi.wkt_writer_destroy
|
||||||
ptr_type = capi.WKT_WRITE_PTR
|
ptr_type = capi.WKT_WRITE_PTR
|
||||||
|
|
||||||
def write(self, geom):
|
def write(self, geom):
|
||||||
|
@ -51,8 +51,8 @@ class WKTWriter(IOBase):
|
||||||
|
|
||||||
# Non-public class for the same reason as _WKTReader above.
|
# Non-public class for the same reason as _WKTReader above.
|
||||||
class _WKBReader(IOBase):
|
class _WKBReader(IOBase):
|
||||||
constructor = capi.wkb_reader_create
|
_constructor = capi.wkb_reader_create
|
||||||
destructor = capi.wkb_reader_destroy
|
_destructor = capi.wkb_reader_destroy
|
||||||
ptr_type = capi.WKB_READ_PTR
|
ptr_type = capi.WKB_READ_PTR
|
||||||
|
|
||||||
def read(self, wkb):
|
def read(self, wkb):
|
||||||
|
@ -71,8 +71,8 @@ class WKBReader(_WKBReader):
|
||||||
return GEOSGeometry(super(WKBReader, self).read(wkb))
|
return GEOSGeometry(super(WKBReader, self).read(wkb))
|
||||||
|
|
||||||
class WKBWriter(IOBase):
|
class WKBWriter(IOBase):
|
||||||
constructor = capi.wkb_writer_create
|
_constructor = capi.wkb_writer_create
|
||||||
destructor = capi.wkb_writer_destroy
|
_destructor = capi.wkb_writer_destroy
|
||||||
ptr_type = capi.WKB_WRITE_PTR
|
ptr_type = capi.WKB_WRITE_PTR
|
||||||
|
|
||||||
def write(self, geom):
|
def write(self, geom):
|
||||||
|
@ -121,3 +121,10 @@ wkt_r = _WKTReader()
|
||||||
wkt_w = WKTWriter()
|
wkt_w = WKTWriter()
|
||||||
wkb_r = _WKBReader()
|
wkb_r = _WKBReader()
|
||||||
wkb_w = WKBWriter()
|
wkb_w = WKBWriter()
|
||||||
|
|
||||||
|
# These instances are for writing EWKB in 2D and 3D.
|
||||||
|
ewkb_w = WKBWriter()
|
||||||
|
ewkb_w.srid = True
|
||||||
|
ewkb_w3d = WKBWriter()
|
||||||
|
ewkb_w3d.srid = True
|
||||||
|
ewkb_w3d.outdim = 3
|
||||||
|
|
|
@ -62,17 +62,16 @@ def string_from_geom(func):
|
||||||
|
|
||||||
### ctypes prototypes ###
|
### ctypes prototypes ###
|
||||||
|
|
||||||
# Deprecated creation routines from WKB, HEX, WKT
|
# Deprecated creation and output routines from WKB, HEX, WKT
|
||||||
from_hex = bin_constructor(lgeos.GEOSGeomFromHEX_buf)
|
from_hex = bin_constructor(lgeos.GEOSGeomFromHEX_buf)
|
||||||
from_wkb = bin_constructor(lgeos.GEOSGeomFromWKB_buf)
|
from_wkb = bin_constructor(lgeos.GEOSGeomFromWKB_buf)
|
||||||
from_wkt = geom_output(lgeos.GEOSGeomFromWKT, [c_char_p])
|
from_wkt = geom_output(lgeos.GEOSGeomFromWKT, [c_char_p])
|
||||||
|
|
||||||
# Output routines
|
|
||||||
to_hex = bin_output(lgeos.GEOSGeomToHEX_buf)
|
to_hex = bin_output(lgeos.GEOSGeomToHEX_buf)
|
||||||
to_wkb = bin_output(lgeos.GEOSGeomToWKB_buf)
|
to_wkb = bin_output(lgeos.GEOSGeomToWKB_buf)
|
||||||
to_wkt = string_from_geom(lgeos.GEOSGeomToWKT)
|
to_wkt = string_from_geom(lgeos.GEOSGeomToWKT)
|
||||||
|
|
||||||
# The GEOS geometry type, typeid, num_coordites and number of geometries
|
# The GEOS geometry type, typeid, num_coordinates and number of geometries
|
||||||
geos_normalize = int_from_geom(lgeos.GEOSNormalize)
|
geos_normalize = int_from_geom(lgeos.GEOSNormalize)
|
||||||
geos_type = string_from_geom(lgeos.GEOSGeomType)
|
geos_type = string_from_geom(lgeos.GEOSGeomType)
|
||||||
geos_typeid = int_from_geom(lgeos.GEOSGeomTypeId)
|
geos_typeid = int_from_geom(lgeos.GEOSGeomTypeId)
|
||||||
|
|
|
@ -71,6 +71,31 @@ class GEOSTest(unittest.TestCase):
|
||||||
geom = fromstr(g.wkt)
|
geom = fromstr(g.wkt)
|
||||||
self.assertEqual(g.hex, geom.hex)
|
self.assertEqual(g.hex, geom.hex)
|
||||||
|
|
||||||
|
def test01b_hexewkb(self):
|
||||||
|
"Testing (HEX)EWKB output."
|
||||||
|
from binascii import a2b_hex
|
||||||
|
|
||||||
|
pnt_2d = Point(0, 1, srid=4326)
|
||||||
|
pnt_3d = Point(0, 1, 2, srid=4326)
|
||||||
|
|
||||||
|
# OGC-compliant HEX will not have SRID nor Z value.
|
||||||
|
self.assertEqual(ogc_hex, pnt_2d.hex)
|
||||||
|
self.assertEqual(ogc_hex, pnt_3d.hex)
|
||||||
|
|
||||||
|
# HEXEWKB should be appropriate for its dimension -- have to use an
|
||||||
|
# a WKBWriter w/dimension set accordingly, else GEOS will insert
|
||||||
|
# garbage into 3D coordinate if there is none.
|
||||||
|
self.assertEqual(hexewkb_2d, pnt_2d.hexewkb)
|
||||||
|
self.assertEqual(hexewkb_3d, pnt_3d.hexewkb)
|
||||||
|
|
||||||
|
# Same for EWKB.
|
||||||
|
self.assertEqual(buffer(a2b_hex(hexewkb_2d)), pnt_2d.ewkb)
|
||||||
|
self.assertEqual(buffer(a2b_hex(hexewkb_3d)), pnt_3d.ewkb)
|
||||||
|
|
||||||
|
# Redundant sanity check.
|
||||||
|
self.assertEqual(True, GEOSGeometry(hexewkb_3d).hasz)
|
||||||
|
self.assertEqual(4326, GEOSGeometry(hexewkb_2d).srid)
|
||||||
|
|
||||||
def test01c_kml(self):
|
def test01c_kml(self):
|
||||||
"Testing KML output."
|
"Testing KML output."
|
||||||
for tg in wkt_out:
|
for tg in wkt_out:
|
||||||
|
|
|
@ -171,3 +171,10 @@ json_geoms = (TestGeom('POINT(100 0)', json='{ "type": "Point", "coordinates": [
|
||||||
not_equal=True,
|
not_equal=True,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# For testing HEX(EWKB).
|
||||||
|
ogc_hex = '01010000000000000000000000000000000000F03F'
|
||||||
|
# `SELECT ST_AsHEXEWKB(ST_GeomFromText('POINT(0 1)', 4326));`
|
||||||
|
hexewkb_2d = '0101000020E61000000000000000000000000000000000F03F'
|
||||||
|
# `SELECT ST_AsHEXEWKB(ST_GeomFromEWKT('SRID=4326;POINT(0 1 2)'));`
|
||||||
|
hexewkb_3d = '01010000A0E61000000000000000000000000000000000F03F0000000000000040'
|
||||||
|
|
Loading…
Reference in New Issue