Atlas: DSGVO-Tile-Proxy + Logistik-Phase-bis-8 + Sounds-Anleitung

Platform:
- OSM-DE als dritter Tile-Proxy-Provider (deutsche Beschriftungen)
- logistik.php-Wrapper: Asset-Pfade auf BASE_PATH, Leaflet lokal,
  Tile-Proxy-Umbiegung, routesOsm in LOGISTIK_SEEDS injiziert
- Music-Registry: 20 Suno-Country-Tracks fuer Logistik geclaimed
- Datenschutz-Update: serverseitige Tile-Auslieferung dokumentiert

Logistik (Instanz-Lieferungen, parallel):
- Phase 0 bis 8 inkl. Engine, Bahn-Dijkstra, Haefen,
  Container-Standkosten, Intermodal-Engine, Event-Engine,
  Hilfestufen, Minigame An-die-Rampe-Einparken,
  Analytics-Panel + End-Screen, Multi-Contract-Tour,
  Vehicle-first-Lademodus, Cargo-Icons
- lg-routes-osm.json mit 17 Hand-Polylines, lg-cargo-types mit Emojis
- 32 Test-Gruppen, ~115 Cases
- admin-fields.json fuer Admin-UI-Integration

Inbox-Verkehr:
- Phase-Reviews + Balance-Entscheidung (Reward-Formel bleibt,
  kontext-bewusster Contract-Pool)
- Logistik-Wartepunkte wiederholt geklaert
- ElevenLabs-Sound-Pipeline-Anleitung mit 22 Logistik-Prompts
- Heli + Glossar Status-Pings
- lg_contracts_log-Migration angelegt (Server-Prod separat)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-23 08:15:00 +02:00
parent eac686ee1a
commit fc8996f064
47 changed files with 9995 additions and 230 deletions
+6 -1
View File
@@ -24,6 +24,11 @@ const PROVIDERS = [
'url_pattern' => 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
'max_zoom' => 18,
],
'osm-de' => [
'label' => 'OpenStreetMap Deutsch (FOSSGIS e.V.)',
'url_pattern' => 'https://tile.openstreetmap.de/{z}/{x}/{y}.png',
'max_zoom' => 18,
],
'carto' => [
'label' => 'CARTO Positron',
'url_pattern' => 'https://cartodb-basemaps-a.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png',
@@ -41,7 +46,7 @@ const UPSTREAM_TIMEOUT = 10; // Sekunden
$z = filter_input(INPUT_GET, 'z', FILTER_VALIDATE_INT, ['options' => ['min_range' => MIN_ZOOM, 'max_range' => MAX_ZOOM]]);
$x = filter_input(INPUT_GET, 'x', FILTER_VALIDATE_INT, ['options' => ['min_range' => 0, 'max_range' => 1 << MAX_ZOOM]]);
$y = filter_input(INPUT_GET, 'y', FILTER_VALIDATE_INT, ['options' => ['min_range' => 0, 'max_range' => 1 << MAX_ZOOM]]);
$p = filter_input(INPUT_GET, 'p', FILTER_CALLBACK, ['options' => fn($v) => is_string($v) && preg_match('/^[a-z]{1,16}$/', $v) ? $v : false]);
$p = filter_input(INPUT_GET, 'p', FILTER_CALLBACK, ['options' => fn($v) => is_string($v) && preg_match('/^[a-z][a-z0-9-]{0,15}$/', $v) ? $v : false]);
if ($z === null || $z === false || $x === false || $y === false || !$p || !isset(PROVIDERS[$p])) {
http_response_code(400);