diff --git a/django/contrib/gis/gdal/__init__.py b/django/contrib/gis/gdal/__init__.py index d47c66fc20..759103282c 100644 --- a/django/contrib/gis/gdal/__init__.py +++ b/django/contrib/gis/gdal/__init__.py @@ -1,8 +1,12 @@ -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 +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 diff --git a/django/contrib/gis/gdal/error.py b/django/contrib/gis/gdal/error.py index 439b2b993d..ed4b035f9c 100644 --- a/django/contrib/gis/gdal/error.py +++ b/django/contrib/gis/gdal/error.py @@ -7,6 +7,14 @@ # OGR & SRS Exceptions class OGRException(Exception): pass class SRSException(Exception): pass +class OGRIndexError(OGRException, KeyError): + """ + This exception is raised when an invalid index is encountered, and has + the 'silent_variable_feature' attribute set to true. This ensures that + django's templates proceed to use the next lookup type gracefully when + an Exception is raised. Fixes ticket #4740. + """ + silent_variable_failure = True # OGR Error Codes OGRERR_DICT = { 1 : (OGRException, 'Not enough data.'), diff --git a/django/contrib/gis/gdal/geometries.py b/django/contrib/gis/gdal/geometries.py index cbf4b39efc..42af45bf2d 100644 --- a/django/contrib/gis/gdal/geometries.py +++ b/django/contrib/gis/gdal/geometries.py @@ -5,7 +5,7 @@ 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 +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 @@ -72,14 +72,6 @@ get_area.restype = c_double get_area.argtypes = [c_void_p] #### OGRGeometry Class #### -class OGRGeometryIndexError(OGRException, KeyError): - """This exception is raised when an invalid index is encountered, and has - the 'silent_variable_feature' attribute set to true. This ensures that - django's templates proceed to use the next lookup type gracefully when - an Exception is raised. Fixes ticket #4740. - """ - silent_variable_failure = True - class OGRGeometry(object): "Generally encapsulates an OGR geometry." @@ -87,11 +79,9 @@ class OGRGeometry(object): "Initializes Geometry on either WKT or an OGR pointer as input." self._g = 0 # Initially NULL + self._init_srs(srs) if isinstance(input, StringType): - # Getting the spatial reference - self._init_srs(srs) - # First, trying the input as WKT buf = c_char_p(input) g = c_void_p() @@ -105,7 +95,6 @@ class OGRGeometry(object): except: raise OGRException, 'Could not initialize on WKT "%s"' % input elif isinstance(input, OGRGeomType): - self._init_srs(srs) g = lgdal.OGR_G_CreateGeometry(input.num) lgdal.OGR_G_AssignSpatialReference(g, self._s._srs) elif isinstance(input, IntType): @@ -237,8 +226,6 @@ class OGRGeometry(object): end.""" # Closing the open rings. lgdal.OGR_G_CloseRings(self._g) - # This "fixes" a GDAL bug. See http://trac.osgeo.org/gdal/ticket/1673 - foo = self.wkt def transform(self, coord_trans): "Transforms this Geometry with the given CoordTransform object." @@ -381,7 +368,7 @@ class LineString(OGRGeometry): elif self.coord_dim == 3: return (x.value, y.value, z.value) else: - raise OGRGeometryIndexError, '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." @@ -414,7 +401,7 @@ class Polygon(OGRGeometry): def __getitem__(self, index): "Gets the ring at the specified index." if index < 0 or index >= self.geom_count: - raise OGRGeometryIndexError, '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)))) @@ -450,7 +437,7 @@ class GeometryCollection(OGRGeometry): def __getitem__(self, index): "Gets the Geometry at the specified index." if index < 0 or index >= self.geom_count: - raise OGRGeometryIndexError, '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)))) diff --git a/django/contrib/gis/gdal/srs.py b/django/contrib/gis/gdal/srs.py index 08b9381eb0..b8632daa3c 100644 --- a/django/contrib/gis/gdal/srs.py +++ b/django/contrib/gis/gdal/srs.py @@ -1,4 +1,3 @@ -# Getting what we need from ctypes import re from types import StringType, UnicodeType, TupleType from ctypes import \ @@ -39,12 +38,12 @@ from django.contrib.gis.gdal.error import check_err, OGRException, SRSException >>> print srs.name NAD83 / Texas South Central """ - - #### ctypes function prototypes #### def ellipsis_func(f): - """Creates a ctypes function prototype for OSR ellipsis property functions, - e.g., OSRGetSemiMajor, OSRGetSemiMinor, OSRGetInvFlattening.""" + """ + Creates a ctypes function prototype for OSR ellipsis property functions, e.g., + OSRGetSemiMajor, OSRGetSemiMinor, OSRGetInvFlattening. + """ f.restype = c_double f.argtypes = [c_void_p, POINTER(c_int)] return f @@ -55,8 +54,10 @@ semi_minor = ellipsis_func(lgdal.OSRGetSemiMinor) invflattening = ellipsis_func(lgdal.OSRGetInvFlattening) def units_func(f): - """Creates a ctypes function prototype for OSR units functions, - e.g., OSRGetAngularUnits, OSRGetLinearUnits.""" + """ + Creates a ctypes function prototype for OSR units functions, e.g., + OSRGetAngularUnits, OSRGetLinearUnits. + """ f.restype = c_double f.argtypes = [c_void_p, POINTER(c_char_p)] return f @@ -67,9 +68,11 @@ angular_units = units_func(lgdal.OSRGetAngularUnits) #### Spatial Reference class. #### class SpatialReference(object): - """A wrapper for the OGRSpatialReference object. According to the GDAL website, - the SpatialReference object 'provide[s] services to represent coordinate systems - (projections and datums) and to transform between them.'""" + """ + A wrapper for the OGRSpatialReference object. According to the GDAL website, + the SpatialReference object 'provide[s] services to represent coordinate + systems (projections and datums) and to transform between them.' + """ # Well-Known Geographical Coordinate System Name _well_known = {'WGS84':4326, 'WGS72':4322, 'NAD27':4267, 'NAD83':4269} @@ -129,8 +132,11 @@ class SpatialReference(object): if self._srs: lgdal.OSRRelease(self._srs) def __getitem__(self, target): - """Returns the value of the given string attribute node, None if the node doesn't exist. - Can also take a tuple as a parameter, (target, child), where child is the child index to get.""" + """ + Returns the value of the given string attribute node, None if the node + doesn't exist. Can also take a tuple as a parameter, (target, child), + where child is the child index to get. + """ if isinstance(target, TupleType): return self.attr_value(*target) else: @@ -141,7 +147,10 @@ class SpatialReference(object): return self.pretty_wkt def _string_ptr(self, ptr): - "Returns the string at the pointer if it is valid, None if the pointer is NULL." + """ + Returns the string at the pointer if it is valid, None if the pointer + is NULL. + """ if not ptr: return None else: return string_at(ptr) @@ -157,8 +166,10 @@ class SpatialReference(object): return self._string_ptr(ptr) def attr_value(self, target, index=0): - """The attribute value for the given target node (e.g. 'PROJCS'). The index keyword - specifies an index of the child node to return.""" + """ + The attribute value for the given target node (e.g. 'PROJCS'). The index + keyword specifies an index of the child node to return. + """ ptr = lgdal.OSRGetAttrValue(self._srs, c_char_p(target), c_int(index)) return self._string_ptr(ptr) @@ -220,13 +231,15 @@ class SpatialReference(object): #### Spheroid/Ellipsoid Properties #### @property def ellipsoid(self): - """Returns a tuple of the ellipsoid parameters: - (semimajor axis, semiminor axis, and inverse flattening).""" + """ + Returns a tuple of the ellipsoid parameters: + (semimajor axis, semiminor axis, and inverse flattening) + """ return (self.semi_major, self.semi_minor, self.inverse_flattening) @property def semi_major(self): - "Gets the Semi Major Axis for this Spatial Reference." + "Returns the Semi Major Axis for this Spatial Reference." err = c_int(0) sm = semi_major(self._srs, byref(err)) check_err(err.value) @@ -234,7 +247,7 @@ class SpatialReference(object): @property def semi_minor(self): - "Gets the Semi Minor Axis for this Spatial Reference." + "Returns the Semi Minor Axis for this Spatial Reference." err = c_int() sm = semi_minor(self._srs, byref(err)) check_err(err.value) @@ -242,7 +255,7 @@ class SpatialReference(object): @property def inverse_flattening(self): - "Gets the Inverse Flattening for this Spatial Reference." + "Returns the Inverse Flattening for this Spatial Reference." err = c_int() inv_flat = invflattening(self._srs, byref(err)) check_err(err.value) @@ -251,7 +264,10 @@ class SpatialReference(object): #### Boolean Properties #### @property def geographic(self): - "Returns True if this SpatialReference is geographic (root node is GEOGCS)." + """ + Returns True if this SpatialReference is geographic + (root node is GEOGCS). + """ if lgdal.OSRIsGeographic(self._srs): return True else: return False @@ -263,7 +279,10 @@ class SpatialReference(object): @property def projected(self): - "Returns True if this SpatialReference is a projected coordinate system (root node is PROJCS)." + """ + Returns True if this SpatialReference is a projected coordinate system + (root node is PROJCS). + """ if lgdal.OSRIsProjected(self._srs): return True else: return False @@ -340,4 +359,3 @@ class CoordTransform(object): def __str__(self): return 'Transform from "%s" to "%s"' % (str(self._srs1_name), str(self._srs2_name)) -