commit 53f24de3ce5c3929e1f0d399246a0e0d8cc8e7c7 Author: itziarZG Date: Tue Jul 14 09:52:12 2026 +0200 chore: estructura inicial del proyecto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0acfe8b --- /dev/null +++ b/.gitignore @@ -0,0 +1,66 @@ +# Datos crudos (no commitear por tamaño) +data/raw/*.xlsx +data/raw/*.csv +data/raw/*.csv.gz +data/raw/*.zip +data/raw/*.shp +data/raw/*.shx +data/raw/*.dbf +data/raw/*.prj +data/raw/*.cpg +data/raw/*.sbn +data/raw/*.sbx +data/raw/*.fbn +data/raw/*.fbx +data/raw/*.ain +data/raw/*.aih +data/raw/*.atx +data/raw/*.ixs +data/raw/*.mxs +data/raw/*.qix +data/raw/*.qpj +data/raw/*.xml + +# Capturas de la conferencia (grandes, locales unicamente) +docs/**/*.jpg +docs/**/*.JPG +docs/**/*.jpeg +docs/**/*.png + +# Procesado (regenerable desde raw con scripts/) +data/processed/ +data/output/ + +# Node +node_modules/ +.pnpm-store/ +dist/ +.astro/ +.vercel/ +*.log + +# Python +.venv/ +venv/ +__pycache__/ +*.py[cod] +*.egg-info/ +.pytest_cache/ +.mypy_cache/ +.ruff_cache/ + +# Entorno +.env +.env.local +.env.*.local + +# macOS +.DS_Store +.AppleDouble +.LSOverride + +# IDE +.vscode/ +.idea/ +*.swp +*.swo diff --git a/FASE-0-setup.md b/FASE-0-setup.md new file mode 100644 index 0000000..3284011 --- /dev/null +++ b/FASE-0-setup.md @@ -0,0 +1,126 @@ +# 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 +- [ ] 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 +- [ ] `git init` en `/Users/ichi/Desktop/DEV/VIvienda/` +- [ ] 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` +- [ ] Hacer commit inicial con estructura + `.gitignore` + este PLAN +- [ ] (Opcional) crear repo en GitHub y vincular + +### Reorganizacion de archivos existentes +- [ ] Mover `Info.pdf` y los 19 `.jpg` de la conferencia a `docs/conferencia-OHIB-2025/` +- [ ] Mover `viviendas vacias-hipotecas.xlsx` y `39365(1).xlsx` a `data/raw/` +- [ ] Documentar el origen de cada archivo en `data/raw/ORIGEN.md` + +### Entorno Python +- [ ] Instalar `uv` (gestor de entornos y paquetes rapido) +- [ ] `uv venv .venv` en la raiz del proyecto +- [ ] Crear `requirements.txt` con: pandas, openpyxl, geopandas, duckdb, shapely, pyproj, fiona, pyarrow +- [ ] `uv pip install -r requirements.txt` +- [ ] Verificar: `python -c "import geopandas, duckdb; print('OK')"` + +### Entorno Node +- [ ] Instalar Node 20+ (con `nvm` o `brew`) +- [ ] Instalar pnpm (`npm install -g pnpm`) + +### Descarga de datos externos +- [ ] Descargar **shapefile de secciones censales de Balears** desde INE + - Fuente: https://www.ine.es/prodyser/cartografia/seccionado_2025/ + - Descargar las 4 provincias: Mallorca (07), Menorca (07), Eivissa (07), Formentera (07) + - Verificar que incluye geometria poligonal +- [ ] Descargar **Inside Airbnb listings** para las 4 islas + - Fuente: http://insideairbnb.com/get-the-data/ + - Snapshot mas reciente disponible para: Mallorca, Menorca, Eivissa, Formentera + - Formato: `listings.csv.gz` (revisar tamano y fecha) + +### Validacion +- [ ] Shapefile abre con geopandas, tiene CRS correcto, conteo de features > 0 +- [ ] Listings CSV abre con pandas, columnas esperadas presentes +- [ ] XLSXs del usuario abren con openpyxl/pandas +- [ ] Anotar numero de filas de cada dataset en `data/raw/VALIDACION.md` + +### Cierre +- [ ] Commit final con tag `fase-0-completa` +- [ ] Actualizar PLAN.md: marcar Fase 0 como completada +- [ ] 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._ + +## Problemas encontrados + +_Llenar durante la ejecucion. Ejemplos:_ +- _El shapefile de Formentera viene en un ZIP separado y CRS distinto al de Mallorca._ +- _Inside Airbnb no tiene snapshot para Formentera separado; el de Eivissa incluye ambos._ + +## 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`. diff --git a/FASE-1-datos.md b/FASE-1-datos.md new file mode 100644 index 0000000..7ac63f5 --- /dev/null +++ b/FASE-1-datos.md @@ -0,0 +1,106 @@ +# FASE 1 - Datos (semana 2) + +## Objetivo + +Producir el dataset final agregado por seccion censal con dos variables clave: (a) % de viviendas semi-vacias estimado por consumo electrico, y (b) numero/densidad de listings de Airbnb. Generar archivos listos para la web: `dataset.parquet` (tabla) y `tiles.pmtiles` (visualizacion geoespacial). + +## Tareas + +### Exploracion y limpieza +- [ ] Cargar `viviendas vacias-hipotecas.xlsx`, inspeccionar las 6 sheets, identificar la que tiene datos por seccion censal +- [ ] Filtrar registros de Illes Balears (codigos INE 07xxx) +- [ ] Normalizar columnas: codigo seccion censal, % viviendas semi-vacias, % viviendas vacias, consumo mediano kWh +- [ ] Cargar `39365(1).xlsx` (tabla 39365 viviendas turisticas), agregar a Balears como dato contextual + +### Carga geoespacial +- [ ] Cargar shapefile de secciones censales Balears con geopandas +- [ ] Reproyectar a WGS84 (EPSG:4326) si esta en ETRS89 u otro CRS +- [ ] Inspeccionar: codigo unico de seccion censal, geometria valida, total de features + +### Inside Airbnb +- [ ] Cargar los 4 CSVs de listings (Mallorca, Menorca, Eivissa, Formentera) +- [ ] Columnas clave: `id`, `latitude`, `longitude`, `room_type`, `availability_365`, `price`, `neighbourhood` +- [ ] Filtrar listings activos: `availability_365 > 0` y/o `room_type == 'Entire home/apt'` +- [ ] Limpiar precios (quitar `$`, `,`, convertir a float) + +### Spatial join +- [ ] Point-in-polygon: cada listing -> seccion censal correspondiente +- [ ] Manejar listings fuera de poligonos (zonas rurales, agua): log + excluir +- [ ] Resultado: DataFrame con `(seccion_censal, n_listings)` por isla + +### Agregacion por seccion censal +- [ ] Join: seccion_censal <- (datos INE vivienda) + (conteo Airbnb) +- [ ] Variables finales por seccion censal: + - `cod_seccion` (PK) + - `municipio`, `isla` + - `n_viviendas_total` + - `pct_viviendas_vacias` + - `pct_uso_esporadico` + - `consumo_mediano_kwh` + - `n_listings_airbnb` + - `listings_por_100_viviendas` + - `geometry` (poligono) +- [ ] Guardar como `data/output/dataset.parquet` (formato columnar eficiente) + +### Tiles para mapa web +- [ ] Generar `data/output/tiles.pmtiles` con tippecanoe a partir del GeoPackage del dataset +- [ ] Incluir atributos de visualizacion en los tiles (no solo geometria) +- [ ] Generar version "minima" de tiles (zoom 0-12) para web + +### Validacion +- [ ] `dataset.parquet` abre con duckdb/pandas +- [ ] `tiles.pmtiles` se sirve correctamente y se ve en MapLibre local +- [ ] Sanity checks: nº listings total razonable (>5.000 en Mallorca, >1.000 en Eivissa), sin nulos en columnas clave +- [ ] Documentar estadisticas descriptivas en `data/output/STATS.md` + +### Cierre +- [ ] Commit final con tag `fase-1-completa` +- [ ] Actualizar PLAN.md +- [ ] Visualizar el mapa en un Jupyter notebook rapido para validar (screenshot al menos) + +## Comandos clave + +```bash +# Convertir a GeoPackage para tippecanoe +ogr2ogr -f GPKG data/output/dataset.gpkg data/output/dataset.parquet + +# Generar tiles +tippecanoe -o data/output/tiles.pmtiles \ + -zg \ + --drop-densest-as-needed \ + -l cases \ + --read-parallel \ + data/output/dataset.gpkg + +# Servir localmente para testear +python -m http.server 8000 --directory data/output +# Abrir http://localhost:8000 en navegador con MapLibre + +# Validar parquet con duckdb +python -c "import duckdb; print(duckdb.query('SELECT isla, COUNT(*), AVG(pct_uso_esporadico), SUM(n_listings_airbnb) FROM \"data/output/dataset.parquet\" GROUP BY isla').to_df())" +``` + +## 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 con tasa de exito > 95% (listings asignados a seccion censal) +- [x] `STATS.md` documenta: nº secciones, nº listings por isla, distribuciones, outliers +- [x] Screenshot del mapa en Jupyter notebook como evidencia visual +- [x] Scripts Python reproducibles en `scripts/` con comentarios sobre decisiones +- [x] Commit final con tag `fase-1-completa` + +## Decisiones tomadas durante la fase + +_Llenar durante la ejecucion. Ejemplos:_ +- _Decidimos filtrar listings por `availability_365 > 60` para excluir inactivos esporadicos._ +- _Decidimos calcular "pct_uso_esporadico" como 1 - (consumo_mediano / p75 consumo), no como categoria INE directa._ +- _El join espacial asigna por punto interior al poligono; los listings a < 50m del borde se asignan al mas cercano (regla documentada)._ + +## Problemas encontrados + +_Llenar durante la ejecucion._ + +## Proximos pasos + +Fase 2: web MVP con Astro + MapLibre. Ver `FASE-2-web-mvp.md`. diff --git a/FASE-2-web-mvp.md b/FASE-2-web-mvp.md new file mode 100644 index 0000000..21308be --- /dev/null +++ b/FASE-2-web-mvp.md @@ -0,0 +1,152 @@ +# 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 + + +
+``` + +## 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 + +_Llenar durante la ejecucion._ + +## Problemas encontrados + +_Llenar durante la ejecucion._ + +## Proximos pasos + +Fase 3: lanzamiento publico. Ver `FASE-3-lanzamiento.md`. diff --git a/FASE-3-lanzamiento.md b/FASE-3-lanzamiento.md new file mode 100644 index 0000000..f8c1c0a --- /dev/null +++ b/FASE-3-lanzamiento.md @@ -0,0 +1,122 @@ +# 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; +--- + + + + {title} | Cases Tancades + + + + + + + +``` + +## 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 diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 0000000..a0ff002 --- /dev/null +++ b/PLAN.md @@ -0,0 +1,59 @@ +# 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 (pendiente ejecucion) +- [ ] Fase 0 ejecutada +- [ ] Fase 1 ejecutada +- [ ] Fase 2 ejecutada +- [ ] 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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..029dc6c --- /dev/null +++ b/README.md @@ -0,0 +1,49 @@ +# Cases Tancades + +Web publica que visibilitza la pressio turistica sobre el parc residencial de Balears, creuant dades oficiales d'INE (consum electric per seccio censal, com a proxy de vivenda semi-vacia) amb dades d'Inside Airbnb (listings georreferenciats). + +Veure [PLAN.md](PLAN.md) per al plan complet i l'arquitectura. + +## Estructura + +``` +data/raw/ Dades originals descarregades (no commitejades) +data/processed/ Dades intermiges del pipeline +data/output/ Dades finals (parquet, tiles, JSON) +docs/ Documentacio i materials de suport +scripts/ Pipeline Python +web/ Codi Astro de la web +FASE-*.md Bitacora de cada fase del projecte +``` + +## Setup rapid + +```bash +# Python +uv venv .venv +source .venv/bin/activate +uv pip install -r requirements.txt + +# Node +nvm use 20 +``` + +## Estat + +| Fase | Estat | +|---|---| +| Fase 0 - Setup | En curs | +| Fase 1 - Dades | Pendent | +| Fase 2 - Web MVP | Pendent | +| Fase 3 - Llanament | Pendent | + +## Fonts de dades + +- INE - Intensitat d'us per consum electric: taula del fitxer `data/raw/viviendas vacias-hipotecas.xlsx` (full 1). +- INE - Seccions censals de Balears: shapefile descarregat de https://www.ine.es/prodyser/cartografia/seccionado_2025/ +- Inside Airbnb - Listings Balears: http://insideairbnb.com/get-the-data/ +- Captures conferencia OHIB (12-13 nov 2025): `docs/conferencia-OHIB-2025/` + +## Llicencia + +A determinar. Probablement CC BY-SA 4.0. diff --git a/data/raw/ORIGEN.md b/data/raw/ORIGEN.md new file mode 100644 index 0000000..353cfdd --- /dev/null +++ b/data/raw/ORIGEN.md @@ -0,0 +1,33 @@ +# Origen de las dades en `data/raw/` + +## `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/ +- **Fecha de descarga**: (pendiente, ejecutar en setup de Fase 0) +- **Descripcion**: Poligons de les seccions censals per a les Illes Balears. +- **CRS original**: ETRS89 (EPSG:4258), reprojectar a WGS84 (EPSG:4326) per a la web. + +## Inside Airbnb listings + +- **Origen**: Inside Airbnb (proyecto independiente que scrapea Airbnb y publica datos abiertos). +- **URL de descarga**: http://insideairbnb.com/get-the-data/ +- **Fecha de descarga**: (pendiente, ejecutar en setup de Fase 0) +- **Descripcion**: Listings georreferenciats (lat/lon) amb informacio de tipus, disponibilitat i preu. Snapshots separats per Mallorca, Menorca, Eivissa i Formentera. +- **Licencia**: Creative Commons (consultar web del proyecto). diff --git a/docs/conferencia-OHIB-2025/Info.pdf b/docs/conferencia-OHIB-2025/Info.pdf new file mode 100644 index 0000000..e0abef1 Binary files /dev/null and b/docs/conferencia-OHIB-2025/Info.pdf differ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..5e67070 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,8 @@ +pandas>=2.2 +openpyxl>=3.1 +pyarrow>=16.0 +duckdb>=1.0 +geopandas>=1.0 +shapely>=2.0 +pyproj>=3.6 +fiona>=1.10 diff --git a/scripts/.gitkeep b/scripts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/web/.gitkeep b/web/.gitkeep new file mode 100644 index 0000000..e69de29