From 034dfbfc057b6090f9f2589731b8f58a70e4f885 Mon Sep 17 00:00:00 2001 From: Sergey Fedoseev Date: Mon, 9 Nov 2015 22:36:12 +0500 Subject: [PATCH] Fixed #25654 -- Added the GEOSGeometry.unary_union property. --- django/contrib/gis/geos/geometry.py | 5 +++++ django/contrib/gis/geos/prototypes/topology.py | 1 + docs/ref/contrib/gis/geos.txt | 15 +++++++++++++++ docs/releases/1.10.txt | 4 ++++ docs/spelling_wordlist | 3 +++ tests/gis_tests/geos_tests/test_geos.py | 9 +++++++++ 6 files changed, 37 insertions(+) diff --git a/django/contrib/gis/geos/geometry.py b/django/contrib/gis/geos/geometry.py index 78e6aa900be..d0d0d9f0081 100644 --- a/django/contrib/gis/geos/geometry.py +++ b/django/contrib/gis/geos/geometry.py @@ -621,6 +621,11 @@ class GEOSGeometry(GEOSBase, ListMixin): """ return self._topology(capi.geos_symdifference(self.ptr, other.ptr)) + @property + def unary_union(self): + "Return the union of all the elements of this geometry." + return self._topology(capi.geos_unary_union(self.ptr)) + def union(self, other): "Returns a Geometry representing all the points in this Geometry and other." return self._topology(capi.geos_union(self.ptr, other.ptr)) diff --git a/django/contrib/gis/geos/prototypes/topology.py b/django/contrib/gis/geos/prototypes/topology.py index fa7af0e0662..b2cf0681a8d 100644 --- a/django/contrib/gis/geos/prototypes/topology.py +++ b/django/contrib/gis/geos/prototypes/topology.py @@ -34,6 +34,7 @@ geos_symdifference = Topology('GEOSSymDifference', argtypes=[GEOM_PTR, GEOM_PTR] geos_union = Topology('GEOSUnion', argtypes=[GEOM_PTR, GEOM_PTR]) geos_cascaded_union = GEOSFuncFactory('GEOSUnionCascaded', argtypes=[GEOM_PTR], restype=GEOM_PTR) +geos_unary_union = GEOSFuncFactory('GEOSUnaryUnion', argtypes=[GEOM_PTR], restype=GEOM_PTR) # GEOSRelate returns a string, not a geometry. geos_relate = GEOSFuncFactory( diff --git a/docs/ref/contrib/gis/geos.txt b/docs/ref/contrib/gis/geos.txt index 7415acea97d..fffaf61fe75 100644 --- a/docs/ref/contrib/gis/geos.txt +++ b/docs/ref/contrib/gis/geos.txt @@ -497,6 +497,21 @@ geometry is a point. Computes and returns a :class:`Point` guaranteed to be on the interior of this geometry. +.. attribute:: GEOSGeometry.unary_union + +.. versionadded:: 1.10 + +Computes the union of all the elements of this geometry. + +The result obeys the following contract: + +* Unioning a set of :class:`LineString`\s has the effect of fully noding and + dissolving the linework. + +* Unioning a set of :class:`Polygon`\s will always return a :class:`Polygon` or + :class:`MultiPolygon` geometry (unlike :meth:`GEOSGeometry.union`, which may + return geometries of lower dimension if a topology collapse occurs). + Other Properties & Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/releases/1.10.txt b/docs/releases/1.10.txt index d16075f00f2..bcda61f09c1 100644 --- a/docs/releases/1.10.txt +++ b/docs/releases/1.10.txt @@ -64,6 +64,10 @@ Minor features * :ref:`Distance lookups ` now accept expressions as the distance value parameter. +* The new :attr:`GEOSGeometry.unary_union + ` property computes the + union of all the elements of this geometry. + :mod:`django.contrib.messages` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/spelling_wordlist b/docs/spelling_wordlist index ba7c5650b39..a75430e8715 100644 --- a/docs/spelling_wordlist +++ b/docs/spelling_wordlist @@ -421,6 +421,7 @@ linebreaks linebreaksbr linenumbers linestring +linework Livni ljust loaddata @@ -520,6 +521,7 @@ nestable neuroscientist newforms nginx +noding nonspatial nullable OAuth @@ -877,6 +879,7 @@ unicode uninstall uninstalling uninstalls +unioning uniterated unittest unittests diff --git a/tests/gis_tests/geos_tests/test_geos.py b/tests/gis_tests/geos_tests/test_geos.py index d983af98eaf..10077ae52eb 100644 --- a/tests/gis_tests/geos_tests/test_geos.py +++ b/tests/gis_tests/geos_tests/test_geos.py @@ -582,6 +582,15 @@ class GEOSTest(SimpleTestCase, TestDataMixin): a |= b # testing __ior__ self.assertEqual(u1, a) + def test_unary_union(self): + "Testing unary_union." + for i in range(len(self.geometries.topology_geoms)): + a = fromstr(self.geometries.topology_geoms[i].wkt_a) + b = fromstr(self.geometries.topology_geoms[i].wkt_b) + u1 = fromstr(self.geometries.union_geoms[i].wkt) + u2 = GeometryCollection(a, b).unary_union + self.assertTrue(u1.equals(u2)) + def test_difference(self): "Testing difference()." for i in range(len(self.geometries.topology_geoms)):