app/django/contrib/gis/gdal/feature.py
changeset 323 ff1a9aa48cfd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/django/contrib/gis/gdal/feature.py	Tue Oct 14 16:00:59 2008 +0000
@@ -0,0 +1,115 @@
+# The GDAL C library, OGR exception, and the Field object
+from django.contrib.gis.gdal.error import OGRException, OGRIndexError
+from django.contrib.gis.gdal.field import Field
+from django.contrib.gis.gdal.geometries import OGRGeometry, OGRGeomType
+from django.contrib.gis.gdal.srs import SpatialReference
+
+# ctypes function prototypes
+from django.contrib.gis.gdal.prototypes.ds import \
+    destroy_feature, feature_equal, get_fd_geom_type, get_feat_geom_ref, \
+    get_feat_name, get_feat_field_count, get_fid, get_field_defn, \
+    get_field_index, get_field_name
+from django.contrib.gis.gdal.prototypes.geom import clone_geom, get_geom_srs
+from django.contrib.gis.gdal.prototypes.srs import clone_srs
+
+# For more information, see the OGR C API source code:
+#  http://www.gdal.org/ogr/ogr__api_8h.html
+#
+# The OGR_F_* routines are relevant here.
+class Feature(object):
+    "A 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."
+        self._ptr = None # Initially NULL
+        if not feat or not fdefn:
+            raise OGRException('Cannot create OGR Feature, invalid pointer given.')
+        self._ptr = feat
+        self._fdefn = fdefn
+
+    def __del__(self):
+        "Releases a reference to this object."
+        if self._ptr: destroy_feature(self._ptr)
+
+    def __getitem__(self, index):
+        """
+        Gets the Field object at the specified index, which may be either
+        an integer or the Field's string label.  Note that the Field object
+        is not the field's _value_ -- use the `get` method instead to 
+        retrieve the value (e.g. an integer) instead of a Field instance.
+        """
+        if isinstance(index, basestring):
+            i = self.index(index)
+        else:
+            if index < 0 or index > self.num_fields:
+                raise OGRIndexError('index out of range')
+            i = index
+        return Field(self._ptr, i)
+    
+    def __iter__(self):
+        "Iterates over each field in the Feature."
+        for i in xrange(self.num_fields):
+            yield self[i]
+
+    def __len__(self):
+        "Returns the count of fields in this feature."
+        return self.num_fields
+        
+    def __str__(self):
+        "The string name of the feature."
+        return 'Feature FID %d in Layer<%s>' % (self.fid, self.layer_name)
+
+    def __eq__(self, other):
+        "Does equivalence testing on the features."
+        return bool(feature_equal(self._ptr, other._ptr))
+
+    #### Feature Properties ####
+    @property
+    def fid(self):
+        "Returns the feature identifier."
+        return get_fid(self._ptr)
+        
+    @property
+    def layer_name(self):
+        "Returns the name of the layer for the feature."
+        return get_feat_name(self._fdefn)
+
+    @property
+    def num_fields(self):
+        "Returns the number of fields in the Feature."
+        return get_feat_field_count(self._ptr)
+
+    @property
+    def fields(self):
+        "Returns a list of fields in the Feature."
+        return [get_field_name(get_field_defn(self._fdefn, i)) 
+                for i in xrange(self.num_fields)]
+
+    @property
+    def geom(self):
+        "Returns the OGR Geometry for this Feature."
+        # Retrieving the geometry pointer for the feature.
+        geom_ptr = get_feat_geom_ref(self._ptr)
+        return OGRGeometry(clone_geom(geom_ptr))
+
+    @property
+    def geom_type(self):
+        "Returns the OGR Geometry Type for this Feture."
+        return OGRGeomType(get_fd_geom_type(self._fdefn))
+    
+    #### Feature Methods ####
+    def get(self, field):
+        """
+        Returns the value of the field, instead of an instance of the Field
+        object.  May take a string of the field name or a Field object as
+        parameters.
+        """
+        field_name = getattr(field, 'name', field)
+        return self[field_name].value
+
+    def index(self, field_name):
+        "Returns the index of the given field name."
+        i = get_field_index(self._ptr, field_name)
+        if i < 0: raise OGRIndexError('invalid OFT field name given: "%s"' % field_name)
+        return i