2

I am making a plugin that loads a WFS layer and lets the user filter out the information they need and create a layer based on that filtering. The new layer is created from the original layer based on expressions that are created from the users filtering. This prosess can be very slow as the WFS layer is rather large. I would therfore like to know if there is any faster or betther ways of doing this.

Here is an example of my code:

expr_string = "\"kommune\"=301 AND \"funksjon\"='kultur'" #example of an expr_string
expr = QgsExpression(expr_string)
it = vlayer.getFeatures( QgsFeatureRequest( expr ) )
ids = [i.id() for i in it]
vlayer.setSelectedFeatures( ids )
selectedFeatures = vlayer.selectedFeatures()
tempLayer = QgsVectorLayer("Point?crs=epsg:4326", "newLayer", "memory")
QgsMapLayerRegistry.instance().addMapLayer(tempLayer)
temp_data = tempLayer.dataProvider()
attr = vlayer.dataProvider().fields().toList()
temp_data.addAttributes(attr)
tempLayer.updateFields()
temp_data.addFeatures(selectedFeatures)

This code is based on an anwer from this post: Quickly make server side spatial filters for WFS layers based on other layer's selected geometries in QGIS

Joseph
76.7k8 gold badges173 silver badges286 bronze badges
asked Nov 7, 2017 at 14:33
2
  • did you check where the bottleneck is? adding a print datetime.datetime.now().time() after every major step might give you an impression where your efforts are needed Commented Nov 7, 2017 at 14:54
  • @Joseph thx, I have tried it now, it seems that it is selectedFeatures = vlayer.selectedFeatures() is the onw that took the most time. Commented Nov 8, 2017 at 15:35

1 Answer 1

2

You could try using virtual layers instead of memory layers. Note that I can't confirm if this is faster than your method as I don't know how large your WFS layer is:

layer_name = vlayer.name()
query = "SELECT * FROM " + layer_name + " WHERE kommune = '301' AND funksjon = 'kultur'"
vLayer = QgsVectorLayer("?query={}".format(query), "Output", "virtual" )
QgsMapLayerRegistry.instance().addMapLayer(vLayer)
answered Nov 7, 2017 at 14:59
2
  • This seems to work quite well, thanks. Do you however know if this is possible to do this without adding the original layer to the layers panel (canvas?)? Commented Nov 7, 2017 at 15:58
  • @KasperSkjeggestad - Most welcome! It may be possible but I haven't found a way to do it unfortunately... Commented Nov 9, 2017 at 10:49

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.