47 lines
2.2 KiB
Dart
47 lines
2.2 KiB
Dart
import 'package:flutter/widgets.dart';
|
|
import 'package:flutter_map/flutter_map.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:latlong2/latlong.dart';
|
|
|
|
import '../../domain/waypoint/flat_waypoint_list.dart';
|
|
|
|
/// Ein einziger, app-lebenslanger MapController statt einer pro
|
|
/// PlanScreen-Mount neu erzeugten Instanz.
|
|
///
|
|
/// Grund: Die Kopfleiste (AppShell/TopModeBar) liegt eine Ebene ueber
|
|
/// PlanScreen und braucht fuer Suche/Home/Fit denselben Controller wie die
|
|
/// Karte - ein PlanScreen-privates Feld waere von dort nicht erreichbar.
|
|
/// Als Nebeneffekt (und in Wahrheit der wichtigere Punkt) bleibt die
|
|
/// Kamera-Position/Zoom jetzt auch ueber einen Wechsel nach Fly und
|
|
/// zurueck erhalten: flutter_map tastet einen extern uebergebenen
|
|
/// MapController beim erneuten Mounten nicht an (siehe
|
|
/// FlutterMap._setMapController()), anders als der bisherige Zustand, wo
|
|
/// PlanScreens eigener Controller beim Verlassen des Plan-Modus komplett
|
|
/// verworfen wurde. Entspricht damit auch besser dem HTML-Demonstrator,
|
|
/// der nur eine einzige Leaflet-Instanz fuer die gesamte App kennt.
|
|
final mapControllerProvider = Provider<MapController>((ref) {
|
|
final controller = MapController();
|
|
ref.onDispose(controller.dispose);
|
|
return controller;
|
|
});
|
|
|
|
/// Zentriert die Karte auf die Bounding-Box der uebergebenen Wegpunkte
|
|
/// (Doku 3.6, analog fitToWaypoints() im HTML-Demonstrator) - geteilt
|
|
/// zwischen dem manuellen Fit-Button (MapSearchControls) und den
|
|
/// map-bezogenen Warnungs-Aktionen (Doku 3.10), damit beide Stellen exakt
|
|
/// dieselbe Zoom-/Padding-Logik verwenden.
|
|
void fitMapToWaypoints(WidgetRef ref, List<Waypoint> waypoints) {
|
|
if (waypoints.isEmpty) return;
|
|
final points = [for (final w in waypoints) LatLng(w.lat, w.lon)];
|
|
ref.read(mapControllerProvider).fitCamera(
|
|
CameraFit.bounds(
|
|
bounds: LatLngBounds.fromPoints(points),
|
|
// Symmetrisch statt vorher unten 140 (Reservierung fuer die
|
|
// Fusszeile) - der Fit soll den ganzen Bildschirm ausnutzen statt
|
|
// dort unnoetig herauszuzoomen (Doku: "Fusszeile wird ausgespart,
|
|
// nicht genutzt").
|
|
padding: const EdgeInsets.all(50),
|
|
),
|
|
);
|
|
}
|