mirror of
https://github.com/django/django.git
synced 2025-07-04 17:59:13 +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))
|
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))
|
||||||
|
@ -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):
|
||||||
|
@ -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))))
|
||||||
|
|
||||||
|
@ -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."
|
||||||
|
@ -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')))
|
||||||
|
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user