0 votos
297 vistas
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)   en ArcGIS Desktop | 297 vistas

1 Respuesta

0 votos

Aquí te dejo algunas sugerencias:

Definición de la variable field_index: Noté que estás intentando usar la variable field_index (en la línea date_string = feature[field_index]), pero no parece estar definida en ninguna parte de tu código. ¿Quizás quisiste asignarle el resultado del método indexFromName? Podrías intentar con algo así:


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


Uso de la variable layer: Pareces estar usando la variable layer (en la línea layer.dataProvider().addAttributes([QgsField('duracion', QVariant.Int)])) pero esta tampoco está definida en ninguna parte de tu código. Creo que quisiste usar capa en su lugar.

Conversión incorrecta de la duración a formato de tiempo: En la línea donde intentas convertir la duración a un formato de tiempo, usas una variable duration en lugar de duracion. Creo que debería ser duracion en lugar de duration.

Desafortunadamente, QGIS no proporciona un sistema robusto de mensajes de error para la Calculadora de Campos. Como alternativa, puedes intentar depurar tu script utilizando la consola de Python en QGIS. Esto te permitirá ver los errores más detallados que podrían estar ocurriendo.

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.dataProvider().deleteAttributes([fields.indexFromName(new_field_name)])
        capa.updateFields()

    # Obtener el índice del campo original
    field_index = capa.dataProvider().fields().indexFromName(field_name)

    # Crear el nuevo campo de tipo entero
    capa.dataProvider().addAttributes([QgsField(new_field_name, 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(duracion // 3600)
        minutes = int((duracion % 3600) // 60)
        seconds = int(duracion % 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.dataProvider().updateFeature(feature)

    return duracion_string


por Administrador (7.9k puntos)  
1,450 preguntas
1,594 respuestas
986 comentarios
1,299 usuarios