You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
4.9 KiB
134 lines
4.9 KiB
""" |
|
The GDAL/OGR library uses an Envelope structure to hold the bounding |
|
box information for a geometry. The envelope (bounding box) contains |
|
two pairs of coordinates, one for the lower left coordinate and one |
|
for the upper right coordinate: |
|
|
|
+----------o Upper right; (max_x, max_y) |
|
| | |
|
| | |
|
| | |
|
Lower left (min_x, min_y) o----------+ |
|
""" |
|
from ctypes import Structure, c_double |
|
from types import TupleType, ListType |
|
from django.contrib.gis.gdal.error import OGRException |
|
|
|
# The OGR definition of an Envelope is a C structure containing four doubles. |
|
# See the 'ogr_core.h' source file for more information: |
|
# http://www.gdal.org/ogr/ogr__core_8h-source.html |
|
class OGREnvelope(Structure): |
|
"Represents the OGREnvelope C Structure." |
|
_fields_ = [("MinX", c_double), |
|
("MaxX", c_double), |
|
("MinY", c_double), |
|
("MaxY", c_double), |
|
] |
|
|
|
class Envelope(object): |
|
""" |
|
The Envelope object is a C structure that contains the minimum and |
|
maximum X, Y coordinates for a rectangle bounding box. The naming |
|
of the variables is compatible with the OGR Envelope structure. |
|
""" |
|
|
|
def __init__(self, *args): |
|
""" |
|
The initialization function may take an OGREnvelope structure, 4-element |
|
tuple or list, or 4 individual arguments. |
|
""" |
|
|
|
if len(args) == 1: |
|
if isinstance(args[0], OGREnvelope): |
|
# OGREnvelope (a ctypes Structure) was passed in. |
|
self._envelope = args[0] |
|
elif isinstance(args[0], (TupleType, ListType)): |
|
# A tuple was passed in. |
|
if len(args[0]) != 4: |
|
raise OGRException('Incorrect number of tuple elements (%d).' % len(args[0])) |
|
else: |
|
self._from_sequence(args[0]) |
|
else: |
|
raise TypeError('Incorrect type of argument: %s' % str(type(args[0]))) |
|
elif len(args) == 4: |
|
# Individiual parameters passed in. |
|
# Thanks to ww for the help |
|
self._from_sequence(map(float, args)) |
|
else: |
|
raise OGRException('Incorrect number (%d) of arguments.' % len(args)) |
|
|
|
# Checking the x,y coordinates |
|
if self.min_x >= self.max_x: |
|
raise OGRException('Envelope minimum X >= maximum X.') |
|
if self.min_y >= self.max_y: |
|
raise OGRException('Envelope minimum Y >= maximum Y.') |
|
|
|
def __eq__(self, other): |
|
""" |
|
Returns True if the envelopes are equivalent; can compare against |
|
other Envelopes and 4-tuples. |
|
""" |
|
if isinstance(other, Envelope): |
|
return (self.min_x == other.min_x) and (self.min_y == other.min_y) and \ |
|
(self.max_x == other.max_x) and (self.max_y == other.max_y) |
|
elif isinstance(other, TupleType) and len(other) == 4: |
|
return (self.min_x == other[0]) and (self.min_y == other[1]) and \ |
|
(self.max_x == other[2]) and (self.max_y == other[3]) |
|
else: |
|
raise OGRException('Equivalence testing only works with other Envelopes.') |
|
|
|
def __str__(self): |
|
"Returns a string representation of the tuple." |
|
return str(self.tuple) |
|
|
|
def _from_sequence(self, seq): |
|
"Initializes the C OGR Envelope structure from the given sequence." |
|
self._envelope = OGREnvelope() |
|
self._envelope.MinX = seq[0] |
|
self._envelope.MinY = seq[1] |
|
self._envelope.MaxX = seq[2] |
|
self._envelope.MaxY = seq[3] |
|
|
|
@property |
|
def min_x(self): |
|
"Returns the value of the minimum X coordinate." |
|
return self._envelope.MinX |
|
|
|
@property |
|
def min_y(self): |
|
"Returns the value of the minimum Y coordinate." |
|
return self._envelope.MinY |
|
|
|
@property |
|
def max_x(self): |
|
"Returns the value of the maximum X coordinate." |
|
return self._envelope.MaxX |
|
|
|
@property |
|
def max_y(self): |
|
"Returns the value of the maximum Y coordinate." |
|
return self._envelope.MaxY |
|
|
|
@property |
|
def ur(self): |
|
"Returns the upper-right coordinate." |
|
return (self.max_x, self.max_y) |
|
|
|
@property |
|
def ll(self): |
|
"Returns the lower-left coordinate." |
|
return (self.min_x, self.min_y) |
|
|
|
@property |
|
def tuple(self): |
|
"Returns a tuple representing the envelope." |
|
return (self.min_x, self.min_y, self.max_x, self.max_y) |
|
|
|
@property |
|
def wkt(self): |
|
"Returns WKT representing a Polygon for this envelope." |
|
# TODO: Fix significant figures. |
|
return 'POLYGON((%s %s,%s %s,%s %s,%s %s,%s %s))' % \ |
|
(self.min_x, self.min_y, self.min_x, self.max_y, |
|
self.max_x, self.max_y, self.max_x, self.min_y, |
|
self.min_x, self.min_y)
|
|
|