Actions — Add some custom buttons
Questa è una funzionalità di Lizmap 3.4.
Regola
Questo modulo permette di aggiungere uno o più pulsanti d’azione nel popup di Lizmap visualizzato per un oggetto PostgreSQL, il quale avvierà una query nel database e restituirà una geometria da visualizzare sulla mappa.
Legge un file di configurazione JSON che deve essere collocato a lato del progetto QGIS nella stessa directory. Questo file elenca le azioni PostgreSQL da aggiungere nel popup per uno o più livelli vettoriali QGIS PostgreSQL.
Configurazione del plugin
Each action is characterized by a
layer id
, aname
, atitle
, anicon
, some optionaloptions
,style
,callbacks
andconfirm
property can be used.Un livello può avere una o più azioni
Si possono avere uno o più livelli con le rispettive azioni
Esempio di questo file di configurazione JSON, nome myproject.qgs.action
se il file del progetto QGIS si chiama myproject.qgs
. In questo progetto, c’è un livello vettoriale chiamato Points
con l’ID interno del livello points_a7e8943b_7138_4788_a775_f94cbd0ad8b6
(puoi ottenere l’ID interno del livello QGIS con l’espressione @layer_id
)
{
"points_a7e8943b_7138_4788_a775_f94cbd0ad8b6": [
{
"name": "buffer_500",
"title": "Buffer 500m around this object",
"confirm": "Do you really want to show the buffer ?",
"icon": "icon-leaf",
"options": {
"buffer_size": 500,
"other_param": "yes"
},
"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": "bati_1a016229_287a_4b5e_a4f7_a2080333f440"},
{"method": "redraw", "layerId": "bati_1a016229_287a_4b5e_a4f7_a2080333f440"}
]
}
]
}
Il file 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 Lizmapuna
icona
che viene visualizzata sul pulsante dell’azione ( Vedere https://getbootstrap.com/2.3.2/base-css.html#icons )una proprietà opzionale
confirm
, da Lizmap 3.5, contenente del testo. Se impostata, un dialogo di conferma verrà mostrato all’utente per chiedere se l’azione deve essere realmente lanciata o no. Usalo se l’azione può modificare alcuni dati nel tuo database.un oggetto
options
, che fornisce alcuni parametri aggiuntivi per questa azione. Puoi aggiungere qualsiasi parametro necessario.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 dimethod
, che al momento può essere:zoom
: zoom sulla geometria restituitaselect`
: seleziona le caratteristiche di un dato livello che intersecano la geometria restituita. Il livello di destinazione QGIS internal ID deve essere aggiunto nella proprietàlayerId
. Nell’esempio, saranno selezionate le caratteristiche del livello contenente edifici, IDbati_1a016229_287a_4b5e_a4f7_a2080333f440
.redraw
: ridisegna (aggiorna) un dato livello nella mappa. 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. In cima ad ogni oggetto popup, una barra degli strumenti mostrerà un pulsante per ogni azione del livello. Il titolo
dell’azione sarà visualizzato al passaggio del mouse sul pulsante dell’azione.
Ogni pulsante attiva l’azione corrispondente, se non è ancora attiva (altrimenti disattiva e cancella la geometria):
Lizmap backend controlla se l’azione è ben configurata,
crea la query **PostgreSQL e la esegue nel database PostgreSQL del livello. (Vedi esempio qui sotto)
Questa query restituisce un GeoJSON che viene poi visualizzato sulla mappa.
Se alcuni callback sono stati configurati, vengono lanciati
A partire da Lizmap 3.5, viene emesso un evento Lizmap
actionResultReceived
con i dati restituiti e le proprietà dell’azione.
La query PostgreSQL creata è costruita dal client web Lizmap e usa la funzione PostgreSQL lizmap_get_data(json)
che deve essere creata prima nella tabella database PostgreSQL. Questa funzione usa anche una funzione più generica query_to_geojson(text)
che trasforma qualsiasi stringa di interrogazione PostgreSQL in un output GeoJSON.
Ecco un esempio qui sotto della query eseguita nel database PostgreSQL da Lizmap Web Client internamente, per la configurazione di esempio data sopra, quando l’utente clicca sul pulsante azione buffer_500, 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":"buffer_500",
"buffer_size":500,
"other_param": "yes"
}') AS data;
Potete notare che Lizmap crea un parametro JSON con tutte le informazioni necessarie ed esegue la funzione PostgreSQL lizmap_get_data(text)
.
Dovete creare questa funzione PostgreSQL lizmap_get_data(text)
che restituisce un testo GeoJSON valido con un singolo oggetto dentro. Il seguente codice SQL è un esempio per aiutarti a creare le funzioni necessarie. Ovviamente, devi adattarlo alle tue esigenze.
-- 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 valid GEOJSON from a given SQL text 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 buffer_500
-- Written here as an example
-- Performs a buffer on the geometry
IF action_name = 'buffer_500' THEN
datasource:= format('
SELECT
%1$s AS id,
''The buffer '' || %4$s || ''m has been displayed in the map'' AS message,
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,
''The geometry of the object have been displayed in the map'' AS message
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 valid 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 additional options.';
La funzione
lizmap_get_data(json)
è fornita qui come esempio. Poiché è il punto di ingresso chiave, è necessario adattarlo alle proprie esigenze. Ha lo scopo di creare una query per ogni nome di azione, creata dinamicamente per i parametri forniti, e restituire una rappresentazione GeoJSON dei dati del risultato della query. Dovreste avere solo un elemento restituito: usate l’aggregazione se necessario. Nell’esempio sopra, usiamo il metodoformat
per impostare il testo della query, e la funzionequery_to_geojson
per restituire il GeoJSON per questa query.Puoi usare tutti i parametri dati (nome dell’azione, schema dei dati sorgente e nome della tabella, id dell’elemento, nome del livello QGIS) per creare la query appropriata per la tua azione, usando le clausole PostgreSQL
IF THEN ELSIF ELSE
. Vedi il contenuto della variabileparameters
nell’esempio sopra, che contiene alcune delle proprietà del file di configurazione JSON e alcune proprietà del livello QGIS:il nome dell’azione
action_name
, per esempiobuffer_500
. Dovresti usare una parola semplice con solo lettere, cifre e_
,QGIS nome del livello (come in leggenda QGIS):
layer_name
, per esempioPunti
,la tabella PostgreSQL schema
layer_schema
e nome della tabellalayer_table
per questo livello,l’oggetto id elemento
feature_id
, che corrisponde al valore del campo chiave primaria dell’oggetto popup,le altre proprietà fornite nel file di configurazione JSON, nella proprietà
options
, comebuffer_size
che è500
nell’esempio
Il
IF ELSE
viene usato per fare una query diversa, costruita nella variabiledatasource
, controllando l” action nameSe i dati restituiti contengono un campo
message
, come mostrato nell’esempio precedente, il testo contenuto in questo campo sarà visualizzato nella mappa in un messaggio a fumetto.La geometria restituita dalla funzione sarà visualizzata sulla mappa.
Potresti usare la tua funzione per modificare alcuni dati nel tuo database, prima di restituire un GeoJSON. Per farlo, devi sostituire la proprietà
IMMUTABLE
conVOLATILE
. Per favore utilizzalo con cura !
Dato che Lizmap Web Client innesca un evento actionResultReceived
ogni volta che l’utente clicca su un pulsante di azione, e i dati vengono restituiti ( nello stesso momento in cui la geometria del risultato viene disegnata sulla mappa), si potrebbe usare il proprio codice Javascript per aggiungere della logica dopo che il risultato viene mostrato.
Vedi anche
Capitolo Aggiungere il proprio JavaScript
Per esempio, qui ci limitiamo a scrivere nella console del browser il contenuto ricevuto:
lizMap.events.on({
actionResultReceived: function(e) {
// QGIS Layer id
var layerId = e.layerId;
console.log('Layer ID = ' + layerId);
// Feature ID, which means the value of the primary key field
var featureId = e.featureId;
console.log('Feature ID = ' + featureId);
// Action item with its name and other properties: name, title, options, styles, etc.
var action = e.action;
console.log('Action properties = ');
console.log(action);
// Features returned by the action
var features = e.features;
console.log('Returned object = ');
console.log(features);
}
});
Potete usare questi dati come preferite nel vostro codice JS.