Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #18640 -- Allowed access to GDAL Feature without Datasource

Thanks Justin Bronn for improving my initial patch.
  • Loading branch information...
commit cb9f71dd99f0e524c871830b248cf28fcacd5753 1 parent 35e8dc5
@claudep claudep authored
View
24 django/contrib/gis/gdal/feature.py
@@ -16,15 +16,21 @@
#
# The OGR_F_* routines are relevant here.
class Feature(GDALBase):
- "A class that wraps an OGR Feature, needs to be instantiated from a Layer object."
+ """
+ This class that wraps an OGR Feature, needs to be instantiated
+ from a Layer object.
+ """
#### Python 'magic' routines ####
- def __init__(self, feat, fdefn):
- "Initializes on the pointers for the feature and the layer definition."
- if not feat or not fdefn:
+ def __init__(self, feat, layer):
+ """
+ Initializes on the feature pointers for the feature and the layer
+ definition, as well as the Layer.
+ """
+ if not feat:
raise OGRException('Cannot create OGR Feature, invalid pointer given.')
self.ptr = feat
- self._fdefn = fdefn
+ self._layer = layer
def __del__(self):
"Releases a reference to this object."
@@ -43,7 +49,7 @@ def __getitem__(self, index):
if index < 0 or index > self.num_fields:
raise OGRIndexError('index out of range')
i = index
- return Field(self.ptr, i)
+ return Field(self, i)
def __iter__(self):
"Iterates over each field in the Feature."
@@ -71,7 +77,7 @@ def fid(self):
@property
def layer_name(self):
"Returns the name of the layer for the feature."
- return capi.get_feat_name(self._fdefn)
+ return capi.get_feat_name(self._layer._ldefn)
@property
def num_fields(self):
@@ -81,7 +87,7 @@ def num_fields(self):
@property
def fields(self):
"Returns a list of fields in the Feature."
- return [capi.get_field_name(capi.get_field_defn(self._fdefn, i))
+ return [capi.get_field_name(capi.get_field_defn(self._layer._ldefn, i))
for i in xrange(self.num_fields)]
@property
@@ -94,7 +100,7 @@ def geom(self):
@property
def geom_type(self):
"Returns the OGR Geometry Type for this Feture."
- return OGRGeomType(capi.get_fd_geom_type(self._fdefn))
+ return OGRGeomType(capi.get_fd_geom_type(self._layer._ldefn))
#### Feature Methods ####
def get(self, field):
View
20 django/contrib/gis/gdal/field.py
@@ -9,12 +9,15 @@
#
# The OGR_Fld_* routines are relevant here.
class Field(GDALBase):
- "A class that wraps an OGR Field, needs to be instantiated from a Feature object."
+ """
+ This class wraps an OGR Field, and needs to be instantiated
+ from a Feature object.
+ """
#### Python 'magic' routines ####
def __init__(self, feat, index):
"""
- Initializes on the feature pointer and the integer index of
+ Initializes on the feature object and the integer index of
the field within the feature.
"""
# Setting the feature pointer and index.
@@ -22,7 +25,7 @@ def __init__(self, feat, index):
self._index = index
# Getting the pointer for this field.
- fld_ptr = capi.get_feat_field_defn(feat, index)
+ fld_ptr = capi.get_feat_field_defn(feat.ptr, index)
if not fld_ptr:
raise OGRException('Cannot create OGR Field, invalid pointer given.')
self.ptr = fld_ptr
@@ -42,21 +45,22 @@ def __str__(self):
#### Field Methods ####
def as_double(self):
"Retrieves the Field's value as a double (float)."
- return capi.get_field_as_double(self._feat, self._index)
+ return capi.get_field_as_double(self._feat.ptr, self._index)
def as_int(self):
"Retrieves the Field's value as an integer."
- return capi.get_field_as_integer(self._feat, self._index)
+ return capi.get_field_as_integer(self._feat.ptr, self._index)
def as_string(self):
"Retrieves the Field's value as a string."
- return capi.get_field_as_string(self._feat, self._index)
+ return capi.get_field_as_string(self._feat.ptr, self._index)
def as_datetime(self):
"Retrieves the Field's value as a tuple of date & time components."
yy, mm, dd, hh, mn, ss, tz = [c_int() for i in range(7)]
- status = capi.get_field_as_datetime(self._feat, self._index, byref(yy), byref(mm), byref(dd),
- byref(hh), byref(mn), byref(ss), byref(tz))
+ status = capi.get_field_as_datetime(
+ self._feat.ptr, self._index, byref(yy), byref(mm), byref(dd),
+ byref(hh), byref(mn), byref(ss), byref(tz))
if status:
return (yy, mm, dd, hh, mn, ss, tz)
else:
View
4 django/contrib/gis/gdal/layer.py
@@ -61,7 +61,7 @@ def __iter__(self):
# ResetReading() must be called before iteration is to begin.
capi.reset_reading(self._ptr)
for i in xrange(self.num_feat):
- yield Feature(capi.get_next_feature(self._ptr), self._ldefn)
+ yield Feature(capi.get_next_feature(self._ptr), self)
def __len__(self):
"The length is the number of features."
@@ -81,7 +81,7 @@ def _make_feature(self, feat_id):
if self._random_read:
# If the Layer supports random reading, return.
try:
- return Feature(capi.get_feature(self.ptr, feat_id), self._ldefn)
+ return Feature(capi.get_feature(self.ptr, feat_id), self)
except OGRException:
pass
else:
View
8 django/contrib/gis/gdal/tests/test_ds.py
@@ -125,7 +125,10 @@ def test03b_layer_slice(self):
self.assertEqual(control_vals, test_vals)
def test03c_layer_references(self):
- "Test to make sure Layer access is still available without the DataSource."
+ """
+ Test to make sure Layer/Feature access is still available without
+ the DataSource/Feature.
+ """
source = ds_list[0]
# See ticket #9448.
@@ -141,6 +144,9 @@ def get_layer():
self.assertEqual(source.nfeat, len(lyr))
self.assertEqual(source.gtype, lyr.geom_type.num)
+ # Same issue for Feature/Field objects, see #18640
+ self.assertEqual(str(lyr[0]['str']), "1")
+
def test04_features(self):
"Testing Data Source Features."
for source in ds_list:
Please sign in to comment.
Something went wrong with that request. Please try again.