[Qgis-developer] iteration over a layer's features in python

Ricardo Filipe Soares Garcia da ricardo.garcia.silva at gmail.com
Mon Jun 17 13:21:33 PDT 2013


Thanks for the tip Nathan!

I thought the while loop was necessary because we had to call
QgsFeatureIterator.nextFeature() and just now realized that the for loop
will do it implicitly. I thought that would work only for python
iterators... I guess QgsFeatureIterator is one of them ;)



On Mon, Jun 17, 2013 at 6:33 PM, Nathan Woodrow <madmanwoo at gmail.com> wrote:

>  plugins
> MIME-Version: 1.0
> Content-Type: multipart/mixed;
> boundary="===============3430773931903739203=="
>
> --===============3430773931903739203==
> Content-Type: multipart/alternative; boundary=089e0102eaa65b15f904df59d6c1
>
> --089e0102eaa65b15f904df59d6c1
> Content-Type: text/plain; charset="utf-8"
> Content-Transfer-Encoding: 7bit
>
> You don't need go use a while, I don't know why people keep using that
> pattern when a simple for will do and is cleaner.
>
> For f in layer.getFeatures:
>
> No it just comes down to
>
> If selected:
> features = layers.selectedFeatures()[]
> Else:
> features = layer.getFeatures()
> From: Ricardo Filipe Soares Garcia da
> Sent: 17/06/2013 11:47 PM
> To: qgis-developer at lists.osgeo.org
> Subject: [Qgis-developer] iteration over a layer's features in python
> plugins
> Hi list
>
> When building plugins that operate on vector layers, it is a common pattern
> to include a checkbox in the plugin's GUI where the user can choose to
> perform the plugin analysis on the whole layer or just using the currently
> selected features (see for example most fTools dialogs).
>
> However, I think the QGIS API does not make the implementation of this
> pattern as easy as it could be. The QgsVectorLayer.getFeatures() method
> returns an iterator but the QgsVectorLayer.selectedFeatures() returns a
> list. It would be nice if they both returned an iterator.
>
> When working with all the features in a layer, I  use:
>
> feat = QgsFeature()
> feat_iterator = v_layer.getFeatures()
> while feat_iterator.nextFeature(feat):
>     # do stuff with the feature
>
> When working with only the currently selected features the code is like:
>
> selected_feats = v_layer.selectedFeatures()
> for feat in selected_feats:
>     # do stuff with the feature
>
> Since QgsVectorLayer.getFeatures can take a QgsFeatureRequest as argument,
> I think a nice solution could be to add one more filter to
> QgsFeatureRequest to allow iterating over a list of feature ids. It
> currently already allows to pass in a single feature id, it would just be a
> matter of expanding that.
>
> In the meantime I am using a custom iterator class[1] in Python that wraps
> this different behaviour and lets me use the same logic for processing the
> whole layer or just the selected features. I think it would be cleaner if
> this could be done on the API side.
>
> Maybe I am asking for too much too late because of the feature freeze for
> 2.0?
>
>
> [1] - (see the FeatureIterator class)
> https://github.com/ricardogsilva/coneforinputs/blob/master/coneforinputs.py
>
>
> --
> ___________________________ ___ __
> Ricardo Garcia Silva
>
> --089e0102eaa65b15f904df59d6c1
> Content-Type: text/html; charset="utf-8"
> Content-Transfer-Encoding: quoted-printable
>
> <html><head><meta content=3D"text/html; charset=3Dutf-8"
> http-equiv=3D"Cont=
> ent-Type"></head><body><div><div style=3D"font-family: Calibri,sans-serif;
> =
> font-size: 11pt;">You don't need go use a while, I don't know why people
> ke=
> ep using that pattern when a simple for will do and is cleaner.<br><br>For
> =
> f in layer.getFeatures:<br><br>No it just comes down to<br><br>If
> selected:=
> <br>    features =3D
> layers.selectedFeatures()[]<br>Else:<br=
> >    features =3D
> layer.getFeatures()<br></div></div><hr><sp=
> an style=3D"font-family: Tahoma,sans-serif; font-size: 10pt; font-weight:
> b=
> old;">From: </span><span style=3D"font-family: Tahoma,sans-serif;
> font-size=
> : 10pt;">Ricardo Filipe Soares Garcia da</span><br><span
> style=3D"font-fami=
> ly: Tahoma,sans-serif; font-size: 10pt; font-weight: bold;">Sent:
> </span><s=
> pan style=3D"font-family: Tahoma,sans-serif; font-size: 10pt;">17/06/2013
> 1=
> 1:47 PM</span><br><span style=3D"font-family: Tahoma,sans-serif;
> font-size:=
>  10pt; font-weight: bold;">To: </span><span style=3D"font-family:
> Tahoma,sa=
> ns-serif; font-size: 10pt;">qgis-developer at lists.osgeo.org</span><br><span
> =
> style=3D"font-family: Tahoma,sans-serif; font-size: 10pt; font-weight:
> bold=
> ;">Subject: </span><span style=3D"font-family: Tahoma,sans-serif;
> font-size=
> : 10pt;">[Qgis-developer] iteration over a layer's features in python
> plugi=
> ns</span><br><br></body></html><div dir=3D"ltr">Hi
> list<div><br></div><div>=
> When building plugins that operate on vector layers, it is a common
> pattern=
>  to include a checkbox in the plugin's GUI where the user can choose
> to=
>  perform the plugin analysis on the whole layer or just using the
> currently=
>  selected features (see for example most fTools dialogs).</div>
>
> <div><br></div><div>However, I think the QGIS API does not make the
> impleme=
> ntation of this pattern as easy as it could be. The
> QgsVectorLayer.getFeatu=
> res() method returns an iterator but the QgsVectorLayer.selectedFeatures()
> =
> returns a list. It would be nice if they both returned an
> iterator.=C2=A0</=
> div>
>
> <div><br></div><div>When working with all the features in a layer, I
> =C2=A0=
> use:</div><div><br></div><div style>feat =3D
> QgsFeature()</div><div>feat_it=
> erator =3D v_layer.getFeatures()</div><div style>while
> feat_iterator.nextFe=
> ature(feat):</div>
>
> <div style>=C2=A0 =C2=A0 # do stuff with the
> feature</div><div><br></div><d=
> iv style>When working with only the currently selected features the code
> is=
>  like:</div><div style><br></div><div style>selected_feats =3D
> v_layer.sele=
> ctedFeatures()</div>
>
> <div style>for feat in selected_feats:</div><div style>=C2=A0 =C2=A0 # do
> s=
> tuff with the feature</div><div><div><br></div><div style>Since
> QgsVectorLa=
> yer.getFeatures can take a QgsFeatureRequest as argument, I think a nice
> so=
> lution could be to add one more filter to QgsFeatureRequest to allow
> iterat=
> ing over a list of feature ids. It currently already allows to pass in a
> si=
> ngle feature id, it would just be a matter of expanding that.</div>
>
> <div style><br></div><div style>In the meantime I am using a custom
> iterato=
> r class[1] in Python that wraps this different behaviour and lets me use
> th=
> e same logic for processing the whole layer or just the selected features.
> =
> I think it would be cleaner if this could be done on the API side.</div>
>
> <div style><br></div><div style>Maybe I am asking for too much too late
> bec=
> ause of the feature freeze for 2.0?</div><div style><br></div><div
> style><b=
> r></div><div style>[1] - (see the FeatureIterator class) <a
> href=3D"https:/=
> /github.com/ricardogsilva/coneforinputs/blob/master/coneforinputs.py
> ">https=
> ://github.com/ricardogsilva/coneforinputs/blob/master/coneforinputs.py
> </a><=
> /div>
>
> <div style><br></div><div style><br></div>--
> <br>__________________________=
> _ ___ __<br>Ricardo Garcia Silva
> </div></div>
>
> --089e0102eaa65b15f904df59d6c1--
>
> --===============3430773931903739203==
> Content-Type: text/plain; charset="us-ascii"
> MIME-Version: 1.0
> Content-Transfer-Encoding: 7bit
> Content-Disposition: inline
>
> _______________________________________________
> Qgis-developer mailing list
> Qgis-developer at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/qgis-developer
>
> --===============3430773931903739203==--
>



-- 
___________________________ ___ __
Ricardo Garcia Silva
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/qgis-developer/attachments/20130617/90beaf20/attachment.html>


More information about the Qgis-developer mailing list