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:
parent
858ae54a11
commit
44069054d7
@ -93,6 +93,10 @@ class Feature(object):
|
||||
return OGRGeomType(lgdal.OGR_FD_GetGeomType(self._fdefn))
|
||||
|
||||
#### 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):
|
||||
"Returns the index of the given field name."
|
||||
i = lgdal.OGR_F_GetFieldIndex(self._feat, c_char_p(field_name))
|
||||
|
@ -7,6 +7,7 @@ from django.contrib.gis.gdal.libgdal import lgdal
|
||||
# Other GDAL imports.
|
||||
from django.contrib.gis.gdal.Envelope import Envelope, OGREnvelope
|
||||
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.SpatialReference import SpatialReference
|
||||
|
||||
@ -83,12 +84,16 @@ class Layer(object):
|
||||
@property
|
||||
def geom_type(self):
|
||||
"Returns the geometry type (OGRGeomType) of the Layer."
|
||||
return lgdal.OGR_FD_GetGeomType(self._ldefn)
|
||||
return OGRGeomType(lgdal.OGR_FD_GetGeomType(self._ldefn))
|
||||
|
||||
@property
|
||||
def srs(self):
|
||||
"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
|
||||
def fields(self):
|
||||
|
@ -131,6 +131,14 @@ class OGRGeomType(object):
|
||||
return self.__ogr_int[self._index]
|
||||
|
||||
#### 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."
|
||||
|
||||
@ -412,7 +420,7 @@ class LineString(OGRGeometry):
|
||||
elif self.coord_dim == 3:
|
||||
return (x.value, y.value, z.value)
|
||||
else:
|
||||
raise IndexError, 'index out of range'
|
||||
raise OGRGeometryIndexError, 'index out of range: %s' % str(index)
|
||||
|
||||
def __iter__(self):
|
||||
"Iterates over each point in the LineString."
|
||||
@ -445,7 +453,7 @@ class Polygon(OGRGeometry):
|
||||
def __getitem__(self, index):
|
||||
"Gets the ring at the specified index."
|
||||
if index < 0 or index >= self.geom_count:
|
||||
raise IndexError, 'index out of range'
|
||||
raise OGRGeometryIndexError, 'index out of range: %s' % str(index)
|
||||
else:
|
||||
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):
|
||||
"Gets the Geometry at the specified index."
|
||||
if index < 0 or index >= self.geom_count:
|
||||
raise IndexError, 'index out of range'
|
||||
raise OGRGeometryIndexError, 'index out of range: %s' % str(index)
|
||||
else:
|
||||
return OGRGeometry(lgdal.OGR_G_Clone(lgdal.OGR_G_GetGeometryRef(self._g, c_int(index))))
|
||||
|
||||
|
@ -85,6 +85,13 @@ else:
|
||||
|
||||
# The GEOSException class
|
||||
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
|
||||
# both *NIX and Windows.
|
||||
@ -345,7 +352,7 @@ class GEOSGeometry(object):
|
||||
|
||||
@property
|
||||
def envelope(self):
|
||||
"Return the geometries bounding box."
|
||||
"Return the envelope for this geometry (a polygon)."
|
||||
return GEOSGeometry(lgeos.GEOSEnvelope(self._g))
|
||||
|
||||
@property
|
||||
@ -432,7 +439,7 @@ class GEOSCoordSeq(object):
|
||||
"Checks the index."
|
||||
sz = self.size
|
||||
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):
|
||||
"Checks the given dimension."
|
||||
@ -594,7 +601,7 @@ class LineString(GEOSGeometry):
|
||||
"Gets the point at the specified index."
|
||||
self._cache_cs()
|
||||
if index < 0 or index >= self._cs.size:
|
||||
raise IndexError, 'index out of range'
|
||||
raise GEOSGeometryIndexError, 'invalid GEOS Geometry index: %s' % str(index)
|
||||
else:
|
||||
return self._cs[index]
|
||||
|
||||
@ -624,7 +631,7 @@ class Polygon(GEOSGeometry):
|
||||
"""Returns the ring at the specified index. The first index, 0, will always
|
||||
return the exterior ring. Indices > 0 will return the interior ring."""
|
||||
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:
|
||||
if index == 0:
|
||||
return self.exterior_ring
|
||||
@ -687,7 +694,7 @@ class GeometryCollection(GEOSGeometry):
|
||||
def _checkindex(self, index):
|
||||
"Checks the given geometry index."
|
||||
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):
|
||||
"For iteration on the multiple geometries."
|
||||
|
@ -48,7 +48,7 @@ class SpatialRefSys(models.Model):
|
||||
db_table = 'spatial_ref_sys'
|
||||
|
||||
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 not hasattr(self, '_srs'):
|
||||
# Trying to get from WKT first
|
||||
@ -71,6 +71,7 @@ class SpatialRefSys(models.Model):
|
||||
|
||||
@property
|
||||
def srs(self):
|
||||
"Returns the SpatialReference equivalent of this model."
|
||||
self._cache_osr()
|
||||
return self._srs.clone()
|
||||
|
||||
@ -79,12 +80,8 @@ class SpatialRefSys(models.Model):
|
||||
"""Returns a tuple of the ellipsoid parameters:
|
||||
(semimajor axis, semiminor axis, and inverse flattening)."""
|
||||
if HAS_OSR:
|
||||
# Setting values initially to False
|
||||
self._cache_osr()
|
||||
major = self._srs.semi_major
|
||||
minor = self._srs.semi_minor
|
||||
invflat = self._srs.inverse_flattening
|
||||
return (major, minor, invflat)
|
||||
return self._srs.ellipsoid
|
||||
else:
|
||||
m = spheroid_regex.match(self.srtext)
|
||||
if m: return (float(m.group('major')), float(m.group('flattening')))
|
||||
|
@ -101,8 +101,10 @@ class DataSourceTest(unittest.TestCase):
|
||||
for k, v in source.fields.items():
|
||||
fld = feat[k] # Indexing with string value
|
||||
|
||||
# Asserting the string representation (which asserts the type)
|
||||
self.assertEqual('%s (%s)' % (k, v.__name__), str(fld))
|
||||
# Asserting the string representation, and making sure we get
|
||||
# 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
|
||||
for fld in feat: self.assertEqual(fld.name in source.fields.keys(), True)
|
||||
|
Loading…
x
Reference in New Issue
Block a user