0 votos
348 vistas

Hola, tengo un problema con la aplicación de funciones definidas dentro del modelador, cree una funcion que me anda correctamente en la calculadora de campos normal, pero cuando la aplico en el modelador y quiero usar como capa de entrada el resultado del algoritmo anterior en el modelador no me funciona, probe con una función mas sencilla hasta solucionar el inconveniente, por ejemplo:


from qgis.core import *

from qgis.gui import *

from qgis.utils import iface

from PyQt5.QtCore import QVariant


@qgsfunction(args='auto', group='Custom')

def sumar_fid(feature, parent,layer):

    layer = QgsProject.instance().mapLayersByName('SALIDA_PRUEBA')[0] #esta es la parte que no me funciona aparentemente (no me toma el resultado del algoritmo anterior)

    fid_sum = 0


    for feature in layer.getFeatures():

        fid = feature['FID']

        fid_sum += fid


    return fid_sum




Una vez realizada mi función la llamo en la calculadora de campos de la siguiente manera: sumar_fid('@cargar_capa_en_el_proyecto_OUTPUT')

que es el nombre de la variable que estimo que hace referencia a mi algoritmo anterior.

image image

por Novato (106 puntos)   en ArcGIS Desktop | 348 vistas

2 Respuestas

0 votos

Estás intentando utilizar una capa generada por un algoritmo anterior en el modelo como entrada para tu función personalizada. Las funciones personalizadas en QGIS no pueden recibir directamente las salidas de los algoritmos del modelador gráfico como una capa de entrada.

La variable que estás intentando pasar a la función (@cargar_capa_en_el_proyecto_OUTPUT) es una salida del algoritmo del modelador gráfico, que es una ruta de archivo (por ejemplo, un archivo .shp) en lugar de una capa cargada en QGIS.

Una solución alternativa podría ser la creación de un script en Python para ejecutar en la Consola Python de QGIS o como un script en la Caja de Herramientas de Procesamiento, en lugar de usar el modelador gráfico. En ese script, podrías utilizar tu algoritmo y tu función personalizada en secuencia.

Te proporciono un ejemplo general de cómo sería:


from qgis.core import *

def ejecutar_algoritmo_y_funcion():
# Ejecuta tu algoritmo y obtén la ruta de salida
salida = processing.run("tu_algoritmo", tus_parametros)['cargar_capa_en_el_proyecto_OUTPUT']

# Carga la capa de salida en el proyecto
layer = QgsVectorLayer(salida, "nombre_de_la_capa", "ogr")
QgsProject.instance().addMapLayer(layer)

# Usa tu función personalizada con esta capa
fid_sum = sumar_fid(None, None, layer)

def sumar_fid(feature, parent, layer):
fid_sum = 0
for feature in layer.getFeatures():
fid = feature['FID']
fid_sum += fid
return fid_sum


Por favor, reemplaza "tu_algoritmo", tus_parametros y "nombre_de_la_capa" con tus valores reales. También, si tu algoritmo requiere capas de entrada, tendrás que cargarlas en el proyecto de QGIS antes de poder usarlas.

Por favor, ten en cuenta que la API de QGIS o la funcionalidad del modelador gráfico podrían haber cambiado según la versión de QGIS.

por Administrador (7.9k puntos)  
editado por
0 votos
Hola, sigo experimentado problemas con funciones en el modelador grafico q QGIS, ya utilice varias funciones que anduvieron utilizando el parametro capa y llamando a la funcion desde la calculadora con ese pasametro algoritmo(@nombreresultadoalgoritmoanterior).

Pero ahora me encuentro con esta función que me funciona en la calculadora de campos comun sobre una capa activa, y la adapte con el nombre del algoritmo anterior al igual que hice con las otras y no funciona. La calculadora de campos sólo me dice que se detecto un error y no puedo ver en que parte del código, hay alguna forma que pueda visualizar esos errores ? 

Aqui va la función (se basa en un campo grupo numerico, y un campo prueba que contiene la fecha y hora que debe restar en formato txto)

from qgis.PyQt.QtCore import QCoreApplication

from qgis import processing

from qgis.gui import *

from qgis.core import *

from datetime import datetime

from PyQt5.QtCore import QVariant

from qgis.utils import iface

@qgsfunction(args='auto', group='Custom')

def duuu_MDL_gg(capa, feature, parent):

    field_name = 'prueba'  # Nombre de la columna

    new_field_name = 'duracion'  # Nombre del nuevo campo

    

    

    # Verificar si el campo ya existe y eliminarlo si es necesario

    fields = capa.fields()

    if new_field_name in fields.names():

        capa.deleteAttribute(fields.indexFromName(new_field_name))

        capa.updateFields()

    

    # Obtener el índice del campo original

    capa.dataProvider().fields().indexFromName('prueba')

    

    # Crear el nuevo campo de tipo texto

    layer.dataProvider().addAttributes([QgsField('duracion', QVariant.Int)])

    capa.updateFields()

    

    # Obtener los registros ordenados por FID ascendente

    features = sorted(capa.getFeatures(), key=lambda x: x.id())

    

    values_by_group = {}  # Diccionario para almacenar los valores de fecha por grupo

    

    # Recorrer las características y almacenar los valores de fecha por grupo

    for feature in features:

        group_value = feature['grupo']  # Obtener el valor del campo 'grupo'

        date_string = feature[field_index]  # Obtener la cadena de la fecha

        

        # Convertir la cadena de fecha a un objeto datetime

        date = datetime.strptime(date_string, '%d/%m/%Y %H:%M:%S')

        

        if group_value not in values_by_group:

            values_by_group[group_value] = []

        

        values_by_group[group_value].append(date)

    

    # Calcular la duración y actualizar el campo 'duracion' por cada grupo

    for feature in features:

        group_value = feature['grupo']  # Obtener el valor del campo 'grupo'

        date_string = feature[field_index]  # Obtener la cadena de la fecha

        

        # Obtener los valores de fecha correspondientes al grupo actual

        group_dates = values_by_group.get(group_value, [])

        

        if not group_dates:

            continue  # Si no hay valores de fecha para el grupo, pasar a la siguiente característica

        

        # Ordenar los valores de fecha de forma ascendente

        sorted_dates = sorted(group_dates)

        

        # Calcular la duración restando el último valor de fecha del primer valor de fecha

        duracion = (sorted_dates[-1] - sorted_dates[0]).total_seconds()

        

        # Convertir la duración a horas, minutos y segundos en formato HH:MM:SS

        hours = int(duration // 3600)

        minutes = int((duration % 3600) // 60)

        seconds = int(duration % 60)

        

        duracion_string = "{:02d}:{:02d}:{:02d}".format(hours, minutes, seconds)

        

        # Actualizar el campo 'duracion' de la característica con el formato HH:MM:SS

        feature[new_field_name] = duracion_string

        capa.updateFeature(feature)

    

    

    return duration_string
por Novato (106 puntos)  
0
Por desgracia, es difícil diagnosticar un problema de script sin tener acceso al entorno y a los datos con los que estás trabajando. Dicho esto, aquí hay algunas cosas que podrías verificar:

Tipo de datos: Asegúrate de que los datos que estás usando son del tipo correcto. Por ejemplo, group_value = feature['grupo'] asume que hay un campo llamado 'grupo' en tus datos. Si ese campo no existe, el script arrojará un error. Lo mismo aplica para date_string = feature[field_index].

Formato de la fecha: date = datetime.strptime(date_string, '%d/%m/%Y %H:%M:%S') asume que tu fecha está en el formato 'día/mes/año hora:minuto:segundo'. Si la fecha en tus datos tiene un formato diferente, deberías modificar la cadena de formato para que coincida.

Debugging: Desafortunadamente, la Calculadora de Campos en QGIS no proporciona mensajes de error muy descriptivos. Podrías intentar depurar tu script imprimiendo mensajes a lo largo del mismo para ver hasta dónde llega antes de fallar. Por ejemplo, puedes usar iface.messageBar().pushMessage("Info", "Debugging message", level=Qgis.Info) para mostrar mensajes en la barra de mensajes de QGIS.

Scripting dentro del modelador gráfico: Puede ser que tu script esté bien escrito, pero el modelador gráfico de QGIS no pueda manejarlo. Las funciones personalizadas pueden tener limitaciones cuando se utilizan dentro del modelador gráfico.

Finalmente, un enfoque alternativo podría ser realizar la operación de cálculo de duración en un paso separado después de que la capa se ha generado y se ha cargado en QGIS, en lugar de hacerlo dentro de la misma función.
1,450 preguntas
1,594 respuestas
986 comentarios
1,300 usuarios