chore: untrack docs de fase i fitxers raw duplicats (ja ignorats)

This commit is contained in:
2026-07-15 09:38:37 +02:00
parent e0fd449b6c
commit 1208342942
12 changed files with 0 additions and 1326 deletions
-29
View File
@@ -1,29 +0,0 @@
# Deploy a Vercel
## Opción A — Dashboard (recomendada para primer deploy)
1. Ve a https://vercel.com/new
2. Conecta el repo `itziarZG/Vivienda` desde GitHub
3. En "Project Name" escribe `casestancades`
4. En "Root Directory" selecciona `web`
5. Vercel detecta Astro automáticamente y usa Node 22 (definido en `web/vercel.json`)
6. Click "Deploy"
7. La URL será `https://casestancades.vercel.app`
## Opción B — CLI
```bash
cd web
npx vercel login # abre navegador para autorizar
npx vercel link # vincula el proyecto
npx vercel --prod # deploy a producción
```
## Variables de entorno
No requiere ninguna variable. Todo es estático.
## Dominio propio
Más adelante (post-MVP): comprar `.cat`/`.org`/`.es` y configurarlo en
Vercel → Settings → Domains.
-159
View File
@@ -1,159 +0,0 @@
# FASE 0 - Setup (semana 1)
## Objetivo
Tener el entorno listo y los datos crudos descargados y validados, sin procesar. Al cerrar esta fase, `git status` muestra una estructura limpia y `data/raw/` contiene los datasets originales descargados, cada uno abrible sin errores.
## Tareas
### Estructura de carpetas
- [x] Crear en `/Users/ichi/Desktop/DEV/VIvienda/`:
- `data/raw/` - datos originales, inmutables
- `data/processed/` - datasets intermedios
- `data/output/` - parquet, tiles, JSONs finales
- `web/` - codigo Astro
- `docs/` - PDFs, capturas, metodologia extendida
- `scripts/` - pipeline Python
### Repositorio
- [x] `git init` en `/Users/ichi/Desktop/DEV/VIvienda/`
- [x] Crear `.gitignore` que ignore:
- `data/raw/*.xlsx` y `data/raw/*.csv.gz` (datos pesados)
- `data/processed/`
- `data/output/`
- `node_modules/`
- `.venv/`, `__pycache__/`
- `.env`, `.env.local`
- [x] Hacer commit inicial con estructura + `.gitignore` + este PLAN (commit `53f24de`)
### Reorganizacion de archivos existentes
- [x] Mover 15 JPGs unicos a `docs/conferencia-OHIB-2025/` (5 duplicados borrados)
- [x] Mover `viviendas vacias-hipotecas.xlsx` y `39365(1).xlsx` a `data/raw/`
- [x] Mover `Info.pdf` a `docs/conferencia-OHIB-2025/`
- [x] Documentar el origen de cada archivo en `data/raw/ORIGEN.md`
### Entorno Python
- [x] `uv` disponible (v0.7.21)
- [x] `uv venv .venv` (Python 3.10.18 seleccionado por uv para compatibilidad con geopandas)
- [x] `requirements.txt` con: pandas, openpyxl, geopandas, duckdb, shapely, pyproj, fiona, pyarrow
- [x] `uv pip install -r requirements.txt` (todas las deps instaladas)
- [x] Verificar: pandas 2.3.3, geopandas 1.1.4, duckdb 1.5.4, shapely 2.1.2, pyproj 3.7.1, fiona 1.10.1, openpyxl 3.1.5, pyarrow 25.0.0
### Entorno Node
- [x] Node 17.1.0 estaba instalado via nvm pero requiere 20+ para Astro
- [x] `nvm install 20` (v20.20.2) y `nvm alias default 20`
- [x] pnpm v9.15.9 instalado (version 9 porque la 10+ requiere Node 22.13)
### Descarga de datos externos
- [x] Descargar **shapefile de secciones censales de Espana 2025** desde INE
- URL final: `https://www.ine.es/prodyser/cartografia/seccionado_2025.zip` (57.5 MB)
- Shapefile procesado: filtrado a Illes Balears (674 features, 67 municipios, 1 provincia)
- Reproyectado de EPSG:25830 a EPSG:4326 (WGS84)
- Guardado como `data/raw/secciones_balears.gpkg` (5.3 MB)
- [x] Descargar **Inside Airbnb listings** Mallorca (45.741 listings) y Menorca (8.492 listings)
- URL Mallorca: `https://data.insideairbnb.com/spain/islas-baleares/mallorca/2026-06-23/data/listings.csv.gz`
- URL Menorca: `https://data.insideairbnb.com/spain/islas-baleares/menorca/2026-06-30/data/listings.csv.gz`
- [x] Recibir **HUT Eivissa 2026** del usuario (archivo HTML-as-xls, convertido a `hut_eivissa_2026-07-14.csv` con 2.369 registros y 18.184 plazas)
- [x] Recibir **IBESTAT Formentera 2019** del usuario (archivo OLE .xls, convertido a `ibestat_formentera_2019.json` con 1.375 establecimientos y 14.935 plazas)
- [x] **Insight del usuario**: el problema real son los ilegales, no los legales. Mallorca/Menorca (Airbnb) capturan realidad; Eivissa/Formentera (HUT) solo capturan legal. **La diferencia entre ambas cifras ES la denuncia narrativa**.
### Validacion
- [x] Shapefile: 36.554 features Espana, 674 en Illes Balears, CRS WGS84 OK
- [x] XLSXs validados con openpyxl. Solo sheet `tabla-59531` de `viviendas vacias-hipotecas.xlsx` es el dato util (los otros 5 sheets son hipotecas). `39365(1).xlsx` tiene 1 sheet util (`tabla-39365`).
- [x] Listings Airbnb Mallorca y Menorca validados (90 columnas, lat/lon/room_type/price/availability_365 OK)
- [x] HUT Eivissa 2026 validado: 2.369 registros en 5 municipios + 5 anomalias. Columna `Referencia cadastral` (20 chars) geocodificable.
- [x] IBESTAT Formentera 2019 validado: 1.375 establecimientos, 14.935 plazas. Datos agregados a nivel isla.
- [x] Anotado en `data/raw/VALIDACION.md`
### Cierre
- [x] Commit final con tag `fase-0-completa` (commits `1e86070` y `99ad1f8`)
- [x] Actualizar PLAN.md: marcar Fase 0 como completada
- [x] Anotar problemas y decisiones en este documento
## Comandos clave
```bash
# Estructura
cd /Users/ichi/Desktop/DEV/VIvienda
mkdir -p data/raw data/processed data/output web docs/conferencia-OHIB-2025 scripts
# Git
git init
git add .
git commit -m "chore: estructura inicial del proyecto"
# Python
brew install uv # o pipx install uv
uv venv .venv
source .venv/bin/activate
uv pip install pandas openpyxl geopandas duckdb shapely pyproj fiona pyarrow
# Node
brew install node pnpm # o nvm install 20 && npm i -g pnpm
# Validacion shapefile (despues de descargar)
python -c "import geopandas as gpd; gdf = gpd.read_file('data/raw/secciones_censales_balears.shp'); print(gdf.head()); print('CRS:', gdf.crs); print('Features:', len(gdf))"
# Validacion listings
python -c "import pandas as pd; df = pd.read_csv('data/raw/eivissa_listings.csv.gz', low_memory=False); print(df.shape); print(df.columns.tolist()[:20])"
# Validacion XLSX
python -c "import pandas as pd; df = pd.read_excel('data/raw/viviendas vacias-hipotecas.xlsx', sheet_name=None); print({k: v.shape for k, v in df.items()})"
```
## Criterio de "fase terminada" (Definition of Done)
- [x] Repo git inicializado con branch `main`
- [x] Estructura de carpetas creada
- [x] `.gitignore` funcionando (verificar con `git status`)
- [x] Entorno Python reproducible: `requirements.txt` con versiones pinneadas + instrucciones
- [x] Entorno Node instalado (Node 20+ + pnpm)
- [x] `data/raw/` contiene: 2 XLSXs INE + shapefile secciones censales Balears + listings Airbnb (4 archivos)
- [x] Cada archivo abre sin error y tiene el numero esperado de filas/features
- [x] `data/raw/VALIDACION.md` documenta conteos y CRS
- [x] Commit final con tag `fase-0-completa`
- [x] PLAN.md actualizado con check de Fase 0
## Decisiones tomadas durante la fase
_Llenar durante la ejecucion. Ejemplos:_
- _Decidimos usar `uv` en vez de `poetry` porque…_
- _El shapefile viene en ETRS89 (EPSG:4258), no WGS84, hay que reproyectar a EPSG:4326 para web._
- _Decidimos ignorar `data/raw/*.xlsx` en git por tamano; el repo solo guarda scripts y docs._
Decisiones reales:
- **uv en vez de poetry/conda**: mas rapido, sin daemon, ya estaba instalado.
- **Python 3.10.18 seleccionado por uv** (no la 3.14.3 del sistema) para maxima compatibilidad con geopandas y GDAL.
- **Node 20 (no la 17 que estaba via nvm)** porque Astro requiere 18.17+ o 20.3+.
- **pnpm 9 (no 10)** porque pnpm 10+ requiere Node 22.13.
- **Shapefile procesado a GeoPackage (.gpkg) en vez de mantener .shp**: 110MB de SHP -> 5.3MB de GPKG, mas portable, mejor soporte en geopandas.
- **Borrados 5 JPGs duplicados** (md5 identico a los ya movidos) para no inflar el repo.
- **15 JPGs y capturas fuera de git** (40MB) por tamano, solo Info.pdf en git (36KB).
- **Dataset hibrido por isla segun la fuente mas adecuada**:
- Mallorca + Menorca: Inside Airbnb (cubre realidad, legal+ilegal, snapshot 2026-06)
- Eivissa: registro HUT oficial (snapshot 2026-07, 2.369 legal, con direccion y referencia catastral)
- Formentera: IBESTAT agregado (snapshot 2019, 1.375 establecimientos, 14.935 plazas)
- **Mensaje narrativo clave**: la diferencia entre HUT (legal) y Airbnb (real) ES la denuncia. Documentar esto en `/metodologia`.
## Problemas encontrados
Problemas reales:
- **URLs INE tradicionales 404**: `https://www.ine.es/prodyser/cartografia/seccionado_2025/` y otras URLs conocidas no funcionan. **Solucion**: la URL real del ZIP es `https://www.ine.es/prodyser/cartografia/seccionado_2025.zip` (sin `/` final, extension `.zip`). El HTML de la pagina es una SPA y no expone el link.
- **Encoding del ZIP**: la carpeta interna `Espana_Seccionado2025_ETRS89H30` lleva caracter `n` con tilde. `unzip` por defecto falla con "Illegal byte sequence" en macOS. **Solucion**: extraer con `zipfile` de Python aplicando cp437 -> utf-8 fallback.
- **nvm no se carga en subshells**: nvm se carga solo en el shell interactivo desde `.zshrc`. Para usarlo en scripts/comandos one-shot hay que hacer `export NVM_DIR="$HOME/.nvm" && . "$NVM_DIR/nvm.sh" && nvm use 20` o usar la ruta absoluta `~/.nvm/versions/node/v20.20.2/bin/`.
- **Disk al 90%**: solo 22GB libres. Considerar borrar el ZIP de 60MB tras validar el .gpkg.
- **Inside Airbnb solo Mallorca+Menorca**: confirmado que no hay datos para Eivissa/Formentera. Resolucion: usar HUT oficial (proporcionado por usuario) + IBESTAT (tambien del usuario).
- **Archivos del usuario con formato incorrecto**:
- `List-habitatges-turistics_*.xls` es HTML con extension .xls (encoding ISO-8859-1, no UTF-8).
- `IBESTAT_indicador_*.xls` es binario OLE .xls real (encoding latin1 implicito).
- Para .xls en pandas moderno: instalar `xlrd<2.0` y usar `engine='xlrd'`. Para .xls binario: usar `xlrd.open_workbook` directo.
## Proximos pasos
Fase 1: pipeline de datos Python. Entrada: archivos en `data/raw/`. Salida: `dataset.parquet` y `tiles.pmtiles` en `data/output/`. Ver `FASE-1-datos.md`.
**Decisiones para Fase 1**:
- Como geocodificar el HUT de Eivissa con su `Referencia cadastral` para hacer join con secciones censales (Catastro publica descargador por referencia, o servicio WFS)
- Como estimar el dato de "vivienda semi-vacia" por seccion censal a partir del XLSX INE (el XLSX tiene datos agregados por municipio, NO por seccion)
- Como unir Airbnb (lat/lon, por isla) con HUT (direccion+catastral, por municipio) en un unico dataset por seccion censal
- Como presentar la falta de uniformidad Mallorca/Menorca vs Eivissa/Formentera en la visualizacion final
-124
View File
@@ -1,124 +0,0 @@
# FASE 1 - Datos (semana 2)
## Objetivo
Producir el dataset final por seccion censal con dos variables clave: (a) % de viviendas semi-vacias (CCAA, del INE) y (b) listings de Airbnb + HUT + IBESTAT por seccion censal (Mallorca, Menorca, Eivissa, Formentera). Generar archivos listos para la web: `dataset.parquet` y `tiles.pmtiles`.
## Limitacion importante detectada
El XLSX `tabla-59531` del INE (vivienda por intensidad de uso a partir del consumo electrico) **solo tiene 2 filas de datos**: Total Nacional y Balears, Illes. Esta a nivel de CCAA, **no a nivel de seccion censal**. No podemos cruzar vivienda semi-vacia con seccion censal.
**Implicacion para el proyecto**: el cruce vivienda-vacia <-> presion-turistica es a nivel CCAA (Balears) en el caso de la vivienda, y a nivel seccion censal en el caso del turismo. La visualizacion final tendra granularidades distintas, y se documentara en `/metodologia`.
**Si en el futuro** encontramos datos del Censo 2021 a nivel de seccion censal (la descarga original del usuario no lo incluye), se podra hacer el cruce a seccion censal. Pendiente explorar.
## Granularidad por fuente de datos
| Fuente | Nivel de dato | Granularidad real |
|---|---|---|
| INE XLSX vivienda | CCAA | Balears Illes (no seccion censal) |
| INE XLSX vivienda turistica | CCAA | Balears Illes serie temporal |
| Inside Airbnb Mallorca+Menorca | Punto (lat/lon) | Seccion censal (spatial join) |
| Shapefile INE | Poligono | Seccion censal |
| HUT Eivissa | Direccion + Ref. Catastral | Municipio (5 chars de la RC) o seccion censal (geocodificando RC) |
| IBESTAT Formentera 2019 | Isla | Isla (agregado, sin parcela) |
## Tareas
### 1. Exploracion y limpieza de datos INE
- [x] Cargar `viviendas vacias-hiopotecas.xlsx` -> sheet `tabla-59531`. Extraer:
- Viviendas totales (Balears Illes): 652.123
- Viviendas vacias: 105.632 (16.2%)
- Mediana consumo: 2.869 kWh
- Viviendas de uso esporadico: 44.802 (6.9%)
- [x] Cargar `39365(1).xlsx` -> sheet `tabla-39365`. Extraer serie temporal % viviendas turisticas en Balears (ultimo: 3.74% en 2025M05)
### 2. Carga geoespacial
- [x] Cargar `data/raw/secciones_balears.gpkg` con geopandas (674 features, CRS WGS84)
### 3. Inside Airbnb Mallorca+Menorca
- [x] Cargar `airbnb_mallorca_listings.csv.gz` y `airbnb_menorca_listings.csv.gz`
- [x] Filtrar listings activos: `availability_365 > 0` o `room_type == 'Entire home/apt'`
- [x] Limpiar precios (quitar `$`, `,`, convertir a float)
- [x] Spatial join con secciones censales (point-in-polygon) usando geopandas sjoin
- [x] Resultado: 18.175 listings geo-localizados (14.644 Mallorca + 3.531 Menorca) en 456 secciones
### 4. HUT Eivissa
- [x] Cargar `hut_eivissa_2026-07-14.csv` (2.364 registros)
- [x] Extraer municipio de la `Referencia cadastral` (primeros 5 chars = CUMUN)
- [x] Join con shapefile por NMUN -> agregar a nivel municipio
- [x] Detalle: Sant Josep 945/7296, Santa Eulària 803/6249, Sant Antoni 330/2486, Sant Joan 245/1917, Eivissa 41/236
- [ ] (Opcional, v2) Geocodificar la RC exacta contra el Catastro para llegar a seccion censal
### 5. IBESTAT Formentera
- [x] Cargar `ibestat_formentera_2019.json`
- [x] Solo permite agregacion a nivel isla (1.375 establecimientos, 14.935 plazas)
### 6. Agregacion por seccion censal + municipio + isla
- [x] Generar tabla final con las 674 secciones censales de Balears
- [x] Mallorca: 545 secciones (409 con Airbnb + 136 rurales sin listings)
- [x] Menorca: 47 secciones (todo con Airbnb)
- [x] Eivissa: 76 secciones (5 municipios, granularidad municipio)
- [x] Formentera: 6 secciones (1 municipio, granularidad municipio)
- [x] Anadir columnas CCAA (constantes): `viviendas_vacias_pct_ccaa=16.2`, `viviendas_uso_esporadico_pct_ccaa=6.9`, `viviendas_turisticas_pct_ccaa_2025M05=3.74`
- [x] Fallback: secciones rurales sin datos asignadas a Mallorca/Menorca por CMUN
### 7. Generacion de archivos finales
- [x] `data/output/dataset.parquet` (41KB, 674 filas, 33 columnas sin geometria)
- [x] `data/output/dataset.gpkg` (5.3MB, geometrias completas)
- [x] `data/output/dataset_web.json` (1.1KB, resumen por isla)
- [x] `data/output/tiles.pmtiles` (1.5MB, choropleth con tippecanoe z0-z13)
- [ ] (Fase 2) Copiar outputs a `web/public/data/`
### 8. Validacion
- [x] `dataset.parquet` abre con duckdb/pandas, todas las secciones censales presentes
- [x] Stats descriptivos: total listings, distribucion por isla, total plazas
- [x] `tiles.pmtiles` magic `PMTi` valido
- [ ] Screenshots del mapa en Jupyter notebook (diferido a Fase 2 con web real)
### 9. Cierre
- [ ] Commit final con tag `fase-1-completa`
- [ ] Actualizar PLAN.md
- [x] Documentar en `data/output/STATS.md` las estadisticas finales
## Comandos clave
```bash
# Validar parquet con duckdb
python -c "import duckdb; print(duckdb.query('SELECT isla, COUNT(*), SUM(airbnb_listings) FROM read_parquet(\"data/output/dataset.parquet\") GROUP BY isla').to_df())"
# Pipeline completo (reproducible)
python3 scripts/01_load_sources.py
python3 scripts/02_build_dataset.py
python3 scripts/03_generate_tiles.py
```
## Criterio de "fase terminada"
- [x] `data/output/dataset.parquet` generado, valido, sin nulos en columnas clave
- [x] `data/output/tiles.pmtiles` generado y servible
- [x] Spatial join Mallorca+Menorca con tasa de exito: 18.175/54.233 = 33.5% (filtrados por actividad real; el resto son anuncios inactivos)
- [x] `STATS.md` documenta: n secciones, n listings por isla, distribuciones, limitaciones
- [x] Scripts Python reproducibles en `scripts/`
- [ ] Screenshots del mapa en Jupyter notebook (diferido a Fase 2)
- [ ] Commit final con tag `fase-1-completa`
## Decisiones tomadas durante la fase
1. **Filtrado de listings activos**: `availability_365 > 0 OR room_type == 'Entire home/apt'`. Razon: muchos listings aparecen como rascados pero no estan disponibles; los entire home/apt son los que afectan al mercado residencial aunque no tengan disponibilidad inmediata (estan bloqueados por el host para uso propio o estacional).
2. **Fallback de isla por CMUN**: para secciones rurales sin listings de Airbnb ni asignacion de Eivissa/Formentera, usar el CMUN (5 chars) para inferir isla. Hardcoded: `Eivissa={24,26,30,48,54}`, `Formentera={17}`, `Menorca={02,15,32,37,40,64,65}`, resto=Mallorca.
3. **Encoding mixto en fuentes**: shapefile (cp437->utf-8), HUT Eivissa (ISO-8859-1 al exportar, ya convertido a UTF-8 en CSV), IBESTAT (latin1->utf-8 al parsear, ya en JSON). El script `01_load_sources.py` asume los archivos ya normalizados en `data/raw/`.
4. **Tippecanoe `-zg` con `--drop-densest-as-needed`**: para 674 features, elige automaticamente maxzoom=7 y un max interno de z=13 para que no se sature a zooms altos.
5. **GeoJSON como intermediario**: tippecanoe no lee bien GPKG directamente; convertimos a GeoJSON (13MB) solo durante la generacion de tiles, luego lo borramos.
6. **Comits de los outputs**: `data/output/dataset.gpkg` (5.3MB) y `dataset.geojson` (intermedio) se ignoran en git; `dataset.parquet` (41KB), `dataset_web.json` (1.1KB), `tiles.pmtiles` (1.5MB) y `STATS.md` (2KB) se commitean para que la web funcione sin re-correr el pipeline.
## Problemas encontrados
1. **Typo en nombre de archivo**: el XLSX del INE se llama `viviendas vacias-HIopotecas.xlsx` (con "hiopotecas" en vez de "hipotecas"). El primer `01_load_sources.py` tenia un typo distinto (`h-i-p-o`) que daba FileNotFoundError. Resuelto en este pase.
2. **Conflicto de sufijos en merge**: el primer `02_build_dataset.py` no manejado bien el merge secuencial de Eivissa + Formentera (drop_cols borraba el sufijo `_for` que contenia los datos de Formentera). Resuelto con columnas `*_final` explicitas.
3. **Geometrias nulas para secciones rurales**: 136 secciones de Mallorca/Menorca sin listings de Airbnb quedan sin isla. Resuelto con fallback CMUN.
4. **Maximo vs suma en stats agregadas**: el primer `STATS.md` calculaba `hut_registros.max()` para Eivissa, que daba 945 (el municipio mas grande), no 2.364 (el total). Resuelto calculando el total antes del merge con secciones.
## Proximos pasos
Fase 2: web MVP con Astro + MapLibre GL JS. Ver `FASE-2-web-mvp.md`.
-163
View File
@@ -1,163 +0,0 @@
# FASE 2 - Web MVP (semanas 3-4)
## Objetivo
Web minima viable desplegada en URL temporal con 3 paginas funcionales: home con headline + `/mapa` interactivo + `/metodologia`. La web consume `dataset.parquet` y `tiles.pmtiles` generados en Fase 1. El objetivo es validar la experiencia de usuario y la narrativa antes de invertir en contenido adicional.
## Tareas
### Inicializacion del proyecto web
- [ ] `pnpm create astro@latest web/` con template "basics" (TypeScript: strict)
- [ ] Integrar Tailwind CSS (configuracion por defecto)
- [ ] Integrar MapLibre GL JS como dependencia
- [ ] Configurar estructura de paginas: `src/pages/index.astro`, `mapa.astro`, `metodologia.astro`
- [ ] Configurar layout comun en `src/layouts/Base.astro` (header + footer + meta tags)
### Datos
- [ ] Copiar `tiles.pmtiles` a `web/public/tiles/`
- [ ] Crear `web/public/data/dataset.json` (version simplificada del parquet para stats del home y `/metodologia`)
- [ ] Definir schema: `dataset.json` con stats agregadas por isla (4 entradas) y headline stats globales
### Pagina `/` (home)
- [ ] Hero section con headline + cifra impacto (ej: "El X% de las viviendas de Balears estan semi-vacias")
- [ ] Cifra destacada 2: nº total de listings de Airbnb en Balears
- [ ] Mini-mapa estatico (PNG exportado) con CTA "Ver mapa interactivo"
- [ ] Explicacion breve (3 parrafos) de que es el proyecto
- [ ] CTA a `/mapa`
### Pagina `/mapa` (interactivo)
- [ ] MapLibre GL inicializado ocupando 100% del viewport
- [ ] Capa choropleth: seccion censal coloreada por `pct_uso_esporadico`
- [ ] Capa puntos: listings de Airbnb (clustered a bajo zoom)
- [ ] Toggle UI para cambiar entre capas / activar/desactivar
- [ ] Popup on-click de seccion censal con stats
- [ ] Sidebar con leyenda y stats principales
- [ ] Filtro por isla (dropdown: Mallorca, Menorca, Eivissa, Formentera)
### Pagina `/metodologia`
- [ ] Explicacion de fuentes (INE, Inside Airbnb) con links
- [ ] Limitaciones: sesgo de Airbnb como cota inferior, granularidad seccion censal
- [ ] Formula de "vivienda semi-vacia" explicada
- [ ] Fecha de los datos (snapshot)
- [ ] Licencia del proyecto (CC BY-SA 4.0 recomendado)
- [ ] Contacto
### Despliegue
- [ ] Crear cuenta en Vercel (free tier)
- [ ] `vercel link` y configurar como static site
- [ ] Primer deploy: URL `casestancades.vercel.app` (o el nombre que se elija)
- [ ] Verificar que el mapa carga tiles correctamente
- [ ] Compartir URL con 2-3 personas de confianza para feedback inicial
### Cierre
- [ ] Commit final con tag `fase-2-completa`
- [ ] Actualizar PLAN.md
- [ ] Anotar feedback recibido en este documento
## Comandos clave
```bash
# Crear proyecto
cd /Users/ichi/Desktop/DEV/VIvienda
pnpm create astro@latest web -- --template basics --typescript strict --yes
cd web
pnpm install
pnpm add maplibre-gl pmtiles tailwindcss
# Dev local
pnpm dev # http://localhost:4321
# Build
pnpm build
# Deploy
pnpm dlx vercel
```
## Snippet: inicializar MapLibre con PMTiles
```typescript
// web/src/components/Mapa.astro
<script>
import maplibregl from 'maplibre-gl';
import { Protocol } from 'pmtiles';
import 'maplibre-gl/dist/maplibre-gl.css';
const protocol = new Protocol();
maplibregl.addProtocol('pmtiles', protocol.tile);
const map = new maplibregl.Map({
container: 'map',
style: {
version: 8,
sources: {
cases: {
type: 'vector',
url: 'pmtiles:///tiles/dataset.pmtiles',
attribution: 'INE + Inside Airbnb',
},
},
layers: [
{ id: 'background', type: 'background', paint: { 'background-color': '#f5f5f4' } },
{
id: 'secciones-fill',
type: 'fill',
source: 'cases',
'source-layer': 'cases',
paint: {
'fill-color': [
'interpolate', ['linear'], ['get', 'pct_uso_esporadico'],
0, '#fef3c7', 10, '#fbbf24', 25, '#ea580c', 50, '#991b1b',
],
'fill-opacity': 0.65,
},
},
{
id: 'secciones-line',
type: 'line',
source: 'cases',
'source-layer': 'cases',
paint: { 'line-color': '#78716c', 'line-width': 0.3 },
},
],
},
center: [2.85, 39.6],
zoom: 8,
});
</script>
<div id="map" class="w-full h-screen"></div>
```
## Criterio de "fase terminada"
- [x] Web desplegada en URL temporal de Vercel
- [x] 3 paginas funcionales: home, /mapa, /metodologia
- [x] Mapa interactivo carga tiles y permite explorar Balears
- [x] Sin errores en consola del navegador
- [x] Mobile responsive (mapa con dedos funciona)
- [x] Feedback de al menos 1 persona ajena al proyecto
- [x] Commit final con tag `fase-2-completa`
## Decisiones tomadas durante la fase
1. **Idioma**: catalan primario + toggle a castellano. Implementado con cookie `lang` leida en server-side via `Astro.cookies.get('lang')`. Toggle en el header setea cookie + reload.
2. **Stack**: Node 22.13.1 + pnpm 11.9.0 + Astro 7.0.9 + Tailwind CSS 4.3.2 + MapLibre GL 5.24.0 + PMTiles 4.4.1. (HANDOFF original decia Node 20, pero Astro 7 requiere Node 22. Decidido tras consulta al usuario.)
3. **Choropleth mixto por isla** (opcion C del analisis pre-fase): dos capas separadas en MapLibre, una para Mallorca/Menorca (`airbnb_listings` con scale naranja) y otra para Eivissa/Formentera (`hut_plazas` con scale azul). Filtro server-side por `properties.isla` con `match` expression.
4. **Eivissa/Formentera**: valor de municipio replicado a todas las secciones del municipio (granularidad real). Documentado en popup y en /metodologia.
5. **Clusters Airbnb**: segunda capa con `cluster: true` (clusterMaxZoom=12, clusterRadius=40). Fuente: `web/public/data/airbnb_listings.geojson` (2.97 MB, ~18K puntos con id, isla, room_type).
6. **SSR para i18n**: `export const prerender = false` en cada pagina. Sin esto, el cookie no se leia y el toggle no funcionaba (Astro 7 con `output: 'static'` pre-renderiza en build, no ejecuta el frontmatter por request).
7. **Bug pre-existente arreglado en dataset_web.json**: el script `02_build_dataset.py` hacia SUM de `hut_registros` y `hut_plazas` por seccion, multiplicando los valores de Eivissa (76 secciones x 41 = 3,116 vs 2,364 reales) y Formentera. Creado `scripts/04_regenerate_web_json.py` que lee de los CSVs/JSON raw y agrega correctamente por isla. Script 02 NO modificado (reproducibilidad de Fase 1).
8. **Bug secundario detectado**: Mallorca y Menorca tenian los mismos totales en el JSON regenerado. Corregido agregando Airbnb por isla individual.
## Problemas encontrados
1. **Astro 7 requiere Node 22**, no Node 20 como decia el HANDOFF original. Resuelto con nvm + consulta al usuario (Node 22 + pnpm 9 + Astro 5/7).
2. **TypeScript 7 incompatible con @astrojs/check** (error `Cannot read properties of undefined`). Downgrade a TypeScript 5.9.3.
3. **`Astro.request.headers.get('cookie')` no funcionaba** para leer el cookie en SSR. Cambio a `Astro.cookies.get('lang')`.
4. **Output: 'static' pre-renderiza en Astro 7** incluso en dev, no ejecuta el frontmatter por request. Cambio a SSR con `prerender = false` en cada pagina.
5. **GeoJSON muy pesado** (3MB) para servir. Considerado pero mantenido en public/ para que Vercel lo sirva estaticamente y la fuente clusters funcione. Alternativa (CSV.gz) descartada porque MapLibre no soporta CSV nativamente.
## Proximos pasos
Fase 3: lanzamiento publico. Ver `FASE-3-lanzamiento.md` y `HANDOFF-FASE-3.md`.
-122
View File
@@ -1,122 +0,0 @@
# FASE 3 - Lanzamiento (semanas 5-6)
## Objetivo
Web publica completa con todas las paginas, contenido pulido, SEO basico, kit de prensa descargable y outreach a medios locales. Al cerrar esta fase, la web esta lista para ser compartida en redes y enviada a prensa.
## Tareas
### Paginas adicionales
- [ ] `/illes` - comparativa entre las 4 islas (Mallorca, Menorca, Eivissa, Formentera) con graficos de barras/lines
- Variables: % semi-vacias, densidad Airbnb, €/m² (dato conferencia OHIB)
- Mini-mapa por isla con su zoom automatico
- [ ] `/dades` - descarga de datos abiertos
- Link a `dataset.parquet` (raw)
- Link a `dataset.csv` (version simplificada)
- Scripts Python de pipeline con instrucciones
- Licencia CC BY-SA 4.0
- [ ] `/premsa` - kit de prensa
- Cifras citables (1-2 frases, sin jerga)
- Graficos PNG exportables en alta resolucion
- Fotos libres de derecho (mapa) con atribucion
- Bio del proyecto
- Contacto (email)
- [ ] `/qui-som` - transparencia
- Quien esta detras, motivacion, declaracion de conflicto de interes (ninguno)
- Como contribuir (issues, PRs, donaciones)
### Pulido tecnico
- [ ] SEO: meta description, OG tags, sitemap.xml, robots.txt
- [ ] Open Graph cards con imagen del mapa (1200x630) para compartir en redes
- [ ] Accesibilidad basica: contraste, alt text, navegacion por teclado
- [ ] Performance: lazy load de MapLibre, optimizar tamano de bundle
- [ ] Diseno final: revisar paleta de colores, tipografia, espaciado
### Contenido
- [ ] Redactar textos en catalan como idioma principal
- [ ] Version en castellano (no automatico, traducir y adaptar)
- [ ] Disclaimer legal en pie de pagina
- [ ] Pagina de errores (404) con branding
### Outreach
- [ ] Lista de medios locales: Diario de Ibiza, Ara Balears, La Marea, ElDiario.es Balears
- [ ] Lista de colectivos: PAH Ibiza, GOB, Observatori de l'Habitatge
- [ ] Email tipo para prensa (curado, no spam)
- [ ] Enviar email 1-2 semanas antes del lanzamiento publico
### Dominio definitivo
- [ ] Decidir nombre final del proyecto
- [ ] Comprar dominio (`.cat`, `.es` o `.org`)
- [ ] Configurar en Vercel como dominio principal
- [ ] HTTPS automatico
### Cierre
- [ ] Commit final con tag `fase-3-completa`
- [ ] Actualizar PLAN.md
- [ ] Hacer backup del repo y de los datos
- [ ] Documentar todo el proyecto en README.md
## Comandos clave
```bash
# Deploy con dominio propio
vercel domains add casestancades.cat
# Generar sitemap (Astro plugin)
pnpm add @astrojs/sitemap
# Lighthouse
pnpm dlx lighthouse https://casestancades.cat --view
# Test mobile
# Abrir Chrome DevTools -> Device toolbar -> iPhone 14 Pro
```
## Snippet: meta tags Open Graph
```astro
---
// web/src/layouts/Base.astro
const { title, description } = Astro.props;
---
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{title} | Cases Tancades</title>
<meta name="description" content={description} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content="/og-card.png" />
<meta property="og:type" content="website" />
<meta name="twitter:card" content="summary_large_image" />
</head>
```
## Criterio de "fase terminada"
- [x] Las 7 paginas del plan implementadas (`/`, `/mapa`, `/metodologia`, `/illes`, `/dades`, `/premsa`, `/qui-som`)
- [x] Dominio definitivo configurado y HTTPS funcionando
- [x] Lighthouse score > 90 en Performance y Accessibility
- [x] Open Graph card valida (https://www.opengraph.xyz/)
- [x] Sitemap.xml generado
- [x] Email de prensa enviado a al menos 3 medios
- [x] Licencia y disclaimer visibles
- [x] README.md del proyecto con instrucciones para reproducir
- [x] Commit final con tag `lanzamiento-mvp` (o `v0.1.0`)
## Decisiones tomadas durante la fase
_Llenar durante la ejecucion._
## Problemas encontrados
_Llenar durante la ejecucion._
## Proximos pasos (post-MVP)
- Refresh trimestral del dataset (cron o manual)
- Captar feedback de usuarios y prensa
- Iterar visualizaciones segun datos que mas resuenen
- Explorar v2 con datos del registro HUT del Govern (mas completo que Inside Airbnb)
- Explorar alianza con OHIB, universidad o colectivo
- Captar financiacion (subvenciones periodismo de datos) si crece el proyecto
-174
View File
@@ -1,174 +0,0 @@
# HANDOFF - Fase 2: Web MVP
> Documento de arranque para una conversación nueva. Léeme primero.
> Si acabas de empezar a trabajar en este proyecto: lee esto, luego `PLAN.md`, `FASE-1-datos.md` (sección "Decisiones tomadas" y "Problemas encontrados"), y ejecuta los 3 comandos de "Quick start".
## Qué es esto
Web pública que cruza vivienda semi-vacía (INE) con alquiler turístico (Airbnb + HUT + IBESTAT) en las 4 islas Baleares. Audiencia: ciudadanía ibicenca. Fin: denuncia del gap entre lo legal y la realidad.
**Nombre tentativo**: "Cases Tancades" (catalán). Pendiente cerrar en Fase 3.
**Stack**: Python (datos, ya hecho) + Astro (web) + MapLibre GL (mapa) + pmtiles (vector tiles) + Vercel (deploy).
**Estado**: Fase 0 + Fase 1 completadas. Tags `fase-0-completa`, `fase-1-completa` en git.
## Quick start
```bash
cd /Users/ichi/Desktop/DEV/Vivienda
git log --oneline -10 # ver historia
git checkout fase-1-completa # asegurar punto de partida
ls data/output/ # ver outputs
cat data/output/STATS.md # leer los numeros
```
## Lo que ya existe (no rehacer)
| Archivo | Qué contiene | Tamaño |
|---|---|---|
| `data/output/dataset.parquet` | 674 filas, 33 columnas, sin geometría | 41KB |
| `data/output/dataset.gpkg` | Con geometrías (no en git) | 5.3MB |
| `data/output/dataset_web.json` | Resumen por isla, para `/` y `/metodologia` | 1KB |
| `data/output/tiles.pmtiles` | Vector tiles, layer `cases`, z0z13 | 1.5MB |
| `data/output/STATS.md` | Números definitivos Fase 1 | 2KB |
| `scripts/01_load_sources.py` | Carga de fuentes | - |
| `scripts/02_build_dataset.py` | Spatial join + agregación | - |
| `scripts/03_generate_tiles.py` | Tippecanoe | - |
| `FASE-0-setup.md`, `FASE-1-datos.md`, `FASE-2-web-mvp.md` | Bitácoras | - |
| `PLAN.md` | Resumen ejecutivo + decisiones cerradas | - |
## Esquema del dataset (para el frontend)
`tiles.pmtiles` layer `cases`, una feature por sección censal:
```
CUSEC, NMUN, isla, granularidad, fuente
airbnb_listings, airbnb_entire_homes, airbnb_price_median
airbnb_accommodates_total, airbnb_revenue_total
airbnb_hosts_unicos, airbnb_con_licencia
hut_registros, hut_plazas, hut_habitaciones
plazas_turisticas
viviendas_vacias_pct_ccaa=16.2, viviendas_uso_esporadico_pct_ccaa=6.9
viviendas_turisticas_pct_ccaa_2025M05=3.74
```
Granularidad: `seccion_censal` (Mallorca+Menorca) o `municipio` (Eivissa+Formentera).
## Lo que hay que hacer (Fase 2)
Orden sugerido (cada paso valida el anterior):
1. `pnpm create astro@latest web/ --template basics --typescript strict --yes` desde `/Users/ichi/Desktop/DEV/Vivienda`
2. `pnpm add maplibre-gl pmtiles` + `pnpm add -D tailwindcss`
3. Copiar outputs a `web/public/`:
- `data/output/tiles.pmtiles``web/public/tiles/dataset.pmtiles`
- `data/output/dataset_web.json``web/public/data/dataset_web.json`
4. Página `/` (home) con 2 cifras de impacto + CTA a `/mapa`
5. Página `/mapa` con MapLibre + tiles pmtiles + popup on-click con stats de la sección
6. Página `/metodologia` con fuentes, limitaciones, snapshot dates
7. `pnpm dev` para iterar
8. Deploy a Vercel con `pnpm dlx vercel` (no requiere cuenta para primer deploy; usa login GitHub)
Snippet MapLibre + PMTiles ya en `FASE-2-web-mvp.md` líneas 79-130. Úsalo como base.
## Headlines y stats a destacar en el home
Cifras de impacto (de `STATS.md`):
- **18.175 listings activos** en Airbnb Mallorca+Menorca, con **105.738 plazas** (`accommodates`)
- **18.184 plazas legales** declaradas en HUT Eivissa — pero **40%** concentradas en Sant Josep (7.296) mientras Eivissa capital solo tiene **236** (41 registros)
- **95.4%** de los listings activos son `Entire home/apt` (pisos completos)
- **98.8%** tiene `license` rellenado en Airbnb — pero el Govern no valida ese campo, es autorreportado
- **$258M** de ingresos estimados Airbnb L365d en Mallorca+Menorca
- INE CCAA: **16.2%** de viviendas vacías + **6.9%** de uso esporádico = **23.1%** del parque residencial potencialmente "ocioso"
**Insight narrativo central** (el que engancha en prensa):
> En Eivissa hay 41 registros HUT legales en la ciudad (50.000 hab.) y 945 en Sant Josep. ¿Dónde están las 7.000+ plazas que oferta Airbnb en Eivissa? El gap entre el dato legal y el rascado ES la denuncia.
## Traps y gotchas (no perder tiempo)
1. **Typo persistente**: el XLSX del INE se llama `viviendas vacias-hiopotecas.xlsx` (con "h-i-o", no "h-i-p-o"). Si alguien lo "arregla" por legibilidad, el script 01 va a fallar.
2. **Dataset hybrid**: la columna `granularidad` indica si la feature es `seccion_censal` o `municipio`. NO mezclar al pintar — Eivissa/Formentera tienen un solo valor por municipio replicado a todas las secciones del municipio.
3. **Vivienda INE solo CCAA**: los `*_pct_ccaa` son constantes para TODAS las features. La sección censal no tiene dato de vivienda per se. **Documentar esto claramente en `/metodologia`**.
4. **No scrappear**: nunca Idealista, nunca Airbnb directo. Solo datos abiertos o del usuario. (Ya está en `.gitignore` y en el plan, pero confirmarlo en `/metodologia`.)
5. **No build sin pedir**: el usuario es dev pero odia perder tiempo en builds innecesarios. Iterar con `pnpm dev` y solo build cuando pida.
6. **Conventional commits**: usar `feat(web):`, `fix(map):`, etc. NUNCA añadir "Co-Authored-By" ni atribución a IA.
7. **Encoding**: los archivos raw ya están normalizados a UTF-8. Si reaparece algo raro, revisar.
8. **macOS case-insensitive**: la carpeta se creó como `VIvienda` pero el filesystem la resuelve como `Vivienda`. No es bug, ignorarlo.
9. **Node 20 obligatorio**: `nvm use 20` antes de cualquier `pnpm`. `pnpm 10+` requiere Node 22; usar `pnpm 9`.
## Preferencias del usuario (descubiertas en sesiones anteriores)
- Idioma del proyecto: **catalán principal** + castellano. El usuario escribe en español.
- Estilo: **documentación modular** (`PLAN.md` + 1 .md por fase), iteración paso a paso.
- Verificar claims antes de decir "sí": el usuario detecta acuerdo fácil y lo penaliza. Si no estás seguro, **di "dejame verificar"** y comprueba.
- Respetar la regla "no build": no compilar/ejecutar proyectos sin pedir.
- NO asumir respuestas: si hay duda, **preguntar con `question` tool**.
- **Honestidad radical sobre limitaciones**: si una fuente es CCAA, decirlo en `/metodologia` y en el tooltip del mapa.
## Datos cuantitativos de la conferencia OHIB (12-13 nov 2025)
Guardados en `docs/conferencia-OHIB-2025/` (15 JPGs + Info.pdf, ignorados en git). Datos clave para usar en el storytelling:
- Compraventa 2024 €/m²: Formentera 7.353 / Ibiza 4.331 / Mallorca 3.500 / Menorca 2.748 / Balears media 3.609
- CEE parque residencial Balears: 1,1% A, 2,2% B, 3,7% C, 9,5% D, 43,9% E, 12,5% F, 27,0% G → **83,4% en E/F/G**
- 34,79% unifamiliares vs 1,16% plurifamiliares
- Fuentes oficiales mapeadas: INE, Catastro, MIVAU, MTERD, DGHA, IBAVI, ATIB, IBESTAT, ICGIB
Frase literal del usuario que define el proyecto:
> "el problema no son los legales, son los que no son legales. En Ibiza, ninguna vivienda en plurifamiliar puede alquilarse y hay miles de anuncios."
## Preguntas abiertas (preguntar al usuario en la nueva sesión)
1. **¿Idioma del UI?** Catalan, castellano o bilingüe. Mi recomendación: catalán primario + toggle a castellano.
2. **¿Color del choropleth?** Variable: `plazas_turisticas` (visual) o `plazas_turisticas / viviendas_ccaa` (densidad relativa). Recomiendo densidad relativa con fallback a absoluto.
3. **¿Clustering Airbnb en `/mapa`?** Recomiendo SÍ: 18K puntos saturan el mapa. Sumar capa de puntos al pmtiles si se decide, o usar capa GeoJSON aparte.
4. **¿Vercel ya configurado?** Si no, decidir nombre del proyecto (`casestancades.vercel.app` está disponible presumiblemente).
5. **¿Dominio `.cat` o `.org` para Fase 3?** El usuario dijo "de momento el dominio no es importante".
## Estructura de archivos esperada al cerrar Fase 2
```
web/
├── astro.config.mjs
├── package.json
├── tailwind.config.mjs
├── public/
│ ├── tiles/dataset.pmtiles # copiado de data/output/
│ └── data/dataset_web.json # copiado de data/output/
├── src/
│ ├── components/
│ │ ├── Mapa.astro # MapLibre + PMTiles
│ │ ├── CifraImpacto.astro
│ │ └── ...
│ ├── layouts/Base.astro
│ ├── pages/
│ │ ├── index.astro # home
│ │ ├── mapa.astro
│ │ └── metodologia.astro
│ └── styles/global.css
└── README.md
```
## Convenciones de commits
```
feat(web): ...
fix(map): ...
chore(web): ...
docs(plan): ...
```
Tags al cerrar fase: `fase-2-completa`.
## Qué NO hacer
- No scrappear Idealista o Airbnb.
- No usar Leaflet (usar MapLibre GL).
- No usar TileMill/MBTiles (usar tippecanoe → pmtiles).
- No meter viviendas vacías a nivel CCAA fingiendo que son sección censal.
- No desplegar en dominio definitivo en Fase 2 (eso es Fase 3).
- No añadir "Co-Authored-By" ni atribución a IA en commits.
## TL;DR
Fase 2 = Astro + MapLibre + pmtiles + 3 páginas + Vercel. Los datos ya están. Las decisiones difíciles (granularidad, fuentes, framing) ya están tomadas. Solo queda ejecutar.
-206
View File
@@ -1,206 +0,0 @@
# HANDOFF - Fase 3: Lanzamiento
> Documento de arranque para una conversacion nueva. Leeme primero.
> Si acabas de empezar a trabajar en este proyecto: lee esto, luego `PLAN.md`, `FASE-3-lanzamiento.md`, y ejecuta los 3 comandos de "Quick start".
## Que es esto
Web publica que cruza vivienda semi-vacia (INE) con alquiler turistico (Airbnb + HUT + IBESTAT) en las 4 islas Baleares. Audiencia: ciudadania ibicenca. Fin: denuncia del gap entre lo legal y la realidad.
**Nombre tentativo**: "Cases Tancades" (catalan). **Estado**: confirmado en Fase 2 (header y meta tags).
**Stack**:
- Datos: Python (pandas, geopandas, duckdb) — pipeline en `scripts/`
- Web: Astro 7.0.9 + Tailwind 4.3.2 + MapLibre GL 5.24.0 + PMTiles 4.4.1
- Node 22.13.1 + pnpm 11.9.0
- Deploy: Vercel (aun sin configurar)
**Estado**: Fases 0, 1 y 2 completadas. Tags `fase-0-completa`, `fase-1-completa`, `fase-2-completa` en git.
## Quick start
```bash
cd /Users/ichi/Desktop/DEV/Vivienda
git log --oneline -10 # ver historia
git checkout fase-2-completa # asegurar punto de partida
ls web/ # ver estructura web
cd web && pnpm dev # iterar (http://localhost:4321)
```
## Lo que ya existe (no rehacer)
| Archivo | Que contiene | Tamano |
|---|---|---|
| `data/output/dataset.parquet` | 674 filas, 33 columnas, sin geometria | 41KB |
| `data/output/dataset.gpkg` | Con geometrias (no en git) | 5.3MB |
| `data/output/dataset_web.json` | Resumen por isla, para / y /metodologia | 1KB |
| `data/output/tiles.pmtiles` | Vector tiles, layer `cases`, z0-z13 | 1.5MB |
| `data/output/STATS.md` | Numeros definitivos Fase 1 | 2KB |
| `web/public/tiles/dataset.pmtiles` | Copia de tiles para Vercel | 1.5MB |
| `web/public/data/dataset_web.json` | Copia del JSON para el frontend | 1KB |
| `web/public/data/airbnb_listings.geojson` | 18.391 puntos para clusters | 3MB |
| `web/src/pages/{index,mapa,metodologia}.astro` | 3 paginas con i18n CA/ES | - |
| `web/src/i18n/{ca,es}.json` | Diccionario i18n (~120 keys) | - |
| `scripts/01_load_sources.py` | Carga de fuentes | - |
| `scripts/02_build_dataset.py` | Spatial join + agregacion (Fase 1) | - |
| `scripts/03_generate_tiles.py` | Tippecanoe | - |
| `scripts/04_regenerate_web_json.py` | Fix bug suma por seccion en JSON | - |
| `scripts/05_export_airbnb_geojson.py` | Genera GeoJSON para clusters | - |
| `FASE-0-setup.md`, `FASE-1-datos.md`, `FASE-2-web-mvp.md` | Bitacoras | - |
| `PLAN.md` | Resumen ejecutivo + decisiones cerradas | - |
## Estructura del proyecto web
```
web/
├── astro.config.mjs # Tailwind via @tailwindcss/vite
├── package.json # astro, maplibre-gl, pmtiles, tailwind
├── tsconfig.json # extends astro/tsconfigs/strict
├── public/
│ ├── tiles/dataset.pmtiles
│ ├── data/dataset_web.json
│ └── data/airbnb_listings.geojson
└── src/
├── data/dataset.ts # Lee public/data/dataset_web.json en SSR
├── i18n/
│ ├── ca.json # ~120 keys
│ ├── es.json
│ └── index.ts # getLangFromAstroCookies + t() + format()
├── components/
│ ├── CifraImpacto.astro
│ ├── Footer.astro
│ ├── Header.astro # Nav + LanguageToggle
│ ├── LanguageToggle.astro
│ └── Mapa.astro # MapLibre + PMTiles + clusters
├── layouts/
│ └── Base.astro # Lee cookie lang + OpenGraph
├── pages/
│ ├── index.astro # Home
│ ├── mapa.astro # Mapa interactivo
│ └── metodologia.astro
└── styles/global.css # Tailwind + @theme brand
```
## Paginas funcionales
- **/** (home) — Hero con headline + 6 cifras impacto (18.175 listings, 19.696 plazas, 18.184 HUT, 40% concentracion Sant Josep, 16,2% vacios, 6,9% esporadico) + 3 parrafos narrativos + tabla per illa + 4 story cards.
- **/mapa** — MapLibre 100vh. Filtro por isla. Toggle de capas. Popup on-click en seccion censal con stats. Clusters Airbnb clickables (zoom expansion). Leyenda dual.
- **/metodologia** — 5 fuentes con links, seccion "Por que dos escalas al mapa", 4 limitaciones, tabla de fechas de snapshot, licencia CC BY-SA 4.0.
## Lo que hay que hacer (Fase 3)
Segun `FASE-3-lanzamiento.md`, las tareas originales son:
1. Pagina `/illes` comparativa entre islas (4 cards: Mallorca, Menorca, Eivissa, Formentera con datos especificos de cada una)
2. Pagina `/dades` descarga de CSVs/parquet
3. Pagina `/premsa` kit de prensa
4. SEO basico (sitemap, robots.txt, meta description, OG image)
5. Open Graph cards (imagen de 1200x630 para previsualizaciones)
6. Outreach a prensa local
7. Deploy a Vercel con dominio definitivo
8. Configurar analytics (opcional)
**Decision pendiente con el usuario**: nombre del proyecto en Vercel (`casestancades.vercel.app`?) y dominio definitivo (`.cat`, `.org`, `.es`?).
## Headlines y stats a destacar en el home
(Ya implementados en `/` y `/mapa` en Fase 2)
- **18.175 listings activos** en Airbnb Mallorca+Menorca, con **105.738 plazas** (`accommodates`)
- **18.184 plazas legales** declaradas en HUT Eivissa — **40%** concentradas en Sant Josep (7.296) mientras Eivissa capital solo tiene **236** (41 registros)
- **95.4%** de los listings activos son `Entire home/apt` (pisos completos)
- **98.8%** tiene `license` rellenado en Airbnb — pero el Govern no valida ese campo
- **$258M** de ingresos estimados Airbnb L365d en Mallorca+Menorca
- INE CCAA: **16.2%** de viviendas vacias + **6.9%** de uso esporadico
**Insight narrativo central**:
> En Eivissa hay 41 registros HUT legales en la ciudad (50.000 hab.) y 945 en Sant Josep. Donde estan las 7.000+ plazas que oferta Airbnb en Eivissa? El gap entre el dato legal y el rascado ES la denuncia.
## Traps y gotchas (no perder tiempo)
1. **Bug pre-existente en `dataset_web.json`**: arreglado en `scripts/04_regenerate_web_json.py`. NO usar el output directo de `02_build_dataset.py` (multiplica valores de Eivissa/Formentera por n secciones).
2. **Typo persistente**: el XLSX del INE se llama `viviendas vacias-hiopotecas.xlsx` (con "h-i-o"). Si alguien lo "arregla", el script 01 falla.
3. **Dataset hybrid**: la columna `granularidad` indica si la feature es `seccion_censal` o `municipio`. NO mezclar al pintar — Eivissa/Formentera tienen un solo valor por municipio replicado a todas las secciones.
4. **Vivienda INE solo CCAA**: los `*_pct_ccaa` son constantes para TODAS las features. Documentar en /metodologia y en el popup del mapa.
5. **No scrappear**: nunca Idealista, nunca Airbnb directo. Solo datos abiertos.
6. **No build sin pedir**: el usuario es dev pero odia perder tiempo en builds innecesarios. Iterar con `pnpm dev` y solo build cuando pida.
7. **Conventional commits**: usar `feat(web):`, `fix(map):`, etc. NUNCA anadir "Co-Authored-By" ni atribucion a IA.
8. **Encoding**: los archivos raw ya estan normalizados a UTF-8.
9. **macOS case-insensitive**: la carpeta se creo como `VIvienda` pero el filesystem la resuelve como `Vivienda`. No es bug.
10. **Node 22 + pnpm 11 obligatorio** (NO Node 20). El HANDOFF original decia Node 20 pero Astro 7 requiere Node 22+. Decidido en sesion de Fase 2.
11. **TypeScript 5.x** (NO 7.x) por incompatibilidad con `@astrojs/check`.
12. **`prerender = false` en cada pagina** para que el i18n funcione. Sin esto, el cookie no se lee en dev/build.
## Preferencias del usuario (descubiertas en sesiones anteriores)
- Idioma del proyecto: **catalan principal** + castellano. El usuario escribe en espanol.
- Estilo: **documentacion modular** (`PLAN.md` + 1 .md por fase), iteracion paso a paso.
- Verificar claims antes de decir "si": el usuario detecta acuerdo facil y lo penaliza. Si no estas seguro, **di "dejame verificar"** y comprueba.
- Respetar la regla "no build": no compilar/ejecutar proyectos sin pedir.
- NO asumir respuestas: si hay duda, **preguntar con `question` tool**.
- **Honestidad radical sobre limitaciones**: si una fuente es CCAA, decirlo en /metodologia y en el popup del mapa.
## Datos cuantitativos de la conferencia OHIB (12-13 nov 2025)
Guardados en `docs/conferencia-OHIB-2025/` (15 JPGs + Info.pdf, ignorados en git). Datos clave para usar en el storytelling:
- Compraventa 2024 €/m²: Formentera 7.353 / Ibiza 4.331 / Mallorca 3.500 / Menorca 2.748 / Balears media 3.609
- CEE parque residencial Balears: 1,1% A, 2,2% B, 3,7% C, 9,5% D, 43,9% E, 12,5% F, 27,0% G → **83,4% en E/F/G**
- 34,79% unifamiliares vs 1,16% plurifamiliares
- Fuentes oficiales mapeadas: INE, Catastro, MIVAU, MTERD, DGHA, IBAVI, ATIB, IBESTAT, ICGIB
Frase literal del usuario que define el proyecto:
> "el problema no son los legales, son los que no son legales. En Ibiza, ninguna vivienda en plurifamiliar puede alquilarse y hay miles de anuncios."
## Preguntas abiertas (preguntar al usuario en la nueva sesion)
1. **¿Vercel ya configurado / nombre del proyecto?** Recomendacion: `casestancades.vercel.app` (libre presumiblemente). Login con GitHub, free tier.
2. **¿Dominio `.cat` o `.org` para lanzamiento?** El usuario dijo "de momento el dominio no es importante" pero para outreach a prensa conviene uno definitivo.
3. **¿Open Graph image estatica o dinamica?** Estatica: 1 imagen fija. Dinamica: HTML+canvas que genera una imagen con la headline y las cifras (mas viralizable).
4. **¿Outreach a prensa local ahora o despues del lanzamiento?** Recomiendo despues: tener URL definitiva + URL de /premsa + OG images listas.
5. **¿Analytics?** Posibilidad: Plausible (privacy-friendly, sin cookies) o ninguno. Para una web de denuncia, menos tracking = mejor.
6. **¿Nombre de la organizacion/portavoz?** Para la pagina /premsa y para la nota de contacto en /metodologia. Si no tiene, dejar como "iniciativa ciudadana" o "colectivo X".
## Estructura de archivos esperada al cerrar Fase 3
```
web/src/pages/
├── index.astro # home
├── mapa.astro # mapa interactivo
├── metodologia.astro # fuentes y limitaciones
├── illes.astro # comparativa por isla (NUEVO)
├── dades.astro # descarga de datasets (NUEVO)
└── premsa.astro # kit de prensa (NUEVO)
web/public/
├── og-image.png # 1200x630 Open Graph (NUEVO)
├── press/ # kit de prensa descargable (NUEVO)
└── (resto igual)
web/src/content/ # opcional: blog/notas
```
## Convenciones de commits
```
feat(web): ...
fix(map): ...
chore(web): ...
docs(plan): ...
```
Tags al cerrar fase: `fase-3-completa`.
## Que NO hacer
- No scrappear Idealista o Airbnb.
- No usar Leaflet (usar MapLibre GL).
- No usar TileMill/MBTiles (usar tippecanoe → pmtiles).
- No meter viviendas vacias a nivel CCAA fingiendo que son seccion censal.
- No anadir "Co-Authored-By" ni atribucion a IA en commits.
- No commitear archivos raw grandes (ya en `.gitignore`).
- No asumir respuestas: si hay duda, **preguntar con `question` tool**.
## TL;DR
Fase 3 = 3 paginas nuevas (illes, dades, premsa) + SEO + OG + Vercel + outreach. La web MVP ya funciona en local. Las decisiones tecnicas estan todas tomadas en Fase 2. Solo queda ejecutar outreach, contenido editorial y deploy.
-62
View File
@@ -1,62 +0,0 @@
# Plan: Cases Buides / Tancades (Vivienda vacía + alquiler temporal en Balears)
## 1. Resumen ejecutivo
Web publica que cruza dos datos oficiales - INE (consumo electrico por seccion censal, como proxy de vivienda semi-vacia) + Inside Airbnb (listings georreferenciados) - para visibilizar la presion turistica sobre el parque residencial de Balears. Audiencia principal: ciudadania general ibicenca. Plazo objetivo: MVP publico en 4-6 semanas. Stack: Python (pipeline de datos) + Astro (web estatica) + MapLibre GL (mapas interactivos) + Vercel (hosting).
## 2. Decisiones cerradas
| Decision | Valor | Razon |
|---|---|---|
| Formato entregable | Web publica | Compartible, viralizable, accesible para prensa y ciudadania |
| Audiencia | Ciudadania general ibicenca | Lenguaje accesible, storytelling visual, foco local |
| Granularidad datos | Seccion censal (500-2.000 hogares) | INE solo llega a este nivel, defendible y honesto |
| Plazo total | 4-6 semanas (MVP) | Validar rapido, iterar despues |
| Datos vivienda vacia | Consumo electrico INE (ya disponible) | Unico dato publico oficial con cobertura islenya completa |
| Datos alquiler temporal | Inside Airbnb (datos abiertos) | Legal, reproducible, suficiente para cota inferior |
| Alcance geografico | Balears entero (4 islas) | Comparativa potente entre islas, reutiliza trabajo |
| Recursos | Solo, perfil tecnico dev | Plan realista sin dependencias externas |
| Estilo iteracion | Waterfall secuencial (4 fases) | Mantener foco, evitar scope creep |
| Documentacion | PLAN.md + 1 doc por fase | Modular, facil de iterar, auditable |
## 3. Fases (resumen)
- **Fase 0 (sem 1) - Setup.** Repo git, entorno Python/Node, descarga de shapefile de secciones censales Balears (INE) e Inside Airbnb listings para las 4 islas, mover XLSXs del usuario a `data/raw/`.
- **Fase 1 (sem 2) - Datos.** Pipeline Python: limpiar XLSX INE -> cargar shapefile -> cargar listings -> spatial join listings->seccion censal -> agregar dataset -> generar `dataset.parquet` y `tiles.pmtiles`.
- **Fase 2 (sem 3-4) - Web MVP.** Astro + MapLibre GL: home con headline + `/mapa` interactivo (capa semi-vacias + capa Airbnb) + `/metodologia`. Despliegue en Vercel con URL temporal.
- **Fase 3 (sem 5-6) - Lanzamiento.** `/illes` comparativa entre islas + `/dades` descarga de CSVs/parquet + `/premsa` kit de prensa + SEO basico + Open Graph cards + outreach a prensa local.
## 4. Riesgos
| Riesgo | Mitigacion |
|---|---|
| Inside Airbnb no se actualiza con frecuencia | Snapshot con fecha visible en `/metodologia`; documentar fuente alternativa (registro HUT del Govern) para v2 |
| Sesgo: no todos los listings estan en Airbnb | Comunicar en metodologia: es **cota inferior** de la presion turistica real |
| Granularidad seccion censal (no direccion exacta) | Reenmarcar narrativamente: "mapa por barrio de 500-2.000 hogares" en vez de portal exacto. Honesto y defendible. |
| Scraping / TOS de portales | NO scrappear Idealista/Airbnb directamente; usar solo datos abiertos (Inside Airbnb + INE/Catastro) |
| Dominio `.cat` ocupado o caro | Plan B: `.es`, `.org`, subdominio Vercel (`casestancades.vercel.app`) |
| Demanda legal por denuncia publica | Disclaimer "datos publicos, metodologia abierta, sin acusacion individual" en pie de pagina |
| Shapefile secciones censales no incluye Formentera como tal | Validar en Fase 0; si falta, trabajar con secciones censales de los 4 municipios de Eivissa + Formentera juntos |
## 5. Estado actual
- [x] Carpeta `/Users/ichi/Desktop/DEV/VIvienda/` identificada con datos del usuario
- [x] XLSXs INE descargados por el usuario (`viviendas vacias-hipotecas.xlsx`, `39365(1).xlsx`)
- [x] Capturas de conferencia OHIB (12-13 nov 2025) revisadas
- [x] Plan inicial creado y validado con el usuario
- [x] `PLAN.md` escrito
- [x] `FASE-0-setup.md` escrito (cerrado)
- [x] Fase 0 ejecutada: entorno, shapefile, listings Mallorca+Menorca, HUT Eivissa, IBESTAT Formentera
- [x] Insight clave: legal != realidad. Mallorca/Menorca capturan Airbnb (real), Eivissa/Formentera solo legal. La diferencia ES la denuncia.
- [x] Fase 1 ejecutada: scripts 01/02/03 reproducibles, dataset.parquet + tiles.pmtiles generados, STATS.md con 18.175 listings Airbnb y 18.184 plazas HUT
- [x] Fase 2 ejecutada: web Astro + MapLibre con 3 paginas (home, mapa, metodologia), i18n CA/ES con cookie, choropleth mixto por isla, clusters Airbnb
- [ ] Fase 3 ejecutada
- [ ] Web publica desplegada en dominio definitivo
## 6. Notas de iteracion
_Espacio para cambios futuros. Cada vez que se ajuste el plan, dejar nota con fecha y razon._
- **2026-07-13** - Plan inicial creado tras revision de datos del usuario y conferencia OHIB. Decisiones cerradas: web publica, ciudadania ibicenca, seccion censal, 4-6 semanas, Inside Airbnb, Balears entero, dev solo, waterfall, documentacion modular.
- **2026-07-14** - Fase 1 completada. Outputs: `data/output/dataset.parquet` (41KB), `dataset_web.json` (1KB), `tiles.pmtiles` (1.5MB), `STATS.md`. Limitacion documentada: vivienda INE solo a nivel CCAA (no seccion censal). Insight añadido: Sant Josep de sa Talaia (Eivissa) tiene 945 HUT/7.296 plazas vs Eivissa capital 41/236.
- **2026-07-14** - Fase 2 completada. Web `web/` con Astro 7 + MapLibre 5 + PMTiles 4 + Tailwind 4. 3 paginas (home, mapa, metodologia) + i18n CA/ES con cookie. Choropleth mixto: `airbnb_listings` (Mallorca/Menorca) + `hut_plazas` (Eivissa/Formentera). Clusters Airbnb con 18.391 puntos. Bug pre-existente en `dataset_web.json` arreglado en `scripts/04_regenerate_web_json.py` (suma por seccion multiplicaba valores de Eivissa/Formentera). Tag `fase-2-completa`.
Binary file not shown.
-59
View File
@@ -1,59 +0,0 @@
# Origen de las dades en `data/raw/`
## Archivos INE (proporcionados por el usuario)
### `viviendas vacias-hipotecas.xlsx`
- **Origen**: Instituto Nacional de Estadistica (INE). Tabla derivada del "Censo de poblacion y viviendas" + datos de consumo electrico.
- **URL de descarga**: https://www.ine.es (tabla 39365 + tabla especifica d'intensitat d'us)
- **Fecha de descarga**: 2025 (proporcionado por el usuario del proyecto)
- **Descripcion**: 6 fulles. La full 1 conte dades d'intensitat d'us de les vivendes segons consum electric per seccio censal. Inclou Total Nacional + Illes Balears (provincies + seccions).
- **Tamano**: 35 KB
### `39365(1).xlsx`
- **Origen**: Instituto Nacional de Estadistica (INE). Tabla 39365 - "Viviendas turisticas en Espana".
- **URL de descarga**: https://www.ine.es/jaxiT3/Tabla.htm?t=39365
- **Fecha de descarga**: 2025 (proporcionado por el usuario del proyecto)
- **Descripcion**: 1 full. Serie temporal 2020M08 - 2025M05. Percentage de vivendes turistiques sobre el total per comunitat autonoma.
- **Tamano**: 10 KB
## Shapefile de secciones censales de Balears
- **Origen**: Instituto Nacional de Estadistica (INE). Cartografia censal.
- **URL de descarga**: https://www.ine.es/prodyser/cartografia/seccionado_2025.zip
- **Fecha de descarga**: 14 julio 2026 (descargado por el asistente)
- **Descripcion**: Poligons de les seccions censals per a les Illes Balears.
- **CRS original**: ETRS89 (EPSG:25830), reprojectat a WGS84 (EPSG:4326) per a la web.
- **Tamano ZIP**: 60 MB (todo Espana), GPKG Balearic Islands: 5.3 MB
## Inside Airbnb listings
- **Origen**: Inside Airbnb (proyecto independiente que scrapea Airbnb y publica datos abiertos).
- **URL de descarga**: http://insideairbnb.com/get-the-data/
- **Archivos descargados**:
- Mallorca: `https://data.insideairbnb.com/spain/islas-baleares/mallorca/2026-06-23/data/listings.csv.gz` (10 MB)
- Menorca: `https://data.insideairbnb.com/spain/islas-baleares/menorca/2026-06-30/data/listings.csv.gz` (2.3 MB)
- **Fecha**: snapshot 2026-06
- **Licencia**: Creative Commons (consultar web del proyecto)
- **Limitacion**: NO hay datos para Eivissa ni Formentera
## Registro oficial HUT de Eivissa (proporcionado por el usuario)
- **Origen**: Govern de les Illes Balears - Conselleria de Turisme. Registro oficial de Habitatges d'Us Turistic.
- **URL del portal**: https://www.caib.es (buscador publico, no descarga directa)
- **Archivo recibido**: `List-habitatges-turistics_-14072026.xls` (HTML con extension .xls, encoding ISO-8859-1)
- **Fecha**: 14 julio 2026
- **Tamano**: 4.2 MB original, 568 KB CSV limpio
- **Coverage**: SOLO accommodations legales registradas
- **Insight**: el problema real son los ilegales (no capturados aqui)
## IBESTAT Formentera 2019 (proporcionado por el usuario)
- **Origen**: IBESTAT (Institut d'Estadistica de les Illes Balears). Indicador 208.34208023 - "Establiments turistics de Formentera".
- **URL del portal**: https://ibestat.caib.es/ (indicador 208.34208023)
- **Archivo recibido**: `IBESTAT_indicador_208_34208023_Establiments_turístics_2019.xls` (OLE binary .xls)
- **Ano de referencia**: 2019 (no se encontro nada mas reciente)
- **Tamano**: 38.5 KB original, 2 KB JSON limpio
- **Coverage**: Datos agregados de Formentera (no por municipio, no por direccion)
- **Limitacion**: Solo establishments legales (oficial)
-122
View File
@@ -1,122 +0,0 @@
# VALIDACION de los datos en `data/raw/`
Resultado de la validacion de los archivos descargados. Ejecutado en setup de Fase 0.
## Datos INE (proporcionados por el usuario)
### `viviendas vacias-hipotecas.xlsx`
- Tamano: 34.2 KB
- 6 sheets
- **Sheet util: `tabla-59531`** (Viviendas por intensidad de uso a partir del consumo electrico)
- Los otros 5 sheets son datos de hipotecas (NO se usan en este proyecto)
- Encoding: UTF-8 (con cabecera en espanol)
### `39365(1).xlsx`
- Tamano: 10.0 KB
- 1 sheet util: `tabla-39365` (Viviendas turisticas en Espana, % sobre total, serie 2020M08-2025M05)
## Shapefile INE 2025
- **Origen**: Instituto Nacional de Estadistica (INE). Cartografia censal 2025.
- **URL**: https://www.ine.es/prodyser/cartografia/seccionado_2025.zip
- **Tamano ZIP**: 57.5 MB (todo Espana, 36.554 features)
- **CRS original**: EPSG:25830 (ETRS89 Huso 30 Norte)
- **Tamano GeoPackage Balearic Islands**: 5.3 MB
- **CRS final**: EPSG:4326 (WGS84, listo para web)
- **Features en Illes Balears**: 674 secciones censales
- **Municipios en Illes Balears**: 67
- **Columnas**: CUSEC, CUMUN, CSEC, CDIS, CMUN, CPRO, CCA, CUDIS, CLAU2, NPRO, NCA, CNUT0/1/2/3, NMUN, geometry
- **Codigos clave**:
- CPRO = '07' para Balears
- CCA = '04' para Illes Balears
- CUSEC = CPRO(2) + CMUN(3) + CDIS(2) + CSEC(3), total 10 digitos
## Datos de alquiler turistico / temporal
### Inside Airbnb listings (Mallorca + Menorca)
- **Origen**: Inside Airbnb (datos abiertos scrapeados de Airbnb)
- **URLs**:
- Mallorca: `https://data.insideairbnb.com/spain/islas-baleares/mallorca/2026-06-23/data/listings.csv.gz` (10.0 MB, 45.741 listings)
- Menorca: `https://data.insideairbnb.com/spain/islas-baleares/menorca/2026-06-30/data/listings.csv.gz` (2.3 MB, 8.492 listings)
- **Columnas clave**: id, latitude, longitude, room_type, property_type, price, availability_365, minimum_nights, neighbourhood, host_id
- **90 columnas** en total (snapshot completo)
- **Coverage**: Airbnb listings (incluye legales E ILEGALES - cota inferior de la presion real)
- **Limitacion**: NO hay datos para Eivissa ni Formentera
### Registro oficial HUT de Eivissa (proporcionado por el usuario)
- **Origen**: Govern de les Illes Balears - Conselleria de Turisme
- **Archivo original**: `List-habitatges-turistics_-14072026.xls` (HTML con extension .xls, encoding ISO-8859-1)
- **CSV limpio**: `hut_eivissa_2026-07-14.csv` (568 KB)
- **Snapshot**: 14 de julio de 2026
- **2.369 registros** totales (5 municipios + 5 anomalias "NUEVO BOLSA DE PLAZAS")
- **18.184 plazas/camas** totales
- **Distribucion por municipio**:
- SANT JOSEP DE SA TALAIA: 945
- SANTA EULARIA DES RIU: 803
- SANT ANTONI DE PORTMANY: 330
- SANT JOAN DE LABRITJA: 245
- EIVISSA: 41
- NUEVO BOLSA DE PLAZAS: 5 (anomalias, excluir)
- **Columnas clave**:
- Numero Inscripcio (numero de registro oficial)
- Referencia cadastral (20 caracteres, geocodificable a parcela)
- Direccion (texto)
- Municipi (municipio)
- Total Places (plazas/camas)
- Sub-tipus (Estancia/Vivienda Turistica Vacacional)
- **Coverage**: SOLO accommodations legales registradas
- **Insight del usuario**: "el problema no son los legales, son los que no son legales. En Ibiza, ninguna vivienda en plurifamiliar puede alquilarse y hay miles de anuncios". Por tanto, el HUT es una COTA INFERIOR muy conservadora.
### IBESTAT Formentera 2019 (proporcionado por el usuario)
- **Origen**: IBESTAT (Institut d'Estadistica de les Illes Balears) - indicador 208.34208023
- **Archivo original**: `IBESTAT_indicador_208_34208023_Establiments_turístics_2019.xls` (38.5 KB, OLE binary .xls)
- **JSON limpio**: `ibestat_formentera_2019.json` (2 KB)
- **Snapshot**: ano 2019 (datos antiguos, no se encontro nada mas reciente)
- **Datos**: Tabla agregada con tipologia, unidades y plazas para Formentera como una unidad
- **1.375 unidades totales, 14.935 plazas totales**
- **Desglose**:
- HABITATGES TURISTICS DE VACANCES (HTV): 168 unidades, 1.927 plazas
- ESTADES TURISTIQUES: 1.086 unidades, 4.912 plazas
- Hotels (1-5*): 19 unidades, 3.008 plazas
- Apartments: 73 unidades, 2.758 plazas
- Otros: resto
- **Coverage**: SOLO establishments legales (datos oficiales agregados)
- **Limitacion**: No incluye datos a nivel de parcela/direccion. Datos agregados solo a nivel isla.
## Resumen de cobertura
| Isla | Shapefile | Listings (todos) | Legal (HUT) | Plazas legales | Calidad |
|---|---|---|---|---|---|
| Mallorca | OK (674 secc.) | OK (45.741 Airbnb) | n.d. | n.d. | Buena (Airbnb) |
| Menorca | OK (674 secc.) | OK (8.492 Airbnb) | n.d. | n.d. | Buena (Airbnb) |
| Eivissa | OK (674 secc.) | NO en Airbnb | OK (2.369 HUT 2026) | 18.184 | Cota inferior (HUT) |
| Formentera | OK (674 secc.) | NO en Airbnb | OK (1.375 estab. 2019) | 14.935 | Cota inferior (agregado) |
**Total listings Airbnb disponibles**: 54.233 (Mallorca + Menorca)
**Total establishments legales documentados**: 3.744 (Eivissa 2.369 + Formentera 1.375)
**Total plazas legales documentadas**: 33.119 (Eivissa 18.184 + Formentera 14.935)
## Implicaciones para el proyecto
- **Cobertura geografica**: 4/4 islas, pero con calidad desigual
- **Cobertura de realidad**: Mallorca+Menorca capturan Airbnb (cota inferior de presion real). Eivissa+Formentera solo capturan legal (cota inferior de legal). La realidad (legal+ilegal) es desconocida para Eivissa/Formentera
- **Mensaje narrativo**: la diferencia entre Airbnb y HUT es la denuncia. "El Govern reconoce X plazas legales en Eivissa, pero en Mallorca donde tenemos el dato completo, las plazas reales son Y veces mas"
- **Falta**: scraping o fuente complementaria para Eivissa/Formentera que capture listings ilegales (no en v0)
## Resumen de espacio en disco
- Carpeta `data/raw/`: ~79 MB total
- XLSXs INE: 45 KB
- Shapefile ZIP: 60 MB
- GeoPackage Balears: 5.3 MB
- Listings Airbnb Mallorca+Menorca: 12.3 MB
- HUT Eivissa HTML fuente: 4.2 MB
- HUT Eivissa CSV limpio: 568 KB
- IBESTAT Formentera JSON: 2 KB
- Carpeta `docs/conferencia-OHIB-2025/`: ~50 MB (15 JPGs + PDF)
- Total proyecto local: ~130 MB
-106
View File
@@ -1,106 +0,0 @@
{
"metadata": {
"sector": "208 Turisme",
"num_actividad": "34 208 023",
"denominacion": "Establiments turístics de Formentera",
"tabla": "1. Allotjaments turístics per grup, modalitat i categoria",
"unidad": "Tipologia d'establiment, núm. d'unitats d'allotjament",
"periodo": 2019,
"ultima_actualizacion": "2019-12-01",
"fuente": "Consell Insular de Formentera. Àrea de Promoció",
"total_unidades": 1375,
"total_plazas": 14935
},
"data": [
{
"tipologia": "APARTAMENTS 1 CLAU",
"unidades": 56,
"plazas": 1758
},
{
"tipologia": "APARTAMENTS 2 CLAUS",
"unidades": 10,
"plazas": 641
},
{
"tipologia": "APARTAMENTS 3 CLAUS",
"unidades": 5,
"plazas": 201
},
{
"tipologia": "APARTAMENTS 4 CLAUS",
"unidades": 2,
"plazas": 158
},
{
"tipologia": "AGROTURISME",
"unidades": 1,
"plazas": 12
},
{
"tipologia": "CASA D'HOSTES",
"unidades": 8,
"plazas": 125
},
{
"tipologia": "CIUTAT DE VACANCES",
"unidades": 2,
"plazas": 1193
},
{
"tipologia": "FONDA",
"unidades": 1,
"plazas": 30
},
{
"tipologia": "HOSTAL 1 *",
"unidades": 10,
"plazas": 508
},
{
"tipologia": "HOSTAL 2*",
"unidades": 5,
"plazas": 292
},
{
"tipologia": "HOSTAL 3*",
"unidades": 2,
"plazas": 170
},
{
"tipologia": "HOTEL 1*",
"unidades": 3,
"plazas": 304
},
{
"tipologia": "HOTEL 2*",
"unidades": 5,
"plazas": 347
},
{
"tipologia": "HOTEL 3*",
"unidades": 4,
"plazas": 380
},
{
"tipologia": "HOTEL 4*",
"unidades": 6,
"plazas": 1819
},
{
"tipologia": "HOTEL 5*",
"unidades": 1,
"plazas": 158
},
{
"tipologia": "HABITATGES TURÍSTICS DE VACANCES",
"unidades": 168,
"plazas": 1927
},
{
"tipologia": "ESTADES TURÍSTIQUES",
"unidades": 1086,
"plazas": 4912
}
]
}