.. _tselection: Selection _________ Attribute selection using copy ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Field values can be also selected using a filter. A filter is always associated to filter fields, which are the fields where the selection takes place. A feature (record) will be copied only if the filter function returns True. The parameter ``filter`` is followed by the layer number; the correspondly field parameter is ``ffields`` (filter fields) followed by the layer number. It contais a field name or a list of field names. .. code-block:: python def filter1(value): return value == 'Bayern' lrs1 = lrs0.copy('', ofields0=['NAME_4', 'TYPE_4', 'NAME_1'], filter0=filter1, ffields0='NAME_1') Note also the order of the output fields:: Bayern geom NAME_4 TYPE_4 NAME_1 0 Polygon Affing Gemeinde Bayern 1 Polygon Aichach Stadt Bayern 2 Polygon Aindling Gemeinde Bayern ... ... ... ... ... 2235 Polygon Weißenstadter Forst-Nord Gemeindefreies Gebiet Bayern 2236 Polygon Weißenstadter Forst-Süd Gemeindefreies Gebiet Bayern 2237 Polygon Wunsiedel Stadt Bayern Using ``lambda`` and two filter fields ('NAME_1', 'NAME_4'): .. code-block:: python lrs1 = lrs0.copy('', ofields0=['NAME_4', 'TYPE_4'], ffields0=['NAME_1', 'NAME_4'], filter=lambda s, t: s == 'Nordrhein-Westfalen' and t.startswith('A')) lrs1.show(max_rows=6) :: geom NAME_4 TYPE_4 0 Polygon Ahaus Stadt 1 Polygon Ascheberg Gemeinde 2 Polygon Aldenhoven Gemeinde .. ... ... ... 12 Polygon Altenberge Gemeinde 13 Polygon Ahlen Stadt 14 Polygon Alpen Gemeinde Attribute selection using filters ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Attribute analysis refeers to the selection of layer field values, excluding geometry fields. .. code-block:: python print lrs.get_feature_count() # returns 11302 lrs.set_attribute_filter("NAME_1 = 'Nordrhein-Westfalen'") print lrs.get_feature_count() # returns 396 lrs.set_attribute_filter("NAME_1 = 'Bayern'") print lrs.get_feature_count() # returns 2238 lrs.set_attribute_filter("NAME_1 = 'Nordrhein-Westfalen' OR NAME_1 = 'Bayern'") print lrs.get_feature_count() # returns 2634 Spatial search ^^^^^^^^^^^^^^ Spatial search selects a subset of features (records) from one layer in Layers according to specified geometric relationships (inside, intersecting, touching, etc.) to features from another layer. The method spatial_filter is a generator returning a feature filtered by the spatial operator. The default operator is 'Intersects'. The feature object should be used only inside the loop. .. code-block:: python lrs0 = LayersReader('D:/tmp/DEU_adm_shp/DEU_adm4.shp') lrs1 = LayersReader('D:/tmp/DEU_wat/DEU_water_areas_dcw.shp') lrs0 = LayersReader('D:/tmp/DEU_adm_shp/DEU_adm4.shp') lrs1 = LayersReader('D:/tmp/DEU_wat/DEU_water_areas_dcw.shp') cities_intersecting_waters = [f.GetField('NAME_4') for f in lrs0.spatial_filter(lrs1)] print 'Number of cities intersecting waters: {}'.format(len(cities_intersecting_waters)) cities_containing_waters = [f.GetField('NAME_4') for f in lrs0.spatial_filter(lrs1, method='Contains')] print 'Number of cities containing waters: {}'.format(len(cities_containing_waters)) The method spatial_filter_to_layer returns a filtered copy of the original layer. If no output filename is given, the returned LayersWriter object is stored in RAM. The example below demonstrates the use of the available operators (Intersects, Equals, Disjoint, Touches, Crosses, Within, Contains, and Overlaps). It checks 11302 cities against 907 water bodies. .. code-block:: python lrs0 = LayersReader('D:/tmp/DEU_adm_shp/DEU_adm4.shp') lrs1 = LayersReader('D:/tmp/DEU_wat/DEU_water_areas_dcw.shp') print lrs0.get_feature_count() methods = ['Intersects', 'Equals', 'Disjoint', 'Touches', 'Crosses', 'Within', 'Contains', 'Overlaps'] for method in methods: beg = time.time() fids = [feat.GetFID() for feat in lrs0.spatial_filter(lrs1, method=method)] print '{:<11}{} {:0.2f} seconds'.format( method, str(len(fids)).rjust(5, ' '), time.time() - beg) print lrs0.get_feature_count() for method in methods: beg = time.time() lrs_out = lrs0.spatial_filter_to_layer(lrs1, method=method) print '{:<11}{} {:0.2f} seconds'.format( method, str(lrs_out.get_feature_count()).rjust(5, ' '), time.time() - beg) Outputs:: 11302 Intersects 1195 4.12 seconds Equals 0 2.04 seconds Disjoint 3230 3.88 seconds Touches 0 4.35 seconds Crosses 0 4.40 seconds Within 0 3.82 seconds Contains 307 2.68 seconds Overlaps 1028 4.09 seconds 11302 Intersects 1195 4.24 seconds Equals 0 2.20 seconds Disjoint 3230 4.06 seconds Touches 0 4.76 seconds Crosses 0 4.96 seconds Within 0 4.37 seconds Contains 307 3.24 seconds Overlaps 1028 4.76 seconds