[QGIS-Developer] get all the features of a specific layer which are visible in the viewport
Jo
winfixit at gmail.com
Sun Jan 19 11:10:42 PST 2020
Wonderful, I'm going to try that. Muchas gracias!
Jo
On Sun, Jan 19, 2020, 16:36 Jorge Gustavo Rocha <jgr at di.uminho.pt> wrote:
> Hi Jo,
>
> You can use setFilterRect (see
> https://docs.qgis.org/3.4/en/docs/pyqgis_developer_cookbook/vector.html).
>
> request = QgsFeatureRequest().setFilterRect(iface.mapCanvas().extent())
> for feature in layer.getFeatures(request):
> print(feature.id)
>
> This way, you only iterate over the visible features.
>
> Regards,
>
> Jorge Gustavo
>
> On 18/01/20 20:39, Jo wrote:
> > Hi,
> >
> > I created the following code:
> >
> > class FBSegmentPoiComboBox(FBComboBox):
> > def __init__(self, name, identifier=None, update_method=None,
> iface=None):
> > super().__init__(name=name, identifier=identifier,
> update_method=update_method)
> > self.iface = iface
> > self.items_list = []
> > self.find_segments()
> > self.rubber_band = QgsRubberBand(self.iface.mapCanvas(), False)
> > self.rubber_band.setWidth(12)
> > self.rubber_band.setStrokeColor(QColor.fromRgb(90, 0, 20))
> > self.highlighted.connect(self.highlight_segment)
> > self.currentIndexChanged.connect(self.clear_rubberband)
> >
> > def find_segments(self):
> > self.clear()
> > self.add_item(REFRESH_SEGMENTS_LIST, None)
> > # put a dummy at position 0
> > self.items_list = ['dummy']
> > segment_layer_list =
> QgsProject.instance().mapLayersByName('segment')
> > if segment_layer_list:
> > segment_layer = segment_layer_list[0]
> > layer =
> QgsProject.instance().layerTreeRoot().findLayer(segment_layer)
> > if layer:
> > layer.setItemVisibilityChecked(True)
> > if self.iface:
> > segments = QgsSpatialIndex()
> > for segment in segment_layer.getFeatures():
> > segments.insertFeature(segment)
> > nearby =
> segments.nearestNeighbor(self.iface.mapCanvas().center(), neighbors=10) # ,
> maxDistance=1000)
> > for featureId in nearby:
> > fit2 =
> segment_layer.getFeatures(QgsFeatureRequest().setFilterFid(featureId))
> > ftr = QgsFeature()
> > fit2.nextFeature(ftr)
> > self.add_item(ftr.attribute(0), ftr.attribute(0))
> > self.items_list.append(ftr)
> > self.changed = False
> >
> > def highlight_segment(self, index):
> > self.rubber_band.reset()
> > if index == 0:
> > self.find_segments()
> > elif index < len(self.items_list):
> >
> self.rubber_band.setToGeometry(self.items_list[index].geometry())
> >
> > def clear_rubberband(self, index):
> > self.rubber_band.reset()
> >
> >
> > It populates a drop down with all the LineStrings near to the center of
> the screen.
> >
> > It's not very efficient though, as I need to first pass all the
> LineStrings on that particular layer to it.
> >
> > Is there a way to replace this code:
> >
> > for segment in segment_layer.getFeatures():
> > segments.insertFeature(segment)
> >
> > So it only works on a smaller subset of features that are actually
> visible to on the user's screen?
> >
> > Jo
> >
> >
> > _______________________________________________
> > QGIS-Developer mailing list
> > QGIS-Developer at lists.osgeo.org
> > List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
> > Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer
> >
>
> J. Gustavo
> --
> Jorge Gustavo Rocha
> Departamento de Informática
> Universidade do Minho
> 4710-057 Braga
> Gabinete 3.29 (Piso 3)
> Tel: +351 253604480
> Fax: +351 253604471
> Móvel: +351 910333888
> skype: nabocudnosor
> _______________________________________________
> QGIS-Developer mailing list
> QGIS-Developer at lists.osgeo.org
> List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
> Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/qgis-developer/attachments/20200119/4bd45b9e/attachment-0001.html>
More information about the QGIS-Developer
mailing list