mirror of https://github.com/django/django.git
Refs #35058 -- Added is_3d and set_3d() to OGRGeometry.
This commit is contained in:
parent
12c71bff83
commit
cfacd69ab8
|
@ -268,6 +268,20 @@ class OGRGeometry(GDALBase):
|
||||||
"Return the envelope as a 4-tuple, instead of as an Envelope object."
|
"Return the envelope as a 4-tuple, instead of as an Envelope object."
|
||||||
return self.envelope.tuple
|
return self.envelope.tuple
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_3d(self):
|
||||||
|
"""Return True if the geometry has Z coordinates."""
|
||||||
|
return capi.is_3d(self.ptr)
|
||||||
|
|
||||||
|
def set_3d(self, value):
|
||||||
|
"""Set if this geometry has Z coordinates."""
|
||||||
|
if value is True:
|
||||||
|
capi.set_3d(self.ptr, 1)
|
||||||
|
elif value is False:
|
||||||
|
capi.set_3d(self.ptr, 0)
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Input to 'set_3d' must be a boolean, got '{value!r}'.")
|
||||||
|
|
||||||
# #### SpatialReference-related Properties ####
|
# #### SpatialReference-related Properties ####
|
||||||
|
|
||||||
# The SRS property
|
# The SRS property
|
||||||
|
@ -546,16 +560,15 @@ class Point(OGRGeometry):
|
||||||
@property
|
@property
|
||||||
def z(self):
|
def z(self):
|
||||||
"Return the Z coordinate for this Point."
|
"Return the Z coordinate for this Point."
|
||||||
if self.coord_dim == 3:
|
if self.is_3d:
|
||||||
return capi.getz(self.ptr, 0)
|
return capi.getz(self.ptr, 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tuple(self):
|
def tuple(self):
|
||||||
"Return the tuple of this point."
|
"Return the tuple of this point."
|
||||||
if self.coord_dim == 2:
|
if self.is_3d:
|
||||||
return (self.x, self.y)
|
|
||||||
elif self.coord_dim == 3:
|
|
||||||
return (self.x, self.y, self.z)
|
return (self.x, self.y, self.z)
|
||||||
|
return self.x, self.y
|
||||||
|
|
||||||
coords = tuple
|
coords = tuple
|
||||||
|
|
||||||
|
@ -566,13 +579,13 @@ class LineString(OGRGeometry):
|
||||||
if 0 <= index < self.point_count:
|
if 0 <= index < self.point_count:
|
||||||
x, y, z = c_double(), c_double(), c_double()
|
x, y, z = c_double(), c_double(), c_double()
|
||||||
capi.get_point(self.ptr, index, byref(x), byref(y), byref(z))
|
capi.get_point(self.ptr, index, byref(x), byref(y), byref(z))
|
||||||
|
if self.is_3d:
|
||||||
|
return x.value, y.value, z.value
|
||||||
dim = self.coord_dim
|
dim = self.coord_dim
|
||||||
if dim == 1:
|
if dim == 1:
|
||||||
return (x.value,)
|
return (x.value,)
|
||||||
elif dim == 2:
|
elif dim == 2:
|
||||||
return (x.value, y.value)
|
return (x.value, y.value)
|
||||||
elif dim == 3:
|
|
||||||
return (x.value, y.value, z.value)
|
|
||||||
else:
|
else:
|
||||||
raise IndexError(
|
raise IndexError(
|
||||||
"Index out of range when accessing points of a line string: %s." % index
|
"Index out of range when accessing points of a line string: %s." % index
|
||||||
|
@ -609,7 +622,7 @@ class LineString(OGRGeometry):
|
||||||
@property
|
@property
|
||||||
def z(self):
|
def z(self):
|
||||||
"Return the Z coordinates in a list."
|
"Return the Z coordinates in a list."
|
||||||
if self.coord_dim == 3:
|
if self.is_3d:
|
||||||
return self._listarr(capi.getz)
|
return self._listarr(capi.getz)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ from django.contrib.gis.gdal.envelope import OGREnvelope
|
||||||
from django.contrib.gis.gdal.libgdal import GDAL_VERSION, lgdal
|
from django.contrib.gis.gdal.libgdal import GDAL_VERSION, lgdal
|
||||||
from django.contrib.gis.gdal.prototypes.errcheck import check_envelope
|
from django.contrib.gis.gdal.prototypes.errcheck import check_envelope
|
||||||
from django.contrib.gis.gdal.prototypes.generation import (
|
from django.contrib.gis.gdal.prototypes.generation import (
|
||||||
|
bool_output,
|
||||||
const_string_output,
|
const_string_output,
|
||||||
double_output,
|
double_output,
|
||||||
geom_output,
|
geom_output,
|
||||||
|
@ -79,6 +80,8 @@ geom_diff = geom_output(lgdal.OGR_G_Difference, [c_void_p, c_void_p])
|
||||||
geom_intersection = geom_output(lgdal.OGR_G_Intersection, [c_void_p, c_void_p])
|
geom_intersection = geom_output(lgdal.OGR_G_Intersection, [c_void_p, c_void_p])
|
||||||
geom_sym_diff = geom_output(lgdal.OGR_G_SymmetricDifference, [c_void_p, c_void_p])
|
geom_sym_diff = geom_output(lgdal.OGR_G_SymmetricDifference, [c_void_p, c_void_p])
|
||||||
geom_union = geom_output(lgdal.OGR_G_Union, [c_void_p, c_void_p])
|
geom_union = geom_output(lgdal.OGR_G_Union, [c_void_p, c_void_p])
|
||||||
|
is_3d = bool_output(lgdal.OGR_G_Is3D, [c_void_p])
|
||||||
|
set_3d = void_output(lgdal.OGR_G_Set3D, [c_void_p, c_int], errcheck=False)
|
||||||
|
|
||||||
# Geometry modification routines.
|
# Geometry modification routines.
|
||||||
add_geom = void_output(lgdal.OGR_G_AddGeometry, [c_void_p, c_void_p])
|
add_geom = void_output(lgdal.OGR_G_AddGeometry, [c_void_p, c_void_p])
|
||||||
|
|
|
@ -489,8 +489,8 @@ class LayerMapping:
|
||||||
the mapped shapefile only contains Polygons).
|
the mapped shapefile only contains Polygons).
|
||||||
"""
|
"""
|
||||||
# Downgrade a 3D geom to a 2D one, if necessary.
|
# Downgrade a 3D geom to a 2D one, if necessary.
|
||||||
if self.coord_dim != geom.coord_dim:
|
if self.coord_dim == 2 and geom.is_3d:
|
||||||
geom.coord_dim = self.coord_dim
|
geom.set_3d(False)
|
||||||
|
|
||||||
if self.make_multi(geom.geom_type, model_field):
|
if self.make_multi(geom.geom_type, model_field):
|
||||||
# Constructing a multi-geometry type to contain the single geometry
|
# Constructing a multi-geometry type to contain the single geometry
|
||||||
|
|
|
@ -556,6 +556,27 @@ coordinate transformation:
|
||||||
Returns or sets the coordinate dimension of this geometry. For example, the
|
Returns or sets the coordinate dimension of this geometry. For example, the
|
||||||
value would be 2 for two-dimensional geometries.
|
value would be 2 for two-dimensional geometries.
|
||||||
|
|
||||||
|
.. attribute:: is_3d
|
||||||
|
|
||||||
|
.. versionadded:: 5.1
|
||||||
|
|
||||||
|
A boolean indicating if this geometry has Z coordinates.
|
||||||
|
|
||||||
|
.. method:: set_3d(value)
|
||||||
|
|
||||||
|
.. versionadded:: 5.1
|
||||||
|
|
||||||
|
A method that adds or removes the Z coordinate dimension.
|
||||||
|
|
||||||
|
.. code-block:: pycon
|
||||||
|
|
||||||
|
>>> p = OGRGeometry("POINT (1 2 3)")
|
||||||
|
>>> p.is_3d
|
||||||
|
True
|
||||||
|
>>> p.set_3d(False)
|
||||||
|
>>> p.wkt
|
||||||
|
"POINT (1 2)"
|
||||||
|
|
||||||
.. attribute:: geom_count
|
.. attribute:: geom_count
|
||||||
|
|
||||||
Returns the number of elements in this geometry:
|
Returns the number of elements in this geometry:
|
||||||
|
|
|
@ -72,6 +72,12 @@ Minor features
|
||||||
|
|
||||||
* :class:`~django.contrib.gis.measure.Area` now supports the ``ha`` unit.
|
* :class:`~django.contrib.gis.measure.Area` now supports the ``ha`` unit.
|
||||||
|
|
||||||
|
* The new :attr:`.OGRGeometry.is_3d` attribute allows checking if a geometry
|
||||||
|
has a ``Z`` coordinate dimension.
|
||||||
|
|
||||||
|
* The new :meth:`.OGRGeometry.set_3d` method allows addition and removal of the
|
||||||
|
``Z`` coordinate dimension.
|
||||||
|
|
||||||
:mod:`django.contrib.messages`
|
:mod:`django.contrib.messages`
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -714,3 +714,16 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
|
||||||
msg = f"Unsupported geometry type: {type_}"
|
msg = f"Unsupported geometry type: {type_}"
|
||||||
with self.assertRaisesMessage(TypeError, msg):
|
with self.assertRaisesMessage(TypeError, msg):
|
||||||
OGRGeometry(f"{geom_type} EMPTY")
|
OGRGeometry(f"{geom_type} EMPTY")
|
||||||
|
|
||||||
|
def test_is_3d_and_set_3d(self):
|
||||||
|
geom = OGRGeometry("POINT (1 2)")
|
||||||
|
self.assertIs(geom.is_3d, False)
|
||||||
|
geom.set_3d(True)
|
||||||
|
self.assertIs(geom.is_3d, True)
|
||||||
|
self.assertEqual(geom.wkt, "POINT (1 2 0)")
|
||||||
|
geom.set_3d(False)
|
||||||
|
self.assertIs(geom.is_3d, False)
|
||||||
|
self.assertEqual(geom.wkt, "POINT (1 2)")
|
||||||
|
msg = "Input to 'set_3d' must be a boolean, got 'None'"
|
||||||
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
|
geom.set_3d(None)
|
||||||
|
|
Loading…
Reference in New Issue