Création d’une base de données Geopackage pour les cartes ENC (2ème partie: ajouter la symbologie)

La première partie du projet Financement Collaboratif pour l’Intégration de Données Marines dans QGIS est arrivée à son terme grâce aux contributions d’ORANGE Marine, Geoconceptos Uruguay, Janez Avzec et Gaetan Mas. Nous les remercions vivement. Nous publions donc le contenu final de cette partie du travail.
La première partie concerne la création et la gestion de la base de données, vous trouverez ici la deuxième partie avec la symbologie S57 sous QGis.

Ajout de la symbologie au Geopackage

La symbologie par défaut des tables d’un geopackage est contenue dans une table nommée layer_styles qui n’est créée que si vous utilisez l’option enregistrer par défaut du bouton style.

Après le clonage des tables dans le fichier ENC, la table n’existe pas. Nous allons donc importer la table contenant toute la symbologie des cartes ENC.

Attention: la table layer_styles est une table système, contrairement à la table natsurf qui est un simple table de données. A différence des tables de données, les tables système n’apparaissent pas dans le panneau explorateur. Vous devez tiliser le Gestionnaire de bases de données de QGis (menu Base de données -> DB Manager) pour voir et manipuler les tables systèmes comme layer_styles. Par contre natsurf sera visible et manipulable comme toute autre couche de données.

Télécharger layer_natsurfV1.gpkg

Ce geopackage contient une table, nommée layer_styles, avec les définitions de symbologies de 153 tables S57 ainsi qu’une table nommée natsurf qui sera utilisée pour la mise en forme du rendu de la table « nature des fonds marins » (SBDARE).

Pour intégrer ces tables dans votre fichier ENC (ici ENC.gpkg):

Dans QGis ouvrez le gestionnaire de base de données.

  1. Vous devriez avoir déjà la connexion geopackage->ENC.gpkg, si ce n’est pas le cas: bouton droit sur ‘Geopackage‘->nouvelle connexion, puis pointez sur votre fichier ENC.gpkg
  2. Connectez-vous à la table layers_natsurf.gpkg téléchargée (bouton droit sur ‘Geopackage‘->nouvelle connexion, puis pointez sur le geopackage téléchargé)
  3. Sélectionnez layer_styles dans layers_natsurf.gpkg puis bouton droit->ajouter au canevas.Vous aurez la table layer_styles dans la liste des couches chargées.
  4. Sélectionnez natsurf dans layers_natsurf.gpkg puis bouton droit->ajouter au canevas.Vous aurez la table natsurf dans la liste des couches chargées.
  5. Sélectionnez le geopackage ENC.gpkg dans le gestionnaire de base de données.
  6. Dans le menu Table, sélectionnez Import de couche/fichier
  7. Dans la liste des couches sélectionnez natsurf, puis OK
  8. Répétez l’opération pour la couche layer_styles.

La version actuelle de layer_styles contient les mises en forme de symbologie de 153 couches. Pensez à vérifier régulièrement s’il n’y a pas des mises à jour disponibles au téléchargement.

Cette symbologie utilise des symboles svg que vous devez télécharger sur votre machine. En cliquant ici vous téléchargerez un répertoire ‘nautical’ contenant tous les symboles svg nécessaires ainsi qu’un répertoire nommé « XML » avec des symboles supplémentaires pour QGis.

Symboles SVG

Par défaut, les références aux symboles svg sont faites vers un répertoire ‘C:/nautical‘. Vous avez plusieurs possibilités:

1- Décompresser le fichier nautical dans un répertoire c:/nautical de votre machine

Dans ce cas vous n’avez plus rien à faire. Les layer_styles trouveront les symboles svg sans problème.

2- Vous souhaitez enregistrer le répertoire nautical dans un répertoire de votre choix

Dans ce cas, vous devez modifier la table layer_styles pour qu’elle trouve les symboles.

Ouvrez le gestionnaire de base de données de QGis.

  1. Sélectionnez la table layer_styles de votre geopackage
  2. Ouvrez une fenêtre SQL
  3. Entrez la requête:
    UPDATE layer_styles
    SET styleQML = REPLACE(styleQML, ‘C:/nautical’, ‘Votre chemin’);
  4. Cliquez sur le bouton Exécuter

3- Vous souhaitez enregistrer le répertoire nautical dans le répertoire de votre geopackage ENC

Dans ce cas, les références aux symboles svg seront relatives au Geopackage et vous pourrez l’utiliser à partir de plusieurs machines. On fera alors la même démarche que précédemment mais la requête SQL sera:

UPDATE layer_styles
SET styleQML = REPLACE(styleQML, ‘C:/nautical’, ‘nautical’);

Bien sûr, il faut que le projet soit configuré pour stocker les chemins relatifs (Propriétés du projet -> Général->Enregistrer les chemins->Relatif) et le fichier projet (.qgz) doit se trouver dabns le répertoire du geopackage. C’est bien les chemins relatifs au projet qui sont stockés et pas les chemins des geopackages.

Symboles XML

Les symboles XML téléchargés correspondent à des symbologies QGis supplémentaires. Elles sont utilisées dans les mises en forme de certains des symboles S57. Vous pouvez les rechercher et les installer à partir de leur entrepôts classiques, mais pour simplifier le travail nous avons mis tous les fichiers XML nécessaires dans le fichier en téléchragement.

Pour cela,

  1. ouvrez le gestionnaire de style (Préférences->Gestionnaire de style)
  2. Cliquez sur le bouton Importer/Exporter
  3. Dans le champ Fichier, pointez sur le fichier XML à charger, puis cliquez sur Importer
  4. Répétez l’opération pour tous les fichiers XML téléchargés

Quelques symbologies particulières

La grande majorité des symbologies des couches S57 ne nécessitent aucun soin particulier. La symbologie est définie par défaut dans le geopackage et elle est chargée et affichée automatiquement.
Mais il y a trois couches qui nécessitent une attention particulière.

1- La couche LIGHTS (feux)

Les différents feux présents sur les cartes ENC peuvent être de deux types: des feux à secteurs, c’est à dire que la couleur du feu est différente selon l’angle à partir duquel on l’observe, ou des feux simples, visibles sur les 360°.

D’autre part, la symbologie utilisée sur les cartes marines papier et celle utilisé par les logiciels de visualisation de ENC numériques n’est pas la même.

La symbologie que nous avons mis en place répond à tous ces critères.

Quand vous chargez la couche LIGHTS vsou aurez dans le panneau des couches:

Par défaut c’est la symbologie des visualisateurs ENC qui et affichée.

La première ligne correspond aux feux à secteur, la deuxième aux feux simples.

Pour ce qui est des feux à secteur, la symbologie est la même que ce soit un visualisateur ou une carte papier. Par contre pour les feux simples, vous pouvez choisir le type de symbologie. Si vous décochez la deuxième ligne et que vous cochez la troisième, vous aurez alors une symbologie de type « papier »:

La couche SOUNDG (sondes bathymétriques)

L’affichage des valeurs des sondes dépend de la qualité de celles-ci: si elles sont fiables, la police de caratère doit être de type italique, par contre si elles ne le sont pas complètement elles doivent être affichées avec une police regular.

La qualité des sondes est stockée dans la couche M_QUAL de fichiers S57.

Par défaut la symbologie de la couche SOUNDG prend en compte la qualité des sondes. Il faut donc, obligatoirement, charger la couche pl_M_QUAL dans le projet QGis. Celle-ci est invisible lors de l’affichage mais est utilisée par l’étiquettage des entités de SOUNDG:

Le processus fait intervenir un croisement entre les deux couches pour obtenir, à partir des polygones pl_M_qual, la valeur de qualité pour chaque sonde. Forcément, le nombre de sondes peut faire que cette étape soit assez longue. Si vous travaillez avec des zones importantes et un nombre de sondes élevé, vous pouvez choisir de ne pas prendre en compte la qualité. Pour cela, téléchargez le fichier qml suivant: soundg.qml. Vous aurez les deux fichiers qml: celui qui utilise M_qual et celui qui ne l’utilise pas.

Ouvrez les propriétés de la couche SOUNDG, cliquez sur le bouton Style (en bas, à gauche) puis sur charger un style et pointez sur le fichier téléchargé. Toutes les sondes seront affichées très rapidement sans prendre en compte la qualité.

La couche SBDARE (nature des fonds)

La gestion de la symbologie de cette couche est assez compliquée car elle comporte le traitement de deux champs de type liste. Il faut combiner la liste des natures de fond avec la granulométrie de chaque fraction.

Le code suivant est l’expression pour générer les étiquettes qui est incluse par défaut:

étiquettes SBDARE

CASE 
  WHEN regexp_substr("NATSUR", '\\((\\d+):') = '1'THEN 
	CASE
		WHEN "NATQUA" IS NOT NULL THEN  
		with_variable('NTS',lpad(regexp_substr("NATSUR", ':(\\d+)'),2,'  ') || lpad(regexp_substr("NATQUA", ':(\\d+)'),2,'  '),
			aggregate(layer:= 'natsurf',aggregate:='max',expression:= "ETIQ",
			filter:= "NATQUAT" = trim(right(@NTS,2)) AND "NATSURT" = trim(left(@NTS,2))))
		WHEN "NATQUA" IS NULL THEN  
		with_variable('NTS',regexp_substr("NATSUR", ':(\\d+)'),
			aggregate(layer:= 'natsurf',aggregate:='max',expression:= "ETIQ",
			filter:= "NATQUAT" IS NULL AND "NATSURT" = @NTS))
		ELSE '?'
		
	END
 WHEN regexp_substr("NATSUR", '\\((\\d+):') = '2' THEN 
	CASE
		WHEN  regexp_substr("NATQUA", '\\((\\d+):') = '1' THEN  
		with_variable('NTS',lpad(regexp_substr("NATSUR", ':(\\d+)'),2,'  ') || lpad(regexp_substr("NATQUA", ':(\\d+)'),2,'  '),
			aggregate(layer:= 'natsurf',aggregate:='max',expression:= "ETIQ",
			filter:= "NATQUAT" = trim(right(@NTS,2)) AND "NATSURT" = trim(left(@NTS,2))))  || '.'  || with_variable('NTS2',regexp_substr("NATSUR", ',(\\d+)'),
			aggregate(layer:= 'natsurf',aggregate:='max',expression:= "ETIQ",
			filter:= "NATQUAT" IS NULL AND "NATSURT" = @NTS2))
			
		WHEN "NATQUA" IS NULL THEN  
		with_variable('NTS',regexp_substr("NATSUR", ':(\\d+)'),
			aggregate(layer:= 'natsurf',aggregate:='max',expression:= "ETIQ",
			filter:= "NATQUAT" IS NULL AND "NATSURT" = @NTS))  || '.' || 
			with_variable('NTS2',regexp_substr("NATSUR", ',(\\d+)'),
			aggregate(layer:= 'natsurf',aggregate:='max',expression:= "ETIQ",
			filter:= "NATQUAT" IS NULL AND "NATSURT" = @NTS2))
		WHEN  regexp_substr("NATQUA", '\\((\\d+):') = '2' THEN  
	 with_variable('NTS',lpad(regexp_substr("NATSUR", ':(\\d+)'),2,'  ') || lpad(regexp_substr("NATQUA", ':(\\d+)'),2,'  '),
			aggregate(layer:= 'natsurf',aggregate:='max',expression:= "ETIQ",
			filter:= "NATQUAT" = trim(right(@NTS,2)) AND "NATSURT" = trim(left(@NTS,2))))  || '.'  || 
			with_variable('NTS2',lpad(regexp_substr("NATSUR", ',(\\d+)'),2,'  ') || lpad(regexp_substr("NATQUA", ',(\\d+)'),2,'  '),
			aggregate(layer:= 'natsurf',aggregate:='max',expression:= "ETIQ",
			filter:= "NATQUAT" = trim(right(@NTS2,2)) AND "NATSURT" = trim(left(@NTS2,2))))
			end
WHEN regexp_substr("NATSUR", '\\((\\d+):') = '3' THEN 	 
		CASE
		WHEN  regexp_substr("NATQUA", '\\((\\d+):') = '1' THEN  
		with_variable('NTS',lpad(regexp_substr("NATSUR", ':(\\d+)'),2,'  ') || lpad(regexp_substr("NATQUA", ':(\\d+)'),2,'  '),
			aggregate(layer:= 'natsurf',aggregate:='max',expression:= "ETIQ",
			filter:= "NATQUAT" = trim(right(@NTS,2)) AND "NATSURT" = trim(left(@NTS,2))))  || '.'  || with_variable('NTS2',regexp_substr("NATSUR", ',(\\d+)'),
			aggregate(layer:= 'natsurf',aggregate:='max',expression:= "ETIQ",
			filter:= "NATQUAT" IS NULL AND "NATSURT" = @NTS2))|| '.' || 
			with_variable('NTS3',regexp_substr("NATSUR", ',(\\d+)\\)'),
			aggregate(layer:= 'natsurf',aggregate:='max',expression:= "ETIQ",
			filter:= "NATQUAT" IS NULL AND "NATSURT" = @NTS3) )
			
		WHEN "NATQUA" IS NULL THEN  
		with_variable('NTS',regexp_substr("NATSUR", ':(\\d+)'),
			aggregate(layer:= 'natsurf',aggregate:='max',expression:= "ETIQ",
			filter:= "NATQUAT" IS NULL AND "NATSURT" = @NTS))  || '.' || 
			with_variable('NTS2',regexp_substr("NATSUR", ',(\\d+)'),
			aggregate(layer:= 'natsurf',aggregate:='max',expression:= "ETIQ",
			filter:= "NATQUAT" IS NULL AND "NATSURT" = @NTS2))|| '.' || 
			with_variable('NTS3',regexp_substr("NATSUR", ',(\\d+)\\)'),
			aggregate(layer:= 'natsurf',aggregate:='max',expression:= "ETIQ",
			filter:= "NATQUAT" IS NULL AND "NATSURT" = @NTS3) )
		WHEN  regexp_substr("NATQUA", '\\((\\d+):') = '2' THEN  
	 with_variable('NTS',lpad(regexp_substr("NATSUR", ':(\\d+)'),2,'  ') || lpad(regexp_substr("NATQUA", ':(\\d+)'),2,'  '),
			aggregate(layer:= 'natsurf',aggregate:='max',expression:= "ETIQ",
			filter:= "NATQUAT" = trim(right(@NTS,2)) AND "NATSURT" = trim(left(@NTS,2))))  || '.'  || 
			with_variable('NTS2',lpad(regexp_substr("NATSUR", ',(\\d+)'),2,'  ') || lpad(regexp_substr("NATQUA", ',(\\d+)'),2,'  '),
			aggregate(layer:= 'natsurf',aggregate:='max',expression:= "ETIQ",
			filter:= "NATQUAT" = trim(right(@NTS2,2)) AND "NATSURT" = trim(left(@NTS2,2)))) || '.' || 
			with_variable('NTS3',regexp_substr("NATSUR", ':(\\d+)'),
			aggregate(layer:= 'natsurf',aggregate:='max',expression:= "ETIQ",
			filter:= "NATQUAT" IS NULL AND "NATSURT" = @NTS3) )
		WHEN  regexp_substr("NATQUA", '\\((\\d+):') = '3' THEN  
	 with_variable('NTS',lpad(regexp_substr("NATSUR", ':(\\d+)'),2,'  ') || lpad(regexp_substr("NATQUA", ':(\\d+)'),2,'  '),
			aggregate(layer:= 'natsurf',aggregate:='max',expression:= "ETIQ",
			filter:= "NATQUAT" = trim(right(@NTS,2)) AND "NATSURT" = trim(left(@NTS,2))))  || '.'  || 
			with_variable('NTS2',lpad(regexp_substr("NATSUR", ',(\\d+)\\)'),2,'  ') || lpad(regexp_substr("NATQUA", ',(\\d+)\\)'),2,'  '),
			aggregate(layer:= 'natsurf',aggregate:='max',expression:= "ETIQ",
			filter:= "NATQUAT" = trim(right(@NTS2,2)) AND "NATSURT" = trim(left(@NTS2,2)))) || '.' || 
			with_variable('NTS4',lpad(regexp_substr("NATSUR", ',(\\d+)'),2,'  ') || lpad(regexp_substr("NATQUA", ',(\\d+)'),2,'  '),
			aggregate(layer:= 'natsurf',aggregate:='max',expression:= "ETIQ",
			filter:= "NATQUAT" = trim(right(@NTS4,2)) AND "NATSURT" = trim(left(@NTS4,2))))
			end
		
END
   

Ce code a été simplifié (eh oui!) grâce au stockage des 143 combinaisons possibles de nature et fraction dans une table externe: natsurf.

Pour que la symbologie fonctionne il faut impérativement ajouter la table natsurf à la liste des couches du projet:

BONUS: Quelques moyens de travailler avec des couches nombreuses

Charger toutes les couches du Geopackage

Vous pouivez charger directement toutes les couches du Geopackage en cliquant-glissant le nom du geopackage depuis le panneau explorateur vers le panneau couches.

Une fenêtre s’ouvre ou vous pouvez sélectionner quelles couches vous voulez charger. Pour charger la totalité des couches, simplement cliquez sur Sélectionner tout, puis sur Ajouter une couche.

La totalité des couches est alors chargée. Selon le nombre de fichiers S57 chargé dans votre base, la mise en forme de la fenêtre peut prendre beaucoup de temps.

Les couches qui consomment beaucoup de ressources c’est les couches que nous avons vu plus haut (feux, sondes et nature du fond). Vous pouvez les décocher pour accélérer le chargement.

Un autre moyen, plus efficace est de définir l’échelle minimum d’affichage de vos couches. Avec 150 couches chargées, les définir une par une est exclu. Nous mettons à votre disposition un script Python qui permet de définir l’échelle minimum d’affichage pour toutes les couches sélectionnées dans le panneau Couches. Une fois enregistré votre projet, ces paramètres seront utilisés à chaque ouverture du projet.

Modifiez la ligne min_scale= pour mettre l’échelle minimale d’affichage en fonction de vos données.

Le script Python pour définir l’échelle minimum d’affichage des couches sélectionnées est le suivant:

setminscale.py

# Récupérer la vue des couches
layer_tree_view = iface.layerTreeView()

# Récupérer les couches sélectionnées
selected_layers = layer_tree_view.selectedLayers()

# Définir l'échelle minimale pour chaque couche sélectionnée
for layer in selected_layers:
    # Définir l'échelle minimale (par exemple, 1:50000)
    min_scale = 250000
    
    # Définir l'échelle minimale d'affichage pour la couche
    layer.setScaleBasedVisibility(True)
    layer.setMinimumScale(min_scale)
    print(f"L'échelle d'affichage de la couche {layer.name()} a été définie sur {min_scale}.")

[/stextbox ]

Vous pouvez le télécharger ici.

Le projet de base de données S57 avec Geopackage est arrivé à son terme. Nous entamons maintenant la mise en place d’une procédure équivalente en utilisant une base de données PostgreSQL/Postgis. Aidez-nous à mener à terme ce projet!

Si cet article vous a intéressé et que vous pensez qu'il pourrait bénéficier à d'autres personnes, n'hésitez pas à le partager sur vos réseaux sociaux en utilisant les boutons ci-dessous. Votre partage est apprécié !

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *