Azione in un popup

Questa è una funzionalità di Lizmap 3.4.

Regola

Questo modulo permette di aggiungere pulsanti di azione nel popup che attiveranno query PostgreSQL e restituiranno una geometria da visualizzare sulla mappa.

Legge un file di configurazione JSON che deve essere collocato all’interno del progetto QGIS. Questo file elenca le azioni PostgreSQL da aggiungere nel popup per uno o più livelli vettoriali QGIS PostgreSQL.

Configurazione del plugin

Ogni azione è caratterizzata da un layer, un nome, un titolo, una icona, alcune opzioni opzionali, stile e callback.

Esempio di questo file di configurazione JSON, denominato myproject.qgs.action se il file del progetto QGIS è denominato myproject.qgs:

{
    "points_a7e8943b_7138_4788_a775_f94cbd0ad8b6": [
        {
            "name": "liztest",
            "title": "Tampon",
            "icon": "icon-leaf",
            "options": {
                "buffer_size": 5000
            },
            "style": {
                "graphicName": "circle",
                "pointRadius": 6,
                "fill": true,
                "fillColor": "lightblue",
                "fillOpacity": 0.3,
                "stroke": true,
                "strokeWidth": 4,
                "strokeColor": "blue",
                "strokeOpacity": 0.8
            },
            "callbacks": [
                {"method": "zoom"},
                {"method": "select", "layerId": "admin_level_8_fcfdc9e0_c9b9_4563_b803_e36f9e2eca6a"},
                {"method": "redraw", "layerId": "admin_level_8_fcfdc9e0_c9b9_4563_b803_e36f9e2eca6a"}
            ]
        }
    ]
}

Il file di configurazione JSON elenca i livelli QGIS per i quali vuoi dichiarare delle azioni. Ogni livello è definito dal suo QGIS layer ID, per esempio qui points_a7e8943b_7138_4788_a775_f94cbd0ad8b6, e per ogni ID, una lista di oggetti che descrivono le azioni da permettere. Ogni azione è un oggetto definito da:

  • un nome che è l’identificatore dell’azione.

  • un titolo che è usato come etichetta nell’interfaccia Lizmap

  • una icona che viene visualizzata sul pulsante dell’azione ( Vedere https://getbootstrap.com/2.3.2/base-css.html#icons )

  • un oggetto options, che fornisce alcuni parametri aggiuntivi per questa azione.

  • un oggetto style che permette di configurare lo stile della geometria restituita. Segue gli attributi di stile di OpenLayers.

  • un oggetto callbacks permette di innescare alcune azioni dopo la restituzione della geometria generata. Sono definiti da un nome di method, che al momento può essere:

    • zoom: zoom sulla geometria restituita

    • select`: seleziona le caratteristiche di un dato livello che intersecano la geometria restituita. L’ID QGIS del livello di destinazione deve essere aggiunto nella proprietà layerId.

    • redraw: ridisegna un dato livello. L’ID QGIS del livello di destinazione deve essere aggiunto nella proprietà layerId.

Lizmap rileva la presenza di questo file di configurazione, e aggiunge la logica necessaria al caricamento della mappa. Quando l’utente clicca su un oggetto di uno di questi livelli nella mappa, il pannello popup mostra i dati della caratteristica. Nella parte superiore di ogni oggetto popup, una barra degli strumenti mostrerà un pulsante per ogni azione del livello.

Ogni pulsante attiva l’azione corrispondente:

  • Lizmap backend controlla se l’azione è ben configurata,

  • crea la query **PostgreSQL e la esegue nel database PostgreSQL del livello.

  • Questa query restituisce un GeoJSON che viene poi visualizzato sulla mappa.

La query creata è costruita dal web client Lizmap e usa la funzione PostgreSQL lizmap_get_data(json) che deve essere creata prima nel database PostgreSQL. Questa funzione usa anche una funzione più generica query_to_geojson(text) che trasforma qualsiasi query PostgreSQL in un output GeoJSON. Ecco un esempio qui sotto della query eseguita da Lizmap, per la configurazione di esempio riportata sopra, quando l’utente clicca sul pulsante azione liztest, per la feature con id 1 del layer points corrispondente alla tabella PostgreSQL test.points:

SELECT public.lizmap_get_data('{"layer_name":"points","layer_schema":"test","layer_table":"points","feature_id":1,"action_name":"liztest","buffer_size":5000}') AS data

Potete vedere che Lizmap crea un parametro JSON con tutte le informazioni necessarie ed esegue la funzione PostgreSQL lizmap_get_data. Il seguente codice SQL permette di creare le funzioni necessarie:

-- Returns a valid GeoJSON from any query
CREATE OR REPLACE FUNCTION query_to_geojson(datasource text)
RETURNS json AS
$$
DECLARE
    sqltext text;
    ajson json;
BEGIN
    sqltext:= format('
        SELECT jsonb_build_object(
            ''type'',  ''FeatureCollection'',
            ''features'', jsonb_agg(features.feature)
        )::json
        FROM (
          SELECT jsonb_build_object(
            ''type'',       ''Feature'',
            ''id'',         id,
            ''geometry'',   ST_AsGeoJSON(ST_Transform(geom, 4326))::jsonb,
            ''properties'', to_jsonb(inputs) - ''geom''
          ) AS feature
          FROM (
              SELECT * FROM (%s) foo
          ) AS inputs
        ) AS features
    ', datasource);
    RAISE NOTICE 'SQL = %s', sqltext;
    EXECUTE sqltext INTO ajson;
    RETURN ajson;
END;
$$
LANGUAGE 'plpgsql'
IMMUTABLE STRICT;
COMMENT ON FUNCTION query_to_geojson(text) IS 'Generate a valide GEOJSON from a given SQL query.';

-- Create a query depending on the action, layer and feature and returns a GeoJSON.
CREATE OR REPLACE FUNCTION lizmap_get_data(parameters json)
RETURNS json AS
$$
DECLARE
    feature_id integer;
    layer_name text;
    layer_table text;
    layer_schema text;
    action_name text;
    sqltext text;
    datasource text;
    ajson json;
BEGIN

    action_name:= parameters->>'action_name';
    feature_id:= (parameters->>'feature_id')::integer;
    layer_name:= parameters->>'layer_name';
    layer_schema:= parameters->>'layer_schema';
    layer_table:= parameters->>'layer_table';

    -- Action liztest
    -- Written here as an example
    -- Performs a buffer on the geometry
    IF action_name = 'liztest' THEN
        datasource:= format('
            SELECT
            %1$s AS id,
            ST_Buffer(geom, %4$s) AS geom
            FROM "%2$s"."%3$s"
            WHERE id = %1$s
        ',
        feature_id,
        layer_schema,
        layer_table,
        parameters->>'buffer_size'
        );
    ELSE
    -- Default : return geometry
        datasource:= format('
            SELECT
            %1$s AS id,
            geom
            FROM "%2$s"."%3$s"
            WHERE id = %1$s
        ',
        feature_id,
        layer_schema,
        layer_table
        );

    END IF;

    SELECT query_to_geojson(datasource)
    INTO ajson
    ;
    RETURN ajson;
END;
$$
LANGUAGE 'plpgsql'
IMMUTABLE STRICT;
COMMENT ON FUNCTION lizmap_get_data(json) IS 'Generate a valide GEOJSON from an action described by a name, PostgreSQL schema and table name of the source data, a QGIS layer name, a feature id and additionnal options.';

La funzione lizmap_get_data(json) è riportata qui come esempio. Dato che è il key entry point, è necessario adattarlo alle proprie esigenze.

Puoi usare tutti i parametri dati (action name, source data schema e table name, feature id, QGIS layer name) per creare la query appropriata per le tue azioni, usando le clausole PostgreSQL IF THEN ELSIF ELSE.