mirror of
https://github.com/django/django.git
synced 2025-07-04 17:59:13 +00:00
gis: geos: added length property and distance method; no more relative imports in geos module; tamed unruly docstrings in base.py.
git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@5991 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
dcf2f144d1
commit
a7297a255f
@ -29,10 +29,10 @@
|
|||||||
http://zcologia.com/news/429/geometries-for-python-update/
|
http://zcologia.com/news/429/geometries-for-python-update/
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from base import GEOSGeometry
|
from django.contrib.gis.geos.base import GEOSGeometry
|
||||||
from geometries import Point, LineString, LinearRing, Polygon, HAS_NUMPY
|
from django.contrib.gis.geos.geometries import Point, LineString, LinearRing, Polygon, HAS_NUMPY
|
||||||
from collections import GeometryCollection, MultiPoint, MultiLineString, MultiPolygon
|
from django.contrib.gis.geos.collections import GeometryCollection, MultiPoint, MultiLineString, MultiPolygon
|
||||||
from error import GEOSException, GEOSGeometryIndexError
|
from django.contrib.gis.geos.error import GEOSException, GEOSGeometryIndexError
|
||||||
|
|
||||||
def fromstr(wkt_or_hex, **kwargs):
|
def fromstr(wkt_or_hex, **kwargs):
|
||||||
"Given a string value (wkt or hex), returns a GEOSGeometry object."
|
"Given a string value (wkt or hex), returns a GEOSGeometry object."
|
||||||
|
@ -272,14 +272,16 @@ class GEOSGeometry(object):
|
|||||||
|
|
||||||
## Internal for GEOS unary & binary predicate functions ##
|
## Internal for GEOS unary & binary predicate functions ##
|
||||||
def _unary_predicate(self, func):
|
def _unary_predicate(self, func):
|
||||||
"Returns the result, or raises an exception for the given unary predicate function."
|
"""Returns the result, or raises an exception for the given unary
|
||||||
|
predicate function."""
|
||||||
val = func(self._ptr())
|
val = func(self._ptr())
|
||||||
if val == 0: return False
|
if val == 0: return False
|
||||||
elif val == 1: return True
|
elif val == 1: return True
|
||||||
else: raise GEOSException, '%s: exception occurred.' % func.__name__
|
else: raise GEOSException, '%s: exception occurred.' % func.__name__
|
||||||
|
|
||||||
def _binary_predicate(self, func, other, *args):
|
def _binary_predicate(self, func, other, *args):
|
||||||
"Returns the result, or raises an exception for the given binary predicate function."
|
"""Returns the result, or raises an exception for the given binary
|
||||||
|
predicate function."""
|
||||||
if not isinstance(other, GEOSGeometry):
|
if not isinstance(other, GEOSGeometry):
|
||||||
raise TypeError, 'Binary predicate operation ("%s") requires another GEOSGeometry instance.' % func.__name__
|
raise TypeError, 'Binary predicate operation ("%s") requires another GEOSGeometry instance.' % func.__name__
|
||||||
val = func(self._ptr(), other._ptr(), *args)
|
val = func(self._ptr(), other._ptr(), *args)
|
||||||
@ -322,11 +324,13 @@ class GEOSGeometry(object):
|
|||||||
return self._binary_predicate(lgeos.GEOSRelatePattern, other, c_char_p(pattern))
|
return self._binary_predicate(lgeos.GEOSRelatePattern, other, c_char_p(pattern))
|
||||||
|
|
||||||
def disjoint(self, other):
|
def disjoint(self, other):
|
||||||
"Returns true if the DE-9IM intersection matrix for the two Geometries is FF*FF****."
|
"""Returns true if the DE-9IM intersection matrix for the two Geometries
|
||||||
|
is FF*FF****."""
|
||||||
return self._binary_predicate(lgeos.GEOSDisjoint, other)
|
return self._binary_predicate(lgeos.GEOSDisjoint, other)
|
||||||
|
|
||||||
def touches(self, other):
|
def touches(self, other):
|
||||||
"Returns true if the DE-9IM intersection matrix for the two Geometries is FT*******, F**T***** or F***T****."
|
"""Returns true if the DE-9IM intersection matrix for the two Geometries
|
||||||
|
is FT*******, F**T***** or F***T****."""
|
||||||
return self._binary_predicate(lgeos.GEOSTouches, other)
|
return self._binary_predicate(lgeos.GEOSTouches, other)
|
||||||
|
|
||||||
def intersects(self, other):
|
def intersects(self, other):
|
||||||
@ -334,12 +338,14 @@ class GEOSGeometry(object):
|
|||||||
return self._binary_predicate(lgeos.GEOSIntersects, other)
|
return self._binary_predicate(lgeos.GEOSIntersects, other)
|
||||||
|
|
||||||
def crosses(self, other):
|
def crosses(self, other):
|
||||||
"""Returns true if the DE-9IM intersection matrix for the two Geometries is T*T****** (for a point and a curve,
|
"""Returns true if the DE-9IM intersection matrix for the two Geometries
|
||||||
a point and an area or a line and an area) 0******** (for two curves)."""
|
is T*T****** (for a point and a curve,a point and an area or a line and
|
||||||
|
an area) 0******** (for two curves)."""
|
||||||
return self._binary_predicate(lgeos.GEOSCrosses, other)
|
return self._binary_predicate(lgeos.GEOSCrosses, other)
|
||||||
|
|
||||||
def within(self, other):
|
def within(self, other):
|
||||||
"Returns true if the DE-9IM intersection matrix for the two Geometries is T*F**F***."
|
"""Returns true if the DE-9IM intersection matrix for the two Geometries
|
||||||
|
is T*F**F***."""
|
||||||
return self._binary_predicate(lgeos.GEOSWithin, other)
|
return self._binary_predicate(lgeos.GEOSWithin, other)
|
||||||
|
|
||||||
def contains(self, other):
|
def contains(self, other):
|
||||||
@ -347,18 +353,20 @@ class GEOSGeometry(object):
|
|||||||
return self._binary_predicate(lgeos.GEOSContains, other)
|
return self._binary_predicate(lgeos.GEOSContains, other)
|
||||||
|
|
||||||
def overlaps(self, other):
|
def overlaps(self, other):
|
||||||
"""Returns true if the DE-9IM intersection matrix for the two Geometries is T*T***T** (for two points
|
"""Returns true if the DE-9IM intersection matrix for the two Geometries
|
||||||
or two surfaces) 1*T***T** (for two curves)."""
|
is T*T***T** (for two points or two surfaces) 1*T***T** (for two curves)."""
|
||||||
return self._binary_predicate(lgeos.GEOSOverlaps, other)
|
return self._binary_predicate(lgeos.GEOSOverlaps, other)
|
||||||
|
|
||||||
def equals(self, other):
|
def equals(self, other):
|
||||||
"Returns true if the DE-9IM intersection matrix for the two Geometries is T*F**FFF*."
|
"""Returns true if the DE-9IM intersection matrix for the two Geometries
|
||||||
|
is T*F**FFF*."""
|
||||||
return self._binary_predicate(lgeos.GEOSEquals, other)
|
return self._binary_predicate(lgeos.GEOSEquals, other)
|
||||||
|
|
||||||
def equals_exact(self, other, tolerance=0):
|
def equals_exact(self, other, tolerance=0):
|
||||||
"Returns true if the two Geometries are exactly equal, up to a specified tolerance."
|
"""Returns true if the two Geometries are exactly equal, up to a
|
||||||
tol = c_double(tolerance)
|
specified tolerance."""
|
||||||
return self._binary_predicate(lgeos.GEOSEqualsExact, other, tol)
|
return self._binary_predicate(lgeos.GEOSEqualsExact, other,
|
||||||
|
c_double(tolerance))
|
||||||
|
|
||||||
#### SRID Routines ####
|
#### SRID Routines ####
|
||||||
def get_srid(self):
|
def get_srid(self):
|
||||||
@ -393,12 +401,14 @@ class GEOSGeometry(object):
|
|||||||
|
|
||||||
#### Topology Routines ####
|
#### Topology Routines ####
|
||||||
def _unary_topology(self, func, *args):
|
def _unary_topology(self, func, *args):
|
||||||
"Returns a GEOSGeometry for the given unary (only takes one geomtry as a paramter) topological operation."
|
"""Returns a GEOSGeometry for the given unary (takes only one Geomtery
|
||||||
return GEOSGeometry(func(self._ptr(), *args))
|
as a paramter) topological operation."""
|
||||||
|
return GEOSGeometry(func(self._ptr(), *args), srid=self.srid)
|
||||||
|
|
||||||
def _binary_topology(self, func, other, *args):
|
def _binary_topology(self, func, other, *args):
|
||||||
"Returns a GEOSGeometry for the given binary (takes two geometries as parameters) topological operation."
|
"""Returns a GEOSGeometry for the given binary (takes two Geometries
|
||||||
return GEOSGeometry(func(self._ptr(), other._ptr(), *args))
|
as parameters) topological operation."""
|
||||||
|
return GEOSGeometry(func(self._ptr(), other._ptr(), *args), srid=self.srid)
|
||||||
|
|
||||||
def buffer(self, width, quadsegs=8):
|
def buffer(self, width, quadsegs=8):
|
||||||
"""Returns a geometry that represents all points whose distance from this
|
"""Returns a geometry that represents all points whose distance from this
|
||||||
@ -432,7 +442,8 @@ class GEOSGeometry(object):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def convex_hull(self):
|
def convex_hull(self):
|
||||||
"Returns the smallest convex Polygon that contains all the points in the Geometry."
|
"""Returns the smallest convex Polygon that contains all the points
|
||||||
|
in the Geometry."""
|
||||||
return self._unary_topology(lgeos.GEOSConvexHull)
|
return self._unary_topology(lgeos.GEOSConvexHull)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -468,9 +479,29 @@ class GEOSGeometry(object):
|
|||||||
"Returns the area of the Geometry."
|
"Returns the area of the Geometry."
|
||||||
a = c_double()
|
a = c_double()
|
||||||
status = lgeos.GEOSArea(self._ptr(), byref(a))
|
status = lgeos.GEOSArea(self._ptr(), byref(a))
|
||||||
if not status: return None
|
if status != 1: return None
|
||||||
else: return a.value
|
else: return a.value
|
||||||
|
|
||||||
|
def distance(self, other):
|
||||||
|
"""Returns the distance between the closest points on this Geometry
|
||||||
|
and the other. Units will be in those of the coordinate system. of
|
||||||
|
the Geometry."""
|
||||||
|
if not isinstance(other, GEOSGeometry):
|
||||||
|
raise TypeError, 'distance() works only on other GEOS Geometries.'
|
||||||
|
dist = c_double()
|
||||||
|
status = lgeos.GEOSDistance(self._ptr(), other._ptr(), byref(dist))
|
||||||
|
if status != 1: return None
|
||||||
|
else: return dist.value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def length(self):
|
||||||
|
"""Returns the length of this Geometry (e.g., 0 for point, or the
|
||||||
|
circumfrence of a Polygon)."""
|
||||||
|
l = c_double()
|
||||||
|
status = lgeos.GEOSLength(self._ptr(), byref(l))
|
||||||
|
if status != 1: return None
|
||||||
|
else: return l.value
|
||||||
|
|
||||||
def clone(self):
|
def clone(self):
|
||||||
"Clones this Geometry."
|
"Clones this Geometry."
|
||||||
return GEOSGeometry(lgeos.GEOSGeom_clone(self._ptr()), srid=self.srid)
|
return GEOSGeometry(lgeos.GEOSGeom_clone(self._ptr()), srid=self.srid)
|
||||||
|
@ -612,6 +612,42 @@ class GEOSTest(unittest.TestCase):
|
|||||||
ls[0] = (1.,2.,3.)
|
ls[0] = (1.,2.,3.)
|
||||||
self.assertEqual((1.,2.,3.), ls[0])
|
self.assertEqual((1.,2.,3.), ls[0])
|
||||||
|
|
||||||
|
def test18_distance(self):
|
||||||
|
"Testing the distance() function."
|
||||||
|
# Distance to self should be 0.
|
||||||
|
pnt = Point(0, 0)
|
||||||
|
self.assertEqual(0.0, pnt.distance(Point(0, 0)))
|
||||||
|
|
||||||
|
# Distance should be 1
|
||||||
|
self.assertEqual(1.0, pnt.distance(Point(0, 1)))
|
||||||
|
|
||||||
|
# Distance should be ~ sqrt(2)
|
||||||
|
self.assertAlmostEqual(1.41421356237, pnt.distance(Point(1, 1)), 11)
|
||||||
|
|
||||||
|
# Distances are from the closest vertex in each geometry --
|
||||||
|
# should be 3 (distance from (2, 2) to (5, 2)).
|
||||||
|
ls1 = LineString((0, 0), (1, 1), (2, 2))
|
||||||
|
ls2 = LineString((5, 2), (6, 1), (7, 0))
|
||||||
|
self.assertEqual(3, ls1.distance(ls2))
|
||||||
|
|
||||||
|
def test19_length(self):
|
||||||
|
"Testing the length property."
|
||||||
|
|
||||||
|
# Points have 0 length.
|
||||||
|
pnt = Point(0, 0)
|
||||||
|
self.assertEqual(0.0, pnt.length)
|
||||||
|
|
||||||
|
# Should be ~ sqrt(2)
|
||||||
|
ls = LineString((0, 0), (1, 1))
|
||||||
|
self.assertAlmostEqual(1.41421356237, ls.length, 11)
|
||||||
|
|
||||||
|
# Should be circumfrence of Polygon
|
||||||
|
poly = Polygon(LinearRing((0, 0), (0, 1), (1, 1), (1, 0), (0, 0)))
|
||||||
|
self.assertEqual(4.0, poly.length)
|
||||||
|
|
||||||
|
# Should be sum of each element's length in collection.
|
||||||
|
mpoly = MultiPolygon(poly.clone(), poly)
|
||||||
|
self.assertEqual(8.0, mpoly.length)
|
||||||
|
|
||||||
def suite():
|
def suite():
|
||||||
s = unittest.TestSuite()
|
s = unittest.TestSuite()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user