12.1. Expressies

Gebaseerd op gegevens van lagen en vooraf gedefinieerd of als gebruikergedefinieerde functies bieden Expressies een krachtige manier om attribuutwaarden, geometrie en variabelen te bewerken om dynamisch de stijl van de geometrie te wijzigen, de inhoud of positie van het label, de waarde voor het diagram, de hoogte van een item voor afdruklay-out, enkele objecten te selecteren of een virtueel veld te maken, …

Notitie

Een lijst met standaard functies en variabelen voor het schrijven van expressies is te vinden op Lijst van functies, met gedetailleerde informatie en voorbeelden.

12.1.1. Expressie-string bouwer

Belangrijkste dialoogvenster om expressies te bouwen, de Expressie string-bouwer is beschikbaar in vele delen van QGIS en is in het bijzonder toegankelijk bij:

Het dialoogvenster Expressie-string bouwer biedt toegang tot de:

  • tab Expressie die, dankzij een lijst met vooraf gedefinieerde functies, helpt bij het schrijven en controleren van de te gebruiken expressie;

  • tab Functiebewerker die helpt om de lijst met functies uit te breiden door aangepaste te maken.

12.1.1.1. De interface

De tab Expressie verschaft de belangrijkste interface voor het schrijven van expressies met functies, velden van lagen en waarden. Het bevat de volgende widgets:

../../../_images/function_list.png

Fig. 12.1 De tab Expressie

  • Een gebied in de bewerker voor expressies om expressies te typen of te plakken. Automatisch aanvullen is beschikbaar om het schrijven van expressies te versnellen:

    • Corresponderende variabelen, functienamen en veldnamen voor de invoer van tekst worden hieronder weergegeven: gebruik de pijlen Omhoog en Omlaag om door de items te bladeren en druk op Tab om het in de expressie in te voegen op klik eenvoudigweg op het gewenste item.

    • Parameters voor functies worden weergegeven als zij worden ingevoerd.

    QGIS controleert ook de geldigheid van de expressie en accentueert alle fouten met:

    • Onderstrepen: voor onbekende functies, foute of ongeldige argumenten;

    • Markering: voor elke andere fout (bijv, ontbrekende haakjes, onverwacht teken) op één enkele plaats.

    Tip

    Documenteer uw expressie met opmerkingen

    Bij het gebruiken van complexe expressies is het een goed gebruik om tekst toe te voegen, ofwel als een opmerking met meerdere regels, of als een opmerking op de regel zelf, om u te helpen herinneren.

    /*
    Labels each region with its highest (in altitude) airport(s)
    and altitude, eg 'AMBLER : 264m' for the 'Northwest Artic' region
    */
    with_variable(
      'airport_alti', -- stores the highest altitude of the region
      aggregate(
        'airports',
        'max',
        "ELEV", -- the field containing the altitude
        -- and limit the airports to the region they are within
        filter := within( $geometry, geometry( @parent ) )
      ),
        aggregate( -- finds airports at the same altitude in the region
          'airports',
          'concatenate',
          "NAME",
          filter := within( $geometry, geometry( @parent ) )
            and "ELEV" = @airport_alti
        )
        || ' : ' || @airport_alti || 'm'
        -- using || allows regions without airports to be skipped
    )
    
  • Boven de bewerker voor expressies helpt een set gereedschappen u:

  • Onder de expressiebewerker vindt u:

    • een set basisoperatoren om u te helpen de expressie te bouwen

    • een indicatie van de verwachte indeling van de uitvoer als u eigenschappen van objecten data-bepaald

    • een levend Uitvoer voorbeeld van de expressie, standaard geëvalueerd op het eerste object van de laag. U kunt door andere objecten van de laag bladeren en die evalueren met het combinatievak Object (de waarden worden genomen uit de eigenschap weergavenaam van de laag).

      In geval van fouten geeft het dat aan en kunt toegang krijgen tot de details met de verschafte hyperlink.

  • Een functieselectie geeft de lijst met functies, variabelen, velden… weer, georganiseerd in groepen. Een zoekvak is beschikbaar om de lijst te filteren en snel een bepaalde functie of veld te vinden. Dubbelklikken op de naam van het item voegt het toe aan de te schrijven expressie.

  • Een paneel Help geeft de help weer voor elk geselecteerd item in de functieselectie.

    Tip

    Drukken op Ctrl+Click, terwijl u met de muis over de naam van een functie in een expressie gaat, zal automatisch de Help daarvoor openen in een dialoogvenster.

    Een widget voor waarden van velden dat wordt weergegeven als een veld is geselecteerd in de functieselectie helpt om attributen van de objecten op te halen.

    • Zoeken naar een bepaalde veldwaarde

    • De lijst met waarden Alle unieke of 10 voorbeelden weergeven. Ook beschikbaar door met rechts te klikken.

      Wanneer het veld is verbonden aan een andere laag of een set waarden, d.i. als de widget Veld van het type Relatie-verwijzing, Waarde relatie of Waardenkaart is, is het mogelijk om alle waarden van het verbonden veld te vermelden (vanuit de verbonden laag, tabel of lijst). Meer nog, u kunt deze lijst filteren om checkbox Alleen gebruikte waarden weergeven in het huidige veld.

    Dubbelklikken op een veldwaarde in de widget voegt het toe aan de expressiebewerker.

    Tip

    Het rechterpaneel, dat Help voor functies of veldwaarden weergeeft, kan worden samengevouwen (onzichtbaar) in het dialoogvenster. Druk op de knoppen Waarden weergeven of Help weergeven om het terug te krijgen.

12.1.1.2. Een expressie schrijven

Expressies van QGIS worden gebruikt om objecten of sets waarden te selecteren. Schrijven van een expressie in QGIS moet voldoen aan enkele regels:

  1. Het dialoogvenster definieert de context: als u gewend bent aan SQL, zult u waarschijnlijk bekend zijn met query’s van het type select features from layer where condition of update layer set field = new_value where condition. Een expressie van QGIS heeft ook al deze informatie nodig, maar het gereedschap dat u gebruikt om het dialoogvenster Expressie-bouwer te openen verschaft er delen van. Bijvoorbeeld: uitgaande van een laag (buildings) met een veld (height):

    • klikken op het gereedschap expressionSelectObjecten selecteren met een expressie betekent dat u wilt “select features from buildings”. De voorwaarde is de enige informatie die u dient op te geven in de widget voor de tekst van de expressie, bijv. typ "height" > 20 om gebouwen te selecteren die hoger zijn dan 20.

    • met deze selectie gemaakt, geeft u door te drukken op de knop calculateField Veldberekening en te kiezen voor “height” als Bestaand veld bijwerken, de opdracht “update buildings set height = ??? where height > 20”. De enige resterende gedeelten die u in dit geval moet opgeven is de nieuwe waarde, voer bijv. eenvoudigweg 50 in het tkstvak van de bewerker voor de expressie in om de hoogte voor de eerder geselecteerde gebouwen in te stellen.

  2. Let op aanhalingstekens: enkele aanhalingstekens geven een letterlijke waarde terug, dus een tekst die is geplaatst tussen enkele aanhalingstekens ('145') wordt geïnterpreteerd als een tekenreeks. Dubbele aanhalingstekens geven u de waarde van die tekst, dus gebruik ze voor velden ("myfield"). Velden kunnen ook zonder aanhalingstekens worden gebruikt (myfield). Geen aanhalingstekens voor getallen (3.16).

    Notitie

    Functies nemen normaal gesproken een tekenreeks of veldnaam als argument. Doe:

    attribute( @atlas_feature, 'height' ) -- returns the value stored in the "height" attribute of the current atlas feature
    

    En niet:

    attribute( @atlas_feature, "height" ) -- fetches the value of the attribute named "height" (e.g. 100), and use that value as a field
                                          -- from which to return the atlas feature value. Probably wrong as a field named "100" may not exist.
    

Tip

Benoemde parameters gebruiken om het lezen van de expressie gemakkelijker te maken

Sommige functies vereisen dat veel parameters moeten worden ingesteld. Het programma voor expressies ondersteunt het gebruiken van benoemde parameters. Dit betekent dat, in plaats van de cryptische expressie: clamp(1, 2, 9) te schrijven, u: clamp( min:=1, value:=2, max:=9) kunt gebruiken. Deze wijziging maakt het ook mogelijk argumenten te wisselen, bijv: clamp( value:=2, max:=9, min:=1). Het gebruiken van benoemde parameters helpt te verduidelijken waar de argumenten voor een functie voor een expressie naar verwijzen, wat nuttig is als u een expressie later probeert te interpreteren!

12.1.1.3. Enkele gebruiksgevallen van expressies

  • Vanuit Veldberekening, bereken een veld “pop_density” met behulp van de bestaande velden “total_pop” en “area_km2”:

    "total_pop" / "area_km2"
    
  • Label of categoriseer objecten gebaseerd op hun gebied:

    CASE WHEN $area > 10 000 THEN 'Larger' ELSE 'Smaller' END
    
  • Werk het veld “density_level” bij met categorieën overeenkomstig de waarden van “pop_density”:

    CASE WHEN "pop_density" < 50 THEN 'Low population density'
         WHEN "pop_density" >= 50 and "pop_density" < 150 THEN 'Medium population density'
         WHEN "pop_density" >= 150 THEN 'High population density'
    END
    
  • Pas een stijl met categorieën toe op alle objecten overeenkomstig het feit of hun gemiddelde huizenprijs minder of meer is dan €10.000 per vierkante meter:

    "price_m2" > 10000
    
  • Selecteer, met het gereedschap “Objecten selecteren met een expressie…”, alle objecten die gebieden vertegenwoordigen van “Dicht bevolkt” en waarvan de gemiddelde huizenprijs hoger is dan €10.000 per vierkante meter:

    "density_level" = 'High population density' and "price_m2" > 10000
    

    De vorige expressie zou ook kunnen worden gebruikt om te definiëren welke objecten te labelen of op de kaart weer te geven.

  • Maak een ander symbool (type) voor de laag, met de geometrie-generator:

    point_on_surface( $geometry )
    
  • Gegeven een object punt, maak een gesloten lijn (met make_line) rondom zijn geometrie:

    make_line(
      -- using an array of points placed around the original
      array_foreach(
        -- list of angles for placing the projected points (every 90°)
        array:=generate_series( 0, 360, 90 ),
        -- translate the point 20 units in the given direction (angle)
        expression:=project( $geometry, distance:=20, azimuth:=radians( @element ) )
      )
    )
    
  • Geef, in een label van afdruklay-out, de naam weer van de objecten “airports” die binnen de lay-out van item “Kaart 1” liggen:

    with_variable( 'extent',
                   map_get( item_variables( 'Map 1' ), 'map_extent' ),
                   aggregate( 'airports', 'concatenate', "NAME",
                              intersects( $geometry, @extent ), ' ,'
                            )
                 )
    

12.1.1.4. Expressies opslaan

Door het gebruiken van de knop fileSave Huidige expressie aan gebruikersexpressies toevoegen boven het frame van de bewerker voor de expressie, kunt u belangrijke expressies, waartoe u snel toegang wilt hebben, opslaan. Deze zijn beschikbaar vanuit de groep Gebruikersexpressies in het middelste paneel. Zij worden opgeslagen in het gebruikersprofiel (bestand <userprofile>/QGIS/QGIS3.ini) en beschikbaar in alle dialoogvensters voor expressies binnen alle projecten van het huidige gebruikersprofiel.

Een set gereedschappen, beschikbaar boven het frame van de expressiebewerker, helpt u de gebruikersexpressies te beheren:

  • fileSaveHuidige expressie aan gebruikersexpressies toevoegen: slaat de expressie op in het gebruikersprofiel. Een label en een helptekst kunnen worden toegevoegd om het gemakkelijk te identificeren.

  • symbologyEdit Geselecteerde expressie uit gebruikersexpressies bewerken, als ook hun help en label

  • deleteSelected Geselecteerde expressie uit gebruikersexpressies verwijderen

  • sharingImport Gebruikersexpressies importeren uit een bestand .json in de map voor het actieve gebruikersprofiel

  • sharingExport Gebruikersexpressies exporteren als een bestand .json; alle gebruikersexpressies in het bestand QGIS3.ini van het gebruikersprofiel worden gedeeld

12.1.2. Functiebewerker

Met de tab Functiebewerker kunt u uw eigen functies schrijven in de taal Python. Dit verschaft een handige en comfortabele manier om bepaalde wensen, die niet door vooraf gedefinieerde functies worden verschaft, aan te pakken.

../../../_images/function_editor.png

Fig. 12.2 De tab Functiebewerker

Een nieuwe functie maken:

  1. Druk op de knop symbologyAdd Nieuw bestand.

  2. Voer een naam in om te gebruiken in het formulier dat opent en druk op OK.

    Een nieuw item van de naam die u opgaf, wordt toegevoegd aan het linkerpaneel van de tab Functiebewerker; dit is een Python-bestand .py gebaseerd op een sjabloonbestand van QGIS en opgeslagen in de map /python/expressions onder de map van het actieve gebruikersprofiel.

  3. Het rechterpaneel geeft de inhoud van het bestand weer: een sjabloon voor een Python-bestand. Werk de code en zijn Help bij overeenkomstig uw behoeften.

  4. Druk op de knop start Functies voor laden en opslaan. De functie die u schreef wordt toegevoegd aan de boom met functies op de tab Expressie, standaard onder de groep Aangepast.

  5. Veel plezier met uw functie.

  6. Als de functie verbeteringen nodig heeft, schakel naar de tab Functiebewerker, maak de wijzigingen en druk opnieuw op de knop start Functies voor laden en opslaan om ze beschikbaar te maken in het bestand, en daarmee op de tab Expressie.

Aangepaste functies voor Python worden opgeslagen onder de map van het gebruikersprofiel, wat betekent dat bij elke keer dat QGIS opstart, het automatisch alle functies zal laden die zijn gedefinieerd met het huidige gebruikersprofiel. Onthoud dat nieuwe functies alleen worden opgeslagen in de map /python/expressions en niet in het projectbestand. Als u een project deelt dat een van uw aangepaste functies gebruikt, moet u ook het bestand .py in de map /python/expressions delen.

Een aangepaste functie verwijderen:

  1. Schakel naar de tab Functiebewerker

  2. Selecteer de functie in de lijst

  3. Druk op de knop symbologyRemove Geselecteerde functiebestand verwijderen. De functie wordt uit de lijst verwijderd en het overeenkomende bestand .py verwijderd uit de map van het gebruikersprofiel.

Voorbeeld

Hier is een kort voorbeeld voor het maken van uw eigen functie my_sum die werkt met twee waarden.

from qgis.core import *
from qgis.gui import *

@qgsfunction(args='auto', group='Custom')
def my_sum(value1, value2, feature, parent):
    """
    Calculates the sum of the two parameters value1 and value2.
    <h2>Example usage:</h2>
    <ul>
      <li>my_sum(5, 8) -> 13</li>
      <li>my_sum("field1", "field2") -> 42</li>
    </ul>
    """
    return value1 + value2

Door het gebruiken van het functieargument args='auto' zal het aantal vereiste argumenten voor de functie worden berekend door het aantal argumenten waarmee de functie is gedefinieerd in Python (minus 2 - feature, en parent). Het argument group='Custom' geeft de groep aan waarin de functie zou moeten worden vermeld in het dialoogvenster Expressie.

Het is ook mogelijk argumenten voor sleutelwoorden toe te voegen, zoals:

  • usesgeometry=True als de expressie toegang vereist tot de geometrie van het object. Standaard False.

  • handlesnull=True als de expressie aangepaste afhandeling heeft voor waarden NULL. Indien False (standaard) zal het resultaat altijd NULL zijn, zodra enige parameter NULL is.

  • referenced_columns=[lijst]: Een array van namen van attributen die vereist zijn voor de functie. Standaard is [QgsFeatureRequest.ALL_ATTRIBUTES].

De vorenstaande voorbeeldfunctie kan dan worden gebruikt in expressies:

../../../_images/customFunction.png

Fig. 12.3 Aangepaste functie toegevoegd aan de tab Expressie

Meer informatie over het maken van code voor Python kan worden gevonden in het PyQGIS Developer Cookbook.