Skip to content

v5.19.1

Choose a tag to compare

@odegaard12 odegaard12 released this 21 Sep 14:54
· 68 commits to main since this release
  • 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 el route_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.mjs hace import "./maplibre-gl-shared.mjs", y con
    ?url Vite sólo copiaba el primero; el segundo daba 404 y el módulo
    moría igual de callado. Medido: fichero servido con 200 y text/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 es false cada 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: relative en 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: regla absolute, 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 era fuente?.setData(datos). Si el estilo del mapa todavía no
    había terminado de montarse, getSource no 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 un requestAnimationFrame, 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
    evento style.load ya 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ó load por style.load dando 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 con isStyleLoaded()
    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.