Actions — Add some custom buttons
Tato funkce je součástí aplikace Lizmap 3.4.
Princip
Tento modul umožňuje přidat jedno nebo více akčních tlačítek do vyskakovacího okna Lizmap zobrazeného pro objekt PostgreSQL, které spustí dotaz v databázi a vrátí geometrii pro zobrazení na mapě.
Čte konfigurační soubor JSON, který musí být umístěn vedle projektu QGIS ve stejném adresáři. Tento soubor obsahuje seznam akcí PostgreSQL, které mají být přidány do popupu pro jednu nebo více vektorových vrstev QGIS PostgreSQL.
Konfigurace nástroje
Každá akce je charakterizována pomocí
layer id
,name
,title
,icon
, lze použít některé volitelné vlastnostioptions
,style
,callbacks
aconfirm
.Vrstva může mít jednu nebo více akcí.
Můžete mít jednu nebo více vrstev s vlastními akcemi.
Příklad tohoto konfiguračního souboru JSON, název myproject.qgs.action
, pokud se soubor projektu QGIS jmenuje myproject.qgs
. V tomto projektu existuje vektorová vrstva s názvem Points
s interním ID vrstvy points_a7e8943b_7138_4788_a775_f94cbd0ad8b6
(interní ID vrstvy QGIS můžete získat pomocí výrazu @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"}
]
}
]
}
Konfigurační soubor JSON obsahuje seznam vrstev QGIS, pro které chcete deklarovat akce. Každá vrstva je definována svým ID vrstvy QGIS, například zde points_a7e8943b_7138_4788_a775_f94cbd0ad8b6
, a pro každé ID seznam objektů popisujících akce, které mají být povoleny.
Každá akce je objekt definovaný:
a
name
, což je identifikátor akce.title
, který se používá jako popisek v rozhraní Lizmapikona
, která se zobrazí na akčním tlačítku ( viz https://getbootstrap.com/2.3.2/base-css.html#icons ).nepovinná vlastnost
potvrzení
, od Lizmap 3.5 obsahující nějaký text. Je-li nastavena, zobrazí se uživateli potvrzovací dialogové okno s dotazem, zda má být akce skutečně spuštěna, nebo ne. Použijte ji, pokud akce může změnit některá data v databázi.objekt
options
, který udává některé další parametry pro tuto akci. Můžete přidat libovolný potřebný parametr.objekt
style
umožňující konfigurovat vrácený styl geometrie. Řídí se atributy stylů OpenLayers.objekt
callbacks
umožňuje spustit některé akce po vrácení vygenerované geometrie. Jsou definovány jménemmethod
, které v současnosti může být:zoom
: přiblížení vrácené geometrieselect
: vybere prvky z dané vrstvy, které protínají vrácenou geometrii. Ve vlastnostilayerId
musí být přidáno interní ID cílové vrstvy QGIS. V příkladu budou vybrány prvky vrstvy obsahující budovy s IDbati_1a016229_287a_4b5e_a4f7_a2080333f440
.redraw
: překreslí (obnoví) danou vrstvu v mapě. ID cílové vrstvy QGIS musí být přidáno do vlastnostilayerId
.
Lizmap zjistí přítomnost tohoto konfiguračního souboru a při načítání mapy přidá potřebnou logiku. Když uživatelé kliknou na objekt jedné z těchto vrstev v mapě, zobrazí se na rozbalovacím panelu údaje o prvku. V horní části každého vyskakovacího panelu se na panelu nástrojů zobrazí jedno tlačítko pro každou akci vrstvy. Po najetí na tlačítko akce se zobrazí její název
.
Každé tlačítko spustí příslušnou akci, pokud ještě není aktivní (jinak se deaktivuje a geometrie se vymaže):
Backend Lizmap kontroluje, zda je akce dobře nakonfigurována,
vytvoří dotaz PostgreSQL a provede jej ve vrstvě databáze PostgreSQL. (Viz příklad níže)
Tento dotaz vrátí GeoJSON, který se poté zobrazí na mapě.
Pokud byly nakonfigurovány některé zpětné odkazy, spustí se.
Od Lizmap 3.5 je emitována událost Lizmap
actionResultReceived
s vrácenými daty a vlastnostmi akce.
Vytvořený dotaz PostgreSQL je sestaven webovým klientem Lizmap a používá funkci PostgreSQL lizmap_get_data(json)
, která musí být předem vytvořena v databázi PostgreSQL. Tato funkce také používá obecnější funkci query_to_geojson(text)
, která transformuje libovolný řetězec dotazu PostgreSQL na výstup GeoJSON.
Níže je uveden příklad dotazu, který interně provede Lizmap Web Client v databázi PostgreSQL pro výše uvedenou příkladovou konfiguraci, když uživatel klikne na tlačítko akce buffer_500`, pro funkci s id 1
vrstvy Points
odpovídající tabulce 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;
Vidíte, že Lizmap vytvoří parametry JSON se všemi potřebnými informacemi a spustí funkci PostgreSQL lizmap_get_data(text)
.
Je třeba vytvořit tuto funkci PostgreSQL lizmap_get_data(text)
, která vrátí platný text GeoJSON s jedním jediným objektem. Následující kód SQL je příkladem, který vám pomůže vytvořit potřebné funkce. Je zřejmé, že je třeba jej upravit podle svých potřeb.
-- 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.';
Jako příklad je zde uvedena funkce
lizmap_get_data(json)
. Jelikož se jedná o klíčový vstupní bod, musíte si ji přizpůsobit svým potřebám. Jejím cílem je vytvořit dotaz pro každý název akce, dynamicky vytvořený pro zadané parametry, a vrátit reprezentaci dat výsledku dotazu ve formátu GeoJSON. Měli byste mít vrácenou pouze jednu funkci: v případě potřeby použijte agregaci. Ve výše uvedeném příkladu použijeme metoduformát
pro nastavení textu dotazu a funkciquery_to_geojson
pro vrácení formátu GeoJSON pro tento dotaz.Pomocí klauzulí PostgreSQL
IF THEN ELSIF ELSE
můžete použít všechny zadané parametry (název akce, schéma zdrojových dat a název tabulky, ID prvku, název vrstvy QGIS) k vytvoření vhodného dotazu pro vaši akci (akce). Viz obsah proměnnéparameters
ve výše uvedeném příkladu, která obsahuje některé vlastnosti konfiguračního souboru JSON a některé vlastnosti vrstvy QGIS:název akce
název_akce
, napříkladbuffer_500
. Měli byste použít jednoduché slovo obsahující pouze písmena, číslice a_
,QGIS název vrstvy (jako v legendě QGIS):
název_vrstvy
, napříkladBody
,schema tabulky PostgreSQL
layer_schema
a název tabulkylayer_table
pro tuto vrstvu,id objektu feature
feature_id
, které odpovídá hodnotě pole primární klíč pro vyskakovací objekt,další vlastnosti uvedené v konfiguračním souboru JSON ve vlastnosti
options
, napříkladbuffer_size
, která je v příkladu500
.
Příkaz
IF ELSE
slouží k provedení jiného dotazu, sestaveného v proměnnédatasource
, a to kontrolou názvu akce.Pokud vrácená data obsahují pole
zpráva
, jak je uvedeno v příkladu výše, text obsažený v tomto poli se zobrazí v mapě v bublině se zprávou.Geometrie vrácená funkcí se zobrazí na mapě.
Funkci můžete použít k úpravě některých dat v databázi a teprve poté vrátit soubor GeoJSON. K tomu je třeba nahradit vlastnost
IMMUTABLE
zaVOLATILE
. Používejte ji prosím opatrně !
Vzhledem k tomu, že Lizmap Web Client spouští událost actionResultReceived
pokaždé, když uživatel klikne na tlačítko akce, a data jsou vrácena (ve stejnou dobu, kdy je geometrie výsledku vykreslena na mapě), můžete použít vlastní kód Javascriptu a přidat nějakou logiku po zobrazení výsledku.
Viz také
Kapitola Přidání vlastního JavaScriptu
Například zde pouze zapíšeme do konzoly prohlížeče přijatý obsah:
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);
}
});
Tyto údaje můžete libovolně použít v kódu JS.