Creación de una base de datos Geopackage para mapas ENC (parte 2: añadir simbología)

Se ha completado la primera parte del proyecto de Financiación Colaborativa para la Integración de Datos Marinos en QGIS, gracias a las contribuciones de ORANGE Marine, Geoconceptos Uruguay, Janez Avzec y Gaetan Mas. Nuestro más sincero agradecimiento a todos ellos. A continuación publicamos el contenido final de esta parte del proyecto.
La primera parte trata de la creación y gestión de la base de datos, y esta segunda parte de la simbología S57 en QGis.

Añadir simbología a un geopackage

La simbología por defecto para las tablas de un geopackage está contenida en una tabla llamada layer_styles, que sólo se crea si se utiliza la opción guardar por defecto en el botón de estilos.

Después de clonar las tablas en el archivo ENC, la tabla no existe. Así que vamos a importar la tabla que contiene toda la simbología para los mapas ENC.

Descargar layer_natsurfV1.gpkg

Este geopackage contiene una tabla, denominada layer_styles, con las definiciones de simbología para todas las tablas S57, así como una tabla denominada natsurf que se utilizará para formatear el renderizado de la tabla «naturaleza del fondo marino» (SBDARE).

Para integrar estas tablas en su archivo ENC (aquí ENC.gpkg):

En QGis, abra el gestor de base de datos.

  1. Ya deberías tener la conexión geopackage->ENC.gpkg, si no es así: haz clic con el botón derecho en ‘Geopackage’->nueva conexión, luego apunta a tu archivo ENC.gpkg.
  2. Conéctese a la tabla layers_natsurf.gpkg descargada (haga clic con el botón derecho en ‘Geopackage’->new connection, luego apunte al geopackage descargado)
  3. Selecciona layer_styles en layers_natsurf.gpkg luego click derecho->add to canvas y tendrás la tabla layer_styles en la lista de capas cargadas.
  4. Seleccione natsurf en layers_natsurf.gpkg y haga clic con el botón derecho del ratón->añadir al lienzo y tendrá la tabla natsurf en la lista de capas cargadas.
  5. Seleccione el geopackage ENC.gpkg en el gestor de base de datos.
  6. En el menú Tabla, seleccione Importar capa/archivo
  7. En la lista de capas, seleccione layer_styles, luego OK
  8. Repita la operación para la capa natsurf.

La versión actual de layer_styles contiene diseños de simbología para 132 capas. Recuerde comprobar regularmente si hay actualizaciones disponibles para su descarga.

Esta simbología utiliza símbolos svg que debe descargar en su máquina. Haga clic aquí para descargar un directorio ‘nautical’ que contiene todos los símbolos svg que necesita, además de un directorio llamado ‘XML’ con símbolos adicionales para QGis.

Símbolos SVG

Por defecto, las referencias a los símbolos svg se hacen a un directorio ‘C:/nautical’. Tienes varias opciones:

1- Descomprime el archivo nautical en un directorio c:/nautical en tu máquina.

Entonces no necesitas hacer nada más. El layer_styles encontrará los símbolos svg sin ningún problema.

2- Quieres guardar el directorio nautical en un directorio de tu elección

En este caso, necesitas modificar la tabla layer_styles para que encuentre los símbolos.

Abre el gestor de bases de datos QGis.

  1. Seleccione la tabla layer_styles en su geopackage
  2. Abra una ventana SQL
  3. Introduzca la consulta:
  4. UPDATE layer_styles
  5. SET styleQML = REPLACE(styleQML, ‘C:/nautical’, ‘Tu ruta’);
  6. Haga clic en el botón Ejecutar

3- Guarda el directorio náutico en el directorio de tu geopackage ENC.

En este caso, las referencias a los símbolos svg serán relativas al Geopackage y podrás utilizarlo desde varias máquinas. En este caso, seguiremos el mismo procedimiento anterior, pero la consulta SQL será

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

Por supuesto, el proyecto debe estar configurado para almacenar rutas relativas (Propiedades del proyecto -> General->Guardar rutas->Relativo).

Símbolos XML

Los símbolos XML descargados corresponden a simbologías adicionales de QGis. Se utilizan en el formateo de algunos de los símbolos S57. Puede buscarlos e instalarlos desde sus repositorios tradicionales, pero para simplificar el trabajo hemos puesto todos los ficheros XML necesarios en el fichero de descarga.

Para ello,

  1. abra el gestor de estilos (Preferencias->Gestor de estilos)
  2. Haga clic en el botón Importar/Exportar
  3. En el campo Archivo, señale el archivo XML que desea cargar y haga clic en Importar
  4. Repita la operación para todos los archivos XML cargados

Algunas simbologías especiales

La gran mayoría de las simbologías de capa S57 no requieren ningún cuidado especial. La simbología está definida por defecto en el geopackage y se carga y muestra automáticamente.
Sin embargo, hay tres capas que requieren una atención particular.

1- La capa LUCES

Las diferentes luces de los mapas ENC pueden ser de dos tipos: luces sectoriales, es decir, que el color de la luz es diferente según el ángulo desde el que se mire, o luces simples, visibles desde 360°.

Además, la simbología utilizada en las cartas náuticas de papel y la utilizada por el software de visualización digital de ENCs no es la misma.

La simbología que hemos implementado cumple todos estos criterios.

Cuando cargue la capa LUCES, la verá en el panel de capas:

Por defecto, se muestra la simbología ENC.

La primera línea corresponde a las luces de sector, la segunda a las luces simples.

Para los semáforos de sector, la simbología es la misma tanto si utiliza un visor como un mapa de papel. Sin embargo, para los semáforos simples, puede elegir el tipo de simbología. Si desmarca la segunda línea y marca la tercera, obtendrá una simbología de tipo «papel»:

La capa SOUNDG (sondeos batimétricos)

La visualización de los valores de los sondeos depende de su calidad: si son fiables, el tipo de letra debe ser cursiva, pero si no son del todo fiables, deben mostrarse en un tipo de letra normal.

La calidad de los sondeos se almacena en la capa M_QUAL de los ficheros S57.

Por defecto, la simbología de la capa SOUNDG tiene en cuenta la calidad de las sondas. Por lo tanto, la capa pl_M_QUAL debe cargarse en el proyecto QGis. Es invisible cuando se visualiza, pero se utiliza para etiquetar las entidades SOUNDG:

El proceso consiste en cruzar las dos capas para obtener el valor de calidad de cada sonda a partir de los polígonos pl_M_qual. Naturalmente, el número de sondas puede hacer que esta etapa sea bastante larga. Si trabaja con zoners grandes y un número elevado de sondas, puede optar por no tener en cuenta la calidad. Para ello, descargue el siguiente archivo qml: soundg.qml. Tendrás dos archivos qml: el que usa M_qual y el que no.

Abra las propiedades de la capa SOUNDG, haga clic en el botón Estilo (abajo a la izquierda) y luego en Cargar un estilo y apunte al archivo descargado. Todas las sondas se mostrarán muy rápidamente sin tener en cuenta la calidad.

La capa SBDARE (naturaleza del fondo marino)

La gestión de la simbología de esta capa es bastante complicada porque implica el tratamiento de dos campos de tipo lista. La lista de los tipos de fondos debe combinarse con la granulometría de cada fracción.

El código siguiente es la expresión utilizada para generar las etiquetas, que se incluye por defecto:

é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
   

Este código se ha simplificado (¡sí!) almacenando las 143 combinaciones posibles de naturaleza y fracción en una tabla externa: natsurf.

Para que la simbología funcione, la tabla natsurf debe añadirse a la lista de capas del proyecto:

BONUS: Algunas formas de trabajar con un gran número de capas

Cargar todas las capas del Geopackage

Puedes cargar todas las capas del Geopackage directamente haciendo clic y arrastrando el nombre del geopackage desde el panel del explorador al panel de capas.

Se abrirá una ventana en la que podrá seleccionar las capas que desea cargar. Para cargar todas las capas, basta con hacer clic en Seleccionar todo y, a continuación, en Añadir una capa.

Se cargarán todas las capas. Dependiendo del número de archivos S57 cargados en tu base de datos, puede tardar mucho tiempo en formatearse la ventana.

Las capas que consumen muchos recursos son las capas que vimos antes (luces, sondas y naturaleza del fondo). Puede desmarcarlas para acelerar la carga.

Otra forma más eficaz es definir la escala mínima de visualización de las capas. Con 150 capas cargadas, definirlas una a una es imposible. Hemos incluido un script en Python que le permite definir la escala mínima de visualización para todas las capas seleccionadas en el panel Capas. Una vez guardado el proyecto, esta configuración se utilizará cada vez que lo abra.

El script de Python para definir la escala mínima de visualización de las capas seleccionadas es el siguiente:

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 ]

Puedes descargarlo aquí.

El proyecto de base de datos S57 con Geopackage ha llegado a su fin. Ahora estamos empezando a implementar un procedimiento equivalente utilizando una base de datos PostgreSQL/Postgis. Por favor, ¡ayúdenos a completar este proyecto!

[/give_form id="12172"]

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é !

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *