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

gis: fixed ticket 4740 with the addition of new exceptions; updated tests for prev change in Field; added get() method to Feature; fixed bug in Layer for geometries w/o srs; SpatialRefSys now uses ellipsoid

git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@5587 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Justin Bronn 2007-07-02 23:47:40 +00:00
parent 858ae54a11
commit 44069054d7
6 changed files with 41 additions and 18 deletions

View File

@ -93,6 +93,10 @@ class Feature(object):
return OGRGeomType(lgdal.OGR_FD_GetGeomType(self._fdefn)) return OGRGeomType(lgdal.OGR_FD_GetGeomType(self._fdefn))
#### Feature Methods #### #### Feature Methods ####
def get(self, field_name):
"Returns the value of the field, instead of an instance of the Field object."
return self.__getitem__(field_name).value
def index(self, field_name): def index(self, field_name):
"Returns the index of the given field name." "Returns the index of the given field name."
i = lgdal.OGR_F_GetFieldIndex(self._feat, c_char_p(field_name)) i = lgdal.OGR_F_GetFieldIndex(self._feat, c_char_p(field_name))

View File

@ -7,6 +7,7 @@ from django.contrib.gis.gdal.libgdal import lgdal
# Other GDAL imports. # Other GDAL imports.
from django.contrib.gis.gdal.Envelope import Envelope, OGREnvelope from django.contrib.gis.gdal.Envelope import Envelope, OGREnvelope
from django.contrib.gis.gdal.Feature import Feature from django.contrib.gis.gdal.Feature import Feature
from django.contrib.gis.gdal.OGRGeometry import OGRGeomType
from django.contrib.gis.gdal.OGRError import OGRException, check_err from django.contrib.gis.gdal.OGRError import OGRException, check_err
from django.contrib.gis.gdal.SpatialReference import SpatialReference from django.contrib.gis.gdal.SpatialReference import SpatialReference
@ -83,12 +84,16 @@ class Layer(object):
@property @property
def geom_type(self): def geom_type(self):
"Returns the geometry type (OGRGeomType) of the Layer." "Returns the geometry type (OGRGeomType) of the Layer."
return lgdal.OGR_FD_GetGeomType(self._ldefn) return OGRGeomType(lgdal.OGR_FD_GetGeomType(self._ldefn))
@property @property
def srs(self): def srs(self):
"Returns the Spatial Reference used in this Layer." "Returns the Spatial Reference used in this Layer."
return SpatialReference(lgdal.OSRClone(lgdal.OGR_L_GetSpatialRef(self._layer)), 'ogr') ptr = lgdal.OGR_L_GetSpatialRef(self._layer)
if ptr:
srs = SpatialReference(lgdal.OSRClone(ptr), 'ogr')
else:
return None
@property @property
def fields(self): def fields(self):

View File

@ -131,6 +131,14 @@ class OGRGeomType(object):
return self.__ogr_int[self._index] return self.__ogr_int[self._index]
#### 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."
@ -412,7 +420,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 IndexError, 'index out of range' raise OGRGeometryIndexError, '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."
@ -445,7 +453,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 IndexError, 'index out of range' raise OGRGeometryIndexError, '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))))
@ -481,7 +489,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 IndexError, 'index out of range' raise OGRGeometryIndexError, '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

@ -85,6 +85,13 @@ else:
# The GEOSException class # The GEOSException class
class GEOSException(Exception): pass class GEOSException(Exception): pass
class GEOSGeometryIndexError(GEOSException, 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
# Getting the GEOS C library. The C interface (CDLL) is used for # Getting the GEOS C library. The C interface (CDLL) is used for
# both *NIX and Windows. # both *NIX and Windows.
@ -345,7 +352,7 @@ class GEOSGeometry(object):
@property @property
def envelope(self): def envelope(self):
"Return the geometries bounding box." "Return the envelope for this geometry (a polygon)."
return GEOSGeometry(lgeos.GEOSEnvelope(self._g)) return GEOSGeometry(lgeos.GEOSEnvelope(self._g))
@property @property
@ -432,7 +439,7 @@ class GEOSCoordSeq(object):
"Checks the index." "Checks the index."
sz = self.size sz = self.size
if (sz < 1) or (index < 0) or (index >= sz): if (sz < 1) or (index < 0) or (index >= sz):
raise IndexError, 'index out of range' raise GEOSGeometryIndexError, 'invalid GEOS Geometry index: %s' % str(index)
def _checkdim(self, dim): def _checkdim(self, dim):
"Checks the given dimension." "Checks the given dimension."
@ -594,7 +601,7 @@ class LineString(GEOSGeometry):
"Gets the point at the specified index." "Gets the point at the specified index."
self._cache_cs() self._cache_cs()
if index < 0 or index >= self._cs.size: if index < 0 or index >= self._cs.size:
raise IndexError, 'index out of range' raise GEOSGeometryIndexError, 'invalid GEOS Geometry index: %s' % str(index)
else: else:
return self._cs[index] return self._cs[index]
@ -624,7 +631,7 @@ class Polygon(GEOSGeometry):
"""Returns the ring at the specified index. The first index, 0, will always """Returns the ring at the specified index. The first index, 0, will always
return the exterior ring. Indices > 0 will return the interior ring.""" return the exterior ring. Indices > 0 will return the interior ring."""
if index < 0 or index > self.num_interior_rings: if index < 0 or index > self.num_interior_rings:
raise IndexError, 'index out of range' raise GEOSGeometryIndexError, 'invalid GEOS Geometry index: %s' % str(index)
else: else:
if index == 0: if index == 0:
return self.exterior_ring return self.exterior_ring
@ -687,7 +694,7 @@ class GeometryCollection(GEOSGeometry):
def _checkindex(self, index): def _checkindex(self, index):
"Checks the given geometry index." "Checks the given geometry index."
if index < 0 or index >= self.num_geom: if index < 0 or index >= self.num_geom:
raise IndexError, 'index out of range' raise GEOSGeometryIndexError, 'invalid GEOS Geometry index: %s' % str(index)
def __iter__(self): def __iter__(self):
"For iteration on the multiple geometries." "For iteration on the multiple geometries."

View File

@ -48,7 +48,7 @@ class SpatialRefSys(models.Model):
db_table = 'spatial_ref_sys' db_table = 'spatial_ref_sys'
def _cache_osr(self): def _cache_osr(self):
"Caches a GDAL OSR object for this Spatial Reference." "Caches a GDAL OSR SpatialReference object for this SpatialRefSys model."
if HAS_OSR: if HAS_OSR:
if not hasattr(self, '_srs'): if not hasattr(self, '_srs'):
# Trying to get from WKT first # Trying to get from WKT first
@ -71,6 +71,7 @@ class SpatialRefSys(models.Model):
@property @property
def srs(self): def srs(self):
"Returns the SpatialReference equivalent of this model."
self._cache_osr() self._cache_osr()
return self._srs.clone() return self._srs.clone()
@ -79,12 +80,8 @@ class SpatialRefSys(models.Model):
"""Returns a tuple of the ellipsoid parameters: """Returns a tuple of the ellipsoid parameters:
(semimajor axis, semiminor axis, and inverse flattening).""" (semimajor axis, semiminor axis, and inverse flattening)."""
if HAS_OSR: if HAS_OSR:
# Setting values initially to False
self._cache_osr() self._cache_osr()
major = self._srs.semi_major return self._srs.ellipsoid
minor = self._srs.semi_minor
invflat = self._srs.inverse_flattening
return (major, minor, invflat)
else: else:
m = spheroid_regex.match(self.srtext) m = spheroid_regex.match(self.srtext)
if m: return (float(m.group('major')), float(m.group('flattening'))) if m: return (float(m.group('major')), float(m.group('flattening')))

View File

@ -101,8 +101,10 @@ class DataSourceTest(unittest.TestCase):
for k, v in source.fields.items(): for k, v in source.fields.items():
fld = feat[k] # Indexing with string value fld = feat[k] # Indexing with string value
# Asserting the string representation (which asserts the type) # Asserting the string representation, and making sure we get
self.assertEqual('%s (%s)' % (k, v.__name__), str(fld)) # the proper OGR Field instance.
self.assertEqual('%s (%s)' % (k, fld.value), str(fld))
self.assertEqual(True, isinstance(fld, v))
# Testing __iter__ on the Feature # Testing __iter__ on the Feature
for fld in feat: self.assertEqual(fld.name in source.fields.keys(), True) for fld in feat: self.assertEqual(fld.name in source.fields.keys(), True)