app/django/contrib/gis/gdal/feature.py
changeset 323 ff1a9aa48cfd
equal deleted inserted replaced
322:6641e941ef1e 323:ff1a9aa48cfd
       
     1 # The GDAL C library, OGR exception, and the Field object
       
     2 from django.contrib.gis.gdal.error import OGRException, OGRIndexError
       
     3 from django.contrib.gis.gdal.field import Field
       
     4 from django.contrib.gis.gdal.geometries import OGRGeometry, OGRGeomType
       
     5 from django.contrib.gis.gdal.srs import SpatialReference
       
     6 
       
     7 # ctypes function prototypes
       
     8 from django.contrib.gis.gdal.prototypes.ds import \
       
     9     destroy_feature, feature_equal, get_fd_geom_type, get_feat_geom_ref, \
       
    10     get_feat_name, get_feat_field_count, get_fid, get_field_defn, \
       
    11     get_field_index, get_field_name
       
    12 from django.contrib.gis.gdal.prototypes.geom import clone_geom, get_geom_srs
       
    13 from django.contrib.gis.gdal.prototypes.srs import clone_srs
       
    14 
       
    15 # For more information, see the OGR C API source code:
       
    16 #  http://www.gdal.org/ogr/ogr__api_8h.html
       
    17 #
       
    18 # The OGR_F_* routines are relevant here.
       
    19 class Feature(object):
       
    20     "A class that wraps an OGR Feature, needs to be instantiated from a Layer object."
       
    21 
       
    22     #### Python 'magic' routines ####
       
    23     def __init__(self, feat, fdefn):
       
    24         "Initializes on the pointers for the feature and the layer definition."
       
    25         self._ptr = None # Initially NULL
       
    26         if not feat or not fdefn:
       
    27             raise OGRException('Cannot create OGR Feature, invalid pointer given.')
       
    28         self._ptr = feat
       
    29         self._fdefn = fdefn
       
    30 
       
    31     def __del__(self):
       
    32         "Releases a reference to this object."
       
    33         if self._ptr: destroy_feature(self._ptr)
       
    34 
       
    35     def __getitem__(self, index):
       
    36         """
       
    37         Gets the Field object at the specified index, which may be either
       
    38         an integer or the Field's string label.  Note that the Field object
       
    39         is not the field's _value_ -- use the `get` method instead to 
       
    40         retrieve the value (e.g. an integer) instead of a Field instance.
       
    41         """
       
    42         if isinstance(index, basestring):
       
    43             i = self.index(index)
       
    44         else:
       
    45             if index < 0 or index > self.num_fields:
       
    46                 raise OGRIndexError('index out of range')
       
    47             i = index
       
    48         return Field(self._ptr, i)
       
    49     
       
    50     def __iter__(self):
       
    51         "Iterates over each field in the Feature."
       
    52         for i in xrange(self.num_fields):
       
    53             yield self[i]
       
    54 
       
    55     def __len__(self):
       
    56         "Returns the count of fields in this feature."
       
    57         return self.num_fields
       
    58         
       
    59     def __str__(self):
       
    60         "The string name of the feature."
       
    61         return 'Feature FID %d in Layer<%s>' % (self.fid, self.layer_name)
       
    62 
       
    63     def __eq__(self, other):
       
    64         "Does equivalence testing on the features."
       
    65         return bool(feature_equal(self._ptr, other._ptr))
       
    66 
       
    67     #### Feature Properties ####
       
    68     @property
       
    69     def fid(self):
       
    70         "Returns the feature identifier."
       
    71         return get_fid(self._ptr)
       
    72         
       
    73     @property
       
    74     def layer_name(self):
       
    75         "Returns the name of the layer for the feature."
       
    76         return get_feat_name(self._fdefn)
       
    77 
       
    78     @property
       
    79     def num_fields(self):
       
    80         "Returns the number of fields in the Feature."
       
    81         return get_feat_field_count(self._ptr)
       
    82 
       
    83     @property
       
    84     def fields(self):
       
    85         "Returns a list of fields in the Feature."
       
    86         return [get_field_name(get_field_defn(self._fdefn, i)) 
       
    87                 for i in xrange(self.num_fields)]
       
    88 
       
    89     @property
       
    90     def geom(self):
       
    91         "Returns the OGR Geometry for this Feature."
       
    92         # Retrieving the geometry pointer for the feature.
       
    93         geom_ptr = get_feat_geom_ref(self._ptr)
       
    94         return OGRGeometry(clone_geom(geom_ptr))
       
    95 
       
    96     @property
       
    97     def geom_type(self):
       
    98         "Returns the OGR Geometry Type for this Feture."
       
    99         return OGRGeomType(get_fd_geom_type(self._fdefn))
       
   100     
       
   101     #### Feature Methods ####
       
   102     def get(self, field):
       
   103         """
       
   104         Returns the value of the field, instead of an instance of the Field
       
   105         object.  May take a string of the field name or a Field object as
       
   106         parameters.
       
   107         """
       
   108         field_name = getattr(field, 'name', field)
       
   109         return self[field_name].value
       
   110 
       
   111     def index(self, field_name):
       
   112         "Returns the index of the given field name."
       
   113         i = get_field_index(self._ptr, field_name)
       
   114         if i < 0: raise OGRIndexError('invalid OFT field name given: "%s"' % field_name)
       
   115         return i