Fixed #18640 -- Allowed access to GDAL Feature without Datasource
Thanks Justin Bronn for improving my initial patch.
This commit is contained in:
parent
35e8dc5169
commit
cb9f71dd99
|
@ -16,15 +16,21 @@ from django.utils.six.moves import xrange
|
|||
#
|
||||
# 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 @@ class Feature(GDALBase):
|
|||
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 @@ class Feature(GDALBase):
|
|||
@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 @@ class Feature(GDALBase):
|
|||
@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 @@ class Feature(GDALBase):
|
|||
@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):
|
||||
|
|
|
@ -9,12 +9,15 @@ from django.contrib.gis.gdal.prototypes import ds as capi
|
|||
#
|
||||
# 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 @@ class Field(GDALBase):
|
|||
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,20 +45,21 @@ class Field(GDALBase):
|
|||
#### 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),
|
||||
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)
|
||||
|
|
|
@ -61,7 +61,7 @@ class Layer(GDALBase):
|
|||
# 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 @@ class Layer(GDALBase):
|
|||
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:
|
||||
|
|
|
@ -125,7 +125,10 @@ class DataSourceTest(unittest.TestCase):
|
|||
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 @@ class DataSourceTest(unittest.TestCase):
|
|||
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:
|
||||
|
|
Loading…
Reference in New Issue