1
0
mirror of https://github.com/django/django.git synced 2025-07-04 09:49:12 +00:00

gis: gdal: Changed name of OGRGeometryIndexError to OGRIndexError and moved to errors mdoule; added HAS_GDAL flag to module; improved docstrings in srs.

git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@6412 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Justin Bronn 2007-09-24 20:28:23 +00:00
parent e95fda3e26
commit 07963be5df
4 changed files with 65 additions and 48 deletions

View File

@ -1,8 +1,12 @@
from django.contrib.gis.gdal.driver import Driver try:
from django.contrib.gis.gdal.envelope import Envelope from django.contrib.gis.gdal.driver import Driver
from django.contrib.gis.gdal.datasource import DataSource from django.contrib.gis.gdal.envelope import Envelope
from django.contrib.gis.gdal.srs import SpatialReference, CoordTransform from django.contrib.gis.gdal.datasource import DataSource
from django.contrib.gis.gdal.geometries import OGRGeometry from django.contrib.gis.gdal.srs import SpatialReference, CoordTransform
from django.contrib.gis.gdal.geomtype import OGRGeomType from django.contrib.gis.gdal.geometries import OGRGeometry
from django.contrib.gis.gdal.error import check_err, OGRException, SRSException 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

View File

@ -7,6 +7,14 @@
# OGR & SRS Exceptions # OGR & SRS Exceptions
class OGRException(Exception): pass class OGRException(Exception): pass
class SRSException(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 # OGR Error Codes
OGRERR_DICT = { 1 : (OGRException, 'Not enough data.'), OGRERR_DICT = { 1 : (OGRException, 'Not enough data.'),

View File

@ -5,7 +5,7 @@ from ctypes import byref, string_at, c_char_p, c_double, c_int, c_void_p
# Getting geodjango gdal prerequisites # Getting geodjango gdal prerequisites
from django.contrib.gis.gdal.libgdal import lgdal from django.contrib.gis.gdal.libgdal import lgdal
from django.contrib.gis.gdal.envelope import Envelope, OGREnvelope 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.geomtype import OGRGeomType
from django.contrib.gis.gdal.srs import SpatialReference, CoordTransform from django.contrib.gis.gdal.srs import SpatialReference, CoordTransform
@ -72,14 +72,6 @@ get_area.restype = c_double
get_area.argtypes = [c_void_p] get_area.argtypes = [c_void_p]
#### OGRGeometry Class #### #### 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): class OGRGeometry(object):
"Generally encapsulates an OGR geometry." "Generally encapsulates an OGR geometry."
@ -87,11 +79,9 @@ class OGRGeometry(object):
"Initializes Geometry on either WKT or an OGR pointer as input." "Initializes Geometry on either WKT or an OGR pointer as input."
self._g = 0 # Initially NULL self._g = 0 # Initially NULL
self._init_srs(srs)
if isinstance(input, StringType): if isinstance(input, StringType):
# Getting the spatial reference
self._init_srs(srs)
# First, trying the input as WKT # First, trying the input as WKT
buf = c_char_p(input) buf = c_char_p(input)
g = c_void_p() g = c_void_p()
@ -105,7 +95,6 @@ class OGRGeometry(object):
except: except:
raise OGRException, 'Could not initialize on WKT "%s"' % input raise OGRException, 'Could not initialize on WKT "%s"' % input
elif isinstance(input, OGRGeomType): elif isinstance(input, OGRGeomType):
self._init_srs(srs)
g = lgdal.OGR_G_CreateGeometry(input.num) g = lgdal.OGR_G_CreateGeometry(input.num)
lgdal.OGR_G_AssignSpatialReference(g, self._s._srs) lgdal.OGR_G_AssignSpatialReference(g, self._s._srs)
elif isinstance(input, IntType): elif isinstance(input, IntType):
@ -237,8 +226,6 @@ class OGRGeometry(object):
end.""" end."""
# Closing the open rings. # Closing the open rings.
lgdal.OGR_G_CloseRings(self._g) 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): def transform(self, coord_trans):
"Transforms this Geometry with the given CoordTransform object." "Transforms this Geometry with the given CoordTransform object."
@ -381,7 +368,7 @@ class LineString(OGRGeometry):
elif self.coord_dim == 3: elif self.coord_dim == 3:
return (x.value, y.value, z.value) return (x.value, y.value, z.value)
else: else:
raise OGRGeometryIndexError, 'index out of range: %s' % str(index) raise OGRIndexError, 'index out of range: %s' % str(index)
def __iter__(self): def __iter__(self):
"Iterates over each point in the LineString." "Iterates over each point in the LineString."
@ -414,7 +401,7 @@ class Polygon(OGRGeometry):
def __getitem__(self, index): def __getitem__(self, index):
"Gets the ring at the specified index." "Gets the ring at the specified index."
if index < 0 or index >= self.geom_count: 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: 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))))
@ -450,7 +437,7 @@ class GeometryCollection(OGRGeometry):
def __getitem__(self, index): def __getitem__(self, index):
"Gets the Geometry at the specified index." "Gets the Geometry at the specified index."
if index < 0 or index >= self.geom_count: 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: 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))))

View File

@ -1,4 +1,3 @@
# Getting what we need from ctypes
import re import re
from types import StringType, UnicodeType, TupleType from types import StringType, UnicodeType, TupleType
from ctypes import \ from ctypes import \
@ -39,12 +38,12 @@ from django.contrib.gis.gdal.error import check_err, OGRException, SRSException
>>> print srs.name >>> print srs.name
NAD83 / Texas South Central NAD83 / Texas South Central
""" """
#### ctypes function prototypes #### #### ctypes function prototypes ####
def ellipsis_func(f): 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.restype = c_double
f.argtypes = [c_void_p, POINTER(c_int)] f.argtypes = [c_void_p, POINTER(c_int)]
return f return f
@ -55,8 +54,10 @@ semi_minor = ellipsis_func(lgdal.OSRGetSemiMinor)
invflattening = ellipsis_func(lgdal.OSRGetInvFlattening) invflattening = ellipsis_func(lgdal.OSRGetInvFlattening)
def units_func(f): 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.restype = c_double
f.argtypes = [c_void_p, POINTER(c_char_p)] f.argtypes = [c_void_p, POINTER(c_char_p)]
return f return f
@ -67,9 +68,11 @@ angular_units = units_func(lgdal.OSRGetAngularUnits)
#### Spatial Reference class. #### #### Spatial Reference class. ####
class SpatialReference(object): class SpatialReference(object):
"""A wrapper for the OGRSpatialReference object. According to the GDAL website, """
the SpatialReference object 'provide[s] services to represent coordinate systems A wrapper for the OGRSpatialReference object. According to the GDAL website,
(projections and datums) and to transform between them.'""" 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 Geographical Coordinate System Name
_well_known = {'WGS84':4326, 'WGS72':4322, 'NAD27':4267, 'NAD83':4269} _well_known = {'WGS84':4326, 'WGS72':4322, 'NAD27':4267, 'NAD83':4269}
@ -129,8 +132,11 @@ class SpatialReference(object):
if self._srs: lgdal.OSRRelease(self._srs) if self._srs: lgdal.OSRRelease(self._srs)
def __getitem__(self, target): 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): if isinstance(target, TupleType):
return self.attr_value(*target) return self.attr_value(*target)
else: else:
@ -141,7 +147,10 @@ class SpatialReference(object):
return self.pretty_wkt return self.pretty_wkt
def _string_ptr(self, ptr): 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 if not ptr: return None
else: return string_at(ptr) else: return string_at(ptr)
@ -157,8 +166,10 @@ class SpatialReference(object):
return self._string_ptr(ptr) return self._string_ptr(ptr)
def attr_value(self, target, index=0): 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)) ptr = lgdal.OSRGetAttrValue(self._srs, c_char_p(target), c_int(index))
return self._string_ptr(ptr) return self._string_ptr(ptr)
@ -220,13 +231,15 @@ class SpatialReference(object):
#### Spheroid/Ellipsoid Properties #### #### Spheroid/Ellipsoid Properties ####
@property @property
def ellipsoid(self): 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) return (self.semi_major, self.semi_minor, self.inverse_flattening)
@property @property
def semi_major(self): 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) err = c_int(0)
sm = semi_major(self._srs, byref(err)) sm = semi_major(self._srs, byref(err))
check_err(err.value) check_err(err.value)
@ -234,7 +247,7 @@ class SpatialReference(object):
@property @property
def semi_minor(self): 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() err = c_int()
sm = semi_minor(self._srs, byref(err)) sm = semi_minor(self._srs, byref(err))
check_err(err.value) check_err(err.value)
@ -242,7 +255,7 @@ class SpatialReference(object):
@property @property
def inverse_flattening(self): def inverse_flattening(self):
"Gets the Inverse Flattening for this Spatial Reference." "Returns the Inverse Flattening for this Spatial Reference."
err = c_int() err = c_int()
inv_flat = invflattening(self._srs, byref(err)) inv_flat = invflattening(self._srs, byref(err))
check_err(err.value) check_err(err.value)
@ -251,7 +264,10 @@ class SpatialReference(object):
#### Boolean Properties #### #### Boolean Properties ####
@property @property
def geographic(self): 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 if lgdal.OSRIsGeographic(self._srs): return True
else: return False else: return False
@ -263,7 +279,10 @@ class SpatialReference(object):
@property @property
def projected(self): 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 if lgdal.OSRIsProjected(self._srs): return True
else: return False else: return False
@ -340,4 +359,3 @@ class CoordTransform(object):
def __str__(self): def __str__(self):
return 'Transform from "%s" to "%s"' % (str(self._srs1_name), str(self._srs2_name)) return 'Transform from "%s" to "%s"' % (str(self._srs1_name), str(self._srs2_name))