fix(map): arreglar 3 bugs criticos que impedian ver el mapa
Bug 1: Content-Type vacio para .pmtiles
- Vite/Astro sirven .pmtiles sin Content-Type (extension desconocida)
- pmtiles del cliente falla al parsear el header del archivo
- Solucion: plugin Vite inline 'assetMimePlugin' en astro.config.mjs que
setea application/octet-stream para .pmtiles, application/geo+json
para .geojson, application/json para /data/*.json
Bug 2: MapLibre override de 'position: absolute'
- El <div id='map' class='absolute inset-0'> era override por la clase
'.maplibregl-map { position: relative }' que MapLibre anade al container
en runtime. Resultado: #map con 0px de alto, canvas de 300x1280
(default) en lugar de 660x1280
- Solucion: cambiar a inline style 'position: absolute; inset: 0;' que
no es override por clases externas
Bug 3: evento 'load' se dispara antes del handler
- Los <script> de Astro 7 se cargan como modulo defer, asi que el
evento 'load' del map puede dispararse ANTES de que registremos el
handler. El loading overlay se queda visible encima del mapa
- Solucion: patron seguro que chequea isStyleLoaded() y si ya paso
ejecuta el callback inmediatamente, si no registra once('load', ...).
Tambien setTimeout(3000) como safety net
Bug 4: zoom 8 demasiado bajo para ver secciones censales
- A zoom 8 las 674 secciones censales de las Balears son 1-2px cada
una: aparecen como ruido gris plano
- Solucion: zoom inicial 9.5 centrado en Mallorca (lat 39.6, lon 2.85)
para que las secciones se vean como poligonos de 3-6px
Cambios adicionales:
- URL del source pmtiles con window.location.origin (protocolo pmtiles
requiere URL absoluta, no funciona con path relativo)
- Data del source airbnb con window.location.origin
- Sintaxis del style arreglada (faltaba { de apertura de la primera layer
tras un edit anterior)
- TypeScript 5.9.3 mantiene typecheck 0/0/0
This commit is contained in:
+24
-1
@@ -2,9 +2,32 @@
|
||||
import { defineConfig } from 'astro/config';
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
|
||||
// Vite plugin inline: añade Content-Type correcto para .pmtiles y .geojson
|
||||
// en dev server. Sin esto, Astro/Vite sirve .pmtiles con Content-Type vacío
|
||||
// y la librería pmtiles del cliente falla al parsear el header del archivo.
|
||||
function assetMimePlugin() {
|
||||
return {
|
||||
name: 'cases-tancades-asset-mime',
|
||||
configureServer(/** @type {any} */ server) {
|
||||
// @ts-expect-error tipos de Vite no exportados
|
||||
server.middlewares.use((_req, res, next) => {
|
||||
const url = _req.url ?? '';
|
||||
if (url.endsWith('.pmtiles')) {
|
||||
res.setHeader('Content-Type', 'application/octet-stream');
|
||||
} else if (url.endsWith('.geojson')) {
|
||||
res.setHeader('Content-Type', 'application/geo+json');
|
||||
} else if (url.endsWith('.json') && url.includes('/data/')) {
|
||||
res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
||||
}
|
||||
next();
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
vite: {
|
||||
plugins: [tailwindcss()],
|
||||
plugins: [assetMimePlugin(), tailwindcss()],
|
||||
},
|
||||
});
|
||||
|
||||
@@ -30,7 +30,7 @@ const popupTitleTmpl = t(lang, "map.popup_title");
|
||||
data-lang={lang}
|
||||
data-popup-title-tmpl={popupTitleTmpl}
|
||||
>
|
||||
<div id="map" class="absolute inset-0"></div>
|
||||
<div id="map" style="position: absolute; inset: 0;"></div>
|
||||
|
||||
<div
|
||||
id="map-loading"
|
||||
@@ -167,12 +167,12 @@ const popupTitleTmpl = t(lang, "map.popup_title");
|
||||
sources: {
|
||||
cases: {
|
||||
type: "vector",
|
||||
url: "pmtiles:///tiles/dataset.pmtiles",
|
||||
url: `pmtiles://${window.location.origin}/tiles/dataset.pmtiles`,
|
||||
attribution: "INE + Inside Airbnb + Govern d'Eivissa + IBESTAT",
|
||||
},
|
||||
airbnb: {
|
||||
type: "geojson",
|
||||
data: "/data/airbnb_listings.geojson",
|
||||
data: `${window.location.origin}/data/airbnb_listings.geojson`,
|
||||
cluster: true,
|
||||
clusterMaxZoom: 12,
|
||||
clusterRadius: 40,
|
||||
@@ -277,19 +277,39 @@ const popupTitleTmpl = t(lang, "map.popup_title");
|
||||
],
|
||||
},
|
||||
center: [2.85, 39.6],
|
||||
zoom: 8,
|
||||
minZoom: 7,
|
||||
zoom: 9.5,
|
||||
minZoom: 6,
|
||||
maxZoom: 14,
|
||||
});
|
||||
|
||||
map.addControl(new maplibregl.NavigationControl({ showCompass: false }), "top-right");
|
||||
map.addControl(new maplibregl.ScaleControl({ unit: "metric" }), "bottom-left");
|
||||
|
||||
map.on("load", () => {
|
||||
// En Astro 7 los <script> se cargan como modulo defer, asi que el
|
||||
// evento "load" del map puede dispararse ANTES de que registremos
|
||||
// el handler. Patron seguro: chequear isStyleLoaded() y si ya paso,
|
||||
// ejecutar el callback inmediatamente.
|
||||
let readyDone = false;
|
||||
const onReady = (cb: () => void) => {
|
||||
if (readyDone) return;
|
||||
readyDone = true;
|
||||
cb();
|
||||
};
|
||||
if (map.isStyleLoaded()) {
|
||||
onReady(hideLoading);
|
||||
} else {
|
||||
map.once("load", () => onReady(hideLoading));
|
||||
}
|
||||
// Safety: si el source pmtiles rompe, isStyleLoaded nunca sera true.
|
||||
setTimeout(() => onReady(hideLoading), 3000);
|
||||
|
||||
function hideLoading() {
|
||||
const loading = document.getElementById("map-loading");
|
||||
if (loading) loading.style.display = "none";
|
||||
}
|
||||
|
||||
const applyFilter = (isla: string) => {
|
||||
map.on("load", () => {
|
||||
const applyFilter = (isla: string) => {
|
||||
const filterExpr =
|
||||
isla === "all"
|
||||
? null
|
||||
|
||||
Reference in New Issue
Block a user