Rencontres des Utilisateurs Francophones de QGIS
Clermont-Ferrand - 13/03/2023
Julien Cabieces / Julien Moura
![]() |
Julien Cabieces Developpeur C++/Python QGIS Core committer |
Julien Moura Developpeur Python Pigiste @ GeoTribu |
![]() |
NM Relation
Les aéroports ont des companies aériennes...
et les companies aériennes ont des aéroports
Voir QGIS doc pour plus d'informations
Créer la base
createdb pgqgis_tips
Vérifier que l'on peut s'y connecter
psql pgqgis_tips
Récupérer le fichier airports.sql et chargez le
psql pgqgis_tips -f airports.sql
Qu'observez-vous ?
Essayer d'ajouter KLM (à Amsterdam) depuis le formulaire enfant de l'aéroport Toulouse
Qu'observez-vous?
nextval('locations.airports_airlines_id_seq'::regclass)
Re-Essayer d'ajouter KLM (à Amsterdam) depuis le formulaire enfant de l'aéroport Toulouse
⚠️NE PAS SAUVEGARDER⚠️
Qu'observez-vous?
Depuis une console psql
pgqgis_tips=# select * from locations.airlines;
Qu'observez vous?
Puis relancer la même requête aprés sauvegarde.
pgqgis_tips=# update locations.airports set airport_name = 'Toulouse or not to lose!' where id = 1;
Qu'observez vous?
Puis sauvegardez.
Re-Re-Essayer d'ajouter Turkish Airlines (à Istanbul) depuis le formulaire enfant de l'aéroport de Lyon
⚠️NE PAS SAUVEGARDER⚠️
Qu'observez-vous?
Depuis une console psql
pgqgis_tips=# select * from locations.airlines;
Qu'observez vous?
Puis relancer la même requête aprés sauvegarde.
pgqgis_tips=# update locations.airports set airport_name = 'Toulouse or not to lose!' where id = 1;
Qu'observez vous?
Puis sauvegardez.
à Nantes!
pgqgis_tips=# insert into locations.airports (airport_name, geom) values( 'Nantes', st_geomfromtext('POINT(-1.5546 47.2191)', 4326));
ou supprimer
delete from locations.airports where id = 6
Rien ne se passe: on doit rafraichir ou se déplacer dans la carte!
CREATE FUNCTION notify_modified_airports() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
NOTIFY qgis, 'airports_modified';
RETURN NULL;
END;
$$;
CREATE TRIGGER notify_modified_airports
AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE ON locations.airports
FOR EACH STATEMENT EXECUTE PROCEDURE notify_modified_airports();
QGIS se met à jour tout seul!
Par exemple: depuis la console Python (Extensions > Console Python)
def onNotify():
iface.messageBar().pushInfo("Notification", "Les aéroports ont été modifiés 😱 !!")
iface.activeLayer().dataProvider().notify.connect(onNotify)
*Dans les limites de ce que propose l'API QGIS
Ajouter une anotation pour chaque nouvelle compagnie aérienne
Envoie l'id de la nouvelle ligne...
CREATE FUNCTION notify_new_airlines() RETURNS trigger
LANGUAGE plpgsql
AS $$
DECLARE
v_txt text;
BEGIN
v_txt := format('new_airlines %s', NEW.id);
PERFORM pg_notify('qgis', v_txt);
RETURN NULL;
END;
$$;
CREATE TRIGGER notify_modified_airports
AFTER INSERT ON locations.airlines
FOR EACH ROW EXECUTE PROCEDURE notify_new_airlines();
Pour chaque ligne
Un petit peu de Python et d'API QGIS
def createAnnotationOnNotify(msg):
id = int(msg[13:len(msg)])
airlines = QgsProject.instance().mapLayersByName("airlines")[0]
new_feat = airlines.getFeature(id)
annotation = QgsTextAnnotation()
annotation.setDocument(QTextDocument("✨✨Nouvelle compagnie {} ici !! ✈✈ ".format(new_feat["airline_name"])))
annotation.setMapPosition(new_feat.geometry().asPoint())
annotation.setMapPositionCrs(airlines.sourceCrs())
annotation.setFrameSizeMm(QSizeF(50,25))
QgsProject.instance().annotationManager().addAnnotation( annotation );
QgsProject.instance().mapLayersByName("airlines")[0].dataProvider().notify.connect(createAnnotationOnNotify)
et c'est bon
pgqgis_tips=# insert into locations.airlines (airline_name, geom) values( 'Iberia', st_geomfromtext('POINT(2.1512 41.3894)', 4326));
Envoyer la sortie d'un traitement directement en base de données
... sur les compagnies aériennes, directement en base
Pourquoi? Je sais pas mais c'est joli🌺🌸
pgqgis_tips=# \d locations.voronoi
Table « locations.voronoi »
Colonne | Type | Collationnement | NULL-able | Par défaut
--------------+------------------------+-----------------+-----------+------------
id | integer | | not null |
geom | geometry(Polygon,4326) | | |
airline_name | character varying | | |
Index :
"voronoi_pkey" PRIMARY KEY, btree (id)
pgqgis_tips=# select count(*) from locations.voronoi;
count
-------
8
(1 ligne)
Et vérifier ce qui se passe en base
Préférer l'accés depuis l'explorateur chaque fois que c'est possible!
Projet > Enregistrer sous > PostgreSQL...
Projet > Ouvrir depuis > PostgreSQL...
pgqgis_tips=# \d locations.qgis_projects
Table « locations.qgis_projects »
Colonne | Type | Collationnement | NULL-able | Par défaut
----------+-------+-----------------+-----------+------------
name | text | | not null |
metadata | jsonb | | |
content | bytea | | |
Index :
"qgis_projects_pkey" PRIMARY KEY, btree (name)
pgqgis_tips=# select name, metadata from locations.qgis_projects ;
name | metadata
------------+--------------------------------------------------------------------------------------
mon_projet | {"last_modified_time": "2023-03-09 10:44:45.330186", "last_modified_user": "julien"}
(1 ligne)
Vous pouvez embarquer un fichier externe dans le projet (SVG par exemple)
Temps total d'exécution en ms
jq '[.[]."Temps total (ms)" | tonumber] | add' ~/test.json
Requêtes différentes
jq -r '.[]."SQL"' ~/test.json | grep -v "CLOSE qgis_" |grep -v "FETCH FORWARD " | sed "s/\\\\//g" | sed "s/BEGIN READ ONLY.*CURSOR FOR //" | sort | uniq -c
Requêtes triées par temps d'exécution
jq -r '.[] | [ ."Temps total (ms)", ."SQL"]|join(" ")' ~/test.json | grep -v "CLOSE qgis_" |grep -v "FETCH FORWARD " | sed "s/\\\\//g" | sed "s/BEGIN READ ONLY.*CURSOR FOR //" | sort -nr
Rencontres des Utilisateurs Francophones de QGIS
Clermont-Ferrand - 13/03/2023
Julien Cabieces / Julien Moura