add PWA installable + recalibrer scoring échelle Guadeloupe
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -312,8 +312,8 @@ class SpotScoreController extends AbstractController
|
|||||||
private function scoreToLevel(int $score): string
|
private function scoreToLevel(int $score): string
|
||||||
{
|
{
|
||||||
return match (true) {
|
return match (true) {
|
||||||
$score <= 30 => 'low',
|
$score <= 15 => 'low',
|
||||||
$score <= 70 => 'medium',
|
$score <= 55 => 'medium',
|
||||||
default => 'high',
|
default => 'high',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ class ImpactScoreService
|
|||||||
{
|
{
|
||||||
private const MAX_DISTANCE_M = 50_000; // 50 km : au-delà score distance = 0
|
private const MAX_DISTANCE_M = 50_000; // 50 km : au-delà score distance = 0
|
||||||
private const MAX_RELEVANT_M = 300_000; // 300 km : au-delà, on ne touche pas au score existant
|
private const MAX_RELEVANT_M = 300_000; // 300 km : au-delà, on ne touche pas au score existant
|
||||||
private const MAX_DENSITY_KM2 = 100; // 100 km² = densité maximale
|
private const MAX_DENSITY_KM2 = 20; // 20 km² = densité maximale pour l'échelle Guadeloupe
|
||||||
private const MAX_APPROACH_KMH = 5; // 5 km/h = vitesse d'approche max
|
private const MAX_APPROACH_KMH = 1; // 1 km/h = vitesse réaliste max des sargasses
|
||||||
private const CACHE_TTL = 10_800; // 3h
|
private const CACHE_TTL = 10_800; // 3h
|
||||||
private const ETA_BUFFER_M = 5_000; // 5 km : seuil "impact imminent" sur le spot
|
private const ETA_BUFFER_M = 5_000; // 5 km : seuil "impact imminent" sur le spot
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ class ImpactScoreService
|
|||||||
private const FEEDBACK_RADIUS_M = 20_000;
|
private const FEEDBACK_RADIUS_M = 20_000;
|
||||||
private const FEEDBACK_WINDOW_H = 6;
|
private const FEEDBACK_WINDOW_H = 6;
|
||||||
private const FEEDBACK_BONUS = 8;
|
private const FEEDBACK_BONUS = 8;
|
||||||
private const HIGH_SCORE_THRESHOLD = 70;
|
private const HIGH_SCORE_THRESHOLD = 55;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private Connection $connection,
|
private Connection $connection,
|
||||||
@@ -335,8 +335,8 @@ class ImpactScoreService
|
|||||||
private function scoreToLevel(int $score): string
|
private function scoreToLevel(int $score): string
|
||||||
{
|
{
|
||||||
return match (true) {
|
return match (true) {
|
||||||
$score <= 30 => 'low',
|
$score <= 15 => 'low',
|
||||||
$score <= 70 => 'medium',
|
$score <= 55 => 'medium',
|
||||||
default => 'high',
|
default => 'high',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,15 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="/icon.svg" />
|
||||||
|
<link rel="apple-touch-icon" href="/icon.svg" />
|
||||||
|
<link rel="manifest" href="/manifest.json" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
||||||
<title>Radar Sargasses Caraïbes</title>
|
<meta name="theme-color" content="#3ab5e6" />
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
|
<meta name="apple-mobile-web-app-title" content="RS 971" />
|
||||||
|
<title>Radar Sargasses 971</title>
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Fredoka+One&family=Fredoka:wght@400;500;600&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Fredoka+One&family=Fredoka:wght@400;500;600&display=swap" rel="stylesheet">
|
||||||
|
|||||||
44
frontend/public/icon.svg
Normal file
44
frontend/public/icon.svg
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||||
|
<!-- Fond plein pour le mode maskable (safe area = 80% du centre) -->
|
||||||
|
<rect width="512" height="512" fill="#1a1a2e"/>
|
||||||
|
|
||||||
|
<!-- Halo océan -->
|
||||||
|
<circle cx="256" cy="256" r="222" fill="#0f1a3a"/>
|
||||||
|
|
||||||
|
<!-- Anneaux radar -->
|
||||||
|
<circle cx="256" cy="256" r="195" fill="none" stroke="#2563eb" stroke-width="2.5" opacity="0.25"/>
|
||||||
|
<circle cx="256" cy="256" r="148" fill="none" stroke="#2563eb" stroke-width="2.5" opacity="0.35"/>
|
||||||
|
<circle cx="256" cy="256" r="100" fill="none" stroke="#2563eb" stroke-width="2.5" opacity="0.50"/>
|
||||||
|
<circle cx="256" cy="256" r="52" fill="none" stroke="#2563eb" stroke-width="2.5" opacity="0.65"/>
|
||||||
|
|
||||||
|
<!-- Réticule -->
|
||||||
|
<line x1="256" y1="61" x2="256" y2="451" stroke="#2563eb" stroke-width="1.5" opacity="0.18"/>
|
||||||
|
<line x1="61" y1="256" x2="451" y2="256" stroke="#2563eb" stroke-width="1.5" opacity="0.18"/>
|
||||||
|
|
||||||
|
<!-- Secteur de balayage (zone de détection sargasses) -->
|
||||||
|
<path d="M256 256 L415 97 A197 197 0 0 0 256 61 Z" fill="#f4720a" opacity="0.14"/>
|
||||||
|
|
||||||
|
<!-- Traîne du balayage (fondu) -->
|
||||||
|
<path d="M256 256 L415 97 A197 197 0 0 1 430 145 Z" fill="#60a5fa" opacity="0.08"/>
|
||||||
|
|
||||||
|
<!-- Tache sargasse détectée -->
|
||||||
|
<ellipse cx="355" cy="167" rx="30" ry="19" fill="#f4720a" opacity="0.75" transform="rotate(-38 355 167)"/>
|
||||||
|
<ellipse cx="326" cy="144" rx="19" ry="13" fill="#c44a05" opacity="0.65" transform="rotate(-30 326 144)"/>
|
||||||
|
|
||||||
|
<!-- Ligne de balayage radar -->
|
||||||
|
<line x1="256" y1="256" x2="415" y2="97" stroke="#60a5fa" stroke-width="4" stroke-linecap="round"/>
|
||||||
|
|
||||||
|
<!-- Blip : détection sargasse -->
|
||||||
|
<circle cx="355" cy="167" r="10" fill="#f4720a"/>
|
||||||
|
<circle cx="355" cy="167" r="17" fill="none" stroke="#f4720a" stroke-width="2" opacity="0.5"/>
|
||||||
|
|
||||||
|
<!-- Point central -->
|
||||||
|
<circle cx="256" cy="256" r="7" fill="#ffffff"/>
|
||||||
|
<circle cx="256" cy="256" r="12" fill="none" stroke="#ffffff" stroke-width="1.5" opacity="0.4"/>
|
||||||
|
|
||||||
|
<!-- "971" — signature Guadeloupe -->
|
||||||
|
<text x="256" y="446" text-anchor="middle"
|
||||||
|
font-family="'Arial Black', Arial, sans-serif"
|
||||||
|
font-size="58" font-weight="900" letter-spacing="4"
|
||||||
|
fill="#60a5fa" opacity="0.82">971</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.1 KiB |
29
frontend/public/manifest.json
Normal file
29
frontend/public/manifest.json
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"name": "Radar Sargasses 971",
|
||||||
|
"short_name": "RS 971",
|
||||||
|
"description": "Surveillance satellite des sargasses en Guadeloupe",
|
||||||
|
"start_url": "/",
|
||||||
|
"scope": "/",
|
||||||
|
"display": "standalone",
|
||||||
|
"background_color": "#1a1a2e",
|
||||||
|
"theme_color": "#3ab5e6",
|
||||||
|
"orientation": "portrait",
|
||||||
|
"lang": "fr",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/icon.svg",
|
||||||
|
"sizes": "any",
|
||||||
|
"type": "image/svg+xml",
|
||||||
|
"purpose": "any maskable"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"screenshots": [
|
||||||
|
{
|
||||||
|
"src": "/assets/logo-radarsargasses971.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png",
|
||||||
|
"form_factor": "narrow",
|
||||||
|
"label": "Carte radar sargasses Guadeloupe"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user