.. _tlayerdefinition: Layer definition ________________ A layer definition describes the layer structure, which includes a list of field definitions. We describe below how to get a layer definition instance ``osgeo.ogr.FeatureDefn`` and use it. Nevertheless, we recommend to avoid using it to work with layer properties. Instead, use the methods provided in `girs`, in order to avoid possible program crashes. .. note:: Avoid using an OGR-layer definition instance directily as shown below. Instead, use the corresponding `girs` methods described in :ref:`tattributefields` to retrieve field properties from layers. Get an instance of osgeo.ogr.FeatureDefn ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Each layer has a layer definition. Therefore, a layer number must be specified in order to retrieve the corresponding layer definition. The default layer number is zero. .. code-block:: python from girs.feat.layers import LayersReader lrs = LayersReader('D:/tmp/girs/DEU_adm_shp/DEU_adm4.shp') print lrs.get_layer_definition() print lrs.get_layer_definition(layer_number=0) Using osgeo.ogr.FeatureDefn methods ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **osgeo.ogr.FeatureDefn methods** The methods available in ``osgeo.ogr.FeatureDefn`` can be found in http://gdal.org/python/osgeo.ogr.FeatureDefn-class.html. Here a list of available methods, excluding the private (internal) methods starting with "__" (double underline): .. code-block:: python from girs.feat.layers import LayersReader lrs = LayersReader('D:/tmp/girs/DEU_adm_shp/DEU_adm4.shp') for m in dir(lrs.get_layer_definition()): if not m.startswith('__'): print m Output:: AddFieldDefn AddGeomFieldDefn DeleteGeomFieldDefn Destroy GetFieldCount GetFieldDefn GetFieldIndex GetGeomFieldCount GetGeomFieldDefn GetGeomFieldIndex GetGeomType GetName GetReferenceCount IsGeometryIgnored IsSame IsStyleIgnored SetGeomType SetGeometryIgnored SetStyleIgnored this thisown **Using osgeo.ogr.FeatureDefn methods** ``GetFieldCount`` will be used to demonstrate how to use any of the ``osgeo.ogr.FeatureDefn`` methods above: .. code-block:: python from osgeo import ogr filename = 'D:/tmp/girs/DEU_adm_shp/DEU_adm4.shp' dataset = ogr.Open(filename, 0) # open read-only if dataset is None: raise ValueError('Could not open {}'.format(filename)) lyr = dataset.GetLayer(0) # osgeo.ogr.Layer instance ldf = lyr.GetLayerDefn() # osgeo.ogr.FeatureDefn instance print ldf.GetFieldCount() Like in the case of using a layer instance directly (``osgeo.ogr.Layer``), also an instance of layer definition (``osgeo.ogr.FeatureDefn``) cause the program to crash if not used carefully: .. code-block:: python from girs.feat.layers import LayersReader # This works print LayersReader('D:/tmp/girs/DEU_adm_shp/DEU_adm4.shp').get_field_count() # This works: the instance LayersReader(filename) is dellocated just after calling # get_layer_definition() print LayersReader('D:/tmp/girs/DEU_adm_shp/DEU_adm4.shp').get_layer_definition() # This crashes: once LayersReader(filename) is deallocated, the return value of # get_layer_definition() is a dangling pointer print LayersReader('D:/tmp/girs/DEU_adm_shp/DEU_adm4.shp').get_layer_definition().GetFieldCount() **Using girs** .. code-block:: python from girs.feat.layers import LayersReader lrs = LayersReader('D:/tmp/girs/DEU_adm_shp/DEU_adm4.shp') print lrs.get_field_count() # using layer number = 0 The `girs` block above has less code lines and is probably easier to understand. In fact, girs just encapsulates the ogr procedures as shown in the upper block and guarantees that neither `dataset`, nor `lyr`, nor `ldf` go out of scope, causing the program to crash. These methods are described in :ref:`tattributefields`.