Infografía animada para el proyecto Bienenatlas — cuadrícula hexagonal de 11 municipios, cuatro tarjetas de estadísticas de fuentes de datos y un diagrama de flujo sobre fondo oscuro
11 min read

Bienenatlas — de la granja de Mehrum a la plataforma para 121 municipios alemanes

#Astro #Nano Banana #GBIF #Fenología DWD #OpenStreetMap #Netlify #SEO #AEO #Periodismo de datos

Mi sobrina Meicken tiene una granja en Mehrum, un barrio de Hohenhameln en el distrito de Peine, en Baja Sajonia. Quería saber cómo está realmente la situación de las abejas en su propio rincón de Alemania — no por reclamos de revista de jardinería, no por consignas de ONGs, sino con datos que pudiera rastrear hasta su fuente primaria. Diez días después aquello se convirtió en bienenatlas.de: un dashboard en tiempo real de la situación de las abejas silvestres en 121 municipios alemanes, con cuatro fuentes de datos, 235 ilustraciones y una promesa editorial rigurosa — ningún número inventado, ningún adjetivo de marketing, cada afirmación trazable a una fuente primaria citada.

134
URLs indexables
121
Municipios con dashboard propio
235
Imágenes generadas
4
Fuentes de datos

V1: un dashboard para una sola granja

La primera iteración fue deliberadamente pequeña: un único dashboard Astro que jalaba registros Apidae (taxonKey 4334) para el bounding box de Mehrum desde la API de GBIF, contaba las especies más frecuentes, comparaba los últimos 30 días contra la misma ventana del año anterior y renderizaba los registros individuales como cards. Sin base de datos, sin estado, sin paso de datos en build — todo SSR por request, con cinco minutos de edge cache en Netlify. Seis días del primer bosquejo a la página viva, sprints MEICKEN-MVP-001 hasta MVP-012.

Meicken lo vio en su teléfono durante el desayuno familiar y preguntó qué era una “bbox”. Ese fue el momento en que quedó claro: funciona para ella como herramienta de granja, pero no escala como idea de plataforma. Nadie fuera de Mehrum aterrizaría en ?gemeinde=hohenhameln. Era una herramienta de granja, no un atlas.

El pivote a 121 municipios

La reconstrucción arrancó con una pregunta: si cada municipio alemán tuviera su propia URL, ¿cuánto costaría? La respuesta es la arquitectura que está en producción hoy:

  • / — landing nacional con datos agregados sobre todos los municipios
  • /<bundesland>/ — 16 hubs por Land (/niedersachsen/, /bayern/, …) con datos regionales y lista de todos los municipios del Land
  • /<bundesland>/<gemeinde>/ — 121 dashboards municipales individuales, misma forma que V1 pero con datos locales

El archivo src/data/regions.ts contiene, para cada municipio, un slug ags, un name, un código land y un bounding box. Astro 6 permite rutas dinámicas SSR sin getStaticPaths() — el archivo src/pages/[bundesland]/[gemeinde]/index.astro resuelve el par de slugs a una región al momento del request, jala los datos GBIF para el bbox, renderiza la página y cachea cinco minutos en el edge. Cuando un usuario escribe /bayern/halle/ (Halle está en Sajonia-Anhalt, no en Baviera), 301-canonicalizo a /sachsen-anhalt/halle/ en vez de servir un 404.

Cuatro fuentes de datos, agregadas por municipio

El mayor riesgo con 134 páginas de misma forma es el Helpful Content Update de Google — el contenido casi-duplicado se demota. La solución no es menos páginas, es más contenido genuino por página. Cuatro fuentes le dan a cada dashboard municipal sustancia única:

1. GBIF (Global Biodiversity Information Facility)

Agregador científico de datos de ocurrencia. API REST sin auth, filtrada por familia Apidae + Alemania + bbox del municipio. Por página: registros totales, especies Apidae más frecuentes (facet API), tendencia anual de tres años, ventana de 30 días vs. año anterior, cards de registros individuales con filtro de licencia de foto (solo se renderiza CC0 / CC BY / CC BY-SA en modo comercial-seguro).

2. Fenología DWD (Servicio Meteorológico Alemán, Climate Data Center)

Promedios a largo plazo de inicio de floración para siete plantas relevantes para abejas (sauce cabruno, endrino, diente de león, manzano, saúco, tilo de verano, brezo). El script scripts/build-phaenologie-context.mjs lee los CSVs annual_reporters/historical/ de opendata.dwd.de (codificación cp1252, separados por punto y coma, con marcador eor al final), calcula la distancia Haversine a la estación más cercana, y escribe src/data/phaenologie-context.json. Resultado: 121 de 121 municipios mapeados, mediana de distancia a la estación más cercana 2,0 km, 769 promedios (estación × planta). Hohenhameln recibe la estación Soßmar a 0,6 km en línea recta, con 14–30 años de datos por planta.

3. OpenStreetMap Overpass — áreas protegidas

Una query por bbox municipal sobre boundary=protected_area + leisure=nature_reserve + boundary=national_park. Clasificadas por protect_class en NP/NSG/FFH/LSG, deduplicadas, máximo cinco por municipio. 119 de 121 municipios tienen al menos un área protegida desde OSM, 559 áreas totales (29 NP, 507 NSG, 7 LSG, 16 otros). Incluye links a Wikipedia y sitio oficial cuando OSM tiene los tags.

4. NABU naturgucker + Wikipedia (contexto por municipio)

Scrape de infobox de Wikipedia por municipio: código postal, distrito, población con año, altitud, superficie. Verificado directamente vía de.wikipedia.org con atribución. Plus: URL del NABU-Landesverband por Land (zero-trust verificado, 14 NABU + Baviera→LBV + Saarland→nabu-saar.de), URL de la autoridad de conservación de la naturaleza (13 ministerios directo, BE+SL bloqueados por bot → verificación cruzada vía WebFetch), estado del plan de acción para protección de insectos (10 existe, 6 ninguno conocido — honestamente marcado).

235 imágenes con Nano Banana

Gemini 2.5 Flash Image (nombre interno “Nano Banana”) de Google genera PNGs de 1024×1024 a unos 0,039 USD por imagen en tier estándar. Tras cinco sprints de generación, existen 235 ilustraciones con una estética acuarela consistente:

SetCantidadCosto
Hero nacional + OG card2$0,08
Heroes por Land (16)16$0,62
Heroes municipales (121)121$4,72
Heroes DIY (5) + paso a paso (16)21$0,82
/about + /404 + 3 variantes sociales5$0,20
Flagships de áreas protegidas (16) + moodboards de género Apidae (10)26$1,02
Acentos 1:1 por Land (16)16$0,62
5 escenas explicativas + 3 divisores panorámicos8$0,32
8 conceptos de logo8$0,31
Total223$8,71

Más 12 íconos favicon/PWA via sharp (derivados programáticamente del favicon.svg) — costo cero. Presupuesto total de generación de imágenes: menos de nueve euros contra el crédito de prueba de €260 que Google Cloud regala al activar billing.

Tres lecciones del workflow Nano Banana:

  1. La tipografía es poco confiable. En los ocho conceptos de logo el modelo renderizó “Bieneatlas” en vez de “Bienenatlas” — desapareció una n. Los modelos de imagen no manejan texto con fiabilidad. Los logos deben finalizarse vectorialmente con tipografía real.
  2. La consistencia requiere un bloque de estilo. Un suffix de prompt reutilizado garantiza consistencia visual entre generaciones: Painted in soft watercolor with a vintage natural-history-book aesthetic, warm honey-amber and forest-green palette. Soft golden-hour light. Hand-illustrated, not photoreal. No text, no labels, no people. Cada generación referencia este bloque.
  3. Los rate limits y los cambios de tier gratuito son una trampa. Gemini 2.5 Flash Image no tiene tier gratuito; el proyecto necesita billing activado. Una vez activo, el crédito de trial cubre todo. Mi script generador (scripts/nano-banana-gen.mjs) tiene retry-on-429 con backoff que parsea el campo retryDelay del cuerpo del error de Gemini.

Sedcards con profundidad científica completa

Cada especie Apidae recibe una ficha en /art/<gbif-speciesKey>/. Esta página es la más densa en datos de la plataforma — el objetivo es una herramienta de referencia científica con claridad visual al mismo tiempo. El layout es de dos columnas (principal + sidebar pegajoso) con cinco tarjetas en el sidebar:

  1. Especies relacionadas — búsqueda del mismo género vía API GBIF Search
  2. Fenología en vivo hoy — compara el día del año actual contra el promedio de inicio de floración a largo plazo de la estación DWD local. Pulsa suavemente cuando “activo ahora”, respeta prefers-reduced-motion
  3. Confundible con — compañeros de confusión curados de Westrich (2018), nueve especies verificadas a mano, cero fabricaciones
  4. Dónde observada — top-5 Länder del facet stateProvince de GBIF, enlazado al municipio correspondiente
  5. Fuentes científicas — ocho URLs externas verificadas vía WebFetch. La Agencia Federal Alemana para la Conservación de la Naturaleza (BfN) tiene cero especies de abejas en su base de retratos de especies — omitida honestamente en vez de fabricada. westrich.de devolvió ECONNREFUSED en la prueba — citado como libro impreso, no como URL. wildbiene.com y el Wildbienen-Kataster Stuttgart fueron verificados como enlaces universales.

Más tres nuevas secciones en la columna principal por sedcard: clasificación taxonómica completa (<dl>), descripción original con autor + año (solo si GBIF la tiene — si no, omitida), corte transversal hábitat-fenología.

Arquitectura SEO y AEO

Una auditoría SEO sistemática de la plataforma produjo 24 hallazgos (2 bloqueadores, 8 altos, 9 medios, 5 bajos) — 14 reparados inline:

  • robots.txt originalmente bloqueaba GPTBot, ChatGPT-User, anthropic-ai, ClaudeBot, PerplexityBot, Google-Extended — todos los crawlers de IA prohibidos. Tras ratificación explícita, revertido a User-agent: * Allow: /. La razón está documentada en el header del archivo: el contenido proviene de datos abiertos (CC-BY GBIF, ODbL OSM, DWD-open), nada es IP-protegible, las citas AEO en ChatGPT/Claude/Perplexity son la palanca de tráfico más importante en 2026.
  • llms.txt añadido según la spec llmstxt.org — vista curada del sitio para crawlers de IA, incluyendo la declaración de disciplina de fuentes UWG §5
  • HowTo schema en las cuatro guías DIY (hotel de insectos, hábitat para abejas que nidifican en suelo, franja de flores silvestres, alternativa a glifosato) con listas de pasos, materiales, herramientas, duraciones — elegibles para snippets de Google AI Overview
  • Place schema en cada página municipal con @id y containedInPlace apuntando al hub del Land — grafo de entidades interno al sitio
  • Bloque de hermanos cross-municipal en cada una de las 121 páginas municipales enlaza a cada ciudad hermana del mismo Land — cierra la mayor brecha de internal linking
  • Prioridades de sitemap por tipo de ruta vía callback serialize: 1,0 landing, 0,9 hubs, 0,8 municipios, 0,7 DIY, 0,3 legal

En paralelo, se añadieron 62 nuevos enlaces internos <a href> a través de ocho archivos. La brecha crítica era /art/<speciesKey>/ con cero enlaces internos — cerrada en nueve. Cada página tiene ahora entre 8 y 14 enlaces internos más una caja CTA “Beobachtungen in deiner Gegend” que canaliza al municipio piloto o al mapa nacional.

Configuración de dominios

Dos dominios curados: bienenatlas.de como primario canónico más wildbienenkarte.de como alias SEO con 301 redirect al host primario. El correo se mantiene separado del web — su propia configuración MX, independiente de cómo se sirve el sitio.

La limpieza de la zona DNS fue quirúrgica: cambiar el apex al host web, eliminar los AAAA records donde no son necesarios, poner www como CNAME, subir el serial SOA — todo lo demás intacto. Los registros de correo (MX, SRV, DKIM, SPF) se mantienen intactos. Los certificados SSL se provisionaron en minutos para los cuatro hostnames (apex y www por dominio).

Cuatro redirects de host hacen que cada alias aterrice en el apex canónico — sin riesgo de contenido duplicado. La sustitución path-splat mantiene /niedersachsen/hohenhameln/ funcionando en cualquier alias como 301 a bienenatlas.de/niedersachsen/hohenhameln/.

Google Search Console: sc-domain:bienenatlas.de registrado como propiedad de dominio vía verificación DNS TXT, sitemap enviado (146 URLs, 0 errores, 0 warnings).

Lo que viene

Tres sprints abiertos:

  1. Observar la indexación real. Google aceptó el sitemap-index y puso 146 URLs en cola para crawling. Cuántas se indexarán y cuándo es impredecible — típicamente una a cuatro semanas para un dominio nuevo. Las solicitudes de reindex para los 20 municipios principales vienen en la fase 2.
  2. Más municipios. Actualmente 121 — Alemania tiene unos 11.000 municipios. Las definiciones de bbox son curadas a mano; un script podría automatizar queries de OSM Nominatim para expandir la lista a 500 o 1.000. Trade-off: cada municipio nuevo necesita una imagen hero generada (Nano Banana), pase de enrichment de Wikipedia, query OSM de áreas protegidas — alrededor de 4 dólares por cada 100 municipios nuevos más 30 minutos de pipeline.
  3. Finalización del logo. Ocho conceptos generados; la wordmark final se pondrá vectorialmente con Inter o Söhne como capa CSS encima del mark elegido. Es un sprint de Figma, no de código.

Stack

Astro 6.3
Framework + SSR
Tailwind 4
Estilos + tokens
Netlify
Hosting + edge + SSL
GBIF
Datos de ocurrencia Apidae
DWD CDC
Promedios de fenología
OSM Overpass
Áreas protegidas
Gemini 2.5 Flash Image
Ilustraciones
sharp
Íconos PWA

Repositorio (privado, Wender Media Brand Property License): arnoldwender/wm-brand-bienenatlas. En vivo: bienenatlas.de.

Lo que funciona aquí no es la tecnología — los componentes son todos estándar. Lo que funciona es la disciplina editorial: ninguna afirmación sin fuente citada, cada URL verificada a mano, cada estimación marcada como tal, cada estado de plan de acción honestamente dividido entre existe y ninguno conocido. Eso es lo que Meicken quería al principio — y es lo que ahora también puede ayudar a 121 municipios más.