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
-~----------~----~----~----~------~----~------~--~---

Reply via email to