Repository navigation
Desarrollo
Para quien cambia el código de MonitorEO o publica sus versiones. Para usar las herramientas, empieza por Primeros pasos.
Los textos de las herramientas (plugin de QGIS, asistente para gestores, app de Earth Engine, visor de resultados, informes, instaladores, línea de comandos, paquetes de R y de Python, servidor MCP) están en inglés; la documentación, en español e inglés. Cada página de la wiki tiene su página en inglés (y el README, los dos idiomas). Así, los textos nuevos de una herramienta se escriben en inglés y las secciones nuevas del manual, en los dos idiomas. El asistente para gestores sigue respondiendo en el idioma de cada pregunta.
Todas usan las mismas funciones (monitoreo.services), así que el mismo cálculo da el mismo resultado en todas;
la app de Earth Engine es la traducción a JavaScript del núcleo del paquete.
| Herramienta | Carpeta del repositorio | Manual |
|---|---|---|
| App de Earth Engine | gee |
App de Earth Engine |
Paquete de Python monitoreo y línea de comandos |
src/monitoreo (cli.py) |
Python, Línea de comandos |
| Plugin de QGIS MonitorEO | qgis/monitoreo_qgis |
QGIS |
| Servidor MCP | src/monitoreo/mcp_server.py |
MCP |
| Asistente para gestores |
src/monitoreo/assistant.py (servidor web, ventana y cliente del MCP), ui/assistant.html (la página, con Leaflet en ui/vendor), report.py (el informe y las vistas del mapa), engine.py (Ollama) y manual.py (búsqueda en esta wiki) |
Asistente |
Paquete de R monitoreo
|
r/monitoreo |
R |
| Visor de resultados |
src/monitoreo/viewer, monitoreo publish
|
Visor de resultados |
Todo se calcula en Google Earth Engine: con la cuenta y el proyecto de cada usuario o, sin proyecto, con la cuenta compartida de MonitorEO (la app, siempre con el proyecto de MonitorEO). El único servidor es el pequeño intermediario de la cuenta compartida, en Cloud Run.
src/monitoreo/catalog.json es el catálogo de variables y se mantiene a mano en este repositorio: colección,
fórmula, escala y desplazamiento de las bandas, unidad, bandas de calidad y rampa de colores de cada una.
catalog.EXTRA añade el NBR de Sentinel-2 y Landsat (incendios). La app de Earth Engine lleva una copia, que escribe
gee/build.py.
Detalles del cálculo, en el código:
-
FIXESencatalog.py: la escala del LAI de MCD15A3H es 0.1, no 0.01. - La escala y el desplazamiento de las bandas se aplican antes de la fórmula (EVI, el albedo y la clorofila de Sentinel-2 necesitan reflectancias, no las bandas sin escalar).
- Los nombres de banda de las fórmulas se comparan sin mayúsculas (
LST_day_1kmde las entradas 15 y 16). - Los valores de bandera de MODIS (p. ej. 250 = nube en
NDSI_Snow_Cover) se descartan siempre. - Landsat 7 solo se usa hasta el 31-5-2003, como dice el catálogo.
- WDPA cambió su esquema en Earth Engine: el ID es ahora
SITE_ID(antesWDPAID).
pytest tests/test_offline.py tests/test_publish.py tests/test_assistant.py # sin Earth Engine ni red
EE_PROJECT=mi-proyecto pytest -m ee # con Earth Engine (la app de gee, con npm install en gee)Las pruebas usan el código de src/ del clon aunque el entorno tenga instalada la versión de GitHub. Si hay paquetes
instalados con pip install --user, añade PYTHONNOUSERSITE=1 (ver Problemas frecuentes).
Para probar la línea de comandos o el servidor MCP con cambios sin publicar:
PYTHONPATH=src python -m monitoreo.cli mcp --no-update (o pip install -e . en un entorno aparte, que ni
monitoreo mcp ni eHabitat+ actualizan). El asistente, igual: PYTHONPATH=src python -m monitoreo.cli assistant --no-update.
En el asistente, el modelo solo ve las respuestas de list_variables, describe_variable y
find_protected_areas (ADVICE en assistant.py) y las de las exportaciones a Google Drive y task_status
(TASKS, sin valores: el identificador y el estado de la tarea); las de las herramientas de cálculo y de descarga
(RESULTS) van a la página y al informe, y el modelo recibe un acuse sin valores. La herramienta manual no es del
servidor MCP: la responde el asistente con manual.search, que busca en esta wiki (descargada de
raw.githubusercontent.com/wiki/... a ~/MonitorEO/wiki); por eso lo que se escriba aquí es lo que el asistente sabe
de MonitorEO. OTHER_TOOLS reconoce las peticiones para otras herramientas, y fix_links cambia los enlaces a la
wiki que no existen. tests/test_assistant.py lo comprueba con un modelo de
prueba. Las instrucciones del modelo (PROMPT, con la guía de sensores y la lista de variables del catálogo) están
en el mismo fichero y se actualizan con el paquete.
La página se abre en una ventana propia con pywebview (WebKit en macOS, WebView2 en
Windows, Qt WebEngine o GTK en Linux): run arranca el servidor en un hilo y la ventana en el principal, y cerrarla para el
servidor (si hay un cálculo en marcha, pywebview pregunta antes: el evento closing pone confirm_close, y
WINDOW_TEXTS traduce la pregunta y el menú de macOS; la página no muestra entonces Close the assistant); sin pywebview, o si no puede abrirla, usa el navegador (--browser lo fuerza). La actualización al
arrancar (_update_in_window en cli.py) muestra una ventanita mientras pip instala y después arranca el asistente
en otro proceso, porque pywebview solo arranca una vez en cada uno. Los mapas de la página usan
Leaflet 1.9.4, copiado en ui/vendor/leaflet (licencia BSD-2) para que funcione sin
depender de un CDN, con las teselas de Earth Engine de map_layer, trend_map y compare_map; los resultados sobre regiones
(PERIOD_MAP) traen además el mapa de la mediana de su periodo, o de su último año si es más largo (Assistant.period_map: map_layer con
quick=True, solo las teselas, sin vista previa y con la rampa de color del catálogo, porque calcular los percentiles
de la mediana de años de imágenes sobre un espacio grande tarda o agota la memoria de Earth Engine; quick está oculto
al modelo como los argumentos de HIDDEN). Los mapas de cada paso (steps.map_steps, con las ventanas de
composite.windows y composite.bins, las mismas de las series) se hacen al elegirlos en la página
(/api/map/step, Assistant.step_map), con quick y el vmin y vmax del mapa del resultado. El plugin de QGIS
ofrece los mismos pasos en las ventanas de sus series y tendencias (result_maps en dock.py), pero como GeoTIFF
(download_image y download_trend), con la rampa del primer mapa del resultado aplicada en QGIS. Si los percentiles fallan en cualquier mapa, maps.vis_params usa también
la rampa del catálogo. El valor y la serie
de un píxel son region_stats y time_series con {"point": [lon, lat]}. Add this view to the report compone en
el servidor (report.map_view, con Pillow) las teselas del fondo y las de Earth Engine del encuadre, con el píxel
marcado y los créditos, en un PNG que va dentro del informe.
Los instaladores están en installer/: macos/instalar.sh, linux/instalar.sh y windows/instalar.bat (guardado con los finales de
línea de Windows, -text en .gitattributes, y sin acentos). Instalan el environment.yml de main con micromamba
en ~/MonitorEO/entorno, crean el acceso del Escritorio (en Windows, un acceso con el mismo nombre) y abren el asistente con python -s -m monitoreo.cli assistant, sin terminal: en macOS, la app MonitorEO Assistant.app (un Info.plist y un script; como la crea el
propio ordenador, no está en cuarentena y no hace falta firmarla); en Windows, un acceso a pythonw.exe. Sin
terminal, los mensajes van a ~/MonitorEO/assistant-output.log. Se descargan de
raw.githubusercontent.com con las órdenes de una línea de Asistente (lo que descarga curl no
queda en cuarentena en macOS ni con la marca de Internet en Windows, así que no los bloquean por no estar firmados) o
en zip: el flujo .github/workflows/installers.yml los comprime (asistente-monitoreo-macos.zip, como
Install the MonitorEO assistant.command con el permiso de ejecución, y asistente-monitoreo-windows.zip, con
Install the MonitorEO assistant.bat) y los adjunta a cada release; la wiki los enlaza en
releases/latest/download/. Para adjuntarlos a una release que ya existe: Actions > Assistant installers > Run
workflow, con su etiqueta. Para que macOS y Windows abran los zips sin avisos habría que firmarlos (en macOS, con un
certificado Developer ID de Apple y su notarización). Para probar el de macOS sin tocar tu carpeta:
HOME=/tmp/prueba bash installer/macos/instalar.sh (la app que abre al final usa tu HOME de verdad, porque macOS
no le pasa el de la orden: ciérrala).
El de Windows comprueba que micromamba.exe arranca: necesita el runtime de Visual C++ (MSVCP140.dll,
VCRUNTIME140.dll...), que un Windows recién instalado no tiene (el error 0xC0000135). Si falta, copia junto a
micromamba.exe las DLL del paquete vc14_runtime de conda-forge (un .conda: un zip con un .tar.zst, que abre
el tar de Windows 11), solo si las firma Microsoft (Get-AuthenticodeSignature), sin instalar nada en el sistema.
Instala con CONDA_PKGS_DIRS=%SystemDrive%\MonitorEO-pkgs, que borra al terminar: micromamba guarda los paquetes bajo
la dirección de su canal (pkgs\https\conda.anaconda.org\conda-forge\win-64\...) y, en la carpeta del usuario,
algunas rutas pasan de los 260 caracteres de MAX_PATH (las rutas largas de Windows necesitan un administrador); allí
la más larga tiene 234 con cualquier nombre de usuario. Por lo mismo el entorno lleva matplotlib-base y no
matplotlib, que en Windows trae PySide6 y Qt (qt6-main, con rutas de 261 caracteres para un usuario de 6 letras), que no
usa. El acceso del Escritorio abre el asistente con pythonw.exe, sin consola: update._pip da a pip un stderr
(su stdout), porque subprocess le daría si no una tubería cerrada, en la que escribir hace que acabe con el estado
120 aunque haya instalado el paquete. Se probó en un Windows 11 recién instalado en una máquina virtual (UTM en un
Mac), con un usuario administrador.
El icono de la app, del acceso de Windows y del lanzador de Ubuntu es el logotipo del plugin de QGIS
(qgis/monitoreo_qgis/icon.png, de 64 px) dibujado otra vez a más resolución, con su geometría y sus colores y las
esquinas transparentes: installer/icons/make_icons.py (con Pillow; el .icns, solo en un Mac, con iconutil)
escribe monitoreo-assistant.icns, .ico y .png en installer/icons, de donde los descargan los instaladores.
El de Ubuntu (linux/instalar.sh, para 22.04, 24.04 y 26.04 LTS, en x86_64 y aarch64) se baja con wget, que
Ubuntu trae siempre (curl no), y no va en zip: el gestor de archivos de Ubuntu no ejecuta scripts. Añade al
environment.yml pyqt6-webengine y qtpy, porque pywebview necesita en Linux Qt WebEngine (el entorno no lleva
Qt: tiene matplotlib-base, matplotlib sin él), y escribe el lanzador entorno/bin/monitoreo-assistant, con el que se abren
~/.local/share/applications/monitoreo-assistant.desktop y su copia del Escritorio (de confianza con
gio set ... metadata::trusted true, para que Ubuntu la abra). El lanzador elige PyQt6 (QT_API), X11 (XWayland en
Wayland) y RESOURCE_NAME=monitoreo-assistant, que da a la ventana el WM_CLASS del .desktop (si no, es
cli.py y el dock no la asocia a su icono), y quita el sandbox de Chromium (QTWEBENGINE_DISABLE_SANDBOX=1): su
filtro seccomp mata el proceso de la página (SIGSYS) con kernels y glibc recientes, y Ubuntu 24.04 solo da los user
namespaces a los programas con perfil de AppArmor; la ventana solo muestra la página local del asistente. El job
linux de installers.yml lo prueba en Ubuntu 22.04 y 24.04 (también en cada push que cambie installer/,
environment.yml o el flujo): lo instala, abre el asistente en una pantalla virtual (Xvfb) y comprueba que la
captura no está en blanco. En local, con Docker y una imagen ubuntu:24.04 con wget, xvfb, x11-utils e
imagemagick, como un usuario que no sea root.
La versión de Ollama que instala el asistente es OLLAMA en engine.py, con el tamaño y el SHA-256 del fichero de
cada sistema en ASSETS (el digest de cada fichero en
https://api.github.com/repos/ollama/ollama/releases/tags/<versión>). Quien ya tiene instalada otra versión la sigue
usando (Engine.installed); la nueva se descarga cuando no hay ninguna.
Generar el zip a mano: python qgis/build_plugin.py (descarga las dependencias, así que necesita
internet; queda en dist/). El zip lleva dentro monitoreo y la librería de Earth Engine con sus dependencias
(Python puro, válido en Windows, macOS y Linux). Con bandit y detect-secrets instalados, lo analiza como
plugins.qgis.org y falla si el plugin o monitoreo tienen algún hallazgo.
Probarlo sin ventana con el Python de QGIS (calcula en Earth Engine):
PYTHONNOUSERSITE=1 EE_PROJECT=mi-proyecto /Applications/QGIS-final-4_0_3.app/Contents/MacOS/python qgis/test_plugin.pyPublicar una versión:
- Sube
version=enqgis/monitoreo_qgis/metadata.txt, haz commit y push. - Publica una release en GitHub (Releases > Draft a new release, etiqueta nueva con esa versión, p. ej.
v0.3.7, Publish release). También vale subir la etiqueta desde GitHub Desktop (History, botón derecho sobre el commit, Create Tag…, Push origin): el flujo crea la release. - Unos minutos después, el flujo
.github/workflows/qgis-plugin.yml(pestaña Actions) genera el zip en GitHub, lo adjunta a la release y, si el repositorio tiene el secretoQGIS_PLUGINS_TOKEN, lo sube a plugins.qgis.org, donde pasa el análisis de seguridad y la aprobación antes de publicarse. Falla si la etiqueta no coincide conversion=(0.2yv0.2.0valen para0.2.0).
Para adjuntar el zip a una release que ya existe: Actions > QGIS plugin > Run workflow, con su etiqueta.
La versión está en pyproject.toml, src/monitoreo/__init__.py y r/monitoreo/DESCRIPTION. Se instalan desde
GitHub (rama main o una etiqueta), así que basta con subir el cambio; el servidor MCP se actualiza solo a la
última versión de GitHub cada vez que arranca (MCP).
Sin proyecto (init() sin EE_PROJECT, init(shared=True), el campo de proyecto vacío en QGIS y en el asistente,
mo_init("") en R), las herramientas calculan con la cuenta de servicio monitoreo-public del proyecto
ee-ugr-default-project. Su token, de una hora y solo para Earth Engine, lo da el intermediario de broker/
(main.py, solo con la biblioteca estándar de Python), desplegado en Cloud Run en
https://monitoreo-broker-872770286973.europe-west1.run.app (GET /token; su dirección está en services.BROKER, y
MONITOREO_BROKER la cambia). El paquete pide otro token cuando caduca y no deja exportar a Google Drive con esta
cuenta.
No hay ninguna clave que pueda filtrarse: el servicio se ejecuta como monitoreo-broker, que solo puede crear tokens
de monitoreo-public, y esta tiene el rol monitoreoCompute, que solo calcula (valores, píxeles, mapas, miniaturas y
tablas del catálogo público de Earth Engine): no lee los assets del proyecto ni sus tareas, ni exporta. Por eso no se
usa el rol earthengine.viewer, que dejaría a cualquiera con un token leer los assets del proyecto. El contenedor lo
compila monitoreo-build (rol run.builder). Cada dirección puede pedir 60 tokens por hora; la cuota de Earth Engine
es la del proyecto, compartida con la app.
Cada usuario de la cuenta compartida tiene sus research EECUs: USER_LIMIT EECU-h al mes (10 por defecto), para
que nadie gaste la cuota del proyecto, que es de todos. El usuario es el identificador anónimo de cada instalación
(services.user_id(): mo- y 16 cifras hexadecimales al azar, en ~/.config/monitoreo/user_id), que el paquete
manda al pedir el token (/token?user=) y pone como workload tag de Earth Engine en todo lo que calcula. El
intermediario (monitoreo-broker, con el rol Monitoring Viewer del proyecto) lee la métrica «Completed EECU-seconds»
de Cloud Monitoring agrupada por workload tag desde el día 1 del mes (una consulta para todos, cada 5 minutos) y no
da tokens a quien ha gastado los suyos hasta el mes siguiente (403 con code: spent; el token que ya tiene dura como
mucho una hora más). GET /usage?user= dice lo gastado por el usuario y por el proyecto (EECU_LIMIT, la cuota del
nivel del proyecto, 150 por defecto). Sin identificador (las versiones anteriores a la 0.3.21) no hay token, salvo con
REQUIRE_USER=0; si Cloud Monitoring no responde, se dan tokens. Se cambian al desplegar:
USER_LIMIT=20 broker/deploy.sh ee-ugr-default-project. El límite se basa en la buena fe: quien borre el fichero del
identificador empieza con uno nuevo (el interruptor de abajo sigue ahí). Con su cuenta, las herramientas leen la
métrica de su proyecto directamente (services.eecu_usage).
-
Desplegar o actualizar:
broker/deploy.sh ee-ugr-default-projectcongcloudiniciado con una cuenta propietaria del proyecto (everest@go.ugr.es). Se puede repetir: crea lo que falta y despliega una revisión nueva. -
Pararla al momento (los tokens ya dados dejan de valer):
gcloud iam service-accounts disable monitoreo-public@ee-ugr-default-project.iam.gserviceaccount.com --project ee-ugr-default-project, yenablepara volver a abrirla. -
Uso: los registros de Cloud Run (
monitoreo-broker, región europe-west1) y la cuota de Earth Engine del proyecto en la consola de Google Cloud.
- La app se genera con
gee/build.pyy se publica desde el Code Editor: ver App de Earth Engine. - El visor es una carpeta estática que escribe
monitoreo publish: ver Visor de resultados.
Copyright (C) 2026 OBSNEV, Universidad de Granada.
GNU General Public License v3.0 o posterior (GPL-3.0-or-later; texto
completo en LICENSE): se puede usar, copiar,
modificar y redistribuir, también con fines comerciales, manteniendo los avisos de autoría (MonitorEO, OBSNEV,
Universidad de Granada) y distribuyendo las versiones modificadas con la misma licencia y su código fuente. Es la
licencia de los plugins de QGIS (QGIS es GPL v2 o posterior) y admite las librerías con licencia Apache 2.0 que lleva
el plugin (earthengine-api y las de Google). Los datos y mapas del visor de resultados tienen su propia licencia
(CC BY 4.0 por defecto).
MonitorEO es un resultado del Proyecto EVEREST (PID2023-151939OB-I00), financiado por MICIU/AEI 10.13039/501100011033 y cofinanciado por FEDER – Unión Europea, y del Proyecto NevadEO (C-EXP-074-UGR23), cofinanciado por el Programa FEDER 2014-2020 y la Consejería de Economía, Conocimiento, Empresa y Universidades de la Junta de Andalucía. Es también un resultado del Proyecto PRESINMED (Preserving the singularity of Mediterranean high-mountain biodiversity hotspots: a NBS approach, PCI 2025-163175) de la convocatoria Biodiversa+ NBS 2023.
MonitorEO is an output of the EVEREST Project (PID2023-151939OB-I00), funded by MICIU/AEI 10.13039/501100011033, and co-funded by ERDF – European Union, as well as of the NevadEO Project (C-EXP-074-UGR23), co-funded by the ERDF 2014-2020 Program and the Regional Ministry of Economy, Knowledge, Enterprise, and Universities of the Regional Government of Andalusia. It is also an output of the PRESINMED Project (Preserving the singularity of Mediterranean high-mountain biodiversity hotspots: a NBS approach, PCI 2025-163175) of the Biodiversa+ NBS 2023 call.
OBSNEV, Universidad de Granada · GPL-3.0-or-later



Empezar
Herramientas
Ayuda
Start
Tools
- Earth Engine app
- QGIS plugin
- MCP: Claude and other assistants
- Python package
- R package
- Results viewer
Help