v5.19.1
-
Relieve offline también para región y comarca (z8-z11), no sólo
para la zona de misión y el corredor. Son unos 50 MB más de paquete, y
se decide a propósito: el enlace se da días antes de la salida, cada
jugador entra en casa con wifi a bajar todo, y la cortina de cuenta
atrás (mission_launch_at) bloquea jugar hasta la hora. A cambio, el
monte es el mismo con o sin cobertura desde la vista de toda Galicia
hasta el camino. Continente y país (z3-z7) siguen sin relieve: a ese
zoom no se lee y la fuente no lo sirve por debajo de z8. -
El paquete offline baja el mapa por niveles de calidad según la
distancia. Continente en calidad general (z3-z5, ±1850..3700 km), país
algo mejor (z6-z7, ±700..925 km), región mejor (z8-z9, ±290..460 km),
comarca mejor (z10-z11, ±115..175 km), y la máxima sólo donde se camina
(zona de misión y corredor, como hasta ahora). Unos 780 teselas de
contexto, 23 MB: al desampliar sin cobertura nunca aparece un hueco. Los
niveles bajos existían, pero con presupuestos que a z3-z4 no llegaban y a
z10-z11 se quedaban cortos. -
El relieve del paquete se limita a la zona de misión y al corredor. Una
tesela de elevación pesa el triple que una de imagen; darle relieve a
media Galicia eran 30 MB para un desnivel que a ese zoom apenas se lee.
Donde se camina, el monte es el mismo con o sin cobertura. -
El mapa se pinta debajo de la pantalla de carga. El velo ya no se
retira hasta que el mapa 3D avisa de que ha pintado su primera vista
-estilo montado, teselas e imágenes cargadas, relieve construido-, con un
tope de siete segundos por si el aviso no llega (sin paquete y sin
cobertura, o con la app en segundo plano). Antes el velo se iba en cuanto
había permisos y todo ese trabajo caía encima del jugador: "tuvo que
renderizar todo mientras me movía". -
Las gemelas de relieve del paquete offline se calculan DESPUÉS del
corredor: el bucle recorre lo que ya está en la lista, y puesto antes no
veía las teselas de z15, las que el terreno pide al caminar. -
Sin cobertura, el relieve. El service worker servía desde la caché
las teselas de imagen pero no las de elevación (/dem-tiles/): sin red
el monte salía plano -"era otro mapa, no tenía el mismo desnivel"-. Ahora
la elevación va por la misma caché que la imagen. -
La pantalla de carga vuelve a bajar lo que falta. Se saltaba la
descarga porque el resumen guardado decía "completo" -de un paquete de
antes de que entraran el relieve a z14-15 y el corredor por el trazado
real-: la barra pasaba al 100 % al instante y lo nuevo no se bajaba
nunca. Cambia la clave del resumen; lo que ya está en el móvil no se
vuelve a pedir, sólo lo que falta. -
El botón 2D/3D tiene el mismo aspecto en los dos estados; cambia la
etiqueta, que dice a qué modo vas. Cambiar de color al pasar a 2D se leía
como avería. -
Botón de norte: aparece sólo cuando el mapa está girado, con la aguja
girando con él; un toque lo devuelve al norte. -
El trazado cuenta la partida. Verde lo andado, azul el tramo en
juego, claro y apagado lo que queda: cada tramo hereda el estado del
nodo al que llega. Y sobre el tramo en juego, un pulso blanco que
respira (opacidad animada diez veces por segundo, sólo con la pestaña
visible): "por aquí, ahora", sin leer nada. -
Tu avatar deja de saltar. Era el último marcador del DOM que quedaba
en el mapa 3D, y por eso el único que seguía descolocándose con el
relieve al hacer zoom. Ahora es un símbolo del mapa como los nodos y las
fotos: círculo con tu foto (o iniciales sobre tu color), anillo blanco y
halo de tu color, dibujado en canvas y colocado por el motor en el mismo
fotograma que el terreno. -
El paquete offline baja lo que el mapa 3D pide de verdad. El
corredor de teselas seguía rectas entre nodos, y la ruta real da rodeos
por caminos que se salían de él: ahora sigue elroute_track. Y el
relieve baja hasta z15 (antes z13): el terreno pide z14-15 en cuanto se
camina, y sin ellas el monte se quedaba plano sin cobertura. -
Las fotos de campo se quedan en su sitio. Eran marcadores del DOM, y
un marcador del DOM va un fotograma por detrás del terreno: con relieve y
zoom "no se quedaban en su posición como los nodos". Ahora son símbolos
del mapa, igual que las chinchetas: la miniatura se carga y se enmarca en
un canvas bajo demanda (marco blanco, esquinas redondeadas, sombra en el
suelo) y el motor la coloca en el mismo fotograma que todo lo demás. El
toque sobre una foto lo resuelve el propio mapa y abre todas las de ese
punto, como antes. -
El mapa ya no da un tirón al terminar de cargar. La pantalla del
jugador abre el mapa sobre el nodo o el GPS, y al llegar los datos se
saltaba OTRA VEZ al nodo: el mapa se movía y las teselas recién pintadas
se borraban. El salto inicial sólo se hace cuando nadie dio un centro. -
Fuera el escalado por zoom de los marcadores del DOM: ya no queda ninguno
que escalar; los símbolos escalan solos. -
El banco de mapa enseña cuántas fotos hay en la fuente del mapa.
-
5.16.1 no bastaba: el worker importa a su vez otro fichero.
maplibre-gl-worker.mjshaceimport "./maplibre-gl-shared.mjs", y con
?urlVite sólo copiaba el primero; el segundo daba 404 y el módulo
moría igual de callado. Medido: fichero servido con 200 ytext/javascript,
y aun así cero respuestas del worker. Ahora se importa con?worker&url,
que empaqueta el worker CON sus dependencias en un único fichero con hash. -
EL fallo de toda la migración al mapa 3D, y el más silencioso.
MapLibre v6 hace su trabajo pesado en un web worker que carga como módulo
desde una URL calculada al lado de su propio chunk
(new URL('./maplibre-gl-worker.mjs', import.meta.url)). Vite no copia
ese fichero porque nadie lo importa, así que devolvía 404 -los dos 404
sin explicar de cada carga- y el worker moría sin decir una palabra.
Todo lo que pasa por el worker estuvo muerto desde 5.10: las fuentes
GeoJSON (trazado, radio, extrusión, símbolos) y la decodificación del
relieve. Las teselas satélite y los marcadores del DOM no lo usan, y por
eso eran lo único que se veía. Tuvo pinta de bug de datos, de eventos,
de posición y del móvil, y no era ninguno. Medido: worker vivo, cero
respuestas a una carga GeoJSON.
Ahora el worker se importa con?url, Vite lo emite con hash en
/assets/y se le da a MapLibre la dirección real. -
El banco de mapa lleva una fila worker (GeoJSON) que mide justo este
síntoma: si dice MUDO, nada de lo que pase por el worker se va a ver. -
Los nodos pasan a ser símbolos del mapa, no marcadores del DOM. Un
marcador del DOM se coloca desde JavaScript un fotograma después de que
el mapa se haya dibujado: con relieve y zoom va siempre por detrás del
terreno -"al ampliar quedan mal y al soltar se recolocan"-. Un símbolo lo
pinta el propio motor, en el mismo fotograma y a la altura correcta del
terreno. La chincheta se dibuja en un canvas al vuelo, con el número
horneado dentro: cabeza con luz, borde oscuro, punta y sombra en el
suelo. Sin fuentes de letras externas, que serían una petición más que
falla sin cobertura. Bajo cada una, un disco de metro y medio pegado al
relieve que la ancla al terreno sin taparla. -
El vigilante del estilo rehacía mapas sanos. Comprobaba
isStyleLoaded(), que esfalsecada vez que hay una tesela cargando
-o sea, en cada zoom-, y rehacía el estilo entero hasta cinco veces:
vaciaba fuentes, recargaba teselas y descolocaba marcadores. Eso era el
"carga raro". Ahora sólo actúa si el estilo no tiene capas. -
Trazado un poco más grueso y radio de entrada con borde continuo y
relleno más presente: las líneas a trazos tienen historial de pintarse
mal sobre relieve en MapLibre, y lo primero es que se vea. -
La guarda de colores del tema cazaba las sombras del terreno de 5.15.0.
Son colores del monte, no de la piel de la app: una ladera a la sombra es
azul oscura con cualquier tema. Quedan marcados como tales. -
Chinchetas 3D de verdad: poste fino y cabeza ancha, en metros. Un
cilindro solo se leía como un depósito de agua. Poste estrecho más cabeza
gorda encima es la silueta de una chincheta clavada, y esa silueta la
reconoce cualquiera desde cualquier ángulo. Son dos volúmenes extruidos
por nodo: crecen, se inclinan y se tapan con la perspectiva, sin
simulaciones. El nodo en juego es más alto. -
Relieve que se lee, como en los mapas de montaña. Sombra azulada y luz
cálida en el sombreado de laderas: con los grises por defecto se fundía
con la foto satélite y el monte parecía plano aunque la malla estuviera
levantada. Y el sombreado pasa a una fuente de elevación propia, porque
MapLibre avisa de que compartirla con el terreno baja la calidad del
dibujo (mismas teselas, misma caché; sólo cambia el nombre). -
El banco de mapa lee las fuentes por
serialize(), que es API pública.
Leía un campo interno que ya no existe y decía 0 con los datos puestos.
Medido: radio 1, trazado 9, volumen 10 -el volcado de 5.14.2 funciona-. -
El asa de depuración expone también el estilo del mapa. En una pestaña
que no pinta MapLibre nunca monta el estilo -espera un fotograma-, y sin
eso no había forma de medir las capas de datos. Ahora se puede forzar el
montaje desde fuera y comprobar trazado, radio y volumen sin que nadie
tenga que estar mirando. -
Los nodos por fin se quedan en su sitio. Salían apilados en columna
y sólo "iban a su ubicación" al ampliar, y a escala de toda Galicia los
diez formaban una fila perfecta y equiespaciada -cosa que ninguna
geografía produce-. La causa: el elemento de la chincheta llevaba
position: relativeen línea, y el estilo en línea gana a la clase de
MapLibre (position: absolute). Los diez nodos estaban en flujo de
documento desde la esquina del mapa, y MapLibre sólo les sumaba el
desplazamiento. Medido en el navegador: reglaabsolute, cálculo
relative. Cinco versiones persiguiendo esto. Hay test que lo blinda
para todos los marcadores. -
El banco de mapa cuenta sus propios montajes y enseña qué respondió la
API (código, nodos, nivel). Se vio "nodos 0" con nueve chinchetas en el
mapa, y en vez de deducir por qué, que lo diga él. -
Botón nodos de prueba: tres nodos inventados cerca de Catoira, con
trazado y radio. Prueban el trazado, el radio y el volumen 3D sin depender
de la API ni de la sesión: si con ellos se ve, el motor está bien y lo que
falla es de dónde salen los datos; y al revés. -
El banco de pruebas mentía, que es peor que no tenerlo. Comprobaba la
fuente de teselas por un nombre que no existe -siempre decía que no había
teselas aunque el mapa las estuviera pintando- y tenía un candado que
impedía repetir la petición de la partida: si el componente se montaba
dos veces, la segunda se quedaba sin nodos para siempre y el panel decía
"nodos 0" mientras el mapa tenía diez marcadores puestos. -
El banco muestra también cuántas fotos cargó y lleva un botón para volver
a pedir los datos sin recargar la página. -
Encontrado el fallo que se llevó media docena de versiones: el trazado,
el radio y los volúmenes 3D nunca recibían sus datos. La línea que los
pintaba erafuente?.setData(datos). Si el estilo del mapa todavía no
había terminado de montarse,getSourceno devolvía nada, la
interrogación se tragaba la llamada en silencio y no se reintentaba
jamás. Los nodos llegan de la API en bastante menos de lo que tarda el
estilo, así que se perdían casi siempre.
El síntoma engañaba y por eso costó tanto: se veían las teselas y el
relieve -van declarados en el estilo, nadie tiene que rellenarlos- y se
veían los nodos y las fotos -son marcadores del DOM-. Faltaba
exactamente lo que hay que rellenar después. Sin un solo error.
Ahora lo último de cada fuente se guarda siempre y se vuelca en cuanto el
estilo está en condiciones. -
Los volúmenes de los nodos suben a 28 m, y 45 m el nodo en juego, con
seis metros de radio. A zoom 16-17 un poste bajo lo aplasta la
perspectiva contra el suelo y no se lee como volumen: lo que hace que un
nodo parezca plantado en el monte es verle el costado. -
La chincheta del número se hace más pequeña, porque ya no es ella la que
marca el sitio. -
El banco de mapa ya no necesitaba recargarse para mostrar los números. Se
pedía el asa del mapa por parámetro en la dirección, y llegaba tarde: los
efectos del hijo corren antes que los del padre, así que el mapa miraba la
dirección antes de que el banco hubiera podido escribir el parámetro. -
Banco de pruebas del mapa en
/banco-mapa?user=NOMBRE. El mapa no se
podía mirar, y ese era el problema de fondo: la pantalla del jugador sólo
se abre en vertical -en un escritorio enseña el aviso de girar el móvil y
el mapa ni llega a montarse-, exige elegir jugador, pide permisos y se
pasa cuarenta y cinco segundos descargando la misión antes de pintar
nada. Con todo eso delante, cada cambio del mapa se corregía a ciegas y
se daba por bueno sin verlo, que es exactamente como se colaron los
últimos fallos.
El banco abre el mapa solo, a pantalla completa, con los datos de verdad
y con los números a la vista: si el estilo montó, si hay teselas, con
cuánto relieve, cuántos vértices tiene el radio, cuántos tramos el
trazado y cuántos nodos tienen volumen. Nada de eso se puede deducir
mirando una captura. -
Los nodos pasan a ser 3D de verdad, no un dibujo que lo imita. Cada
nodo levanta un volumen extruido desde el suelo, con altura en METROS: se
inclina con la cámara, lo tapa el monte que tiene delante y crece en
perspectiva al acercarse. Un marcador del DOM nunca podía hacer eso -es
una calcomanía pegada a la pantalla- por mucha sombra que se le pintara.
El nodo en juego se levanta más que los demás, para localizarlo de lejos. -
Fuera el volcado falso de las fotos. Se les había puesto un
rotateX
en CSS para que parecieran tumbadas sobre el terreno. Es mentira y se
nota: un giro de CSS no sigue a la cámara, así que al desplazar o girar
el mapa quedaban inclinadas hacia un lado que no correspondía a nada. -
Al abrir, el mapa va al nodo actual, no a la ruta entera. Encuadrar
los diez nodos de golpe sonaba bien y quedó peor: a zoom 13 los
alfileres, que miden lo mismo en píxeles a cualquier escala, se amontonan
en una fila de chinchetas sobre medio mapa de Galicia. -
El mapa podía quedarse EN BLANCO, y esto explica el "está todo mal".
MapLibre v6 monta el estilo dentro de unrequestAnimationFrame, y un
navegador no ejecuta fotogramas en una pestaña que no se está pintando.
Si el mapa nace con la pantalla bloqueada o con la app en segundo plano
-normalísimo durante los segundos que tarda la descarga offline- ese
fotograma no llega nunca: no hay teselas, no hay relieve, no hay radio ni
trazado. Y encima los nodos SÍ se ven, porque son marcadores del DOM, así
que parece que el mapa casi funciona en vez de estar sin estilo. Sin un
solo error en consola. Ahora hay un vigilante que vuelve a aplicar el
estilo al recuperar visibilidad, con tope de cinco intentos. -
La ruta se encuadra al entrar cuando todavía no hay GPS. Abriendo
siempre a zoom 16 sobre un punto, los diez nodos de una ruta de
kilómetros caen fuera de la pantalla o salen alineados contra un borde. -
El radio y el trazado, por fin. 5.13.1 y 5.13.3 no lo arreglaron, y
las dos veces se dio por bueno sin comprobarlo en la página. El estilo se
declara en línea, así que MapLibre lo monta dentro del constructor: el
eventostyle.loadya ha ocurrido cuando se engancha el escuchador, y
isStyleLoaded()no vale de red porque es más estricto que el evento
-exige además que carguen todas las fuentes-. Entre las dos señales, el
código se quedaba en tierra de nadie y no pintaba nunca.
Ahora las dos fuentes y sus cuatro capas nacen declaradas en el
estilo, así que existen desde el primer fotograma y no hay nada que
esperar. El estado de "estilo listo" desaparece. -
El radio y el trazado seguían sin pintarse, y ahora se sabe por qué.
En 5.13.1 se cambióloadporstyle.loaddando por hecho que era el
evento correcto. Lo es, pero llega tarde: el estilo se declara EN LÍNEA
-no por URL- y MapLibre lo monta de forma síncrona dentro del
constructor, así que para cuando se engancha el escuchador el evento ya
ocurrió y no vuelve a ocurrir. Ahora se pregunta conisStyleLoaded()
antes de escuchar. Se cazó porque el asa de depuración de 5.13.2 no
aparecía en la página, que es exactamente para lo que se puso. -
Tu posición vuelve a ser tu avatar, no una chincheta. En el motor
nuevo había quedado el marcador por defecto de MapLibre, y eso no es un
detalle estético: en un mapa lleno de chinchetas numeradas, una chincheta
más no dice "este eres tú". Ahora va tu foto, con tu color de halo, como
en el motor de siempre. -
Relieve más marcado. A la altura a la que se juega -zoom 17-18, unos
cientos de metros de ancho- el desnivel real de un valle son unos pocos
metros: geométricamente correcto e invisible. El sombreado de laderas
pasa de 0,5 a 0,85 y la exageración del terreno de 1,5 a 2,2, que es lo
que hace legible la FORMA del terreno a esa escala. -
Asa de depuración del mapa con
?depurar-mapa=1. Sin ella no había modo
de comprobar desde fuera si el terreno estaba puesto o qué capas había, y
se estaba verificando a ojo -que es justo como se colaron los fallos de
esta pantalla-. No se expone nunca por defecto.