Hoe kan ik de verborgen kolom met feature id's ($id) vanuit pyQGIS benaderen?

Namens mijn collega Arja de vraag:
Hoe kan ik de verborgen kolom met feature id’s ($id) vanuit pyQGIS benaderen?

Niet elke kaartlaag heeft een ‘harde’ kolom met een unieke ID erin. Een shapefile bijvoorbeeld, toont in ArcGIS wel een ID maar in QGIS niet. Er is wel een ID want je kunt het met de expressies benaderen via $id. Alleen, bij gebruik van een python script kan dit opeens niet meer? Hoe zou je de verborgen kolom met feature id’s vanuit pyQGIS kunnen benaderen?.


Hieronder haar uitleg:

We hebben een vectorlaag met de gemeenten in Gelderland:
image

Voeren we (via PyQGIS) een selectie uit op de kolom met de gemeente-code ‘GM_CODE’:
image

Dan geeft dat in de console:
image

In het kaartbeeld ziet het er dan als volgt uit:
image

Doen we dezelfde stappen nogmaals, maar nu met een selectie op de verborgen kolom met feature id’s ($id), dan levert dat het volgende op:
image

image

image

Kortom: er wordt geen match gevonden.

Echter, voeren we dezelfde selectie handmatig uit met ‘Selectby Expression’, dan wordt er wel een match gevonden!
image
image

Ik kan me eigenlijk niet voorstellen dat je een zinnige filterexpressie kan maken op de fids van een layer.

Maar als je een lijst met ids hebt, dan kun je de setFilterFids() methode gebruiken op QgsFeatureRequest.

Beste Marco,

Hartelijk dank voor het antwoord.

De reden dat ik een filterexpressie wil maken op de fids van een layer, is de volgende:

Ik ben bezig met een Python-script binnen QGIS. Daarin komt een query voor, waarmee ik een query wil doen op unieke ids van een feature layer. Soms heeft zo’n feature layer een uniek sleutelveld en kan ik de query uitvoeren (en dat werkt ook). Er zijn echter ook feature layers zonder eigen uniek sleutelveld.

Ik wil mijn query daarom generiek maken, oftewel onafhankelijk van het feit of er een uniek sleutelveld aanwezig is of niet. Ik kan en wil dat doen door gebruik te maken van de fids van een layer, die in ArcGIS wel zichtbaar zijn en in QGIS niet.

In QGIS kan ik zo’n feature id wel handmatig selecteren via een query (Select by Expression). Dan maak ik gebruik van $id. Als ik exact dezelfde query binnen mijn PyQGIS code plaats, dan gebeurt er niets. Dan wordt de betreffende feature niet gevonden.

Ik vroeg mij nu af of er een andere schrijfwijze o.i.d. nodig is, om $id in een query in een PyQGIS-script aan te roepen.

Met vriendelijke groeten, Arja Biebericher.

Je wilt een query doen op unieke ids van een feature layer.

Maar wat voor soort expressie wil je dan gebruiken om deze te selecteren? Geef eens een voorbeeld.

De query in mijn script heeft betrekking op het genereren van een virtual layer:

vlayer_gem_selection = QgsVectorLayer(selection_string, “virtual layer”, “virtual”)

waarbij:

selection_string = "?query=SELECT * FROM " + layer_gem.name() + " WHERE " + unique_key + " IN " + (‘GM1876’,‘GM0200’)

met

layer_gem = QgsProject.instance().mapLayersByName(“gemeenten_Gelderland”)[0]

unique_key = “GM_CODE”

In dit geval is de unique_key gelijk aan de gemeentecode “GM_CODE”. Dat is een sleutelveld. Maar wat nu, als ik niet de gemeentecode, maar de generieke $id wil gebruiken in de selection_string (waarbij achter IN dan de verzameling met fids komt te staan)?

In geposte code van de vraag was er sprake van een QgsFeatureRequest. Ik heb voor je uitgezocht dat je daar een setFilterFids() methode hebt waarin je je lijst met fids op kunt geven. In dit geval dus een lijst met waarden als alternatief voor (‘GM1876’,‘GM0200’).

Nu blijkt dat er helemaal geen sprake is van een QgsFeatureRequest. Dat schiet niet op zo.

Ik stel voor dat je een volgende keer direct de juiste vraag post ipv een andere.

Ok, het bleek dus iets anders te zijn - het leek generieker te zijn vandaar eerste code. Is de tweede of verduidelijktevraag nu wel duidelijk?

En belangrijker natuurlijk: kan een generieke $id opgevraagd worden in python? Want dat is het probleem als ik alles goed begrijp.

Beste Jonna,

Nu wel duidelijk, maar ik heb niet zo’n zin om weer een andere vraag uit te gaan zoeken. Mede omdat mijn gevoel zegt dat het probleem hier op de verkeerde manier wordt aangevlogen.

Ik kan me niet voorstellen dat het zinvol kan zijn om een virtuele layer te baseren op een query op fids. Deze fids hebben geen enkele inhoudelijke betekenis. Dus ze zijn een proxy voor ‘iets anders’. Ik verwacht dat je dat ‘iets anders’ moet gebruiken, en niet een (hele lange) lijst met fids die op basis van dat ‘iets anders’ is gegenereerd.

Hmm, ja als die fid’s echt geen inhoudelijke betekenis hebben is het natuurlijk logisch om deze niet te gebruiken.

Even hardop denken:
Een virtual layer maak je meestal door een query op een laag te maken. Maar wat nou, als je al een selectie hebt (die bijvoorbeeld is gemaakt door in de kaart te klikken of tools te draaien) en je wilt dan met die geselecteerde records verder werken, die moeten dan opgepakt worden in het script. En daar heb je unieke id’s voor nodig, die niet elke laag standaard in een kolom heeft.

We hebben net een plan 1a gebrainstormed, nu op naar plan b, c en d.

Dank alvast voor je tijd!

In QGIS kun je wel gemakkelijk loopen over de geselecteerde records in een laag. Wellicht kun je daar iets mee?

Waarom wil je eigenlijk een virtual layer?

Ik heb net een mail gekregen dat het gelukt is via plan 1b! Dus dat is mooi.

Plan 1b was via een virtuele kolom en deze vullen met id’s. Nu kan ik me herinneren dat dat de eerste optie was een aantal weken terug en dat dat toen niet lukte. Het lastige is dat Arja als programmeur en ik als niet-programmeur met functioneel meedenken alleen op dinsdag tegelijk werken. Ik kan hier verder dus weinig zinnigs over zeggen, behalve dat plan 1b toch gelukt is.

Dus wat het benaderen van de verborgen kolom $id via pyQGIS betreft weten we nu dat dit waarschijnlijk expres is omdat deze waarde geen inhoudelijke betekenis heeft.