1
0
mirror of https://github.com/django/django.git synced 2025-07-04 09:49:12 +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:
Justin Bronn 2007-08-21 03:24:22 +00:00
parent dcf2f144d1
commit a7297a255f
3 changed files with 90 additions and 23 deletions

View File

@ -29,10 +29,10 @@
http://zcologia.com/news/429/geometries-for-python-update/
"""
from base import GEOSGeometry
from geometries import Point, LineString, LinearRing, Polygon, HAS_NUMPY
from collections import GeometryCollection, MultiPoint, MultiLineString, MultiPolygon
from error import GEOSException, GEOSGeometryIndexError
from django.contrib.gis.geos.base import GEOSGeometry
from django.contrib.gis.geos.geometries import Point, LineString, LinearRing, Polygon, HAS_NUMPY
from django.contrib.gis.geos.collections import GeometryCollection, MultiPoint, MultiLineString, MultiPolygon
from django.contrib.gis.geos.error import GEOSException, GEOSGeometryIndexError
def fromstr(wkt_or_hex, **kwargs):
"Given a string value (wkt or hex), returns a GEOSGeometry object."

View File

@ -272,14 +272,16 @@ class GEOSGeometry(object):
## Internal for GEOS unary & binary predicate functions ##
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())
if val == 0: return False
elif val == 1: return True
else: raise GEOSException, '%s: exception occurred.' % func.__name__
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):
raise TypeError, 'Binary predicate operation ("%s") requires another GEOSGeometry instance.' % func.__name__
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))
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)
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)
def intersects(self, other):
@ -334,12 +338,14 @@ class GEOSGeometry(object):
return self._binary_predicate(lgeos.GEOSIntersects, 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,
a point and an area or a line and an area) 0******** (for two curves)."""
"""Returns true if the DE-9IM intersection matrix for the two Geometries
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)
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)
def contains(self, other):
@ -347,18 +353,20 @@ class GEOSGeometry(object):
return self._binary_predicate(lgeos.GEOSContains, other)
def overlaps(self, other):
"""Returns true if the DE-9IM intersection matrix for the two Geometries is T*T***T** (for two points
or two surfaces) 1*T***T** (for two curves)."""
"""Returns true if the DE-9IM intersection matrix for the two Geometries
is T*T***T** (for two points or two surfaces) 1*T***T** (for two curves)."""
return self._binary_predicate(lgeos.GEOSOverlaps, 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)
def equals_exact(self, other, tolerance=0):
"Returns true if the two Geometries are exactly equal, up to a specified tolerance."
tol = c_double(tolerance)
return self._binary_predicate(lgeos.GEOSEqualsExact, other, tol)
"""Returns true if the two Geometries are exactly equal, up to a
specified tolerance."""
return self._binary_predicate(lgeos.GEOSEqualsExact, other,
c_double(tolerance))
#### SRID Routines ####
def get_srid(self):
@ -393,12 +401,14 @@ class GEOSGeometry(object):
#### Topology Routines ####
def _unary_topology(self, func, *args):
"Returns a GEOSGeometry for the given unary (only takes one geomtry as a paramter) topological operation."
return GEOSGeometry(func(self._ptr(), *args))
"""Returns a GEOSGeometry for the given unary (takes only one Geomtery
as a paramter) topological operation."""
return GEOSGeometry(func(self._ptr(), *args), srid=self.srid)
def _binary_topology(self, func, other, *args):
"Returns a GEOSGeometry for the given binary (takes two geometries as parameters) topological operation."
return GEOSGeometry(func(self._ptr(), other._ptr(), *args))
"""Returns a GEOSGeometry for the given binary (takes two Geometries
as parameters) topological operation."""
return GEOSGeometry(func(self._ptr(), other._ptr(), *args), srid=self.srid)
def buffer(self, width, quadsegs=8):
"""Returns a geometry that represents all points whose distance from this
@ -432,7 +442,8 @@ class GEOSGeometry(object):
@property
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)
@property
@ -468,9 +479,29 @@ class GEOSGeometry(object):
"Returns the area of the Geometry."
a = c_double()
status = lgeos.GEOSArea(self._ptr(), byref(a))
if not status: return None
if status != 1: return None
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):
"Clones this Geometry."
return GEOSGeometry(lgeos.GEOSGeom_clone(self._ptr()), srid=self.srid)

View File

@ -612,6 +612,42 @@ class GEOSTest(unittest.TestCase):
ls[0] = (1.,2.,3.)
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():
s = unittest.TestSuite()