Code

Ticket #10368: gis_envelope_expand.diff

File gis_envelope_expand.diff, 5.2 KB (added by psmith, 5 years ago)

Patch to add expand_to_include to Envelope (with unit tests)

Line 
1Index: django/contrib/gis/tests/test_gdal_envelope.py
2===================================================================
3--- django/contrib/gis/tests/test_gdal_envelope.py      (revision 9822)
4+++ django/contrib/gis/tests/test_gdal_envelope.py      (working copy)
5@@ -1,7 +1,10 @@
6 import unittest
7 from django.contrib.gis.gdal import Envelope, OGRException
8+from django.contrib.gis.geos import Point
9 
10 class EnvelopeTest(unittest.TestCase):
11+    def setUp(self):
12+        self.e = Envelope(0, 0, 5, 5)
13 
14     def test01_init(self):
15         "Testing Envelope initilization."
16@@ -36,6 +39,42 @@
17         self.assertEqual(e1, e2)
18         self.assertEqual((0.523, 0.217, 253.23, 523.69), e1)
19 
20+    def test04_expand_to_include_pt_2_params(self):
21+        "Testing Envelope expand_to_include -- point as two parameters."
22+        self.e.expand_to_include(2, 6)
23+        self.assertEqual((0, 0, 5, 6), self.e)
24+        self.e.expand_to_include(-1, -1)
25+        self.assertEqual((-1, -1, 5, 6), self.e)
26+
27+    def test05_expand_to_include_pt_2_tuple(self):
28+        "Testing Envelope expand_to_include -- point as a single 2-tuple parameter."
29+        self.e.expand_to_include((10, 10))
30+        self.assertEqual((0, 0, 10, 10), self.e)
31+        self.e.expand_to_include((-10, -10))
32+        self.assertEqual((-10, -10, 10, 10), self.e)
33+
34+    def test06_expand_to_include_extent_4_params(self):
35+        "Testing Envelope expand_to_include -- extent as 4 parameters."
36+        self.e.expand_to_include(-1, 1, 3, 7)
37+        self.assertEqual((-1, 0, 5, 7), self.e)
38+
39+    def test06_expand_to_include_extent_4_tuple(self):
40+        "Testing Envelope expand_to_include -- extent as a single 4-tuple parameter."
41+        self.e.expand_to_include((-1, 1, 3, 7))
42+        self.assertEqual((-1, 0, 5, 7), self.e)
43+
44+    def test07_expand_to_include_envelope(self):
45+        "Testing Envelope expand_to_include with Envelope as parameter."
46+        self.e.expand_to_include(Envelope(-1, 1, 3, 7))
47+        self.assertEqual((-1, 0, 5, 7), self.e)
48+
49+    def test08_expand_to_include_point(self):
50+        "Testing Envelope expand_to_include with Point as parameter."
51+        self.e.expand_to_include(Point(-1, 1))
52+        self.assertEqual((-1, 0, 5, 5), self.e)
53+        self.e.expand_to_include(Point(10, 10))
54+        self.assertEqual((-1, 0, 10, 10), self.e)
55+
56 def suite():
57     s = unittest.TestSuite()
58     s.addTest(unittest.makeSuite(EnvelopeTest))
59Index: django/contrib/gis/gdal/envelope.py
60===================================================================
61--- django/contrib/gis/gdal/envelope.py (revision 9822)
62+++ django/contrib/gis/gdal/envelope.py (working copy)
63@@ -13,6 +13,7 @@
64 from ctypes import Structure, c_double
65 from types import TupleType, ListType
66 from django.contrib.gis.gdal.error import OGRException
67+from django.contrib.gis.geos import Point
68 
69 # The OGR definition of an Envelope is a C structure containing four doubles.
70 #  See the 'ogr_core.h' source file for more information:
71@@ -132,3 +133,45 @@
72                (self.min_x, self.min_y, self.min_x, self.max_y,
73                 self.max_x, self.max_y, self.max_x, self.min_y,
74                 self.min_x, self.min_y)
75+
76+    def expand_to_include(self, *args):
77+        """
78+        Modifies the envelope to expand to include the boundaries of
79+        the passed-in 2-tuple (a point), 4-tuple (an extent) or
80+        envelope.
81+        """
82+        # We provide a number of different signatures for this method,
83+        # and the logic here is all about converting them into a
84+        # 4-tuple single parameter which does the actual work of
85+        # expanding the envelope.
86+        if len(args) == 1:
87+            if isinstance(args[0], Envelope):
88+                return self.expand_to_include(args[0].tuple)
89+            elif isinstance(args[0], Point):
90+                return self.expand_to_include(args[0].x, args[0].y, args[0].x, args[0].y)
91+            elif isinstance(args[0], (TupleType, ListType)):
92+                # A tuple was passed in.
93+                if len(args[0]) == 2:
94+                    return self.expand_to_include((args[0][0], args[0][1], args[0][0], args[0][1]))
95+                elif len(args[0]) == 4:
96+                    (minx, miny, maxx, maxy) = args[0]
97+                    if minx < self._envelope.MinX:
98+                        self._envelope.MinX = minx
99+                    if miny < self._envelope.MinY:
100+                        self._envelope.MinY = miny
101+                    if maxx > self._envelope.MaxX:
102+                        self._envelope.MaxX = maxx
103+                    if maxy > self._envelope.MaxY:
104+                        self._envelope.MaxY = maxy
105+                else:
106+                    raise OGRException('Incorrect number of tuple elements (%d).' % len(args[0]))
107+            else:
108+                raise TypeError('Incorrect type of argument: %s' % str(type(args[0])))
109+        elif len(args) == 2:
110+            # An x and an y parameter were passed in
111+            return self.expand_to_include((args[0], args[1], args[0], args[1]))
112+        elif len(args) == 4:
113+            # Individiual parameters passed in.
114+            return self.expand_to_include(args)
115+        else:
116+            raise OGRException('Incorrect number (%d) of arguments.' % len(args[0]))