Skip to content

Commit

Permalink
Refs #35058 -- Made centroid available on all geometry types.
Browse files Browse the repository at this point in the history
Centroid is available on all geometry types since GDAL 1.8.0.
Previously it was restricted to Polygon.

https://gdal.org/doxygen/classOGRGeometry.html#a91787f669b2a148169667e270e7e40df
  • Loading branch information
smithdc1 authored and felixxm committed Jan 28, 2024
1 parent 9c6d7b4 commit 2005530
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 12 deletions.
16 changes: 8 additions & 8 deletions django/contrib/gis/gdal/geometries.py
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,14 @@ def union(self, other):
"""
return self._geomgen(capi.geom_union, other)

@property
def centroid(self):
"""Return the centroid (a Point) of this Polygon."""
# The centroid is a Point, create a geometry for this.
p = OGRGeometry(OGRGeomType("Point"))
capi.get_centroid(self.ptr, p.ptr)
return p


# The subclasses for OGR Geometry.
class Point(OGRGeometry):
Expand Down Expand Up @@ -708,14 +716,6 @@ def point_count(self):
# Summing up the number of points in each ring of the Polygon.
return sum(self[i].point_count for i in range(self.geom_count))

@property
def centroid(self):
"Return the centroid (a Point) of this Polygon."
# The centroid is a Point, create a geometry for this.
p = OGRGeometry(OGRGeomType("Point"))
capi.get_centroid(self.ptr, p.ptr)
return p


# Geometry Collection base class.
class GeometryCollection(OGRGeometry):
Expand Down
13 changes: 9 additions & 4 deletions docs/ref/contrib/gis/gdal.txt
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,15 @@ coordinate transformation:
Returns the region consisting of the union of this geometry and
the other, as a new :class:`OGRGeometry` object.

.. attribute:: centroid

Returns a :class:`Point` representing the centroid of this geometry.

.. versionchanged:: 5.1

``centroid`` was promoted from a :class:`.Polygon` only attribute to
being available on all geometry types.

.. attribute:: tuple

Returns the coordinates of a point geometry as a tuple, the
Expand Down Expand Up @@ -939,10 +948,6 @@ coordinate transformation:

An alias for :attr:`shell`.

.. attribute:: centroid

Returns a :class:`Point` representing the centroid of this polygon.

.. class:: GeometryCollection

.. method:: add(geom)
Expand Down
3 changes: 3 additions & 0 deletions docs/releases/5.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ Minor features
via the new :attr:`.OGRGeometry.is_measured` and :attr:`.Point.m` properties,
and the :meth:`.OGRGeometry.set_measured` method.

* :attr:`.OGRGeometry.centroid` is now available on all supported geometry
types.

:mod:`django.contrib.messages`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
23 changes: 23 additions & 0 deletions tests/gis_tests/gdal_tests/test_geom.py
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,29 @@ def test_point_m_dimension_geos(self):
geom = OGRGeometry("POINT M (1 2 3)")
self.assertEqual(geom.geos.wkt, "POINT (1 2)")

def test_centroid(self):
point = OGRGeometry("POINT (1 2 3)")
self.assertEqual(point.centroid.wkt, "POINT (1 2)")
linestring = OGRGeometry("LINESTRING (0 0 0, 1 1 1, 2 2 2)")
self.assertEqual(linestring.centroid.wkt, "POINT (1 1)")
polygon = OGRGeometry("POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))")
self.assertEqual(polygon.centroid.wkt, "POINT (5 5)")
multipoint = OGRGeometry("MULTIPOINT (0 0,10 10)")
self.assertEqual(multipoint.centroid.wkt, "POINT (5 5)")
multilinestring = OGRGeometry(
"MULTILINESTRING ((0 0,0 10,0 20),(10 0,10 10,10 20))"
)
self.assertEqual(multilinestring.centroid.wkt, "POINT (5 10)")
multipolygon = OGRGeometry(
"MULTIPOLYGON(((0 0, 10 0, 10 10, 0 10, 0 0)),"
"((20 20, 20 30, 30 30, 30 20, 20 20)))"
)
self.assertEqual(multipolygon.centroid.wkt, "POINT (15 15)")
geometrycollection = OGRGeometry(
"GEOMETRYCOLLECTION (POINT (110 260),LINESTRING (110 0,110 60))"
)
self.assertEqual(geometrycollection.centroid.wkt, "POINT (110 30)")


class DeprecationTests(SimpleTestCase):
def test_coord_setter_deprecation(self):
Expand Down

0 comments on commit 2005530

Please sign in to comment.