Eliminación de solapamientos y huecos entre polígonos de una capa (con QGis y Geopackage)

Aquí retomamos el ejemplo tratado en el artículo Eliminación de solapamientos y espacios entre polígonos de una capa (con QGis y Postgis) para ver el mismo tipo de solución cuando no se dispone de una base de datos PostgreSQL/Postgis. Aquí sólo vamos a utilizar las posibilidades que ofrece QGis trabajando sobre un formato de datos Geopackage.

Si tiene la oportunidad de trabajar con los datos catastrales franceses correspondientes a Localidades, observará que no se respeta la coherencia espacial (topología):

De hecho, el límite de cada localidad es el borde de la carretera colindante, lo que deja espacios vacíos donde están las carreteras. Aunque en algunos casos esto no es un problema, se convierte en uno cuando se añade la capa «Comunas» (del mismo catastro) al mapa:

A esta escala no parece muy limpio, pero si se amplía es aún peor.

Y si nos fijamos en la propia capa de localidad, encontramos numerosas anomalías topológicas:

Aquí veremos cómo resolver el primer problema: Cómo corregir la topología de la capa de localidad eliminando los polígonos superpuestos y los espacios vacíos entre ellos.

Para el segundo problema: Cómo volver a crear una capa común coherente con la nueva capa de localidad y superpuesta exactamente a los límites de las localidades, consulte el artículo citado anteriormente (Eliminación de superposiciones y espacios entre polígonos en una capa (con QGis y Postgis)), ya que en esta parte se utilizan simplemente QGis y Geopackage.

El ejemplo siguiente se creó utilizando datos del catastro oficial del departamento 71, descargados del enlace https://cadastre.data.gouv.fr/data/etalab-cadastre/2023-01-01/shp/departements/71/.

Cómo corregir la topología de la capa de localidad

La solución aquí propuesta no requiere una base de datos PostgreSQL/Postgis. Sin embargo, dadas las limitaciones de SQLite3 y un error en el DB Manager de QGis 3.30, habrá algunas manipulaciones adicionales. También debe esperar largos tiempos de procesamiento, por lo que no es adecuado para el procesamiento de grandes capas.

1-Crear una capa con un buffer alrededor de las localidades

Para gestionar los espacios entre polígonos, aunque se pueden utilizar algunas herramientas de ajuste para tratar ciertos problemas, la solución más sencilla y radical es construir un búfer alrededor de los polígonos para transformar los espacios vacíos en superposiciones. En el caso de las localidades, los espacios vacíos son del orden de 10 m. Construimos un búfer de 6 m alrededor de las localidades, lo que dará lugar a una superposición de unos 2-3 metros.

Elija un archivo de salida permanente en formato Geopackage, que le permitirá seguir directamente el procedimiento del paso siguiente sin modificaciones.

El resultado de la capa intermedia es el siguiente:

Ya no tenemos que gestionar los espacios entre polígonos, sólo tenemos superposiciones.

2- Abrir el QGis DataBase Manager

Aparecerá la ventana DB Manager

Si su archivo geopackage no aparece en la lista de archivos, haz clic con el botón derecho del ratón en Geopackage->Nueva conexión y cárguelo.

Haz clic en la capa almacenada en el paso anterior, y luego en el Menú Base de Datos -> Ventana SQL.

3- Ejecuta las líneas del script SQL

Todas las líneas del siguiente script corresponden a las siguientes tareas

  1. Crear una vista con dos colecciones de geometrías. Inicialmente, se trata de los polígonos de las localidades por duplicado.
  2. La primera colección contiene las partes de los polígonos que no se solapan con otras
  3. Las partes superpuestas se guardan en la segunda colección
  4. Por último, añadimos la parte superpuesta al menor de los dos polígonos afectados por la superposición.

A diferencia de la ventana SQL en pgAdmin y PostgreSQL/Postgis, en la ventana SQL del DB Manager es necesario ejecutar el script consulta por consulta.

Para adaptar el script a tu caso, necesitas reemplazar los siguientes elementos utilizando un procesador de textos:

  1. todas las apariciones de tampon por el nombre de la tabla que contiene las localidades con su buffer,
  2. todas las apariciones de table_corrigee por el nombre de la tabla de resultados que desees,
  3. y comprueba que el identificador de tu tabla de buffers es id. Por defecto puede llamarse fid. En este caso, sustituye todas las apariciones de id por fid.

Estas son las líneas del script:

Primera consulta (si ya ha ejecutado el script)

DROP TABLE IF EXISTS table_corrigee ; 

Segunda consulta (si ya ha ejecutado el script)

DROP VIEW auto_jointure;

Tercera consulta

CREATE OR REPLACE VIEW auto_jointure AS SELECT

    tampon.id as id,
    tampon.nom as "nom",
    tampon.commune as "commune",
-- recuperar todos los polígonos de la tabla buffer en dos colecciones: una que contiene las geometrías completas y otra que contiene las partes superpuestas. Por el momento, ambas colecciones contienen las geometrías completas.
    ST_Union(tampon.geom) AS full_geom,
    ST_Union(tampon_bis.geom) AS shared_geom
    FROM  tampon ,tampon AS tampon_bis
    WHERE
      --comprobar la validez del polígono como precaución
      ST_IsValid(tampon.geom) AND ST_IsValid(tampon_bis.geom)
      --filtro para retener los polígonos que se intersecan
      AND ST_intersects(tampon.geom,tampon_bis.geom)   
      --eliminar los polígonos de intersección con ellos mismos
      AND tampon.id <> tampon_bis.id          
      --para una intersección de 2 polígonos, conservar sólo el más pequeño
      AND ST_Area(tampon_bis.geom) < ST_Area(tampon.geom)
      --ya que estamos haciendo 'uniones', necesitamos realizar una agrupación en los otros atributos
    GROUP BY tampon.id,tampon."nom" , tampon.commune ;

Cuarta consulta

/*
Vamos a crear una tabla que contendrá el resultado final: el primer paso consiste en eliminar todas las áreas superpuestas. El segundo paso consiste en añadir las áreas solapadas al menor de los dos polígonos. Los huecos creados por el primer paso se rellenan con este segundo paso. Los polígonos finales están unidos, sin solapamientos ni huecos.
*/

    CREATE TABLE table_corrigee AS SELECT
    id,
    "nom",
    commune,
/* Las intersecciones se restan de la capa que contiene todos los polígonos; de este modo, se eliminan las partes conflictivas*/
    ST_Multi(ST_Difference(full_geom,shared_geom)) as geom,
    ST_Area(full_geom) as area
    FROM auto_jointure
    WHERE ST_IsValid(full_geom) AND ST_IsValid(shared_geom)
/*A continuación, debemos añadir las intersecciones que acabamos de restar para rellenar los espacios creados.*/
    UNION 
      SELECT
      id,
      "nom",
      commune,
      geom,
      ST_Area(geom)
      FROM tampon
      WHERE id NOT IN (SELECT id FROM auto_jointure);

Solución de los problemas de DB Managerr

Después de ejecutar las consultas, puede que se sorprenda al ver que ni el establo ni las vistas creadas durante los scripts aparecen en la lista de tablas de Geopackage.

Y sin embargo, si escribes una consulta referida a las tablas del script, funcionan. Las tablas están en alguna parte, pero DB Manager no las ve… Es un error, conocido y reconocido, y… ¡aceptado! Como los desarrolladores de QGis están preparando un sustituto para DB Manager, Data Source Manager, no tienen intención de solucionar este problema.

En resumen, si no podemos resolver el problema, podemos sortearlo.

Con DB Manager vamos a crear una tabla, con la opción estándar

Y creamos una tabla con los mismos campos que la capa bufferizada

Que aparece en la lista de tablas del geopackagee

Ahora todo lo que tenemos que hacer es cargar el resultado de nuestro script en esta tabla «oficial» utilizando la siguiente consulta SQL:

insert into recup
select fid,geom,nom,commune from lieux_dits_corr

Cargamos esta nueva capa en QGis:

A la izquierda la capa corregida, a la derecha la capa de localidades original

Hemos resuelto el problema de la consistencia topológica de las localidades.

Para los puristas, una explicación final del problema con la visualización de tablas en DB Manager.

El problema no viene de QGIS, sino del estándar de geopackage.
OGR (y qgis) sólo buscan tablas en la tabla gpkg_contents. Para que sean visibles, es necesario añadir una nueva línea a estas tablas:

INSERT INTO gpkg_contents (table_name, data_type) values (table_name,'attributes'). # attributes or features (if geometry); INSERT INTO gpkg_geometry (table_name, column_name, geometry_type_name, srs_id, z, m) (table_name, 'geom', 'Point', 4326, 1, 1);

En este caso, sin embargo, cabría esperar que QGIS DB Manager ejecutara estas consultas automáticamente.

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 *