From 17824e2b74ca02b9914e853c818fa512a0f9ef34 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Wed, 6 Jun 2012 10:05:27 +0200 Subject: [PATCH] Fixed #17736 -- Kept maximal floating-point accuracy in from_bbox When constructing a polygon with Polygon.from_bbox, do not convert parameters to strings at this stage (str defaults to 12 significant digits). Thanks tdihp@hotmail.com for the report and David Eklung for the patch. --- AUTHORS | 1 + django/contrib/gis/geos/polygon.py | 7 +++++-- django/contrib/gis/geos/tests/test_geos.py | 7 +++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/AUTHORS b/AUTHORS index 45a0544e65..ad0e886981 100644 --- a/AUTHORS +++ b/AUTHORS @@ -171,6 +171,7 @@ answer newbie questions, and generally made Django that much better: Clint Ecker Nick Efford eibaan@gmail.com + David Eklund Julia Elman enlight Enrico diff --git a/django/contrib/gis/geos/polygon.py b/django/contrib/gis/geos/polygon.py index 77ce60cf16..2c0f90be3c 100644 --- a/django/contrib/gis/geos/polygon.py +++ b/django/contrib/gis/geos/polygon.py @@ -55,8 +55,11 @@ class Polygon(GEOSGeometry): def from_bbox(cls, bbox): "Constructs a Polygon from a bounding box (4-tuple)." x0, y0, x1, y1 = bbox - return GEOSGeometry( 'POLYGON((%s %s, %s %s, %s %s, %s %s, %s %s))' % ( - x0, y0, x0, y1, x1, y1, x1, y0, x0, y0) ) + for z in bbox: + if not isinstance(z, (int, long, float)): + return GEOSGeometry('POLYGON((%s %s, %s %s, %s %s, %s %s, %s %s))' % + (x0, y0, x0, y1, x1, y1, x1, y0, x0, y0)) + return Polygon(((x0, y0), (x0, y1), (x1, y1), (x1, y0), (x0, y0))) ### These routines are needed for list-like operation w/ListMixin ### def _create_polygon(self, length, items): diff --git a/django/contrib/gis/geos/tests/test_geos.py b/django/contrib/gis/geos/tests/test_geos.py index f435cdaff1..ed38283dfc 100644 --- a/django/contrib/gis/geos/tests/test_geos.py +++ b/django/contrib/gis/geos/tests/test_geos.py @@ -384,6 +384,13 @@ class GEOSTest(unittest.TestCase, TestDataMixin): p = Polygon.from_bbox(bbox) self.assertEqual(bbox, p.extent) + # Testing numerical precision + x = 3.14159265358979323 + bbox = (0, 0, 1, x) + p = Polygon.from_bbox(bbox) + y = p.extent[-1] + self.assertEqual(format(x, '.13f'), format(y, '.13f')) + def test_polygons(self): "Testing Polygon objects."