Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

gis: geos: added length property and distance method; no more relativ…

…e 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
  • Loading branch information...
commit a7297a255f4bb86f608ea251e00253d18c31d9d4 1 parent dcf2f14
@jbronn jbronn authored
View
8 django/contrib/gis/geos/__init__.py
@@ -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
69 django/contrib/gis/geos/base.py
@@ -272,14 +272,16 @@ def normalize(self):
## 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 @@ def relate_pattern(self, other, pattern):
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 @@ def intersects(self, other):
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 @@ def contains(self, other):
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 @@ def kml(self):
#### 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 @@ def boundary(self):
@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 @@ def area(self):
"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
36 django/contrib/gis/tests/test_geos.py
@@ -612,6 +612,42 @@ def test17_threed(self):
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()
Please sign in to comment.
Something went wrong with that request. Please try again.