Author: jbronn
Date: 2007-09-29 09:02:41 -0500 (Sat, 29 Sep 2007)
New Revision: 6436
Added:
django/branches/gis/django/contrib/gis/tests/test_gdal.py
django/branches/gis/django/contrib/gis/tests/test_gdal_envelope.py
Modified:
django/branches/gis/django/contrib/gis/gdal/__init__.py
django/branches/gis/django/contrib/gis/gdal/datasource.py
django/branches/gis/django/contrib/gis/gdal/driver.py
django/branches/gis/django/contrib/gis/gdal/envelope.py
django/branches/gis/django/contrib/gis/gdal/feature.py
django/branches/gis/django/contrib/gis/gdal/field.py
django/branches/gis/django/contrib/gis/gdal/geometries.py
django/branches/gis/django/contrib/gis/gdal/geomtype.py
django/branches/gis/django/contrib/gis/gdal/srs.py
django/branches/gis/django/contrib/gis/tests/__init__.py
django/branches/gis/django/contrib/gis/tests/test_gdal_ds.py
django/branches/gis/django/contrib/gis/tests/test_gdal_geom.py
Log:
gis: gdal: OSGeo sprint -- cleaned up spatial references associated with
geometries (fixed a segfault); cleaned up Envelope module (thanks to ww for
help), and added tests; added a test module for invoking all gdal tests;
changed exception style.
Modified: django/branches/gis/django/contrib/gis/gdal/__init__.py
===================================================================
--- django/branches/gis/django/contrib/gis/gdal/__init__.py 2007-09-28
22:34:27 UTC (rev 6435)
+++ django/branches/gis/django/contrib/gis/gdal/__init__.py 2007-09-29
14:02:41 UTC (rev 6436)
@@ -1,12 +1,39 @@
+"""
+ This module houses ctypes interfaces for GDAL objects. The following GDAL
+ objects are supported:
+
+ CoordTransform: Used for coordinate transformations from one spatial
+ reference system to another.
+
+ Driver: Wraps an OGR data source driver.
+
+ DataSource: Wrapper for the OGR data source object, supports
+ OGR-supported data sources.
+
+ Envelope: A ctypes structure for bounding boxes (GDAL library
+ not required).
+
+ OGRGeometry: Layer for accessing OGR Geometry objects.
+
+ OGRGeomType: A class for representing the different OGR Geometry
+ types (GDAL library not required).
+
+ SpatialReference: Represents OSR Spatial Reference objects.
+"""
+# Attempting to import objects that depend on the GDAL library. The
+# HAS_GDAL flag will be set to True if the library is present on
+# the system.
try:
from django.contrib.gis.gdal.driver import Driver
- from django.contrib.gis.gdal.envelope import Envelope
from django.contrib.gis.gdal.datasource import DataSource
from django.contrib.gis.gdal.srs import SpatialReference, CoordTransform
from django.contrib.gis.gdal.geometries import OGRGeometry
- from django.contrib.gis.gdal.geomtype import OGRGeomType
- from django.contrib.gis.gdal.error import check_err, OGRException,
SRSException
HAS_GDAL = True
except:
HAS_GDAL = False
+# The envelope, error, and geomtype modules do not actually require the
+# GDAL library.
+from django.contrib.gis.gdal.envelope import Envelope
+from django.contrib.gis.gdal.error import check_err, OGRException,
OGRIndexError, SRSException
+from django.contrib.gis.gdal.geomtype import OGRGeomType
Modified: django/branches/gis/django/contrib/gis/gdal/datasource.py
===================================================================
--- django/branches/gis/django/contrib/gis/gdal/datasource.py 2007-09-28
22:34:27 UTC (rev 6435)
+++ django/branches/gis/django/contrib/gis/gdal/datasource.py 2007-09-29
14:02:41 UTC (rev 6436)
@@ -4,7 +4,7 @@
# The GDAL C library, OGR exceptions, and the Layer object.
from django.contrib.gis.gdal.libgdal import lgdal
-from django.contrib.gis.gdal.error import OGRException, check_err
+from django.contrib.gis.gdal.error import OGRException, OGRIndexError,
check_err
from django.contrib.gis.gdal.layer import Layer
from django.contrib.gis.gdal.driver import Driver
@@ -60,7 +60,7 @@
# Registering all the drivers, this needs to be done
# _before_ we try to open up a data source.
if not lgdal.OGRGetDriverCount() and not lgdal.OGRRegisterAll():
- raise OGRException, 'Could not register all the OGR data source
drivers!'
+ raise OGRException('Could not register all the OGR data source
drivers!')
if isinstance(ds_input, StringType):
@@ -72,12 +72,12 @@
elif isinstance(ds_input, c_void_p) and isinstance(ds_driver,
c_void_p):
ds = ds_input
else:
- raise OGRException, 'Invalid data source input type: %s' %
str(type(ds_input))
+ raise OGRException('Invalid data source input type: %s' %
str(type(ds_input)))
# Raise an exception if the returned pointer is NULL
if not ds:
self._ds = False
- raise OGRException, 'Invalid data source file "%s"' % ds_input
+ raise OGRException('Invalid data source file "%s"' % ds_input)
else:
self._ds = ds
self._driver = Driver(ds_driver)
@@ -95,10 +95,10 @@
"Allows use of the index [] operator to get a layer at the index."
if isinstance(index, StringType):
l = lgdal.OGR_DS_GetLayerByName(self._ds, c_char_p(index))
- if not l: raise IndexError, 'invalid OGR Layer name given: "%s"' %
index
+ if not l: raise OGRIndexError('invalid OGR Layer name given: "%s"'
% index)
else:
if index < 0 or index >= self.layer_count:
- raise IndexError, 'index out of range'
+ raise OGRIndexError('index out of range')
l = lgdal.OGR_DS_GetLayer(self._ds, c_int(index))
return Layer(l)
Modified: django/branches/gis/django/contrib/gis/gdal/driver.py
===================================================================
--- django/branches/gis/django/contrib/gis/gdal/driver.py 2007-09-28
22:34:27 UTC (rev 6435)
+++ django/branches/gis/django/contrib/gis/gdal/driver.py 2007-09-29
14:02:41 UTC (rev 6436)
@@ -45,11 +45,11 @@
elif isinstance(input, c_void_p):
dr = input
else:
- raise OGRException, 'Unrecognized input type for OGR Driver: %s' %
str(type(input))
+ raise OGRException('Unrecognized input type for OGR Driver: %s' %
str(type(input)))
# Making sure we get a valid pointer to the OGR Driver
if not dr:
- raise OGRException, 'Could not initialize OGR Driver on input: %s'
% str(input)
+ raise OGRException('Could not initialize OGR Driver on input: %s'
% str(input))
self._dr = dr
def __str__(self):
@@ -61,7 +61,7 @@
# Only register all if the driver count is 0 (or else all drivers
# will be registered over and over again)
if not self.driver_count and not lgdal.OGRRegisterAll():
- raise OGRException, 'Could not register all the OGR data source
drivers!'
+ raise OGRException('Could not register all the OGR data source
drivers!')
# Driver properties
@property
Modified: django/branches/gis/django/contrib/gis/gdal/envelope.py
===================================================================
--- django/branches/gis/django/contrib/gis/gdal/envelope.py 2007-09-28
22:34:27 UTC (rev 6435)
+++ django/branches/gis/django/contrib/gis/gdal/envelope.py 2007-09-29
14:02:41 UTC (rev 6436)
@@ -1,6 +1,3 @@
-from ctypes import Structure, c_double
-from types import TupleType
-
"""
The GDAL/OGR library uses an Envelope structure to hold the bounding
box information for a geometry. The envelope (bounding box) contains
@@ -14,6 +11,9 @@
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:
@@ -27,25 +27,48 @@
]
class Envelope(object):
- "A class that will wrap an OGR Envelope structure."
+ """
+ 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) and len(args[0]) == 4:
- # A Tuple was passed in
- self._from_tuple(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 OGRException, 'Incorrect type of argument: %s' %
str(type(args[0]))
+ raise TypeError('Incorrect type of argument: %s' %
str(type(args[0])))
elif len(args) == 4:
- self._from_tuple(args)
+ # Individiual parameters passed in.
+ # Thanks to ww for the help
+ self._from_sequence(map(float, args))
else:
- raise OGRException, 'Incorrect number of arguments!'
+ 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."
+ """
+ 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)
@@ -53,19 +76,19 @@
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.'
+ 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_tuple(self, tup):
- "Initializes the C OGR Envelope structure from the given tuple."
+ def _from_sequence(self, seq):
+ "Initializes the C OGR Envelope structure from the given sequence."
self._envelope = OGREnvelope()
- self._envelope.MinX = tup[0]
- self._envelope.MinY = tup[1]
- self._envelope.MaxX = tup[2]
- self._envelope.MaxY = tup[3]
+ 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):
@@ -106,7 +129,7 @@
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)
-
+ 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)
Modified: django/branches/gis/django/contrib/gis/gdal/feature.py
===================================================================
--- django/branches/gis/django/contrib/gis/gdal/feature.py 2007-09-28
22:34:27 UTC (rev 6435)
+++ django/branches/gis/django/contrib/gis/gdal/feature.py 2007-09-29
14:02:41 UTC (rev 6436)
@@ -7,6 +7,7 @@
from django.contrib.gis.gdal.error import OGRException, OGRIndexError
from django.contrib.gis.gdal.field import Field
from django.contrib.gis.gdal.geometries import OGRGeometry, OGRGeomType
+from django.contrib.gis.gdal.srs import SpatialReference
# For more information, see the OGR C API source code:
# http://www.gdal.org/ogr/ogr__api_8h.html
@@ -21,7 +22,7 @@
self._feat = 0 # Initially NULL
self._fdefn = 0
if not f:
- raise OGRException, 'Cannot create OGR Feature, invalid pointer
given.'
+ raise OGRException('Cannot create OGR Feature, invalid pointer
given.')
self._feat = f
self._fdefn = lgdal.OGR_F_GetDefnRef(f)
@@ -35,7 +36,7 @@
i = self.index(index)
else:
if index < 0 or index > self.num_fields:
- raise OGRIndexError, 'index out of range'
+ raise OGRIndexError('index out of range')
i = index
return Field(lgdal.OGR_F_GetFieldDefnRef(self._feat, c_int(i)),
string_at(lgdal.OGR_F_GetFieldAsString(self._feat,
c_int(i))))
@@ -84,9 +85,21 @@
@property
def geom(self):
"Returns the OGR Geometry for this Feature."
- # A clone is used, so destruction of the Geometry won't bork the
Feature.
- return
OGRGeometry(lgdal.OGR_G_Clone(lgdal.OGR_F_GetGeometryRef(self._feat)))
+ # Retrieving the geometry pointer for the feature.
+ geom_ptr = lgdal.OGR_F_GetGeometryRef(self._feat)
+ if not geom_ptr:
+ raise OGRException('Cannot retrieve Geometry from the feature.')
+ # Attempting to retrieve the Spatial Reference for the geometry.
+ srs_ptr = lgdal.OGR_G_GetSpatialReference(geom_ptr)
+ if srs_ptr:
+ srs = SpatialReference(srs_ptr, 'ogr')
+ else:
+ srs = None
+
+ # Geometry is cloned so the feature isn't invalidated.
+ return OGRGeometry(lgdal.OGR_G_Clone(geom_ptr), srs)
+
@property
def geom_type(self):
"Returns the OGR Geometry Type for this Feture."
@@ -105,7 +118,7 @@
def index(self, field_name):
"Returns the index of the given field name."
i = lgdal.OGR_F_GetFieldIndex(self._feat, c_char_p(field_name))
- if i < 0: raise OGRIndexError, 'invalid OFT field name given: "%s"' %
field_name
+ if i < 0: raise OGRIndexError('invalid OFT field name given: "%s"' %
field_name)
return i
def clone(self):
Modified: django/branches/gis/django/contrib/gis/gdal/field.py
===================================================================
--- django/branches/gis/django/contrib/gis/gdal/field.py 2007-09-28
22:34:27 UTC (rev 6435)
+++ django/branches/gis/django/contrib/gis/gdal/field.py 2007-09-29
14:02:41 UTC (rev 6436)
@@ -1,5 +1,4 @@
from ctypes import string_at
-
from django.contrib.gis.gdal.libgdal import lgdal
from django.contrib.gis.gdal.error import OGRException
@@ -16,7 +15,7 @@
self._fld = 0 # Initially NULL
if not fld:
- raise OGRException, 'Cannot create OGR Field, invalid pointer
given.'
+ raise OGRException('Cannot create OGR Field, invalid pointer
given.')
self._fld = fld
self._val = val
@@ -64,7 +63,10 @@
return None
class OFTRealList(Field): pass
-class OFTString(Field): pass
+class OFTString(Field):
+ def __str__(self):
+ return '%s ("%s")' % (self.name, self.value)
+
class OFTStringList(Field): pass
class OFTWideString(Field): pass
class OFTWideStringList(Field): pass
Modified: django/branches/gis/django/contrib/gis/gdal/geometries.py
===================================================================
--- django/branches/gis/django/contrib/gis/gdal/geometries.py 2007-09-28
22:34:27 UTC (rev 6435)
+++ django/branches/gis/django/contrib/gis/gdal/geometries.py 2007-09-29
14:02:41 UTC (rev 6436)
@@ -1,24 +1,13 @@
-# types & ctypes
-from types import IntType, StringType
-from ctypes import byref, string_at, c_char_p, c_double, c_int, c_void_p
-
-# Getting geodjango gdal prerequisites
-from django.contrib.gis.gdal.libgdal import lgdal
-from django.contrib.gis.gdal.envelope import Envelope, OGREnvelope
-from django.contrib.gis.gdal.error import check_err, OGRException,
OGRIndexError
-from django.contrib.gis.gdal.geomtype import OGRGeomType
-from django.contrib.gis.gdal.srs import SpatialReference, CoordTransform
-
"""
The OGRGeometry is a wrapper for using the OGR Geometry class
- (see http://www.gdal.org/ogr/classOGRGeometry.html). OGRGeometry
- may be instantiated when reading geometries from OGR Data Sources
- (e.g. SHP files), or when given OGC WKT (a string).
+ (see http://www.gdal.org/ogr/classOGRGeometry.html). OGRGeometry
+ may be instantiated when reading geometries from OGR Data Sources
+ (e.g. SHP files), or when given OGC WKT (a string).
While the 'full' API is not present yet, the API is "pythonic" unlike
- the traditional and "next-generation" OGR Python bindings. One major
- advantage OGR Geometries have over their GEOS counterparts is support
- for spatial reference systems and their transformation.
+ the traditional and "next-generation" OGR Python bindings. One major
+ advantage OGR Geometries have over their GEOS counterparts is support
+ for spatial reference systems and their transformation.
Example:
>>> from django.contrib.gis.gdal import OGRGeometry, OGRGeomType,
SpatialReference
@@ -49,7 +38,17 @@
>>> print gt1 == 3, gt1 == 'Polygon' # Equivalence works w/non-OGRGeomType
objects
True
"""
+# types & ctypes
+from types import IntType, StringType
+from ctypes import byref, string_at, c_char_p, c_double, c_int, c_void_p
+# Getting GDAL prerequisites
+from django.contrib.gis.gdal.libgdal import lgdal
+from django.contrib.gis.gdal.envelope import Envelope, OGREnvelope
+from django.contrib.gis.gdal.error import check_err, OGRException,
OGRIndexError
+from django.contrib.gis.gdal.geomtype import OGRGeomType
+from django.contrib.gis.gdal.srs import SpatialReference, CoordTransform
+
# For more information, see the OGR C API source code:
# http://www.gdal.org/ogr/ogr__api_8h.html
#
@@ -75,37 +74,45 @@
class OGRGeometry(object):
"Generally encapsulates an OGR geometry."
- def __init__(self, input, srs=False):
+ def __init__(self, geom_input, srs=None):
"Initializes Geometry on either WKT or an OGR pointer as input."
self._g = 0 # Initially NULL
- self._init_srs(srs)
- if isinstance(input, StringType):
+ if isinstance(geom_input, StringType):
# First, trying the input as WKT
- buf = c_char_p(input)
+ buf = c_char_p(geom_input)
g = c_void_p()
try:
- check_err(lgdal.OGR_G_CreateFromWkt(byref(buf), self._s._srs,
byref(g)))
- except OGRException, msg:
+ check_err(lgdal.OGR_G_CreateFromWkt(byref(buf), c_void_p(),
byref(g)))
+ except OGRException:
try:
- ogr_t = OGRGeomType(input) # Seeing if the input is a
valid short-hand string
+ # Seeing if the input is a valid short-hand string
+ ogr_t = OGRGeomType(geom_input)
g = lgdal.OGR_G_CreateGeometry(ogr_t.num)
except:
- raise OGRException, 'Could not initialize on WKT "%s"' %
input
- elif isinstance(input, OGRGeomType):
- g = lgdal.OGR_G_CreateGeometry(input.num)
- lgdal.OGR_G_AssignSpatialReference(g, self._s._srs)
- elif isinstance(input, IntType):
+ raise OGRException('Could not initialize OGR Geometry
from: %s' % geom_input)
+ elif isinstance(geom_input, OGRGeomType):
+ g = lgdal.OGR_G_CreateGeometry(geom_input.num)
+ elif isinstance(geom_input, IntType):
# OGR Pointer (integer) was the input
- g = input
+ g = geom_input
else:
- raise OGRException, 'Type of input cannot be determined!'
+ raise OGRException('Type of input cannot be determined!')
+ # Assigning the SpatialReference object to the geometry, if valid.
+ if bool(srs):
+ if isinstance(srs, SpatialReference):
+ srs_ptr = srs._srs
+ else:
+ sr = SpatialReference(srs)
+ srs_ptr = sr._srs
+ lgdal.OGR_G_AssignSpatialReference(g, srs_ptr)
+
# Now checking the Geometry pointer before finishing initialization
if not g:
- raise OGRException, 'Cannot create OGR Geometry from input: %s' %
str(input)
+ raise OGRException('Cannot create OGR Geometry from input: %s' %
str(geom_input))
self._g = g
# Setting the class depending upon the OGR Geometry Type
@@ -115,13 +122,6 @@
"Deletes this Geometry."
if self._g: lgdal.OGR_G_DestroyGeometry(self._g)
- def _init_srs(self, srs):
- # Getting the spatial
- if not isinstance(srs, SpatialReference):
- self._s = SpatialReference() # creating an empty spatial reference
- else:
- self._s = srs.clone() # cloning the given spatial reference
-
### Geometry set-like operations ###
# g = g1 | g2
def __or__(self, other):
@@ -184,7 +184,11 @@
@property
def srs(self):
"Returns the Spatial Reference for this Geometry."
- return
SpatialReference(lgdal.OSRClone(lgdal.OGR_G_GetSpatialReference(self._g)),
'ogr')
+ srs_ptr = lgdal.OGR_G_GetSpatialReference(self._g)
+ if srs_ptr:
+ return SpatialReference(lgdal.OSRClone(srs_ptr), 'ogr')
+ else:
+ return None
@property
def geom_type(self):
@@ -197,13 +201,6 @@
return string_at(lgdal.OGR_G_GetGeometryName(self._g))
@property
- def wkt(self):
- "Returns the WKT form of the Geometry."
- buf = c_char_p()
- check_err(lgdal.OGR_G_ExportToWkt(self._g, byref(buf)))
- return string_at(buf)
-
- @property
def area(self):
"Returns the area for a LinearRing, Polygon, or MultiPolygon; 0
otherwise."
return get_area(self._g)
@@ -214,6 +211,21 @@
env = OGREnvelope()
lgdal.OGR_G_GetEnvelope(self._g, byref(env))
return Envelope(env)
+
+ #### Output Methods ####
+ @property
+ def gml(self):
+ "Returns the GML representation of the Geometry."
+ buf = c_char_p()
+ check_err(lgdal.OGR_G_ExportToGML(self._g, byref(buf)))
+ return string_at(buf)
+
+ @property
+ def wkt(self):
+ "Returns the WKT representation of the Geometry."
+ buf = c_char_p()
+ check_err(lgdal.OGR_G_ExportToWkt(self._g, byref(buf)))
+ return string_at(buf)
#### Geometry Methods ####
def clone(self):
@@ -230,13 +242,13 @@
def transform(self, coord_trans):
"Transforms this Geometry with the given CoordTransform object."
if not isinstance(coord_trans, CoordTransform):
- raise OGRException, 'CoordTransform object required for transform.'
+ raise OGRException('CoordTransform object required for transform.')
check_err(lgdal.OGR_G_Transform(self._g, coord_trans._ct))
def transform_to(self, srs):
"Transforms this Geometry with the given SpatialReference."
if not isinstance(srs, SpatialReference):
- raise OGRException, 'SpatialReference object required for
transform_to.'
+ raise OGRException('SpatialReference object required for
transform_to.')
check_err(lgdal.OGR_G_TransformTo(self._g, srs._srs))
#### Topology Methods ####
@@ -244,7 +256,7 @@
"""A generalized function for topology operations, takes a GDAL
function and
the other geometry to perform the operation on."""
if not isinstance(other, OGRGeometry):
- raise OGRException, 'Must use another OGRGeometry object for
topology operations!'
+ raise OGRException('Must use another OGRGeometry object for
topology operations!')
# Calling the passed-in topology function with the other geometry
status = topo_func(self._g, other._g)
@@ -368,7 +380,7 @@
elif self.coord_dim == 3:
return (x.value, y.value, z.value)
else:
- raise OGRIndexError, 'index out of range: %s' % str(index)
+ raise OGRIndexError('index out of range: %s' % str(index))
def __iter__(self):
"Iterates over each point in the LineString."
@@ -401,9 +413,9 @@
def __getitem__(self, index):
"Gets the ring at the specified index."
if index < 0 or index >= self.geom_count:
- raise OGRIndexError, 'index out of range: %s' % str(index)
+ raise OGRIndexError('index out of range: %s' % str(index))
else:
- return
OGRGeometry(lgdal.OGR_G_Clone(lgdal.OGR_G_GetGeometryRef(self._g,
c_int(index))))
+ return
OGRGeometry(lgdal.OGR_G_Clone(lgdal.OGR_G_GetGeometryRef(self._g,
c_int(index))), self.srs)
# Polygon Properties
@property
@@ -437,9 +449,9 @@
def __getitem__(self, index):
"Gets the Geometry at the specified index."
if index < 0 or index >= self.geom_count:
- raise OGRIndexError, 'index out of range: %s' % str(index)
+ raise OGRIndexError('index out of range: %s' % str(index))
else:
- return
OGRGeometry(lgdal.OGR_G_Clone(lgdal.OGR_G_GetGeometryRef(self._g,
c_int(index))))
+ return
OGRGeometry(lgdal.OGR_G_Clone(lgdal.OGR_G_GetGeometryRef(self._g,
c_int(index))), self.srs)
def __iter__(self):
"Iterates over each Geometry."
@@ -458,7 +470,7 @@
tmp = OGRGeometry(geom)
ptr = tmp._g
else:
- raise OGRException, 'Must add an OGRGeometry.'
+ raise OGRException('Must add an OGRGeometry.')
lgdal.OGR_G_AddGeometry(self._g, ptr)
@property
Modified: django/branches/gis/django/contrib/gis/gdal/geomtype.py
===================================================================
--- django/branches/gis/django/contrib/gis/gdal/geomtype.py 2007-09-28
22:34:27 UTC (rev 6435)
+++ django/branches/gis/django/contrib/gis/gdal/geomtype.py 2007-09-29
14:02:41 UTC (rev 6436)
@@ -11,21 +11,21 @@
'LinearRing']
__ogr_int = [1, 2, 3, 4, 5, 6, 7, 101]
- def __init__(self, input):
+ def __init__(self, type_input):
"Figures out the correct OGR Type based upon the input."
- if isinstance(input, OGRGeomType):
- self._index = input._index
- elif isinstance(input, StringType):
- idx = self._has_str(self.__ogr_str, input)
+ if isinstance(type_input, OGRGeomType):
+ self._index = type_input._index
+ elif isinstance(type_input, StringType):
+ idx = self._has_str(self.__ogr_str, type_input)
if idx == None:
- raise OGRException, 'Invalid OGR String Type "%s"' % input
+ raise OGRException('Invalid OGR String Type "%s"' % type_input)
self._index = idx
- elif isinstance(input, int):
- if not input in self.__ogr_int:
- raise OGRException, 'Invalid OGR Integer Type: %d' % input
- self._index = self.__ogr_int.index(input)
+ elif isinstance(type_input, int):
+ if not type_input in self.__ogr_int:
+ raise OGRException('Invalid OGR Integer Type: %d' % type_input)
+ self._index = self.__ogr_int.index(type_input)
else:
- raise TypeError, 'Invalid OGR Input type given!'
+ raise TypeError('Invalid OGR Input type given!')
def __str__(self):
"Returns a short-hand string form of the OGR Geometry type."
@@ -44,7 +44,7 @@
if not other in self.__ogr_int: return False
return self.__ogr_int.index(other) == self._index
else:
- raise TypeError, 'Cannot compare with type: %s' % str(type(other))
+ raise TypeError('Cannot compare with type: %s' % str(type(other)))
def _has_str(self, arr, s):
"Case-insensitive search of the string array for the given pattern."
Modified: django/branches/gis/django/contrib/gis/gdal/srs.py
===================================================================
--- django/branches/gis/django/contrib/gis/gdal/srs.py 2007-09-28 22:34:27 UTC
(rev 6435)
+++ django/branches/gis/django/contrib/gis/gdal/srs.py 2007-09-29 14:02:41 UTC
(rev 6436)
@@ -79,7 +79,7 @@
_epsg_regex = re.compile('^EPSG:(?P<epsg>\d+)$', re.I)
#### Python 'magic' routines ####
- def __init__(self, input='', srs_type='wkt'):
+ def __init__(self, srs_input='', srs_type='wkt'):
"Creates a spatial reference object from the given OGC Well Known Text
(WKT)."
self._srs = 0 # Initially NULL
@@ -87,45 +87,46 @@
# Creating an initial empty string buffer.
buf = c_char_p('')
- if isinstance(input, UnicodeType):
- input = input.encode('ascii')
+ # Encoding to ASCII if unicode passed in.
+ if isinstance(srs_input, UnicodeType):
+ srs_input = srs_input.encode('ascii')
- if isinstance(input, StringType):
+ if isinstance(srs_input, StringType):
# Is this an EPSG well known name?
- m = self._epsg_regex.match(input)
+ m = self._epsg_regex.match(srs_input)
if m:
srs_type = 'epsg'
- input = int(m.group('epsg'))
+ srs_input = int(m.group('epsg'))
# Is this a short-hand well known name?
- elif input in self._well_known:
+ elif srs_input in self._well_known:
srs_type = 'epsg'
- input = self._well_known[input]
+ srs_input = self._well_known[srs_input]
elif srs_type == 'proj':
pass
else:
- buf = c_char_p(input)
- elif isinstance(input, int):
+ buf = c_char_p(srs_input)
+ elif isinstance(srs_input, int):
if srs_type == 'wkt': srs_type = 'epsg' # want to try epsg if only
integer provided
if srs_type not in ('epsg', 'ogr'):
- raise SRSException, 'Integer input requires SRS type of "ogr"
or "epsg".'
+ raise SRSException('Integer input requires SRS type of "ogr"
or "epsg".')
else:
- raise TypeError, 'Invalid SRS type "%s"' % srs_type
+ raise TypeError('Invalid SRS type "%s"' % srs_type)
# Calling OSRNewSpatialReference with the string buffer.
if srs_type == 'ogr':
- srs = input # Input is OGR pointer
+ srs = srs_input # SRS input is OGR pointer
else:
srs = lgdal.OSRNewSpatialReference(buf)
# If the pointer is NULL, throw an exception.
if not srs:
- raise SRSException, 'Could not create spatial reference from WKT!
(%s)' % input
+ raise SRSException('Could not create spatial reference from: %s' %
srs_input)
else:
self._srs = srs
# Post-processing if in PROJ.4 or EPSG formats.
- if srs_type == 'proj': self.import_proj(input)
- elif srs_type == 'epsg': self.import_epsg(input)
+ if srs_type == 'proj': self.import_proj(srs_input)
+ elif srs_type == 'epsg': self.import_epsg(srs_input)
def __del__(self):
"Destroys this spatial reference."
@@ -142,6 +143,14 @@
else:
return self.attr_value(target)
+ def __nonzero__(self):
+ "Returns True if this SpatialReference object is valid."
+ try:
+ self.validate()
+ return True
+ except OGRException:
+ return False
+
def __str__(self):
"The string representation uses 'pretty' WKT."
return self.pretty_wkt
@@ -188,7 +197,15 @@
elif self.geographic: return self.attr_value('GEOGCS')
elif self.local: return self.attr_value('LOCAL_CS')
else: return None
-
+
+ @property
+ def srid(self):
+ """
+ Returns the EPSG SRID of this Spatial Reference, will be None if
+ if undefined.
+ """
+ return self.srs['AUTHORITY', 1]
+
#### Unit Properties ####
def _cache_linear(self):
"Caches the linear units value and name."
@@ -345,10 +362,10 @@
"Initializes on a source and target SpatialReference objects."
self._ct = 0 # Initially NULL
if not isinstance(source, SpatialReference) or not isinstance(target,
SpatialReference):
- raise SRSException, 'source and target must be of type
SpatialReference'
+ raise SRSException('source and target must be of type
SpatialReference')
ct = lgdal.OCTNewCoordinateTransformation(source._srs, target._srs)
if not ct:
- raise SRSException, 'could not intialize CoordTransform object'
+ raise SRSException('could not intialize CoordTransform object')
self._ct = ct
self._srs1_name = source.name
self._srs2_name = target.name
Modified: django/branches/gis/django/contrib/gis/tests/__init__.py
===================================================================
--- django/branches/gis/django/contrib/gis/tests/__init__.py 2007-09-28
22:34:27 UTC (rev 6435)
+++ django/branches/gis/django/contrib/gis/tests/__init__.py 2007-09-29
14:02:41 UTC (rev 6436)
@@ -13,6 +13,7 @@
test_suite_names += [
'test_gdal_driver',
'test_gdal_ds',
+ 'test_gdal_envelope',
'test_gdal_geom',
'test_gdal_srs',
'test_spatialrefsys',
Added: django/branches/gis/django/contrib/gis/tests/test_gdal.py
===================================================================
--- django/branches/gis/django/contrib/gis/tests/test_gdal.py
(rev 0)
+++ django/branches/gis/django/contrib/gis/tests/test_gdal.py 2007-09-29
14:02:41 UTC (rev 6436)
@@ -0,0 +1,24 @@
+from unittest import TestSuite, TextTestRunner
+
+# Importing the GDAL test modules.
+from django.contrib.gis.tests import \
+ test_gdal_driver, test_gdal_ds, test_gdal_envelope, \
+ test_gdal_geom, test_gdal_srs
+
+
+test_suites = [test_gdal_driver.suite(),
+ test_gdal_ds.suite(),
+ test_gdal_envelope.suite(),
+ test_gdal_geom.suite(),
+ test_gdal_srs.suite(),
+ ]
+
+def suite():
+ "Builds a test suite for the GDAL tests."
+ s = TestSuite()
+ map(s.addTest, test_suites)
+ return s
+
+def run(verbosity=1):
+ "Runs the tests that do not require geographic (GEOS, GDAL, etc.) models."
+ TextTestRunner(verbosity=verbosity).run(suite())
Modified: django/branches/gis/django/contrib/gis/tests/test_gdal_ds.py
===================================================================
--- django/branches/gis/django/contrib/gis/tests/test_gdal_ds.py
2007-09-28 22:34:27 UTC (rev 6435)
+++ django/branches/gis/django/contrib/gis/tests/test_gdal_ds.py
2007-09-29 14:02:41 UTC (rev 6436)
@@ -1,6 +1,5 @@
import os, os.path, unittest
-from django.contrib.gis.gdal import DataSource, OGRException
-from django.contrib.gis.gdal.envelope import Envelope
+from django.contrib.gis.gdal import DataSource, Envelope, OGRException,
OGRIndexError
from django.contrib.gis.gdal.field import OFTReal, OFTInteger, OFTString
# Path for SHP files
@@ -48,7 +47,7 @@
# Making sure indexing works
try:
ds[len(ds)]
- except IndexError:
+ except OGRIndexError:
pass
else:
self.fail('Expected an IndexError!')
@@ -106,7 +105,9 @@
# Asserting the string representation, and making sure
we get
# the proper OGR Field instance.
- self.assertEqual('%s (%s)' % (k, fld.value), str(fld))
+ if isinstance(fld, OFTString): fmt = '%s ("%s")'
+ else: fmt = '%s (%s)'
+ self.assertEqual(fmt % (k, fld.value), str(fld))
self.assertEqual(True, isinstance(fld, v))
# Testing __iter__ on the Feature
@@ -136,5 +137,3 @@
def run(verbosity=2):
unittest.TextTestRunner(verbosity=verbosity).run(suite())
-
-
Added: django/branches/gis/django/contrib/gis/tests/test_gdal_envelope.py
===================================================================
--- django/branches/gis/django/contrib/gis/tests/test_gdal_envelope.py
(rev 0)
+++ django/branches/gis/django/contrib/gis/tests/test_gdal_envelope.py
2007-09-29 14:02:41 UTC (rev 6436)
@@ -0,0 +1,45 @@
+import unittest
+from django.contrib.gis.gdal import Envelope, OGRException
+
+class EnvelopeTest(unittest.TestCase):
+
+ def test01_init(self):
+ "Testing Envelope initilization."
+ e1 = Envelope((0, 0, 5, 5))
+ e2 = Envelope(0, 0, 5, 5)
+ e3 = Envelope(0, '0', '5', 5) # Thanks to ww for this
+ e4 = Envelope(e1._envelope)
+ self.assertRaises(OGRException, Envelope, (5, 5, 0, 0))
+ self.assertRaises(OGRException, Envelope, 5, 5, 0, 0)
+ self.assertRaises(OGRException, Envelope, (0, 0, 5, 5, 3))
+ self.assertRaises(OGRException, Envelope, ())
+ self.assertRaises(ValueError, Envelope, 0, 'a', 5, 5)
+ self.assertRaises(TypeError, Envelope, u'foo')
+
+ def test02_properties(self):
+ "Testing Envelope properties."
+ e = Envelope(0, 0, 2, 3)
+ self.assertEqual(0, e.min_x)
+ self.assertEqual(0, e.min_y)
+ self.assertEqual(2, e.max_x)
+ self.assertEqual(3, e.max_y)
+ self.assertEqual((0, 0), e.ll)
+ self.assertEqual((2, 3), e.ur)
+ self.assertEqual((0, 0, 2, 3), e.tuple)
+ self.assertEqual('POLYGON((0.0 0.0,0.0 3.0,2.0 3.0,2.0 0.0,0.0 0.0))',
e.wkt)
+ self.assertEqual('(0.0, 0.0, 2.0, 3.0)', str(e))
+
+ def test03_equivalence(self):
+ "Testing Envelope equivalence."
+ e1 = Envelope(0.523, 0.217, 253.23, 523.69)
+ e2 = Envelope((0.523, 0.217, 253.23, 523.69))
+ self.assertEqual(e1, e2)
+ self.assertEqual((0.523, 0.217, 253.23, 523.69), e1)
+
+def suite():
+ s = unittest.TestSuite()
+ s.addTest(unittest.makeSuite(EnvelopeTest))
+ return s
+
+def run(verbosity=2):
+ unittest.TextTestRunner(verbosity=verbosity).run(suite())
Modified: django/branches/gis/django/contrib/gis/tests/test_gdal_geom.py
===================================================================
--- django/branches/gis/django/contrib/gis/tests/test_gdal_geom.py
2007-09-28 22:34:27 UTC (rev 6435)
+++ django/branches/gis/django/contrib/gis/tests/test_gdal_geom.py
2007-09-29 14:02:41 UTC (rev 6436)
@@ -1,5 +1,5 @@
import unittest
-from django.contrib.gis.gdal import OGRGeometry, OGRGeomType, OGRException
+from django.contrib.gis.gdal import OGRGeometry, OGRGeomType, OGRException,
SpatialReference
from geometries import *
class OGRGeomTest(unittest.TestCase):
@@ -130,6 +130,18 @@
self.assertEqual(mp.n_p, mpoly.point_count)
self.assertEqual(mp.num_geom, len(mpoly))
+ def test09_srs(self):
+ "Testing OGR Geometries with Spatial Reference objects."
+ for mp in multipolygons:
+ sr = SpatialReference('WGS84')
+ mpoly = OGRGeometry(mp.wkt, sr)
+ self.assertEqual(sr.wkt, mpoly.srs.wkt)
+ for poly in mpoly:
+ self.assertEqual(sr.wkt, poly.srs.wkt)
+ for ring in poly:
+ self.assertEqual(sr.wkt, ring.srs.wkt)
+
+
def suite():
s = unittest.TestSuite()
s.addTest(unittest.makeSuite(OGRGeomTest))
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---