LICENCIAS Y TÉRMINOS — «Playas de España» (playas_demo.html / playas.json / mar_grid.json / mar_tierra_fina.json) ================================================================================================================== Verificado el 2026-09-02 con peticiones reales (curl/httpx) desde este Mac. Texto LITERAL entre comillas; el HTML crudo de cada página queda en playas_verif/ (om_*.html, osm_copyright.html, ne_terms.html, photon.html). 1) AEMET — predicción específica de playas (opendata.aemet.es) -------------------------------------------------------------- Endpoint: GET https://opendata.aemet.es/opendata/api/prediccion/especifica/playa/{codigo} (la clave viaja en una cabecera HTTP; vive solo en /Users/gonzalo/Trabajo/mapasvivos/.env y ningún fichero de esta demo la contiene) → {"estado":200,"datos":url,"metadatos":url} → GET datos → JSON. Probado 2026-09-02 22:30 con la playa 4804801 (Laida, Ibarrangelu): estado 200, «elaborado»: "2026-09-02T08:50:30". Muestra en playas_verif/aemet_playa_muestra.json. Metadatos oficiales del producto (playas_verif/aemet_playa_meta.json), literal: "periodicidad": "Dos veces al día" "descripcion": "Predicciones para playas generadas de forma automática a partir de modelos numéricos y estadísticos de predicción meteorológica" Copyright que viaja en cada respuesta (campo origen.copyright), literal: "© AEMET. Autorizado el uso de la información y su reproducción citando a AEMET como autora de la misma." Nota legal https://www.aemet.es/es/nota_legal (capturada en aemet_licencia.txt), literal: "Las condiciones generales recogidas en la presente nota legal permiten la reutilización de los documentos sometidos a ellas para fines comerciales y no comerciales. Se entiende por reutilización el uso de documentos que obran en poder de AEMET de acuerdo con lo establecido en el artículo 3 de la Ley 18/2015, de 9 de julio" "En caso, de realizar con ella servicios de valor añadido en base a la información meteorológica y climatológica suministrada por AEMET para su difusión o suministro a terceros, se debe mencionar explícitamente a AEMET como propietaria de dicha información, incluyendo la referencia "Fuente: AEMET" o en su lugar el texto: "Información elaborada utilizando, entre otras, la obtenida de la Agencia Estatal de Meteorología"." "Debe mencionarse la fecha de la última actualización de los documentos objeto de la reutilización" "No se puede indicar, insinuar o sugerir que AEMET como titular de la información reutilizada participa, patrocina, o apoya la reutilización que se lleve a cabo con ella." Maestro de playas (591 códigos): https://www.aemet.es/documentos/es/eltiempo/prediccion/playas/Playas_codigos.csv (copia en /Users/gonzalo/Trabajo/tumontana/ingest/playas_aemet.csv; misma licencia). Avisos costeros: avisos.json (hornea_avisos.py, CAP /api/avisos_cap/ultimoelaborado/area/esp), misma licencia. FÓRMULA USADA EN EL MAPA: «Fuente: AEMET» + fecha de elaboración de cada predicción y del lote de avisos. 2) Open-Meteo — Marine Weather API y Forecast API (sin clave) ------------------------------------------------------------- Términos https://open-meteo.com/en/terms (capturado 2026-09-02), literal: "Non-Commercial Use By using the Free API for non-commercial use you agree to following terms: Less than 10'000 API calls per day, 5'000 per hour and 600 per minute. You may only use the free API services for non-commercial purposes. You accept to the CC-BY 4.0 licence, as specified in the licence conditions. We reserve the right to block applications and IP addresses that misuse our service without prior notice." "Non-commercial use is defined as elaborated by creative commons. To make it easier to understand, here are some examples that qualify as non-commercial use: Using our service for private or non-profit websites or apps that do not have subscriptions or advertising." Precios/atribución https://open-meteo.com/en/pricing, literal: "The free API is for non-commercial use, rate-limited to 10,000 calls/day, and carries no uptime guarantee." "Open-Meteo relies on open data that is licenced under Attribution 4.0 International (CC BY 4.0). This licence mandates giving appropriate credit and indicating any modifications made to the data." Tabla de planes, columna «Free / Open-Access API» (texto extraído de la tabla, literal celda a celda): "Minutely Limit ⚠️ 600 calls / min" · "Hourly Limit ⚠️ 5.000 calls / hour" · "Daily Limit ⚠️ 10.000 calls / day" · "Monthly Limit ⚠️ 300.000 calls / month" CÓMO CUENTA OPEN-METEO: cada LOCALIZACIÓN de una petición es una llamada (una petición con 100 coordenadas = 100 llamadas); con hourly de varios días el peso por localización puede ser mayor (hubo un 429 a 12 s entre lotes). CUOTA DE LA CASA (revisada 2026-09-03; antes era «4 horneados/día» sin ponderar, que con 4 de la rejilla del mar habría sido ≈ 11.000 > 10.000): se cuenta por LLAMADAS. hornea_playas.py ≈ 1.600 llamadas por horneado (≈ 1.598 localizaciones en 19 peticiones) y hornea_mar_grid.py (rejilla «EL MAR») ≈ 2.800 (2.766 puntos en 28 peticiones). Topes, con margen sobre el plan gratuito: 4.750 llamadas en los últimos 60 min · 8.000 en las últimas 24 h · 240.000 en los últimos 31 días (ventanas móviles, más estrictas que el día o mes natural del proveedor) · y 4 horneados con red por día. Lo vigila cuota_om.py con un registro COMPARTIDO por los dos horneadores (hornea_playas_horneados.json: hora, script, n_llamadas, n_peticiones, estado): cada horneador RESERVA antes de pedir nada con las localizaciones que va a pedir, aborta si no cabe y cierra al acabar con lo realmente pedido (cada intento HTTP cuenta sus localizaciones, 429 incluidos). --sin-red no cuenta; --forzar lo salta bajo responsabilidad propia. Prueba unitaria sin red y con registro temporal: test_cuota_om.py. Al día caben, p. ej., mar + playas + mar (≈ 7.140) o mar + playas + playas (≈ 5.970); dos de cada (≈ 8.740) no. REJILLA «EL MAR» (hornea_mar_grid.py → mar_grid.json, capa «el mar, pintado» de playas_demo.html): Marine API, `current` de 8 variables (agua, ola total, fondo, mar de viento) en 2.766 puntos de una rejilla de 0,2° sobre las aguas de España (cell_selection=sea, lotes de 100). Es MODELO (celdas ~5-8 km) y en el mapa se pinta como manto de temperatura del agua o de altura de ola, con crestas DIBUJADAS a partir del fondo (no olas reales); lleva la hora del dato en la leyenda, en el sello y en «lo que este mapa no sabe», y se apaga sola si mar_grid.json falta o es de otra hora que playas.json (> 60 min). Atribución en el sello: «Open-Meteo Marine (CC BY 4.0), modelo». Documentación Marine API https://open-meteo.com/en/docs/marine-weather-api, literal: "Hourly wave forecasts at 5 km resolution" "Note: Tides and ocean currents are computed at 0.08° (~8 km) resolution using numerical models. Accuracy at coastal areas is limited. This is not suitable for coastal navigation and does not replace your nautical almanac. Use with caution!" "Note: Current conditions are based on 15-minutely weather model data." "cell_selection ... The default land finds a suitable grid-cell on land with similar elevation to the requested coordinates using a 90-meter digital elevation model. sea prefers grid-cells on sea." (en Marine el defecto es sea) "sea_level_height_msl Instant metre The sea level height accounts for ocean tides, the inverted barometer effect, sea surface height, global mean steric variation, and global mean mass volume variation." Peticiones de prueba 2026-09-02 22:30: marine-api.open-meteo.com/v1/marine (3 puntos, current+hourly 2 días) → 200 en 0,2 s; api.open-meteo.com/v1/forecast (3 puntos, current+daily+hourly) → 200. Muestras en playas_verif/om_*_muestra.json. Observación: dos puntos distintos (Mundaka mar 43,43/-2,70 y Mundaka pueblo 43,407/-2,698) devuelven la MISMA celda marina (43,5417/-2,7083): rejilla ≈0,08°; por eso el horneado agrupa las playas en TRAMOS de ~0,1° y pide una vez por tramo (respeta el límite diario: ~2.300 llamadas/horneado de las 10.000 permitidas). FÓRMULA USADA EN EL MAPA: «Open-Meteo (CC BY 4.0) · modelo, no medición»; en la ficha «modelo Open-Meteo» y «marea: cálculo del nivel del mar horario del modelo (±30 min), no tabla oficial». 3) OpenStreetMap — playas (natural=beach), spots (sport=surfing) y línea de costa (natural=coastline) -------------------------------------------------------------------------------------------------------- https://www.openstreetmap.org/copyright/es (capturado 2026-09-02), literal: "OpenStreetMap es un sistema de datos abiertos, licenciado bajo la Licencia de Base de Datos Abierta de Open Data Commons (ODbL) por la Fundación OpenStreetMap. En resumen: Puede copiar, distribuir, transmitir y adaptar nuestros datos libremente, siempre que cite a OpenStreetMap y a sus colaboradores. Si modificas o amplías nuestros datos, podrás distribuir el resultado solo bajo la misma licencia." Datos usados: osm_playas_crudo.json (barrido Overpass del 2026-08-30, 3.792 playas tras deduplicar), surf-spots-osm.json (75 playas sport=surfing), cache_geo/*.json (coastline por costa) — todos en /Users/gonzalo/Trabajo/tumontana/ingest. FÓRMULA USADA: «© OpenStreetMap contributors (ODbL)». El municipio de las playas OSM es APROXIMADO (el de la playa oficial más cercana) y se pinta con «≈». MÁSCARA DE COSTA DEL MANTO DEL MAR (hornea_mar_tierra.py → mar_tierra_fina.json): la línea de costa OSM (natural=coastline, cache_geo) cerrada por tierra es la tierra con la que playas_demo.html RECORTA el manto del mar y con la que hornea_mar_grid.py descarta los puntos de la rejilla que caen en tierra; fuera de una banda de ±0,1° de esa costa manda Natural Earth 50 m (dominio público). Es una obra derivada de datos OSM → ODbL; atribución en el sello: «máscara de tierra del manto: costa OSM (© OpenStreetMap contributors, ODbL) + Natural Earth». 4) Natural Earth — límites de CCAA (limites_ccaa.json) y tierra gruesa del mar (ne50.json → mar_tierra.json; países vecinos fuera de la banda OSM en mar_tierra_fina.json) -------------------------------------------------------------------------------------------------------- https://www.naturalearthdata.com/about/terms-of-use/ (capturado 2026-09-02), literal: "All versions of Natural Earth raster + vector map data found on this website are in the public domain." "No permission is needed to use Natural Earth. Crediting the authors is unnecessary." 5) Photon (komoot) — buscador de lugares en el cliente ----------------------------------------------------- https://photon.komoot.io/ (capturado 2026-09-02), literal: "Terms of Use You can use the API for your project, but please be fair - extensive usage will be throttled. We do not guarantee for the availability and usage might be subject of change in the future." (datos OSM/ODbL; el buscador solo se llama al teclear, con retardo de 350 ms, límite 5 resultados) 6) Esri — mapa base (World_Light_Gray_Base) y relieve (World_Hillshade) ------------------------------------------------------------------------ Patrón heredado de las demás demos del laboratorio («base y relieve: Esri»); NO verificado hoy por este horneado. 7) Lo que es NUESTRO (estimación de la casa, etiquetado así en el mapa) ------------------------------------------------------------------------ - Semáforo de BAÑO (mismo criterio que Tu Montaña, web/src/playa.ts semaforo()): ola < 0,5 m y viento < 22 km/h → verde «baño tranquilo»; ola < 1,2 m y viento < 32 km/h → ámbar «con precaución»; resto → rojo «mar complicada». Entradas: ola total y viento actuales del modelo Open-Meteo. Sin ola → sin semáforo. NO es la bandera del socorrista. - Semáforo de SURF: estimación PROPIA de este horneador. Reutiliza las piezas de ingest/mar.py (tipo_viento offshore/cruzado/onshore, marea preferida, ventana_hoy) y añade umbrales de dirección que NO están en mar.py (mar.py no tiene semáforo de surf): fondo ≥ 0,4 m; «bueno» si el fondo llega a ≤ 50° de la orientación con viento calma/offshore y la marea que pide el spot; «malo» si llega a > 90° o el viento es onshore ≥ 12 km/h o ≥ 30 km/h; «regular» el resto; «sin ola» bajo 0,4 m. Verificado el 2026-09-02 con las funciones de mar.py para Mundaka, Zarautz y Rodiles (tipo de viento, estado de marea, pleamar/bajamar y ventana coinciden). - Playas INTERIORES (río o embalse): playa OSM a ≥ 2 km de la línea de costa OSM (o «fluvial» a ≥ 1 km). Van con interior=1 y SIN agua, ola, marea ni semáforo, porque el modelo marino no les aplica (antes heredaban el mar del tramo: corregido el 2026-09-02). Conservan viento/aire/UV de su celda de tierra. - Orientación de los spots OSM: ESTIMADA con la normal a la línea de costa OSM (el mar queda a la derecha del sentido de la línea). Los tres spots de mar.py (Mundaka, Zarautz, Rodiles) llevan orientación y marea de la casa. - Tramos de costa: agrupación propia de ~0,1° para pedir el mar una vez por tramo.