Fixed #25950 -- Added support for GEOSisClosed.

This commit is contained in:
Sergey Fedoseev 2015-12-18 15:26:22 +05:00 committed by Tim Graham
parent 64ba7d8252
commit 5d348bba31
8 changed files with 60 additions and 24 deletions

View File

@ -7,10 +7,9 @@ import warnings
from ctypes import byref, c_int, c_uint
from django.contrib.gis.geos import prototypes as capi
from django.contrib.gis.geos.geometry import (
GEOSGeometry, ProjectInterpolateMixin,
)
from django.contrib.gis.geos.libgeos import get_pointer_arr
from django.contrib.gis.geos.error import GEOSException
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.linestring import LinearRing, LineString
from django.contrib.gis.geos.point import Point
from django.contrib.gis.geos.polygon import Polygon
@ -114,17 +113,15 @@ class MultiPoint(GeometryCollection):
_typeid = 4
class MultiLineString(ProjectInterpolateMixin, GeometryCollection):
class MultiLineString(LinearGeometryMixin, GeometryCollection):
_allowed = (LineString, LinearRing)
_typeid = 5
@property
def merged(self):
"""
Returns a LineString representing the line merge of this
MultiLineString.
"""
return self._topology(capi.geos_linemerge(self.ptr))
def closed(self):
if geos_version_info()['version'] < '3.5':
raise GEOSException("MultiLineString.closed requires GEOS >= 3.5.0.")
return super(MultiLineString, self).closed
class MultiPolygon(GeometryCollection):

View File

@ -685,7 +685,7 @@ class GEOSGeometry(GEOSBase, ListMixin):
return GEOSGeometry(capi.geom_clone(self.ptr), srid=self.srid)
class ProjectInterpolateMixin(object):
class LinearGeometryMixin(object):
"""
Used for LineString and MultiLineString.
"""
@ -706,3 +706,17 @@ class ProjectInterpolateMixin(object):
if not isinstance(point, Point):
raise TypeError('locate_point argument must be a Point')
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)

View File

@ -1,15 +1,13 @@
from django.contrib.gis.geos import prototypes as capi
from django.contrib.gis.geos.coordseq import GEOSCoordSeq
from django.contrib.gis.geos.error import GEOSException
from django.contrib.gis.geos.geometry import (
GEOSGeometry, ProjectInterpolateMixin,
)
from django.contrib.gis.geos.geometry import GEOSGeometry, LinearGeometryMixin
from django.contrib.gis.geos.point import Point
from django.contrib.gis.shortcuts import numpy
from django.utils.six.moves import range
class LineString(ProjectInterpolateMixin, GEOSGeometry):
class LineString(LinearGeometryMixin, GEOSGeometry):
_init_func = capi.create_linestring
_minlength = 2
has_cs = True
@ -154,11 +152,6 @@ class LineString(ProjectInterpolateMixin, GEOSGeometry):
"Returns a numpy array for the LineString."
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
def x(self):
"Returns a list or numpy array of the X variable."

View File

@ -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.predicates import ( # NOQA
geos_contains, geos_covers, geos_crosses, geos_disjoint, geos_equals,
geos_equalsexact, geos_hasz, geos_intersects, geos_isempty, geos_isring,
geos_issimple, geos_isvalid, geos_overlaps, geos_relatepattern,
geos_touches, geos_within,
geos_equalsexact, geos_hasz, geos_intersects, geos_isclosed, geos_isempty,
geos_isring, geos_issimple, geos_isvalid, geos_overlaps,
geos_relatepattern, geos_touches, geos_within,
)
from django.contrib.gis.geos.prototypes.topology import * # NOQA

View File

@ -23,6 +23,7 @@ class BinaryPredicate(UnaryPredicate):
# ## Unary Predicates ##
geos_hasz = UnaryPredicate('GEOSHasZ')
geos_isclosed = UnaryPredicate('GEOSisClosed')
geos_isempty = UnaryPredicate('GEOSisEmpty')
geos_isring = UnaryPredicate('GEOSisRing')
geos_issimple = UnaryPredicate('GEOSisSimple')

View File

@ -694,6 +694,12 @@ is returned instead.
In previous versions, an empty ``LineString`` couldn't be instantiated.
.. attribute:: closed
.. versionadded:: 1.10
Returns whether or not this ``LineString`` is closed.
``LinearRing``
--------------
@ -790,6 +796,11 @@ Geometry Collections
Returns a :class:`LineString` representing the line merge of
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``
----------------

View File

@ -104,6 +104,11 @@ Minor features
of :class:`~django.contrib.gis.geos.WKTWriter` allow controlling
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`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -15,6 +15,7 @@ from django.contrib.gis.geos import (
fromfile, fromstr,
)
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.template import Context
from django.template.engine import Engine
@ -660,6 +661,20 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
self.assertTrue(poly.covers(Point(5, 5)))
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):
"Testing the SRID property and keyword."
# Testing SRID keyword on Point