2
def get_subsel(layer,filter):
    layers = iface.mapCanvas().layers()
    for lyr in layers:
        if lyr.name() == layer:
            request = QgsFeatureRequest().setFilterExpression(filter)

            iter = lyr.getFeatures(request)
            ids = [i.id() for i in iter]
            lyr.setSelectedFeatures(ids)

            selected_feats = lyr.selectedFeatures()

    new_layer = QgsVectorLayer("Point?crs=epsg:277000", "acc_subselection", "memory")
    data_prov = new_layer.dataProvider()
    data_prov.addFeatures(selected_feats)
    QgsMapLayerRegistry().instance().addMapLayer(new_layer)

I'm trying to use the code above with filter = ("\"accdate\" >= '1990-01-01' AND \"accdate\" <= '1992-12-31'"). If I type this in to the python console line for line (i.e. without using the function) it works fine. But typing the filter as defined above in to the function I get an error in the first line (so the code hasn't executed yet):

get_subsel("accident", "("\"accdate\" >= '1990-01-01' AND \"accdate\" <= '1992-12-31'") SyntaxError: unexpected character after line continuation character with the ^ pointing at '1990-01-01' (where bold).

It looks like it's getting confused with the \ escape-character...but like I said it works when typed in to the console. I'm more experienced in MapBasic programming (MapInfo GIS), where I would build filter by concatenating strings and e.g. CHR$(34) or CHR$(92), which at runtime are interpreted as " and \, respectively. Hopefully that's clear enough

So do I need to do something similar in order for python to interpret the various quotes and backslashes correctly at runtime?

the layer is from a Postgres database

2

Your escaping isn't write quite right. It should be:

(\"accdate\" >= '1990-01-01' AND \"accdate\" <= '1992-12-31')

(You have some extra "s)

Also note that:

iter = lyr.getFeatures(request)
ids = [i.id() for i in iter]
lyr.setSelectedFeatures(ids)
selected_feats = lyr.selectedFeatures()

Is quite inefficient. Try:

iter = lyr.getFeatures(request)
selected_feats = [f for f in iter]

instead

  • have only just got round to actually trying this. I've now used the function like this get_subsel("accident", "\"accdate\" >= '1990-01-01' AND \"accdate\" <= '1992-12-31'") and it appears to work. well, i have a different error but unrelated – Alex Jul 1 '16 at 13:36
  • improved comment above, but after the 5 minute edit-window: have only just got round to actually trying this. maybe I misunderstood your instructions, I got pretty much the same error putting the filter-string in (without brackets) as you suggested. but I've now used the function like this get_subsel("accident", "\"accdate\" >= '1990-01-01' AND \"accdate\" <= '1992-12-31'") and it appears to work. well, i have a different error but unrelated – Alex Jul 1 '16 at 13:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.