mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #25950 -- Added support for GEOSisClosed.
This commit is contained in:
		
				
					committed by
					
						 Tim Graham
						Tim Graham
					
				
			
			
				
	
			
			
			
						parent
						
							64ba7d8252
						
					
				
				
					commit
					5d348bba31
				
			| @@ -7,10 +7,9 @@ import warnings | |||||||
| from ctypes import byref, c_int, c_uint | from ctypes import byref, c_int, c_uint | ||||||
|  |  | ||||||
| from django.contrib.gis.geos import prototypes as capi | from django.contrib.gis.geos import prototypes as capi | ||||||
| from django.contrib.gis.geos.geometry import ( | from django.contrib.gis.geos.error import GEOSException | ||||||
|     GEOSGeometry, ProjectInterpolateMixin, | from django.contrib.gis.geos.geometry import GEOSGeometry, LinearGeometryMixin | ||||||
| ) | from django.contrib.gis.geos.libgeos import geos_version_info, get_pointer_arr | ||||||
| from django.contrib.gis.geos.libgeos import get_pointer_arr |  | ||||||
| from django.contrib.gis.geos.linestring import LinearRing, LineString | from django.contrib.gis.geos.linestring import LinearRing, LineString | ||||||
| from django.contrib.gis.geos.point import Point | from django.contrib.gis.geos.point import Point | ||||||
| from django.contrib.gis.geos.polygon import Polygon | from django.contrib.gis.geos.polygon import Polygon | ||||||
| @@ -114,17 +113,15 @@ class MultiPoint(GeometryCollection): | |||||||
|     _typeid = 4 |     _typeid = 4 | ||||||
|  |  | ||||||
|  |  | ||||||
| class MultiLineString(ProjectInterpolateMixin, GeometryCollection): | class MultiLineString(LinearGeometryMixin, GeometryCollection): | ||||||
|     _allowed = (LineString, LinearRing) |     _allowed = (LineString, LinearRing) | ||||||
|     _typeid = 5 |     _typeid = 5 | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def merged(self): |     def closed(self): | ||||||
|         """ |         if geos_version_info()['version'] < '3.5': | ||||||
|         Returns a LineString representing the line merge of this |             raise GEOSException("MultiLineString.closed requires GEOS >= 3.5.0.") | ||||||
|         MultiLineString. |         return super(MultiLineString, self).closed | ||||||
|         """ |  | ||||||
|         return self._topology(capi.geos_linemerge(self.ptr)) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class MultiPolygon(GeometryCollection): | class MultiPolygon(GeometryCollection): | ||||||
|   | |||||||
| @@ -685,7 +685,7 @@ class GEOSGeometry(GEOSBase, ListMixin): | |||||||
|         return GEOSGeometry(capi.geom_clone(self.ptr), srid=self.srid) |         return GEOSGeometry(capi.geom_clone(self.ptr), srid=self.srid) | ||||||
|  |  | ||||||
|  |  | ||||||
| class ProjectInterpolateMixin(object): | class LinearGeometryMixin(object): | ||||||
|     """ |     """ | ||||||
|     Used for LineString and MultiLineString. |     Used for LineString and MultiLineString. | ||||||
|     """ |     """ | ||||||
| @@ -706,3 +706,17 @@ class ProjectInterpolateMixin(object): | |||||||
|         if not isinstance(point, Point): |         if not isinstance(point, Point): | ||||||
|             raise TypeError('locate_point argument must be a Point') |             raise TypeError('locate_point argument must be a Point') | ||||||
|         return capi.geos_project_normalized(self.ptr, point.ptr) |         return capi.geos_project_normalized(self.ptr, point.ptr) | ||||||
|  |  | ||||||
|  |     @property | ||||||
|  |     def merged(self): | ||||||
|  |         """ | ||||||
|  |         Return the line merge of this Geometry. | ||||||
|  |         """ | ||||||
|  |         return self._topology(capi.geos_linemerge(self.ptr)) | ||||||
|  |  | ||||||
|  |     @property | ||||||
|  |     def closed(self): | ||||||
|  |         """ | ||||||
|  |         Return whether or not this Geometry is closed. | ||||||
|  |         """ | ||||||
|  |         return capi.geos_isclosed(self.ptr) | ||||||
|   | |||||||
| @@ -1,15 +1,13 @@ | |||||||
| from django.contrib.gis.geos import prototypes as capi | from django.contrib.gis.geos import prototypes as capi | ||||||
| from django.contrib.gis.geos.coordseq import GEOSCoordSeq | from django.contrib.gis.geos.coordseq import GEOSCoordSeq | ||||||
| from django.contrib.gis.geos.error import GEOSException | from django.contrib.gis.geos.error import GEOSException | ||||||
| from django.contrib.gis.geos.geometry import ( | from django.contrib.gis.geos.geometry import GEOSGeometry, LinearGeometryMixin | ||||||
|     GEOSGeometry, ProjectInterpolateMixin, |  | ||||||
| ) |  | ||||||
| from django.contrib.gis.geos.point import Point | from django.contrib.gis.geos.point import Point | ||||||
| from django.contrib.gis.shortcuts import numpy | from django.contrib.gis.shortcuts import numpy | ||||||
| from django.utils.six.moves import range | from django.utils.six.moves import range | ||||||
|  |  | ||||||
|  |  | ||||||
| class LineString(ProjectInterpolateMixin, GEOSGeometry): | class LineString(LinearGeometryMixin, GEOSGeometry): | ||||||
|     _init_func = capi.create_linestring |     _init_func = capi.create_linestring | ||||||
|     _minlength = 2 |     _minlength = 2 | ||||||
|     has_cs = True |     has_cs = True | ||||||
| @@ -154,11 +152,6 @@ class LineString(ProjectInterpolateMixin, GEOSGeometry): | |||||||
|         "Returns a numpy array for the LineString." |         "Returns a numpy array for the LineString." | ||||||
|         return self._listarr(self._cs.__getitem__) |         return self._listarr(self._cs.__getitem__) | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def merged(self): |  | ||||||
|         "Returns the line merge of this LineString." |  | ||||||
|         return self._topology(capi.geos_linemerge(self.ptr)) |  | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def x(self): |     def x(self): | ||||||
|         "Returns a list or numpy array of the X variable." |         "Returns a list or numpy array of the X variable." | ||||||
|   | |||||||
| @@ -19,8 +19,8 @@ from django.contrib.gis.geos.prototypes.geom import (  # NOQA | |||||||
| from django.contrib.gis.geos.prototypes.misc import *  # NOQA | from django.contrib.gis.geos.prototypes.misc import *  # NOQA | ||||||
| from django.contrib.gis.geos.prototypes.predicates import (  # NOQA | from django.contrib.gis.geos.prototypes.predicates import (  # NOQA | ||||||
|     geos_contains, geos_covers, geos_crosses, geos_disjoint, geos_equals, |     geos_contains, geos_covers, geos_crosses, geos_disjoint, geos_equals, | ||||||
|     geos_equalsexact, geos_hasz, geos_intersects, geos_isempty, geos_isring, |     geos_equalsexact, geos_hasz, geos_intersects, geos_isclosed, geos_isempty, | ||||||
|     geos_issimple, geos_isvalid, geos_overlaps, geos_relatepattern, |     geos_isring, geos_issimple, geos_isvalid, geos_overlaps, | ||||||
|     geos_touches, geos_within, |     geos_relatepattern, geos_touches, geos_within, | ||||||
| ) | ) | ||||||
| from django.contrib.gis.geos.prototypes.topology import *  # NOQA | from django.contrib.gis.geos.prototypes.topology import *  # NOQA | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ class BinaryPredicate(UnaryPredicate): | |||||||
|  |  | ||||||
| # ## Unary Predicates ## | # ## Unary Predicates ## | ||||||
| geos_hasz = UnaryPredicate('GEOSHasZ') | geos_hasz = UnaryPredicate('GEOSHasZ') | ||||||
|  | geos_isclosed = UnaryPredicate('GEOSisClosed') | ||||||
| geos_isempty = UnaryPredicate('GEOSisEmpty') | geos_isempty = UnaryPredicate('GEOSisEmpty') | ||||||
| geos_isring = UnaryPredicate('GEOSisRing') | geos_isring = UnaryPredicate('GEOSisRing') | ||||||
| geos_issimple = UnaryPredicate('GEOSisSimple') | geos_issimple = UnaryPredicate('GEOSisSimple') | ||||||
|   | |||||||
| @@ -694,6 +694,12 @@ is returned instead. | |||||||
|  |  | ||||||
|        In previous versions, an empty ``LineString`` couldn't be instantiated. |        In previous versions, an empty ``LineString`` couldn't be instantiated. | ||||||
|  |  | ||||||
|  |    .. attribute:: closed | ||||||
|  |  | ||||||
|  |    .. versionadded:: 1.10 | ||||||
|  |  | ||||||
|  |    Returns whether or not this ``LineString`` is closed. | ||||||
|  |  | ||||||
| ``LinearRing`` | ``LinearRing`` | ||||||
| -------------- | -------------- | ||||||
|  |  | ||||||
| @@ -790,6 +796,11 @@ Geometry Collections | |||||||
|    Returns a :class:`LineString` representing the line merge of |    Returns a :class:`LineString` representing the line merge of | ||||||
|    all the components in this ``MultiLineString``. |    all the components in this ``MultiLineString``. | ||||||
|  |  | ||||||
|  |    .. attribute:: closed | ||||||
|  |  | ||||||
|  |    .. versionadded:: 1.10 | ||||||
|  |  | ||||||
|  |    Returns ``True`` if and only if all elements are closed. Requires GEOS 3.5. | ||||||
|  |  | ||||||
| ``MultiPolygon`` | ``MultiPolygon`` | ||||||
| ---------------- | ---------------- | ||||||
|   | |||||||
| @@ -104,6 +104,11 @@ Minor features | |||||||
|   of :class:`~django.contrib.gis.geos.WKTWriter` allow controlling |   of :class:`~django.contrib.gis.geos.WKTWriter` allow controlling | ||||||
|   output of the fractional part of the coordinates in WKT. |   output of the fractional part of the coordinates in WKT. | ||||||
|  |  | ||||||
|  | * Added the :attr:`LineString.closed | ||||||
|  |   <django.contrib.gis.geos.LineString.closed>` and | ||||||
|  |   :attr:`MultiLineString.closed | ||||||
|  |   <django.contrib.gis.geos.MultiLineString.closed>` properties. | ||||||
|  |  | ||||||
| :mod:`django.contrib.messages` | :mod:`django.contrib.messages` | ||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||||||
|  |  | ||||||
|   | |||||||
| @@ -15,6 +15,7 @@ from django.contrib.gis.geos import ( | |||||||
|     fromfile, fromstr, |     fromfile, fromstr, | ||||||
| ) | ) | ||||||
| from django.contrib.gis.geos.base import GEOSBase | from django.contrib.gis.geos.base import GEOSBase | ||||||
|  | from django.contrib.gis.geos.libgeos import geos_version_info | ||||||
| from django.contrib.gis.shortcuts import numpy | from django.contrib.gis.shortcuts import numpy | ||||||
| from django.template import Context | from django.template import Context | ||||||
| from django.template.engine import Engine | from django.template.engine import Engine | ||||||
| @@ -660,6 +661,20 @@ class GEOSTest(SimpleTestCase, TestDataMixin): | |||||||
|         self.assertTrue(poly.covers(Point(5, 5))) |         self.assertTrue(poly.covers(Point(5, 5))) | ||||||
|         self.assertFalse(poly.covers(Point(100, 100))) |         self.assertFalse(poly.covers(Point(100, 100))) | ||||||
|  |  | ||||||
|  |     def test_closed(self): | ||||||
|  |         ls_closed = LineString((0, 0), (1, 1), (0, 0)) | ||||||
|  |         ls_not_closed = LineString((0, 0), (1, 1)) | ||||||
|  |         self.assertFalse(ls_not_closed.closed) | ||||||
|  |         self.assertTrue(ls_closed.closed) | ||||||
|  |  | ||||||
|  |         if geos_version_info()['version'] >= '3.5': | ||||||
|  |             self.assertFalse(MultiLineString(ls_closed, ls_not_closed).closed) | ||||||
|  |             self.assertTrue(MultiLineString(ls_closed, ls_closed).closed) | ||||||
|  |  | ||||||
|  |         with mock.patch('django.contrib.gis.geos.collections.geos_version_info', lambda: {'version': '3.4.9'}): | ||||||
|  |             with self.assertRaisesMessage(GEOSException, "MultiLineString.closed requires GEOS >= 3.5.0."): | ||||||
|  |                 MultiLineString().closed | ||||||
|  |  | ||||||
|     def test_srid(self): |     def test_srid(self): | ||||||
|         "Testing the SRID property and keyword." |         "Testing the SRID property and keyword." | ||||||
|         # Testing SRID keyword on Point |         # Testing SRID keyword on Point | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user