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 <[email protected]> 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: [email protected] > 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;">[email protected]</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 > [email protected] > http://lists.osgeo.org/mailman/listinfo/qgis-developer > > --===============3430773931903739203==-- > -- ___________________________ ___ __ Ricardo Garcia Silva
_______________________________________________ Qgis-developer mailing list [email protected] http://lists.osgeo.org/mailman/listinfo/qgis-developer
