Het regenblok linksonder opent een overlay met de geanimeerde regenradar van Buienradar (550x512, tijd in het beeld), naast de regencijfers die we al hebben: vandaag, de 3 vorige dagen en het maandtotaal. Sluit na 20 seconden of bij een tik, net als het uuroverzicht. Het beeld loopt via onze eigen /api/radar.php in plaats van een <img> rechtstreeks naar Buienradar: de spec wil alles lokaal geserveerd, de iPad praat zo nooit met een derde partij, we cachen 4 minuten (de radar ververst elke 5) en de servicewerker kan het laatste beeld offline bewaren. Bij een storing komt het laatst opgehaalde beeld terug; pas als er niets is, een nette melding in plaats van een leeg vlak. Bronvermelding staat in de overlay, zoals Buienradar vraagt. Verder: de overlay-machinerie (20s-timer, balk, sluiten) staat nu een keer in plaats van per overlay, Http kan optioneel redirects volgen (de beeld-API leidt door naar een CDN), en alle /api/-paden zijn in de servicewerker network-first met een cachesleutel zonder querystring. Servicewerker naar v7. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
36 lines
1.1 KiB
PHP
36 lines
1.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Weerscherm;
|
|
|
|
/**
|
|
* Haalt de geanimeerde regenradar op bij Buienradar. Vrij te gebruiken met bronvermelding;
|
|
* de frontend toont daarom "bron: Buienradar.nl" bij het beeld.
|
|
*
|
|
* De endpoint leidt door naar een CDN, dus de meegegeven HttpClient moet redirects volgen.
|
|
* Het beeld is 550 x 512 met de tijd erin gebrand; opgegeven afmetingen worden genegeerd.
|
|
*/
|
|
final class BuienradarClient
|
|
{
|
|
private const URL = 'https://image.buienradar.nl/2.0/image/animation/RadarmapRainNL';
|
|
|
|
public function __construct(private readonly HttpClient $http)
|
|
{
|
|
}
|
|
|
|
/** @return string de ruwe bytes van een geanimeerde GIF */
|
|
public function rainRadar(): string
|
|
{
|
|
$res = $this->http->get(self::URL, ['w' => 550, 'h' => 512], ['Accept: image/gif,image/*']);
|
|
|
|
if ($res->status !== 200) {
|
|
throw new UpstreamException("Buienradar: HTTP {$res->status}");
|
|
}
|
|
if (!str_starts_with($res->body, 'GIF8')) {
|
|
throw new UpstreamException('Buienradar: antwoord is geen GIF');
|
|
}
|
|
return $res->body;
|
|
}
|
|
}
|