Code

Ticket #18640: 18640-2.diff

File 18640-2.diff, 7.4 KB (added by jbronn, 22 months ago)
Line 
1diff --git a/django/contrib/gis/gdal/feature.py b/django/contrib/gis/gdal/feature.py
2index 2920048..db40357 100644
3--- a/django/contrib/gis/gdal/feature.py
4+++ b/django/contrib/gis/gdal/feature.py
5@@ -15,15 +15,21 @@ from django.utils.six.moves import xrange
6 #
7 # The OGR_F_* routines are relevant here.
8 class Feature(GDALBase):
9-    "A class that wraps an OGR Feature, needs to be instantiated from a Layer object."
10+    """
11+    This class that wraps an OGR Feature, needs to be instantiated
12+    from a Layer object.
13+    """
14 
15     #### Python 'magic' routines ####
16-    def __init__(self, feat, fdefn):
17-        "Initializes on the pointers for the feature and the layer definition."
18-        if not feat or not fdefn:
19+    def __init__(self, feat, layer):
20+        """
21+        Initializes on the feature pointers for the feature and the layer
22+        definition, as well as the Layer
23+        """
24+        if not feat or not layer:
25             raise OGRException('Cannot create OGR Feature, invalid pointer given.')
26         self.ptr = feat
27-        self._fdefn = fdefn
28+        self._layer = layer
29 
30     def __del__(self):
31         "Releases a reference to this object."
32@@ -42,7 +48,7 @@ class Feature(GDALBase):
33             if index < 0 or index > self.num_fields:
34                 raise OGRIndexError('index out of range')
35             i = index
36-        return Field(self.ptr, i)
37+        return Field(self, i)
38 
39     def __iter__(self):
40         "Iterates over each field in the Feature."
41@@ -70,7 +76,7 @@ class Feature(GDALBase):
42     @property
43     def layer_name(self):
44         "Returns the name of the layer for the feature."
45-        return capi.get_feat_name(self._fdefn)
46+        return capi.get_feat_name(self._layer._ldefn)
47 
48     @property
49     def num_fields(self):
50@@ -80,7 +86,7 @@ class Feature(GDALBase):
51     @property
52     def fields(self):
53         "Returns a list of fields in the Feature."
54-        return [capi.get_field_name(capi.get_field_defn(self._fdefn, i))
55+        return [capi.get_field_name(capi.get_field_defn(self._layer._ldefn, i))
56                 for i in xrange(self.num_fields)]
57 
58     @property
59@@ -93,7 +99,7 @@ class Feature(GDALBase):
60     @property
61     def geom_type(self):
62         "Returns the OGR Geometry Type for this Feture."
63-        return OGRGeomType(capi.get_fd_geom_type(self._fdefn))
64+        return OGRGeomType(capi.get_fd_geom_type(self._layer._ldefn))
65 
66     #### Feature Methods ####
67     def get(self, field):
68diff --git a/django/contrib/gis/gdal/field.py b/django/contrib/gis/gdal/field.py
69index 12dc8b9..16230af 100644
70--- a/django/contrib/gis/gdal/field.py
71+++ b/django/contrib/gis/gdal/field.py
72@@ -9,12 +9,15 @@ from django.contrib.gis.gdal.prototypes import ds as capi
73 #
74 # The OGR_Fld_* routines are relevant here.
75 class Field(GDALBase):
76-    "A class that wraps an OGR Field, needs to be instantiated from a Feature object."
77+    """
78+    This class wraps an OGR Field, and needs to be instantiated
79+    from a Feature object.
80+    """
81 
82     #### Python 'magic' routines ####
83     def __init__(self, feat, index):
84         """
85-        Initializes on the feature pointer and the integer index of
86+        Initializes on the feature object and the integer index of
87         the field within the feature.
88         """
89         # Setting the feature pointer and index.
90@@ -22,7 +25,7 @@ class Field(GDALBase):
91         self._index = index
92 
93         # Getting the pointer for this field.
94-        fld_ptr = capi.get_feat_field_defn(feat, index)
95+        fld_ptr = capi.get_feat_field_defn(feat.ptr, index)
96         if not fld_ptr:
97             raise OGRException('Cannot create OGR Field, invalid pointer given.')
98         self.ptr = fld_ptr
99@@ -42,21 +45,22 @@ class Field(GDALBase):
100     #### Field Methods ####
101     def as_double(self):
102         "Retrieves the Field's value as a double (float)."
103-        return capi.get_field_as_double(self._feat, self._index)
104+        return capi.get_field_as_double(self._feat.ptr, self._index)
105 
106     def as_int(self):
107         "Retrieves the Field's value as an integer."
108-        return capi.get_field_as_integer(self._feat, self._index)
109+        return capi.get_field_as_integer(self._feat.ptr, self._index)
110 
111     def as_string(self):
112         "Retrieves the Field's value as a string."
113-        return capi.get_field_as_string(self._feat, self._index)
114+        return capi.get_field_as_string(self._feat.ptr, self._index)
115 
116     def as_datetime(self):
117         "Retrieves the Field's value as a tuple of date & time components."
118         yy, mm, dd, hh, mn, ss, tz = [c_int() for i in range(7)]
119-        status = capi.get_field_as_datetime(self._feat, self._index, byref(yy), byref(mm), byref(dd),
120-                                            byref(hh), byref(mn), byref(ss), byref(tz))
121+        status = capi.get_field_as_datetime(
122+            self._feat.ptr, self._index, byref(yy), byref(mm), byref(dd),
123+            byref(hh), byref(mn), byref(ss), byref(tz))
124         if status:
125             return (yy, mm, dd, hh, mn, ss, tz)
126         else:
127diff --git a/django/contrib/gis/gdal/layer.py b/django/contrib/gis/gdal/layer.py
128index 2357fbb..8c53831 100644
129--- a/django/contrib/gis/gdal/layer.py
130+++ b/django/contrib/gis/gdal/layer.py
131@@ -22,7 +22,10 @@ from django.utils.six.moves import xrange
132 #
133 # The OGR_L_* routines are relevant here.
134 class Layer(GDALBase):
135-    "A class that wraps an OGR Layer, needs to be instantiated from a DataSource object."
136+    """
137+    This class wraps an OGR Layer, and needs to be instantiated
138+    from a DataSource object.
139+    """
140 
141     #### Python 'magic' routines ####
142     def __init__(self, layer_ptr, ds):
143@@ -60,7 +63,7 @@ class Layer(GDALBase):
144         # ResetReading() must be called before iteration is to begin.
145         capi.reset_reading(self._ptr)
146         for i in xrange(self.num_feat):
147-            yield Feature(capi.get_next_feature(self._ptr), self._ldefn)
148+            yield Feature(capi.get_next_feature(self._ptr), self)
149 
150     def __len__(self):
151         "The length is the number of features."
152@@ -80,7 +83,7 @@ class Layer(GDALBase):
153         if self._random_read:
154             # If the Layer supports random reading, return.
155             try:
156-                return Feature(capi.get_feature(self.ptr, feat_id), self._ldefn)
157+                return Feature(capi.get_feature(self.ptr, feat_id), self)
158             except OGRException:
159                 pass
160         else:
161diff --git a/django/contrib/gis/gdal/tests/test_ds.py b/django/contrib/gis/gdal/tests/test_ds.py
162index 71d22a0..4d7d075 100644
163--- a/django/contrib/gis/gdal/tests/test_ds.py
164+++ b/django/contrib/gis/gdal/tests/test_ds.py
165@@ -126,7 +126,10 @@ class DataSourceTest(unittest.TestCase):
166             self.assertEqual(control_vals, test_vals)
167 
168     def test03c_layer_references(self):
169-        "Test to make sure Layer access is still available without the DataSource."
170+        """
171+        Test to make sure Layer/Feature access is still available without
172+        the DataSource/Feature.
173+        """
174         source = ds_list[0]
175 
176         # See ticket #9448.
177@@ -142,6 +145,9 @@ class DataSourceTest(unittest.TestCase):
178         self.assertEqual(source.nfeat, len(lyr))
179         self.assertEqual(source.gtype, lyr.geom_type.num)
180 
181+        # Same issue for Feature/Field objects, see #18640
182+        self.assertEqual(str(lyr[0]['str']), "1")
183+
184     def test04_features(self):
185         "Testing Data Source Features."
186         for source in ds_list: