1 votos

Forma basada en script para cargar varios archivos de texto delimitado en QGIS

Estoy generando montones de salidas de modelos desde un flujo de trabajo scriptado. La parte más consumidora de tiempo ahora es cargar los resultados uno por uno en QGIS para su exploración. Encontré una manera de cargar varios archivos, pero no incluye soporte para archivos de texto delimitados (¿aún?). Luego tengo que configurar/cargar/copiar la simbología, lo cual está bien pero no es ideal.

Me pregunto si hay una forma de "agrupar" archivos en una carpeta. Por (pseudo)ejemplo,

for d in ["fino","grueso"]:
    for f in os.listdir(d):
        if f.endswith('.head.head.csv'):

Para obtener un proyecto con las siguientes capas:

Grupos y capas en el proyecto de QGIS

Nunca antes he trabajado con archivos de QGIS fuera de la interfaz gráfica, ¡así que no estoy seguro por dónde empezar con los <> bits! Estoy investigando en PyQGIS pero no encuentro nada sobre archivos delimitados.

1voto

Jeremy White Puntos 381

Puedes usar el siguiente script, o al menos te debería encaminar en tu camino. Deberás editar las primeras 5 variables después de las declaraciones de importación, como se indica en los comentarios del script. Estas son la ruta a la carpeta que contiene tus archivos CSV a granel, los nombres de las columnas en los CSV que contienen las coordenadas, el código EPSG del CRS correcto para tus CSV y la ruta a tu archivo de estilo. Por supuesto, para que esto funcione correctamente, los nombres de las columnas y el CRS deben ser consistentes para todos los archivos CSV. Este script también asume que las coordenadas están en formato decimal.

import os
from pathlib import Path

# *****Edit these 5 variables according to your file system and CSVs...*****#
# Ruta a tu directorio fuente...
source_folder = r'Ruta/Hacia/Carpeta/Que/Contiene/CSVs'
# Nombre de la columna CSV que contiene los valores de latitud
lat_col = 'ycoord'
# Nombre de la columna CSV que contiene los valores de longitud
lon_col = 'xcoord'
# Código EPSG del CRS correcto para tus coordenadas CSV
epsg_code = 'epsg:4326'
# Ruta a tu archivo de estilo .qml
style_file = r'Ruta/Hacia/head.qml'
#***************************************************************************#

project = QgsProject.instance()

# Crea los 2 grupos en el árbol de capas si no existen aún
fine_group = project.layerTreeRoot().findGroup('head fine')
if not fine_group:
    fine_group = project.layerTreeRoot().insertGroup(0, 'head fine')

coarse_group = project.layerTreeRoot().findGroup('head coarse')
if not coarse_group:
    coarse_group = project.layerTreeRoot().insertGroup(1, 'head coarse')

# Itera sobre los archivos en el directorio fuente, crea y carga las capas CSV
for file in os.scandir(source_folder):
    file_path = os.path.join(source_folder, file.name)
    ext = os.path.splitext(file_path)[1]
    if ext == '.csv':
        file_stem = Path(file_path).stem
        uri = f'file:///{file_path}?type=csv&maxFields=10000&detectTypes=yes&xField={lon_col}&yField={lat_col}&crs={epsg_code}&spatialIndex=no&subsetIndex=no&watchFile=no'
        csv_lyr = QgsVectorLayer(uri, file_stem,'delimitedtext')
        if csv_lyr.isValid():
            # Carga el estilo desde el archivo .qml
            csv_lyr.loadNamedStyle(style_file)
            # Agrega la capa al proyecto pero no la agregues al legendario (la agregaremos a los grupos a continuación)
            project.addMapLayer(csv_lyr, False)
            # Agrega la capa al grupo correcto
            if 'fine' in file_stem:
                fine_group.addLayer(csv_lyr)
            else:
                coarse_group.addLayer(csv_lyr)

# Expande los grupos en la vista del árbol de capas (opcional)
vista = iface.layerTreeView()
vista.setExpanded(vista.node2index(fine_group), True)
vista.setExpanded(vista.node2index(coarse_group), True)

Resultado de ejemplo (Estos son solo algunos CSV ficticios que creé con nombres iguales a los tuyos):

Introducir descripción de la imagen aquí

Nota: Este no es un script independiente. Simplemente se ejecuta desde la consola de Python y agregará las capas y grupos al proyecto actual, insertando los nodos del árbol de capas en la parte superior del árbol de capas.

Por cierto, en caso de que te preguntes de dónde viene esta cadena de uri...

uri = f'file:///{file_path}?type=csv&maxFields=10000&detectTypes=yes&xField={lon_col}&yField={lat_col}&crs={epsg_code}&spatialIndex=no&subsetIndex=no&watchFile=no'

La idea básica es cargar un CSV manualmente, seleccionarlo y ejecutar:

print(iface.activeLayer().source())

Esto imprimirá una cadena de origen válida para un solo CSV. Luego podemos tomar esa cadena y modificarla dentro de un bucle for, insertando dinámicamente algunas variables de bucle utilizando las f-strings de Python para construir cadenas de origen válidas para cada CSV en un directorio.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X