[general]
name=GeoForest Tools
qgisMinimumVersion=3.28
qgisMaximumVersion=4.99
description=Tool for forest analysis and management integrated with Google Earth Engine.
version=2.1.1
author=Geomatica Ambiental
email=nino@geomatica.pe
authorUrl=https://www.geomatica.pe/
about=GeoForest Tools is a plugin that connects QGIS with Google Earth Engine to perform massive processing of satellite data in the cloud aimed at forest monitoring, downloading historical deforestation and early warnings (GEOBOSQUES, GFW, GLCLUC).
tracker=https://github.com/Ninobravo55/geoforest-tools/issues
repository=https://github.com/Ninobravo55/geoforest-tools
homepage=https://www.geomatica.pe/
category=Raster
tags=earth engine, gee, geobosques, forest, deforestation, gcp, gfw, global forest watch, glcluc, monitoring, remote sensing
icon=icon.png
hasProcessingProvider=yes
experimental=False
deprecated=False
changelog=
    2.1.1: Auditoría y refactor por fases — ver detalle agrupado por área:

    Arquitectura y plugin.py: refactor de plugin.py (425→175 líneas). NUEVO utils/action_registry.py con tabla declarativa de las 26 herramientas del menú (9 categorías), reemplaza ~24 bloques de QAction y 22 métodos run_X casi idénticos por un único enrutador genérico. NUEVO utils/dependencies.py: fuente única de verdad para las 8 dependencias de runtime, reemplaza las dos listas hardcodeadas y desincronizadas que existían en plugin.py. Migrado dynamic_world_algorithm.py a la base reutilizable GeeRasterAlgorithm (5to algoritmo migrado tras evaluar los 22 restantes y descartar migración forzada donde no calzaba el contrato de "una imagen → un raster"). Fix en geobosques_provider.loadAlgorithms — antes un solo algoritmo roto al importar abortaba el registro de los 26; ahora cada uno se carga aislado vía tabla _ALGORITHM_SPECS, con log individual de fallos en el panel de mensajes de QGIS. Eliminado core/session/ (GEESession) — wrapper singleton sin ningún uso real en el plugin ni mención en README/docs de migración; toda inicialización de GEE ya pasaba por utils/gee_init.py, que sigue siendo la única ruta.

    Manejo de errores: fix de manejo de errores en dynamic_world_algorithm.build_export_image — el except envolvía la llamada a GEE y tragaba silenciosamente cualquier error que no fuera "0 imágenes" (timeout de red, cuota excedida), ahora se propaga el error real. Fix funcional en gbif_occurrences — el except capturaba urllib.error.HTTPError, excepción que requests nunca lanza, por lo que el manejo diferenciado 4xx/5xx nunca se ejecutaba (corregido con requests.exceptions.HTTPError); eliminado objeto urllib.request.Request muerto. Corregido en gee_auth_dialog.start_auth() un try/except con un 'pass' que nunca podía disparar ImportError — el mensaje de "instala earthengine-api" nunca se mostraba antes de lanzar la tarea de autenticación, el fallo solo aparecía después, de forma más confusa, dentro de GEEAuthTask.

    Compatibilidad QGIS3/QGIS4 (Qt5/Qt6): corregido en gee_auth_dialog.py el uso directo de Qt.AlignCenter y QFrame.StyledPanel (namespaces planos que PyQt6/QGIS4 no expone) por ALIGN_CENTER de utils/qt_compat.py, que ya resolvía este caso pero no se usaba aquí. Documentado como riesgo pendiente de verificación real en QGIS4 (no corregido sin evidencia concluyente): QgsProcessingParameterDateTime.Date usado en 5 algoritmos podría requerir QgsProcessingParameterDateTime.Type.Date en versiones recientes de la API de QGIS.

    Reportes y gráficos: fix de threading en geobosques_charts.py y glcluc_charts.py — faltaba matplotlib.use("Agg") antes de importar pyplot, patrón ya aplicado en gfw_charts.py y early_warning_charts.py para evitar crashes intermitentes al graficar fuera del hilo principal de QGIS; MIGRATION_v2.0.md afirmaba que se había aplicado a "los 12 módulos que generan gráficos" pero estos dos quedaron sin el fix. Consolidados en ambos archivos los imports de os/pandas/matplotlib.pyplot/numpy/datetime que se reimportaban localmente dentro de cada método. Eliminadas variables muertas: 'ax' en geobosques_charts.generate_perdida_charts, 'ax' en gfw_charts (mismo patrón), y 'bars' en glcluc_charts.generate_altura_charts. Limpieza en mapbiomas_c3_algorithm.py — eliminada la variable vlayer (QgsVectorLayer creada con costo real de I/O y nunca usada) e imports muertos de requests y download_or_export. Nota: el reporte original en docs/MIGRATION_v2.0.md sugería que "la capa no se carga en QGIS" en mapbiomas_c3; verificado que es impreciso — el resultado final sí se carga vía vlayer_final, lo que sobraba era una instancia intermedia sin uso. Agregado rasterio a requirements.txt (se usaba en dnbr_algorithm y se verificaba en check_dependencies pero no estaba declarado).

    Internacionalización: NUEVO docs/I18N_PENDING.md — el código ya usa self.tr() consistentemente en los 26 algoritmos y en gui/, pero faltan los archivos .ts/.qm reales (requieren herramientas de Qt Linguist no generables en este ciclo de auditoría; documentado el procedimiento exacto a seguir). Corregido en plugin.py::run_deps() un mensaje de QMessageBox que estaba hardcodeado sin pasar por self.tr(), inconsistente con el resto del plugin.

    Documentación: README.md reescrito para reflejar el estado real verificado contra el código — compatibilidad QGIS 3.28-4.x (antes decía "QGIS 3.x"), las 8 dependencias de requirements.txt (antes mencionaba solo 3), e inventario completo de las 26 herramientas en sus 9 categorías (antes solo describía el producto GEOBOSQUES original).

    Hallazgos documentados pero NO corregidos en este ciclo (requieren alcance y decisión aparte): inventario de pyflakes con ~50 hallazgos en 15+ archivos no auditados a este nivel de detalle (imports muertos repetidos de download_or_export en 6 algoritmos, bloque de imports duplicado en geobosques_algorithm.py, variables sin uso varias); 5 algoritmos (mapbiomas_c3, gedi_canopy, gedi_l2b, gedi_l4b y posibles otros) con bucles for sobre getFeatures() que no verifican feedback.isCanceled() ni reportan progreso granular; generación de PDF nunca existió en el plugin (no es una regresión, el plan de trabajo original asumía que sí).

    2.1.0: AOI unificado — etiquetas "Opción 1/2" consistentes en los 21 algoritmos. Detección de proyección en build_aoi vía parameterAsExtentCrs del canvas. estimate_pixels() en AOIResult para decisión pre-descarga. NUEVO grid_downloader.py: descarga local por grilla adaptiva (reemplaza ~140 líneas duplicadas). download_or_export() en export_router como punto de entrada único (Local/Drive/GCS).
    2.1.0: AOI unificado — etiquetas "Opción 1/2" consistentes en los 21 algoritmos. Detección de proyección en build_aoi vía parameterAsExtentCrs del canvas. estimate_pixels() en AOIResult para decisión pre-descarga. NUEVO grid_downloader.py: descarga local por grilla adaptiva (reemplaza ~140 líneas duplicadas). download_or_export() en export_router como punto de entrada único (Local/Drive/GCS).
    2.0.9: Fix missing import requests in gbif_occurrences.
    2.0.8: Minor updates and bug fixes.
    2.0.2: Less strict geometry validation (removes isGeosValid() that rejected valid geometries).
    2.0.1: QGIS 3.x/4.x compatibility fix in aoi_builder. Replacement of urllib with requests in gbif_occurrences.
    2.0: Architecture consolidation. Reusable base GeeRasterAlgorithm. Adoption of export_router. Fixes in GLCLUC. Improved matplotlib backend. Tests and CI.
    1.2: Elimination of duplication in AOI and GEE init. Qt5/Qt6 compatibility layer.
    1.1: Code optimization and improvements in export to Google Drive/GCS. Integration of Global Forest Watch (GFW) and GLCLUC 2020.
    1.0: Initial release with integration to GEOBOSQUES.
