Django

Code

root/django/branches/gis/django/contrib/gis/gdal/envelope.py

Revision 6686, 4.9 kB (checked in by jbronn, 1 year ago)

gis: gdal: refactor of the GDAL ctypes interface

(1) All interactions with the GDAL library take place through predefined ctypes prototypes, abstracting away error-checking.
(2) Fixed memory leaks by properly freeing pointers allocated w/in GDAL.
(3) Improved OFTField support, and added support for the OGR date/time fields.
(4) Significantly improved the OGRGeometry tests.

Line 
1 """
2  The GDAL/OGR library uses an Envelope structure to hold the bounding
3  box information for a geometry.  The envelope (bounding box) contains
4  two pairs of coordinates, one for the lower left coordinate and one
5  for the upper right coordinate:
6
7                            +----------o Upper right; (max_x, max_y)
8                            |          |
9                            |          |
10                            |          |
11  Lower left (min_x, min_y) o----------+
12 """
13 from ctypes import Structure, c_double
14 from types import TupleType, ListType
15 from django.contrib.gis.gdal.error import OGRException
16
17 # The OGR definition of an Envelope is a C structure containing four doubles.
18 #  See the 'ogr_core.h' source file for more information:
19 #   http://www.gdal.org/ogr/ogr__core_8h-source.html
20 class OGREnvelope(Structure):
21     "Represents the OGREnvelope C Structure."
22     _fields_ = [("MinX", c_double),
23                 ("MaxX", c_double),
24                 ("MinY", c_double),
25                 ("MaxY", c_double),
26                 ]
27
28 class Envelope(object):
29     """
30     The Envelope object is a C structure that contains the minimum and
31     maximum X, Y coordinates for a rectangle bounding box.  The naming
32     of the variables is compatible with the OGR Envelope structure.
33     """
34
35     def __init__(self, *args):
36         """
37         The initialization function may take an OGREnvelope structure, 4-element
38         tuple or list, or 4 individual arguments.
39         """
40        
41         if len(args) == 1:
42             if isinstance(args[0], OGREnvelope):
43                 # OGREnvelope (a ctypes Structure) was passed in.
44                 self._envelope = args[0]
45             elif isinstance(args[0], (TupleType, ListType)):
46                 # A tuple was passed in.
47                 if len(args[0]) != 4:
48                     raise OGRException('Incorrect number of tuple elements (%d).' % len(args[0]))
49                 else:
50                     self._from_sequence(args[0])
51             else:
52                 raise TypeError('Incorrect type of argument: %s' % str(type(args[0])))
53         elif len(args) == 4:
54             # Individiual parameters passed in.
55             #  Thanks to ww for the help
56             self._from_sequence(map(float, args))
57         else:
58             raise OGRException('Incorrect number (%d) of arguments.' % len(args))
59
60         # Checking the x,y coordinates
61         if self.min_x >= self.max_x:
62             raise OGRException('Envelope minimum X >= maximum X.')
63         if self.min_y >= self.max_y:
64             raise OGRException('Envelope minimum Y >= maximum Y.')
65
66     def __eq__(self, other):
67         """
68         Returns True if the envelopes are equivalent; can compare against
69         other Envelopes and 4-tuples.
70         """
71         if isinstance(other, Envelope):
72             return (self.min_x == other.min_x) and (self.min_y == other.min_y) and \
73                    (self.max_x == other.max_x) and (self.max_y == other.max_y)
74         elif isinstance(other, TupleType) and len(other) == 4:
75             return (self.min_x == other[0]) and (self.min_y == other[1]) and \
76                    (self.max_x == other[2]) and (self.max_y == other[3])
77         else:
78             raise OGRException('Equivalence testing only works with other Envelopes.')
79
80     def __str__(self):
81         "Returns a string representation of the tuple."
82         return str(self.tuple)
83
84     def _from_sequence(self, seq):
85         "Initializes the C OGR Envelope structure from the given sequence."
86         self._envelope = OGREnvelope()
87         self._envelope.MinX = seq[0]
88         self._envelope.MinY = seq[1]
89         self._envelope.MaxX = seq[2]
90         self._envelope.MaxY = seq[3]
91    
92     @property
93     def min_x(self):
94         "Returns the value of the minimum X coordinate."
95         return self._envelope.MinX
96
97     @property
98     def min_y(self):
99         "Returns the value of the minimum Y coordinate."
100         return self._envelope.MinY
101
102     @property
103     def max_x(self):
104         "Returns the value of the maximum X coordinate."
105         return self._envelope.MaxX
106
107     @property
108     def max_y(self):
109         "Returns the value of the maximum Y coordinate."
110         return self._envelope.MaxY
111
112     @property
113     def ur(self):
114         "Returns the upper-right coordinate."
115         return (self.max_x, self.max_y)
116
117     @property
118     def ll(self):
119         "Returns the lower-left coordinate."
120         return (self.min_x, self.min_y)
121
122     @property
123     def tuple(self):
124         "Returns a tuple representing the envelope."
125         return (self.min_x, self.min_y, self.max_x, self.max_y)
126
127     @property
128     def wkt(self):
129         "Returns WKT representing a Polygon for this envelope."
130         # TODO: Fix significant figures.
131         return 'POLYGON((%s %s,%s %s,%s %s,%s %s,%s %s))' % \
132                (self.min_x, self.min_y, self.min_x, self.max_y,
133                 self.max_x, self.max_y, self.max_x, self.min_y,
134                 self.min_x, self.min_y)
Note: See TracBrowser for help on using the browser.