Manual de campo y de desarrollo
YieldRadar
Todo lo que hace la aplicación, pantalla por pantalla, más los tres capítulos que faltaban: cómo está protegida, cómo funcionan las licencias y cómo escribir, firmar y cobrar un plugin.
- Versión
- 7.21.19 · 168
- Android
- 7.0 o superior
- APK
- universal · 4 ABI
- Idiomas
- ES · EN · PT · AR · DE
Índice del manual
Qué es YieldRadar y qué trae esta versión
YieldRadar es un colector de datos geográficos que trabaja sin cobertura. Los
datos viven en un GeoPackage —el formato abierto de la OGC, un solo archivo
.gpkg que abre QGIS, ArcGIS y GDAL sin conversión— dentro del teléfono, y salen de él
cuando usted decida.
La aplicación cubre el ciclo completo: preparar el trabajo, conectar el receptor, capturar en campo, revisar, calcular y entregar. Funciona con el GPS del teléfono y con receptores GNSS externos de precisión centimétrica.
Novedades de 7.21.19
Atajo por modo nuevo
Cada modo de interfaz nombra su faena y la deja a un toque. El botón de modo del mapa ahora hace dos cosas: cambia de modo, o lanza el atajo si ya está en él.
Replanteo nuevo
Guiado a un punto de proyecto con distancia, azimut y ΔN/ΔE, aviso al entrar en tolerancia y registro de la estaca realmente clavada.
«Agro» ahora es «Campo»
Sólo cambia el nombre visible. Su configuración guardada y la de fábrica de la marca siguen intactas.
Barra inferior pareja
Los cuatro accesos —Mapa, GNSS, AR, Buscar— son ahora iconos del mismo peso, sin la pastilla que envolvía al elegido.
De las versiones inmediatamente anteriores conviene recordar: descarga de áreas y ruteo sin
conexión (7.21.17), candado de capa por niveles, trazo y ancho de línea en la simbología, perfil
del terreno accesible desde el modelo de elevación, y soporte de capas
GEOMETRYCOLLECTION.
Instalación y permisos
El entregable es un APK universal: un solo archivo válido para cualquier procesador (arm64, arm32, x86 y x86_64), incluidos los espacios virtuales y clonadores de aplicaciones. Va firmado con los tres esquemas —v1, v2 y v3— porque los clonadores reempaquetan y exigen el v1.
- Copie el
.apkal teléfono y ábralo. Android pedirá permiso para instalar aplicaciones de esta fuente: concédalo. - Abra la aplicación. En el primer arranque pedirá los permisos que necesita.
- Active la licencia (capítulo 3).
Qué permisos pide y para qué
| Permiso | Para qué | ¿Se puede negar? |
|---|---|---|
| Ubicación precisa | Posición GNSS, captura, replanteo, navegación | No: sin él la app no mide |
| Ubicación en segundo plano | Seguir grabando con la pantalla apagada | Sí, pierde el registro continuo |
| Cámara | Fotos y vídeo adjuntos a una entidad, vista AR | Sí, hasta que la use |
| Micrófono | Notas de audio y grabación de pantalla con voz | Sí |
| Almacenamiento / archivos | Leer e importar proyectos, escribir exportaciones | No para importar y exportar |
| Bluetooth | Receptor GNSS externo por Bluetooth o BLE | Sí, si usa el GPS interno |
| Notificaciones | Servicio en primer plano de GNSS y de descarga de áreas | Sí, pero conviene concederlo |
Un permiso declarado no es un permiso concedido. Si al abrir la cámara no ocurre nada, revise Ajustes de Android → Aplicaciones → YieldRadar → Permisos: Android puede haberlos revocado tras meses sin usar la aplicación.
Dónde viven sus datos
En el almacenamiento público del teléfono, en la carpeta YieldRadar/
(las instalaciones antiguas conservan también AgriCien/). Dentro, una carpeta por
proyecto:
YieldRadar/
proyectos/
Muestreo/
Muestreo.gpkg ← el proyecto entero: capas, entidades, atributos
multimedia/ ← fotos, audio y vídeo adjuntos
layers/ ← capas auxiliares importadas
offline/ ← mapas descargados (.mbtiles) y redes viales (.roads)
Esa ruta no depende del nombre visible de la marca, a propósito: renombrar la aplicación no debe dejar sus proyectos huérfanos.
Activar la licencia
Al primer arranque aparece la pantalla de licencia. Escriba el código que recibió y toque Activar. Hace falta conexión sólo en ese momento.
| Lo que ve | Qué significa | Qué hacer |
|---|---|---|
| Licencia activada | El código quedó vinculado a este equipo | Nada; a trabajar |
| Otro dispositivo | Ese código ya se activó en otro teléfono | Pida que liberen el equipo en el panel |
| Licencia vencida | Pasó la fecha de expiración | Renovar |
| Licencia inexistente | El código no está en el panel | Revise mayúsculas y guiones |
| Sin conexión | No se pudo consultar al servidor | Conéctese una vez; después funciona sin cobertura |
Trabajar sin cobertura
Tras la activación, la licencia queda validada localmente y la aplicación abre sin red durante 30 días. Pasado ese plazo pide una reconexión, que se resuelve en segundos con datos o WiFi. Es el equilibrio entre trabajar en una finca sin señal y que una licencia no siga viva indefinidamente en un equipo perdido.
El identificador de equipo depende de la clave con la que se firmó el APK. Si pasa de una versión de pruebas a una comercial, el mismo teléfono se presenta como un equipo distinto: hay que liberarlo en el panel y activarlo una vez más. No es un fallo, es cómo Android deriva ese identificador.
El detalle técnico —firma del veredicto, caché anti-fraude, panel— está en el capítulo 24.
Los tres modos y sus atajos
La misma aplicación, vestida para tres oficios. Los tres modos existen siempre y ninguno esconde funciones: cambian la densidad de la pantalla, el vocabulario y —desde 7.21.19— qué faena está a un toque.
| Modo | Pensado para | Atajo | Rejilla |
|---|---|---|---|
| Campo | Cuadrillas agrícolas; lenguaje llano, botones grandes | Empezar a trabajar | 2 columnas |
| GIS | Trabajo con capas, atributos y simbología | Revisar capas | 3 columnas |
| Topo | Topografía; todo a la vista, botones compactos | Replantear | 4 columnas |
Cómo se usa el atajo
Los tres botones de modo están en el mapa, arriba a la izquierda (se repliegan con la doble flecha). El activo va en naranja.
- Toque un modo distinto → cambia a ese modo, y el aviso que aparece abajo ofrece además su atajo: «Modo de interfaz: GIS · Revisar capas».
- Toque el modo en el que ya está → lanza el atajo directamente.
Es la diferencia entre seis toques y uno. Mantenga pulsado el botón del modo activo si duda: el tooltip dice qué va a hacer.
Qué hace cada atajo
Campo · Empezar a trabajar
Abre la sesión de captura sobre las capas activas, enciende el seguimiento GPS, despliega el panel de captura si estaba plegado y avisa: «Listo: pulse ➕ para tomar el punto en lotes». Un toque para armar, y uno por punto.
Si no hay ninguna capa activa lleva a Proyectos y lo dice. No elige la capa por usted: así es como se acaban los puntos del lote de ayer mezclados con los de hoy.
GIS · Revisar capas
Abre una hoja con todas las capas del proyecto, cada una con su número de entidades, su geometría y su candado. Al tocar una: la enciende en el mapa, la encuadra y la deja como capa de consulta, de modo que el siguiente toque sobre una entidad abre su ficha con Editar y Borrar. Manteniendo pulsada una capa se abre su tabla de atributos.
Topo · Replantear
Pregunta de dónde salen los puntos de proyecto —de una capa, de coordenadas tecleadas o siguiendo con el replanteo en curso— y entra en modo replanteo. Capítulo 13.
El hub: cuatro pestañas
La pantalla de entrada tiene cuatro pestañas fijas —preparar el trabajo, conectar el instrumento, levantar, calcular— y una rejilla de módulos en cada una. Los nombres de las pestañas cambian según el modo; los destinos, no.
| Pestaña | En Topo / GIS | En Campo | Qué hay dentro |
|---|---|---|---|
| 1 | Proyecto | Trabajo | Proyectos, Capas, Atributos, Puntos, Exportar, Importar, Unidades y coordenadas |
| 2 | Instrumento / GPS | Equipo | GNSS externo, NTRIP, Minicaster, Compartir GNSS, PPK, Estado del equipo |
| 3 | Levantamiento / Datos | Campo | Abrir mapa, Puntos, Líneas, Polígonos, AR |
| 4 | Herramientas | Utilidades | Mapa base, Servicios, Mapas sin conexión, Simbología, Módulos, Medir |
Arriba se ven siempre dos datos: el proyecto activo y el estado GNSS (calidad del fix, satélites usados/visibles, precisión y PDOP).
En modo Campo se ocultan de la rejilla los módulos que ese oficio no usa —minicaster, compartir GNSS, PPK, servicios OGC, simbología, tabla de atributos—. Siguen existiendo: se llega a ellos desde Ajustes y desde el menú lateral.
Barra inferior y menú lateral
La barra inferior flotante lleva cuatro accesos: Mapa, GNSS, AR y Buscar. El menú lateral (icono de hamburguesa) da acceso a Inicio, Módulos, Atajos, Ajustes, Registro de diagnóstico y Salir.
El mapa por dentro
Es la pantalla donde se pasa el día. Todo lo que flota sobre el mapa se puede plegar o mover.
Cintillos, de arriba abajo
| Cintillo | Qué muestra |
|---|---|
| Estado GNSS | Origen (📱 interno / 📡 externo), calidad, satélites, precisión, PDOP, edad de correcciones y su posición en la proyección elegida |
| Ruta | Maniobra actual, calle, distancia al giro y lo que queda |
| Replanteo | Punto, avance, distancia, azimut y componentes |
| Captura | Capa y número de nodos tomados |
Botones
- Barra de modos (izquierda): Topo · GIS · Campo, con su atajo.
- Barra de herramientas (derecha, arrastrable y plegable): superficie de elevación, acercar, alejar, norte, mi posición, captura de pantalla, hablar, capas y medir.
- Botón de captura ➕: se arrastra donde quiera y se queda ahí.
- Panel de captura: guardar, deshacer nodo, nueva parte, cancelar, automático, coordenadas y proyección de punto.
Gestos
- Un toque sobre una entidad de la capa de consulta abre su ficha.
- Mantener pulsado en cualquier punto abre el diálogo de navegación: guiado AR, Waze o Google Maps, y ruta sin conexión.
- Dos dedos: girar el mapa (si la rotación está activada en Ajustes).
Proyectos
Un proyecto es una carpeta con un GeoPackage dentro. Todo lo que capture vive ahí.
- Hub → Proyecto → Proyectos y toque +.
- Escriba el nombre. El diálogo muestra la proyección vigente y deja cambiarla ahí mismo; si no entra, se queda con la de siempre.
- Toque el proyecto para abrirlo. La aplicación lo recordará entre arranques.
Desde la lista se puede además renombrar, duplicar, borrar y compartir el .gpkg
entero. El primer arranque siembra un proyecto de ejemplo, GeoDataCollector, con capas de
los tres tipos para trastear sin miedo.
Al abrir la aplicación con un trabajo en curso, pregunta «¿Continúa con el mismo proyecto?» y dice cuál y con qué capa. Se pregunta una vez por lanzamiento: entrar y salir del mapa cincuenta veces al día no debe costar un diálogo cada vez.
Capas y candados
Una capa es una tabla de entidades de un tipo de geometría. Hub → Proyecto → Capas.
Crear y activar
Al crear una capa elige tipo: punto, línea, polígono o colección (una capa que admite las tres formas a la vez, como las que traen los geopaquetes de catastro).
Activar una capa es decir «aquí es donde van los puntos que tome». Hay una ranura por tipo de geometría más una de colección, así que puede tener a la vez la capa de puntos, la de líneas y la de polígonos recibiendo datos. En la lista, la capa en edición va en naranja y negrita; las simplemente visibles, en el color de acento.
Visibilidad y orden
El ojo enciende y apaga la capa en el mapa; las flechas la suben o bajan en el orden de dibujado; la lupa encuadra el mapa en ella.
El candado: tres niveles
Editar capa → Permisos de edición
| Nivel | Crear | Editar y borrar | Para qué |
|---|---|---|---|
| Abierta | Sí | Sí | Lo normal |
| Solo agregar | Sí | No | Proteger el trabajo de ayer mientras se sigue levantando |
| Bloqueada | No | No | Capa de consulta: catastro, cartografía de referencia |
El candado se impone en el motor de datos, no en cada pantalla: cubre el mapa, la lista de entidades, la importación de archivos y los plugins. Las pantallas además quitan de antemano lo que no se puede: el menú de una entidad bloqueada no ofrece Editar ni Borrar.
El candado es por dispositivo y no viaja dentro del .gpkg.
Protege del error de dedo en campo —borrar el lote de ayer mientras se toma el de hoy—, no de
quien quiera saltárselo.
Otras acciones de capa
- Vaciar: borra las entidades y deja la estructura.
- Copiar vacía: clona la capa con sus campos, sin datos. Es la vía rápida para la campaña del mes siguiente.
- Reconstruir índice: si el dibujado se vuelve lento tras miles de entidades.
- Importar entidades de otro archivo a esta capa.
- Exportar: GeoJSON, Shapefile (zip), GML, CSV, KML y GPX.
Atributos y entidades
Campos
Capas → Atributos. Cada capa nace con seis campos de plantilla —nombre, descripción, fecha de inicio, observaciones, creado y modificado— y las capas de punto suman trece de trazabilidad GNSS. Encima de eso se añaden los suyos: texto, número entero, número decimal, fecha, sí/no, lista de opciones y archivo adjunto (BLOB).
Los campos de plantilla no cuentan como campos propios: la guía le seguirá recordando que añada los suyos hasta que lo haga.
La tabla de entidades
Capas → Entidades abre la tabla completa: filtrar, ordenar, buscar, editar celda a celda, ver adjuntos, borrar y hacer zoom a una entidad. Es también el sitio donde se corrige a la vuelta lo que se anotó deprisa en campo.
El bloque de atributos
Al guardar una entidad se abre el formulario con sus campos. Recuerda el último valor escrito por capa (si lo activa en Ajustes) y avisa de nombres duplicados. Los campos GNSS se rellenan solos con la calidad del momento de la captura, no del momento en que usted termina de escribir.
Capturar datos
Cinco vías, todas sobre la capa activa.
| Vía | Cómo | Cuándo |
|---|---|---|
| Punto GNSS | Botón ➕ | Lo habitual: toma la posición actual |
| Punto promediado | Panel → promediar | Vértices y mojones: promedia N épocas y reporta σ |
| Toque en el mapa | Tocar donde va el nodo | Digitalizar sobre ortofoto |
| Coordenadas | Panel → coordenadas | Punto de una libreta, en WGS84 o CRTM05 |
| Automático | Panel → auto | Recorridos: un nodo cada X metros o cada X segundos |
Líneas y polígonos
Cada toque o cada ➕ añade un nodo. Nueva parte empieza otro trazado dentro de la misma entidad (una finca con dos lotes separados). Deshacer quita el último nodo. Guardar cierra la geometría y abre el formulario.
Proyección de punto
Distancia y azimut desde el último punto capturado, desde su posición o desde el centro del mapa. Para el vértice al que no se puede llegar con el jalón.
Puertas de calidad
Antes de escribir nada, la aplicación comprueba:
- Que la posición venga de satélites. Si hay satélites a la vista y ninguno en el cálculo, lo que entrega el teléfono es un relleno de red con precisión de cientos de metros: se rechaza con «No viene de satélites: N a la vista, 0 en el cálculo. Punto no registrado». Esta puerta no se puede desactivar.
- RTK fijo, si lo exige en Ajustes (sólo con receptor externo).
- Precisión mínima en metros, si la configuró.
GNSS y RTK
Hub → Instrumento. Cada mosaico abre su sección del panel GNSS.
Origen de la posición
La aplicación usa el chip del teléfono por defecto y un receptor externo cuando lo configura. El chip queda de reserva caliente: si el receptor externo calla más de ocho segundos —batería, Bluetooth, fuera de alcance—, la posición vuelve al interno en vez de quedarse ciega, y regresa al externo en cuanto vuelve.
Receptor externo
| Vía | Notas |
|---|---|
| Bluetooth clásico | Empareje primero en Android; luego elija el equipo en la lista |
| Bluetooth LE | Receptores modernos de bajo consumo |
| WiFi (TCP) | Host y puerto del receptor; puerto RTCM aparte para las correcciones |
| USB serie | FTDI, Prolific, CP210x, CH340 y CDC-ACM; se elige la velocidad |
Con el teléfono conectado a la WiFi del receptor no hay salida a internet por esa red. La aplicación lo tiene en cuenta y busca conexión por cualquier red disponible, así que los datos móviles siguen sirviendo para NTRIP y para el catálogo de plugins.
NTRIP
Proveedores y credenciales, descarga del sourcetable, elección de mountpoint y estado de la conexión. Con redes virtuales (VRS/NEAR), la aplicación envía su posición al caster automáticamente. La edad de las correcciones sale en el cintillo del mapa: si crece, el RTK se está degradando.
Minicaster y compartir
Minicaster convierte el equipo en base: retransmite las correcciones de su receptor a otros equipos de la cuadrilla. Compartir GNSS publica la posición para que otra aplicación del mismo teléfono la consuma.
PPK
Registro crudo de observaciones para postproceso. Se graba durante el levantamiento y se descarga después.
Estado del equipo
Constelaciones, relación señal/ruido por satélite, DOP, tipo de solución y edad de correcciones. Es la pantalla a la que hay que mirar antes de dudar de un dato.
Precisión, alturas y coordenadas
Altura de antena
La cota que se guarda es la del terreno, no la de la antena. Escriba la altura del bastón en Ajustes → Levantamiento.
Si su receptor tiene compensación de inclinación (IMU) y entrega ya la posición de la punta del bastón, active «el receptor referencia la punta». Con esa opción la corrección vertical es cero: restar además la altura del bastón la descontaría dos veces, y con el bastón inclinado ni siquiera sería la corrección correcta.
Promediado
Actívelo para que cada punto sea la media de N épocas o de T segundos, lo que ocurra primero. El diálogo muestra el avance, la media en coordenadas proyectadas y las desviaciones σ horizontal y vertical. Con el filtro de RTK fijo activo sólo cuentan las épocas fijas.
Geoide y cota ortométrica
Con un modelo de geoide instalado (EGM2008), la aplicación convierte la altura elipsoidal en ortométrica: H = h − N. Sin modelo, marca el valor como elipsoidal en vez de fingir.
Sistema de coordenadas
Hub → Proyecto → Unidades y coordenadas. Elija el EPSG —CRTM05 (8908) es el predeterminado en Costa Rica— o pegue una cadena proj4 propia. Ahí mismo se fijan las unidades de longitud (m, km, ft) y de área (m², ha, ac, km²), que mandan en todo lo que muestra la aplicación.
En el primer arranque, la aplicación pregunta si conoce la proyección que utiliza. Si dice que no, fija el UTM WGS 84 de su zona y se lo comunica.
Replanteo nuevo
Llevar al terreno un punto que existe en el proyecto: ir hasta él, clavar la estaca y dejar registrado dónde quedó realmente.
- Póngase en modo Topo y toque su botón otra vez (o use Replantear del aviso al cambiar de modo).
- Elija de dónde salen los puntos: Puntos de una capa del proyecto, o Coordenadas tecleadas en WGS84 o CRTM05.
- Camine siguiendo la flecha y los números. Al entrar en tolerancia, el equipo pita y la diana se pone verde.
- Clave la estaca y toque Guardar: se registra su posición medida con la desviación respecto al proyecto, y pasa al punto siguiente.
Lo que dice el cintillo
P-14 · 3/37 · 12 ✓ · 3,42 m · 47°
2,33 m al norte · 2,50 m al este · cortar 0,18 m
| Dato | Qué es |
|---|---|
| P-14 | Nombre del punto de proyecto |
| 3/37 · 12 ✓ | Va por el tercero de treinta y siete; doce ya clavados |
| 3,42 m | Distancia horizontal. Bajo 1 m pasa a centímetros, bajo 1 cm a milímetros |
| 47° | Azimut geográfico al punto, el que se teclea en una estación total |
| 2,33 m al norte | Componentes que hay que caminar. En palabras, no en signos |
| cortar 0,18 m | Diferencia de cota, si el punto de proyecto trae cota |
Detalles que importan en el terreno
- La flecha gira respecto a su rumbo sólo si el rumbo vale algo. Parado, el rumbo del GNSS da vueltas enteras, así que por debajo de 0,5 m/s la flecha apunta al azimut geográfico: no ayuda a girar, pero no miente.
- El pitido suena al entrar en tolerancia, no mientras se está dentro. Un pitido por época con el jalón apoyado acaba con el sonido apagado y el punto siguiente sin aviso.
- La tolerancia se fija una vez (10 cm por defecto) desde el mismo diálogo del atajo, y sólo mira la planta: un centímetro en planta con medio metro de desnivel es una estaca bien puesta.
- ◀ ▶ recorren la lista y dan la vuelta al llegar al final: en campo se salta el punto que tiene un carro encima y se vuelve a él al terminar.
- La lista no ofrece el registro interno de capturas ni las capas vacías: un replanteo se hace contra puntos de proyecto.
Qué se guarda
La posición medida, no la coordenada de proyecto — es lo que distingue un
replanteo de un dibujo. En la descripción queda la desviación: Replanteo de P-14 · N 2,33 m ·
E 2,50 m · dist 3,42 m, y los campos GNSS de la capa recogen la calidad del momento.
Hace falta una capa de puntos activa donde escribir. Si la capa está bajo candado, se dice como tal; y si la posición no viene de satélites, no se registra nada.
Las componentes se resuelven sobre el plano tangente al elipsoide WGS 84 con el radio real de cada dirección —el del meridiano para el norte, el de la primera vertical para el este—, y la distancia es exactamente la hipotenusa de las dos: lo que dice el cintillo se puede comprobar con una calculadora. Por encima de 10 km la aplicación deja de hablar de replanteo y dice que se acerque.
Medir y calcular
El botón de medición del mapa abre un trazado temporal que no toca sus datos: toque para poner nodos y lea distancias parciales, distancia total, área y ángulos interiores. Cerrando el trazado se obtiene el área del recinto.
El cintillo de medición es además la puerta a los cálculos de movimiento de tierras y al perfil del terreno (capítulo 15).
Extensión de cálculos topográficos
Como módulo aparte se distribuye la calculadora de campo: inversa y directa, factores de cuadrícula a terreno, intersecciones, resección con aviso de círculo peligroso, poligonal con ajuste, división de líneas y áreas, curvas horizontales y verticales, nivelación, volúmenes y conversión de coordenadas. Toma puntos del proyecto o del GNSS y devuelve los resultados a una capa del GeoPackage. No declara permiso de red: los cálculos no salen del equipo.
Modelo de elevación y movimiento de tierras
El botón de superficie del mapa levanta un modelo del terreno con los puntos que ya tiene levantados: interpolación IDW o triangulación TIN, con rampa hipsométrica de colores.
De qué puntos se construye
De las capas con cota y del registro de captura. Puede excluir puntos por precisión —descartar todo lo que pase de X metros— para que un fix malo no deforme la superficie.
Corte y relleno
Con una superficie y un recinto medido: la aplicación calcula volumen de corte, de relleno, su diferencia, y el nivel de plataforma que los equilibra. Con la capacidad de la vagoneta configurada, traduce el volumen a viajes. El resultado se comparte como texto o imagen.
Perfil del terreno
Modelo de elevación → Perfil del terreno → Trazar un perfil. La aplicación da el paso que falte: sin modelo lo enciende, sin trazado entra en Medir y pide los puntos, y con todo listo calcula. IDW o TIN se eligen en el mismo diálogo.
Auto-survey
Con la superficie encendida, la aplicación puede ir añadiendo puntos al modelo mientras camina, respetando la precisión mínima y una distancia mínima entre muestras.
Multimedia y evidencias
| Qué | Dónde | Cómo se guarda |
|---|---|---|
| Fotos y vídeo | Formulario de la entidad | En multimedia/ del proyecto, referenciados desde la entidad |
| Notas de audio | Formulario de la entidad | Grabadas dentro de la aplicación |
| Archivos | Campo de tipo adjunto | Cualquier documento; también dentro del .gpkg como BLOB |
| Captura de pantalla | Botón del mapa | Sólo el mapa o la pantalla completa |
| Grabación de pantalla | Botón del mapa | Para soporte: reproduce el problema y lo manda |
Al exportar el proyecto puede incluirse el paquete multimedia completo, de modo que quien lo reciba vea las fotos junto a las entidades.
Mapa base y servicios OGC
Mapa base
Hub → Herramientas → Mapa base: callejero, satélite, satélite con rótulos o ninguno (fondo limpio para trabajar sólo con sus capas).
Servicios
Hub → Herramientas → Servicios añade capas remotas:
- WMS y WMTS: cartografía oficial, ortofotos institucionales.
- XYZ: cualquier teselado estándar.
- WFS: entidades vectoriales consultables.
Se guarda nodo, tipo, capas y cobertura. Desde la hoja de capas activas del mapa se elige cuál responde a los toques, y se ocultan las que estorben.
Trabajar sin conexión
Lo que se lleva al campo se baja antes, con cobertura.
- Hub → Herramientas → Mapas sin conexión → + → Descargar área desde el mapa
- Encuadre el área en el mapa y ajuste el recuadro. La pantalla se abre donde usted está: primero en el fix GNSS, y si no lo hay, en el último centro del mapa.
- Elija el rango de zoom. La aplicación estima cuántas teselas y cuántos megas son antes de empezar.
- Descargue. Es un servicio en primer plano: bajar un cantón son minutos y apagar la pantalla no lo aborta.
El resultado son dos archivos hermanos en la carpeta offline:
<área>.mbtiles— las teselas de la capa base activa.<área>.roads— la red vial de la zona, para rutear sin cobertura.
Los servidores públicos de datos viales se saturan. Si las teselas se bajaron y la red vial no, la aplicación lo dice y conserva lo descargado: 22 MB de ortofoto siguen sirviendo aunque no haya ruteo.
Otros archivos sin conexión
También se importan mapas propios: .mbtiles ya hechos y ortofotos georreferenciadas
en GeoTIFF. Se encienden, se apagan y se encuadran desde la misma pantalla.
Navegación y rutas
Mantenga pulsado un punto del mapa —o busque un lugar por nombre— y aparecen las tres vías, cada una con su estado real debajo:
| Vía | Qué hace | Necesita |
|---|---|---|
| Guiado AR | Campo a través, con brújula, distancia y avisos sonoros de rumbo | Nada |
| Waze / Google Maps | Por carretera, en la aplicación que ya usa | Internet y la app instalada |
| Ruta sin conexión | Por calles reales, con maniobras habladas en el cintillo | Un área descargada con su red vial |
Ninguna se oculta cuando no sirve: si falta el área descargada, la opción lleva a descargarla. Al llegar por carretera, el guiado AR toma el relevo para el último tramo a pie.
Herramientas AR
La vista de realidad aumentada añade sobre la cámara: brújula con rumbo objetivo, distancia acumulada, nivel de burbuja, clinómetro, cruz de suelo, linterna, captura y compartir posición. Los avisos sonoros permiten caminar mirando el terreno en vez de la pantalla.
Simbología
Hub → Herramientas → Simbología, con un proyecto abierto.
Tipos de simbología
- Único: un color y un trazo para toda la capa.
- Categorizado: un color por valor de un campo (por variedad, por estado).
- Graduado: rampa por rango numérico (por rendimiento, por profundidad).
Línea y borde
Ancho de 1 a 20 px y cinco trazados: continuo, discontinuo, punteado, raya-punto y marcadores. La muestra en vivo es una línea quebrada a propósito: en una recta, discontinuo y punteado no se distinguen. El patrón se escala con el ancho, no en píxeles fijos.
Etiquetas
Se elige el campo que rotula cada entidad, si se evitan solapes y desde qué número empieza la numeración automática.
Exportar e importar
Formatos
| Formato | Exporta | Importa | Nota |
|---|---|---|---|
| GeoPackage | Sí | Sí | El proyecto entero, tal cual |
| GeoJSON | Sí | Sí | RFC 7946 |
| Shapefile | Sí (zip) | Sí | Con su .prj; se reproyecta al leer |
| KML / KMZ | Sí | Sí | Google Earth |
| GPX | Sí | Sí | Waypoints y trazas |
| CSV | Sí | Sí | Tabla con coordenadas |
| GML | Sí | — | OGC GML 3.2.1 |
| GeoTIFF | — | Sí | Ortofotos y ráster georreferenciado |
Destinos
Además de guardar en el teléfono y compartir por cualquier aplicación:
- PostgreSQL / PostGIS — escribe directo a la base corporativa.
- FTP y SFTP — servidores propios.
- Amazon S3 — con cifrado del lado del cliente: lo que sube ya va cifrado y el proveedor no puede leerlo.
- Google Drive y GitHub — repositorios de la organización.
Las credenciales de todos ellos se guardan cifradas (capítulo 23).
Copia de la configuración
Ajustes → Copia de configuración exporta e importa los ajustes del equipo —unidades, proyección, receptores, proveedores NTRIP, destinos— para clonar la configuración en el resto de la cuadrilla sin repetirla equipo por equipo. Las contraseñas no viajan en claro.
Ajustes: referencia completa
| Pantalla | Qué contiene |
|---|---|
| General | Idioma (ES · EN · PT · AR · DE) y copia de configuración |
| Apariencia | Modo de interfaz, tema claro/oscuro/sistema, paleta para daltonismo, tamaño de letra |
| Mapa | Rotación, zoom automático por velocidad, guardar al volver, centrar siempre en el GPS, botón de medir, etiquetas de distancia, botones de zoom, mantener pantalla encendida |
| Unidades y coordenadas | EPSG, proj4 propio, unidad de longitud y de área, capacidad de vagoneta |
| Levantamiento | Exportar info GPS, cota ortométrica, modelo de geoide, altura de antena, duración del promedio, precisión mínima, aviso de nombre duplicado, reutilizar el último nombre |
| Otros | Navegación (Waze, radio de llegada), seguimiento (grabar traza, exigir RTK fijo, automático por distancia y por tiempo, punta referenciada, altura, promediado, épocas y segundos) y exportación (nombre de equipo, prefijos de punto, línea y polígono) |
| Conexiones remotas | PostGIS, FTP/SFTP, S3, Google Drive, repositorios de GitHub, con botones de prueba |
| GNSS externo | Bluetooth, BLE, TCP/WiFi, USB y sus parámetros |
| NTRIP | Proveedores, credenciales y mountpoints |
| Plugins | Modo desarrollador (permite ejecutar módulos sin firmar) |
| Acerca de | Versión, estado de licencia, patente, desarrollador, documentación y contacto |
Las secciones de GNSS externo y NTRIP no aparecen en el índice de Ajustes: se abren desde el panel del instrumento, junto a las acciones con las que se usan.
Seguridad de YieldRadar
Qué protege la aplicación, con qué, y —tan importante como lo anterior— qué no protege.
Credenciales cifradas
Las contraseñas de PostGIS, FTP/SFTP, S3, NTRIP y los tokens de repositorios no se guardan en claro. Se cifran con AES-256-GCM usando una clave que vive en el Android Keystore —en el elemento seguro del equipo cuando el hardware lo soporta— y que no es extraíble ni con acceso al almacenamiento de la aplicación.
Tráfico de red
El tráfico en claro está prohibido salvo donde el protocolo no deja alternativa (un caster NTRIP en HTTP simple, un servidor FTP de la propia organización). Cada excepción está declarada en la política de red del paquete, no abierta en general.
Cifrado del lado del cliente
Al exportar a S3, los archivos se cifran antes de salir del teléfono, con una clave por proyecto. El proveedor de almacenamiento guarda un bloque opaco: aunque el bucket quedara expuesto, el contenido no es legible.
Informe de seguridad auditable
La aplicación puede generar un informe de su propia postura de seguridad: dónde vive la clave maestra, si el paquete es depurable, qué extensiones hay instaladas y con qué permisos, y qué controles cumple o incumple. Está pensado para que el responsable de seguridad de un cliente lo revise sin creer en promesas.
La huella del certificado de firma es pública y se entrega con el producto. Comparándola con la
del paquete instalado se comprueba que nadie lo reempaquetó por el camino. La huella de YieldRadar
empieza por A5:46:32:45:39:99.
Lo que no protege
- Un equipo con root. Quien ejecuta código dentro del proceso de la aplicación puede leer lo que la aplicación lee.
- El candado de capa es contra el error de dedo, no contra un adversario.
- Los tokens de repositorio incrustados en el APK —el buzón compartido de datos de la marca— viajan dentro del paquete: son compartidos por todos los usuarios de la marca y la propia aplicación los señala como tales. No ponga ahí nada privado.
- Un APK depurable permitiría adjuntar un depurador al proceso. Por eso lo que se entrega es la variante de publicación, no la de depuración.
Licencias por dentro
Para quien administra la flota o integra el panel.
Cómo se valida
- La aplicación envía el código de licencia y el identificador de equipo al endpoint
/api/validar-licenciadel panel de YieldRadar. - El servidor responde con un veredicto: si es válida, de qué tipo, cuándo expira y —lo importante— una firma ECDSA P-256 sobre esa respuesta.
- El APK verifica la firma con la clave pública que lleva dentro. Una respuesta sin firma válida se rechaza, venga de donde venga.
- El veredicto se guarda cifrado para poder abrir sin cobertura durante 30 días.
La presencia de la clave pública en el APK es el interruptor: con clave, se exige respuesta firmada; sin ella, se acepta sin firmar. Eso permitió desplegar el servidor primero y publicar el APK después sin dejar a nadie fuera.
Anti-fraude local
- Una activación por licencia. El servidor vincula el equipo la primera vez; a
partir de ahí, otro teléfono recibe
otro_dispositivo. - Detección de reloj atrasado. Retrasar la fecha del teléfono no alarga la ventana sin conexión.
- Reconexión obligatoria a los 30 días.
Operación
| Situación | Qué hacer en el panel |
|---|---|
| El usuario cambió de teléfono | Liberar el equipo; la próxima activación lo vincula |
| Se pasó de APK de pruebas a comercial | Liberar y reactivar una vez por equipo: el identificador cambia con la clave de firma |
| Teléfono perdido | Liberar; el equipo perdido deja de abrir a los 30 días como mucho |
| Renovación | Ampliar la fecha; el equipo lo recoge en la siguiente comprobación |
La clave privada con la que el panel firma los veredictos y la clave de firma del APK son los dos secretos que no se pueden perder ni filtrar. Si se pierde la clave de firma del APK, esa marca no se puede volver a actualizar jamás: Android sólo acepta actualizar un paquete con la misma clave que lo firmó.
Plugins: qué son y cómo se usan
Un plugin es una aplicación web —HTML, CSS y JavaScript— que corre dentro de YieldRadar y habla con el proyecto a través de un puente controlado por permisos. Sirve para lo que el núcleo no hace: una calculadora de un gremio, un formulario de una norma, un informe propio de la empresa.
Instalar uno
- Menú lateral → Módulos → Instalar módulo
- Elija el archivo
.mtplug, o descárguelo del catálogo del repositorio configurado. - La aplicación verifica la firma y muestra qué permisos pide. Acepte o cancele.
- El módulo aparece en Hub → Herramientas → Módulos y en el menú lateral.
Los tres niveles de confianza
| Nivel | Qué significa | ¿Se ejecuta? |
|---|---|---|
| Verificado | Cadena raíz → editor → paquete correcta, y todos los archivos íntegros | Sí |
| Sin firmar | El paquete no trae META/ | Sólo con el modo desarrollador activado |
| Inválido | Hay firma pero no valida, o algún archivo fue alterado | Nunca |
Permisos que puede pedir un plugin
| Permiso | Le permite |
|---|---|
gnss | Leer la posición actual y encender/apagar el GNSS |
network | Llamar por HTTP a los dominios que declare, y sólo a esos |
storage.read | Listar proyectos y capas, leer entidades y esquemas |
storage.write | Crear capas y campos, insertar y modificar entidades |
storage.delete | Borrar entidades |
camera | Tomar una foto y adjuntarla a una entidad |
map | Centrar el mapa |
license | Pedir la identidad del equipo y un token firmado (para cobrar) |
audit | Generar el informe de seguridad del núcleo |
Cada método del puente exige el suyo. Sin declararlo en el manifiesto y sin que el usuario lo conceda, la llamada devuelve error. Un plugin del formato antiguo (v1, sin declaración) recibe sólo los permisos de lectura y escritura no destructiva: nunca borrado ni cámara.
Aislamiento entre plugins
Cada plugin corre en su propio origen web, así que su almacenamiento del navegador está separado
del de los demás. Para lo sensible hay un almacén cifrado por plugin (secureGet /
securePut) cuya clave vive en el Keystore y cuya identidad va atada al plugin: un valor
guardado por el plugin A no se puede descifrar presentándolo como del plugin B.
Catálogo por repositorio
Compartir un .mtplug por mensajería no es fiable —WhatsApp y otros renombran o
recomprimen los adjuntos que no reconocen—. Por eso los módulos se publican en un repositorio de
GitHub con un catalog.json; el usuario elige de una lista y las actualizaciones llegan
solas. La seguridad no depende del transporte: la firma cubre el hash de cada archivo, así que un
repositorio comprometido no puede colar un plugin alterado, como mucho dejar de servirlo.
QuickStart: un plugin interno para su empresa
Objetivo: en una tarde, un módulo que sólo usará su cuadrilla. Ejemplo real: un control de visitas que registra el punto donde está el técnico, con el número de finca y el motivo, en una capa del proyecto abierto.
1 · La estructura mínima
ControlVisitas/
manifest.json ← identidad y permisos
index.html ← su interfaz
app.js ← su lógica
geodata-sdk.js ← el SDK (cópielo de plugins_seguros/sdk/)
2 · El manifiesto
manifest.json
{
"manifest_version": 2,
"plugin_id": "cr.miempresa.controlvisitas",
"publisher_id": "miempresa",
"title": "Control de visitas",
"version": "1.0.0",
"entryPoint": "index.html",
"author": "Mi Empresa S.A.",
"description": "Registra la visita del tecnico con finca y motivo.",
"min_app_version": "7.21.15",
"license_mode": "free",
"permissions": ["gnss", "storage.read", "storage.write"],
"network": { "allowedHosts": [] }
}
plugin_id + publisher_id son la identidad real del módulo: el nombre
de la carpeta y el título no identifican nada. Use un identificador con su dominio invertido para
no chocar con nadie. Y no declare network si no llama a ningún servidor: el usuario
ve la lista de permisos antes de aceptar, y una lista corta genera confianza.
3 · La interfaz
index.html
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Control de visitas</title>
<style>
body { font: 16px/1.5 system-ui, sans-serif; margin: 0; padding: 16px; }
label { display: block; margin: 14px 0 4px; font-weight: 600; }
input, select, button { width: 100%; padding: 12px; font-size: 16px; }
button { margin-top: 20px; background: #0B5C48; color: #fff; border: 0; border-radius: 6px; }
#estado { margin-top: 14px; min-height: 24px; }
</style>
</head>
<body>
<h1>Control de visitas</h1>
<label for="finca">Finca</label>
<input id="finca" placeholder="F-104">
<label for="motivo">Motivo</label>
<select id="motivo">
<option>Inspeccion</option>
<option>Muestreo</option>
<option>Entrega</option>
</select>
<button id="guardar">Registrar aqui</button>
<p id="estado"></p>
<script src="geodata-sdk.js"></script>
<script src="app.js"></script>
</body>
</html>
4 · La lógica
app.js
const CAPA = "visitas";
const estado = document.getElementById("estado");
let PROYECTO = null;
// Al abrir: averiguar en que proyecto esta trabajando el usuario y asegurar la capa.
// Ojo: las llamadas de datos del SDK son SINCRONAS, no llevan await.
(function preparar() {
try {
const activo = GeoData.data.active(); // permiso: storage.read
PROYECTO = activo && activo.project;
if (!PROYECTO) { estado.textContent = "Abra un proyecto primero."; return; }
if (!GeoData.data.layerExists(PROYECTO, CAPA)) {
GeoData.data.createLayer(PROYECTO, CAPA, "POINT"); // permiso: storage.write
GeoData.data.addAttribute(PROYECTO, CAPA, "finca", "TEXT");
GeoData.data.addAttribute(PROYECTO, CAPA, "motivo", "TEXT");
estado.textContent = "Capa «visitas» creada.";
}
} catch (e) {
estado.textContent = "No se pudo preparar la capa: " + e.message;
}
})();
document.getElementById("guardar").addEventListener("click", () => {
estado.textContent = "Tomando posicion...";
try {
const fix = GeoData.gnss.current(); // permiso: gnss → {lat, lon}
if (!fix || (fix.lat === 0 && fix.lon === 0)) {
estado.textContent = "Todavia sin posicion: salga a cielo abierto.";
return;
}
GeoData.data.insert(PROYECTO, CAPA, "POINT", [fix.lon, fix.lat], {
nombre: document.getElementById("finca").value || "sin finca",
finca: document.getElementById("finca").value,
motivo: document.getElementById("motivo").value
});
estado.textContent = "Visita registrada.";
} catch (e) {
if (e.name === "PermissionError") {
estado.textContent = "Falta el permiso " + e.permission;
} else {
estado.textContent = "Error: " + e.message;
}
}
});
El orden de la coordenada es [lon, lat], no al revés: es el orden
de GeoJSON y del GeoPackage, y equivocarlo le deja los puntos en el otro hemisferio.
gnss.current() devuelve sólo {lat, lon} —si aún no hay
fix devuelve ceros, que es el caso que hay que atrapar; la calidad del fix la vigila la aplicación
con sus propias puertas, no el plugin. Y active() es la forma correcta de
saber dónde escribir: listProjects() enumera los proyectos del equipo pero
no dice cuál está abierto.
5 · Probarlo sin firmar
- Active Ajustes → Plugins → Modo desarrollador. Con él, la aplicación ejecuta módulos sin firma —y lo advierte en pantalla—.
- Comprima la carpeta y renómbrela a
ControlVisitas.mtplug. - Instálelo desde Módulos, ábralo y pruebe.
- Para depurar, conecte el teléfono y abra
chrome://inspecten el ordenador: el WebView del plugin aparece ahí con su consola completa.
El puente es síncrono y devuelve cadenas JSON; el SDK lo envuelve en promesas y
objetos, y convierte los errores de permiso en PermissionError. Escriba siempre contra
el SDK: si mañana cambia el nombre del puente, su plugin no se entera.
6 · Repartirlo a la cuadrilla
Para uso interno hay dos vías. La rápida: pasar el .mtplug por USB o por correo (no
por mensajería, que renombra los adjuntos). La ordenada: un repositorio de GitHub privado de la
empresa con un catalog.json, configurado una vez en cada equipo desde
Ajustes → Conexiones remotas → Repositorios de GitHub; a partir de ahí las
actualizaciones se instalan desde la lista.
Antes de repartirlo, fírmelo: es el siguiente capítulo, y evita que sus técnicos tengan que dejar el modo desarrollador encendido.
Firmar y proteger el código
La cadena de confianza
clave raiz (fabricante) --firma--> certificado de editor
clave de editor --firma--> META/hashes.json del paquete
META/hashes.json --cubre--> SHA-256 de CADA archivo del plugin
Criptografía: ECDSA sobre la curva P-256 con SHA-256. Se eligió P-256 y no Ed25519 porque Android sólo trae Ed25519 nativo desde la versión 13 y la aplicación soporta desde la 7.0; además P-256 es la curva que admite el Keystore, que es lo que se usa para los tokens de licencia.
Qué hay dentro de un paquete firmado
| Archivo | Contenido |
|---|---|
META/hashes.json | {"alg":"SHA-256","files":{"index.html":"…", …}} |
META/publisher.cert.json | Identidad del editor y su clave pública, firmadas por la raíz |
META/signature.json | Firma del editor sobre los bytes crudos de hashes.json |
Los bytes que se firman están definidos literalmente, no como JSON canonicalizado, para que
reimplementar el verificador en cualquier lenguaje sea inequívoco: el certificado firma la cadena
publisher_id \n name \n pubkey \n issued \n expires, y el paquete firma los bytes
exactos del archivo hashes.json tal y como quedan en disco.
Firmar, paso a paso
herramienta de referencia: mtsign.py
# Una sola vez, en un equipo controlado: la clave raiz (la guarda el fabricante)
python mtsign.py root-init
# Una vez por editor: el fabricante emite su certificado
python mtsign.py publisher-new --id miempresa --name "Mi Empresa S.A." --years 3
# Cada vez que publique una version del plugin
python mtsign.py pack ControlVisitas --publisher publishers/miempresa \
-o ControlVisitas-1.0.0.mtplug
# Comprobar antes de repartir
python mtsign.py verify ControlVisitas-1.0.0.mtplug
Para sustituir la raíz: genere una nueva, actualice la constante del binario, reemita los certificados de editor y deje la clave antigua aceptada durante una versión, para no invalidar de golpe lo ya distribuido. Un OEM puede además añadir su propia autoridad dejando claves públicas en los assets de su sabor — como viajan dentro del APK firmado, añadir una raíz exige recompilar la aplicación.
Qué protege la firma… y qué no
| Amenaza | ¿Cubierta? |
|---|---|
| Alguien modifica un archivo del paquete | Sí: el hash no cuadra y no se ejecuta |
| Alguien sustituye el plugin en el repositorio | Sí: no puede firmar como su editor |
| Alguien publica un plugin haciéndose pasar por usted | Sí: su publisher_id exige el certificado |
| El usuario lee su código JavaScript | No. El paquete está en su teléfono |
| El usuario parchea su código y lo reempaqueta | Quedaría sin firmar: sólo corre con modo desarrollador |
Proteger de verdad su propiedad intelectual
La firma garantiza integridad y origen, no confidencialidad. Si su valor está en el algoritmo, aplique estas tres, por orden de eficacia:
- Lo que vale, en el servidor. El plugin es la interfaz; el cálculo caro vive en su API. Es la única protección que no se puede revertir en el teléfono.
- Minifique y ofusque lo que sí baja (esbuild, terser). Sube el coste de leerlo; no lo impide.
- Nunca incruste secretos en el paquete. Ni claves de API, ni contraseñas: lo
que va dentro del
.mtpluges público de facto. Para lo que deba persistir en el equipo use el almacén cifrado del puente (securePut), nolocalStorage.
Monetizar un plugin
El problema a resolver: su servidor de licencias no puede distinguir una
petición hecha por su plugin, dentro de la aplicación de verdad, de un curl que imita
la llamada. La attestation lo resuelve.
Cómo funciona
- Su plugin pide un nonce a su servidor.
- Llama a
GeoData.license.attest(nonce): la aplicación firma ese nonce con una clave privada que vive en el Android Keystore del equipo y que no es extraíble. - Su servidor verifica la firma y decide si ese dispositivo tiene licencia.
- Guarde la respuesta cifrada con
GeoData.secure.setpara trabajar sin cobertura un tiempo.
puerta de licencia, esquema
// El SDK ya encadena las cuatro fases: nonce → firma → canje → guardado cifrado.
// Su servidor sólo tiene que ofrecer GET /nonce y POST /verify.
const API = "https://licencias.miempresa.com/api/v1/controlvisitas";
async function comprobarLicencia() {
try {
const r = await GeoData.license.verify(API, { graceDays: 30 });
if (r.valid && r.offline) {
estado.textContent = "Licencia validada sin cobertura, con la copia guardada.";
}
return r.valid;
} catch (e) {
return false;
}
}
Si necesita el control fino —porque su protocolo no es ese— las tres piezas están sueltas:
const info = GeoData.license.info(); // sin permiso: quien soy y en que marca corro
const nonce = await (await fetch(API + "/nonce")).json();
// Requiere el permiso `license` declarado en el manifiesto
const token = GeoData.license.attest(nonce.nonce); // {alg, payload_b64, sig_b64, device_key_b64, key_chain_b64}
const r = await fetch(API + "/verify", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ nonce: nonce.nonce, attestation: token,
plugin: info.plugin_id, version: info.version })
});
const veredicto = await r.json();
if (veredicto.valid) {
GeoData.secure.set("licencia", JSON.stringify({
hasta: veredicto.claims && veredicto.claims.expira, guardado: Date.now()
}));
}
return veredicto.valid;
Sin un nonce fresco por cada comprobación, un token capturado una vez sirve para siempre y la
attestation deja de probar nada. license.attest() es síncrona y lanza
PermissionError si no declaró license en el manifiesto;
license.verify() sí devuelve una promesa, porque habla con la red.
Qué recibe usted del dispositivo
| Dato | Qué es |
|---|---|
device_alias | Alias derivado por HMAC, distinto para cada par editor+plugin |
| Firma del nonce | Hecha con clave de hardware no extraíble |
plugin_id, publisher_id, versión | Qué se está ejecutando |
| Marca y versión de la app | Para exigir un mínimo |
Usted puede atar una licencia a un dispositivo, pero no obtiene el identificador real del equipo ni puede correlacionar al mismo usuario entre plugins de editores distintos. Es deliberado: la privacidad del usuario final no es negociable a cambio de su modelo de negocio.
Lo que se paga debe estar en el servidor, no en el plugin. El archivo de la puerta de licencia se ejecuta en el teléfono del cliente y es legible: alguien con conocimientos puede parchear la comprobación. Reparta su producto como lo hace AgriClima: el pronóstico básico funciona sin licencia, y lo que de verdad se cobra —el pronóstico estacional calibrado— lo calcula el servidor y sólo se sirve con un token válido. Parchear el JavaScript no da acceso a eso.
Lista de comprobación antes de vender
| Punto | Por qué |
|---|---|
"license_mode": "licensed" en el manifiesto | La aplicación lo presenta como módulo de pago |
Permiso license declarado | Sin él, requestAttestation devuelve error |
allowedHosts con su API | Sin declararla, la llamada de red se bloquea |
| Nonce de un solo uso y con caducidad | Un token capturado no debe valer dos veces |
| Periodo de gracia sin cobertura | El campo no siempre tiene señal; 30 días es lo razonable |
| Qué pasa al vencer | Degradar a la versión gratuita, nunca perder los datos del usuario |
| Paquete firmado | Sus clientes no deberían necesitar el modo desarrollador |
| Versionado y catálogo | Publicar correcciones sin volver a repartir archivos a mano |
API del puente
Los 33 métodos del puente nativo y el permiso que exige cada uno. Esta tabla es la del puente
crudo; lo que usted escribe es el SDK, que los agrupa por familias con nombres más
cortos: GeoData.data.*, GeoData.gnss.*, GeoData.map.*,
GeoData.license.* y GeoData.secure.*.
El puente es síncrono: devuelve una cadena JSON en el acto y el SDK la
convierte en objeto. Poner await delante no rompe nada, pero delata que se copió sin
entender. Las únicas asíncronas de verdad son las que salen a la red o abren una pantalla:
httpGet, httpPost, httpRequest,
data.attachPhoto y license.verify. Cuando el usuario deniega un permiso
la llamada lanza PermissionError con el permiso que falta en
e.permission: no devuelve un JSON raro que nadie comprueba.
| Método | Permiso | Devuelve |
|---|---|---|
getAppName() | — | Nombre de la marca |
getLocation() | gnss | {lat, lon}, ceros si aún no hay fix |
getGnssLocation() | gnss | Alias del anterior |
setGnss(bool) | gnss | Enciende o apaga el GNSS |
getGnssPointFields() | — | Los campos de trazabilidad disponibles |
httpGet(url) | network | Cuerpo de la respuesta |
httpRequest(m,url,h,b) | network | Respuesta completa |
listProjects() | storage.read | Proyectos del equipo (no dice cuál está abierto) |
listLayers(p) | storage.read | Capas con tipo y conteo |
getActiveLayers() | storage.read | Las capas en edición |
readFeatures(p,c,n) | storage.read | Entidades con sus atributos |
getLayerSchema(p,c) | storage.read | Campos y tipos |
geoPackageExists(p) | storage.read | Booleano |
layerExists(p,c) | storage.read | Booleano |
listAttributeTypes() | — | Tipos de campo admitidos |
createGeoPackage(n) | storage.write | Crea un proyecto |
createLayer(p,c,tipo) | storage.write | Crea una capa |
addAttribute(...) | storage.write | Añade un campo |
insertFeature(...) | storage.write | Inserta una entidad |
updateFeatureAttributes(...) | storage.write | Modifica atributos |
updateFeatureGeometry(...) | storage.write | Modifica la geometría |
deleteFeature(p,c,fid) | storage.delete | Borra una entidad |
takePhotoAndAttach(...) | camera | Foto adjunta a la entidad |
centerMapAt(lat,lon,z) | map | Centra el mapa |
getSecurityAudit() | audit | Informe de seguridad |
getIdentity() | license | Alias del equipo para este plugin |
requestAttestation(nonce) | license | Token firmado por el equipo |
getTrust() | — | Nivel de confianza del propio plugin |
getPluginInfo() | — | Identidad, versión, marca y versión de la app |
securePut(n,v) | — | Guarda cifrado y aislado |
secureGet(n) | — | Lee del almacén cifrado |
secureRemove(n) | — | Borra del almacén cifrado |
closePlugin() | — | Cierra el módulo |
Todas las operaciones de escritura respetan el candado de capa: sobre una capa bloqueada devuelven error, igual que le ocurriría al usuario desde la interfaz.
Si algo va mal
| Síntoma | Causa probable | Solución |
|---|---|---|
| «No viene de satélites» | El teléfono entrega posición de red, sin satélites en el cálculo | Salga a cielo abierto y espere el fix. Es una protección, no un fallo |
| Precisión de ±200 m bajo techo | Lo mismo: no hay señal de satélite dentro de un edificio | Normal; en campo baja a metros o centímetros |
| El receptor externo no aparece | Sin emparejar en Android, o permiso de Bluetooth denegado | Emparéjelo en Android y revise permisos |
| El RTK no fija | Correcciones viejas o mountpoint equivocado | Mire la edad de correcciones en el cintillo; reconecte el NTRIP |
| La ruta sin conexión no aparece | No hay red vial descargada | La propia opción lleva a descargar el área |
| «Sin vías» al descargar | El servidor de datos viales estaba saturado | Reintente; las teselas ya descargadas se conservan |
| La simbología no cambia nada | La pantalla se abrió sin proyecto | Ábrala desde el hub con un proyecto activo |
| Una capa se abre vacía | Geometría no reconocida en versiones antiguas | Actualice: desde 7.21.17 se leen las colecciones |
| El módulo dice «sin firmar» | Paquete sin META/ | Fírmelo, o active el modo desarrollador para probar |
| El módulo no se ejecuta («inválido») | Un archivo cambió después de firmar | Vuelva a empaquetar y firmar |
| «Otro dispositivo» al activar | La licencia está vinculada a otro equipo | Libérela en el panel |
| Pide activar tras meses funcionando | Se cumplieron los 30 días sin conexión | Conéctese un momento |
Para cualquier cosa que no esté aquí: Menú lateral → Registro de diagnóstico guarda lo que hizo la aplicación por dentro y se comparte desde ahí mismo. Con la grabación de pantalla adjunta, un problema de campo se diagnostica sin viajar.
Glosario
| Término | Qué es |
|---|---|
| GeoPackage (.gpkg) | Formato abierto de la OGC: un archivo SQLite con capas, geometrías y atributos |
| Fix | Posición calculada por el receptor, con su calidad asociada |
| RTK fijo / flotante | Solución centimétrica con ambigüedades resueltas (fijo) o no (flotante) |
| NTRIP | Protocolo para recibir correcciones de una red de estaciones por internet |
| Mountpoint | El flujo concreto de correcciones dentro de un caster NTRIP |
| PDOP | Efecto de la geometría de los satélites en la precisión: cuanto más bajo, mejor |
| PPK | Postproceso: se graba en crudo y se corrige después en gabinete |
| EPSG | Código de un sistema de coordenadas. CRTM05 es el 8908 |
| Cota ortométrica | Altura sobre el geoide (el «nivel del mar»), no sobre el elipsoide |
| ΔN / ΔE | Metros que faltan hacia el norte y hacia el este para llegar al punto |
| Tolerancia | Distancia a la que un punto replanteado se da por clavado |
| MBTiles | Un archivo con teselas de mapa dentro, para usar sin conexión |
| Attestation | Token firmado por el equipo que prueba a un servidor que habla con una instalación genuina |
| .mtplug | Paquete de un módulo: sus archivos web más la carpeta META/ de firma |