Skip to content

Commit

Permalink
gis: fixed ticket 4740 with the addition of new exceptions; updated t…
Browse files Browse the repository at this point in the history
…ests 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
  • Loading branch information
jbronn committed Jul 2, 2007
1 parent 858ae54 commit 4406905
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 18 deletions.
4 changes: 4 additions & 0 deletions django/contrib/gis/gdal/Feature.py
Expand Up @@ -93,6 +93,10 @@ def geom_type(self):
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))
Expand Down
9 changes: 7 additions & 2 deletions django/contrib/gis/gdal/Layer.py
Expand Up @@ -7,6 +7,7 @@
# 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


Expand Down Expand Up @@ -83,12 +84,16 @@ def num_fields(self):
@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):
Expand Down
14 changes: 11 additions & 3 deletions django/contrib/gis/gdal/OGRGeometry.py
Expand Up @@ -131,6 +131,14 @@ def num(self):
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."


Expand Down Expand Up @@ -412,7 +420,7 @@ def __getitem__(self, index):
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."
Expand Down Expand Up @@ -445,7 +453,7 @@ def __iter__(self):
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))))


Expand Down Expand Up @@ -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))))


Expand Down
17 changes: 12 additions & 5 deletions django/contrib/gis/geos/GEOSGeometry.py
Expand Up @@ -85,6 +85,13 @@


# 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.
Expand Down Expand Up @@ -345,7 +352,7 @@ def buffer(self, width, quadsegs=8):


@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
Expand Down Expand Up @@ -432,7 +439,7 @@ def _checkindex(self, index):
"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."
Expand Down Expand Up @@ -594,7 +601,7 @@ def __getitem__(self, index):
"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]


Expand Down Expand Up @@ -624,7 +631,7 @@ def __getitem__(self, index):
"""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
Expand Down Expand Up @@ -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."
Expand Down
9 changes: 3 additions & 6 deletions django/contrib/gis/models.py
Expand Up @@ -48,7 +48,7 @@ class Meta:
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
Expand All @@ -71,6 +71,7 @@ def _cache_osr(self):


@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()


Expand All @@ -79,12 +80,8 @@ def ellipsoid(self):
"""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')))
Expand Down
6 changes: 4 additions & 2 deletions django/contrib/gis/tests/test_gdal_ds.py
Expand Up @@ -101,8 +101,10 @@ def test04_features(self):
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)
Expand Down

0 comments on commit 4406905

Please sign in to comment.