anyway/frontend/lib/modules/current_trip_map.dart

151 lines
4.3 KiB
Dart

import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:widget_to_marker/widget_to_marker.dart';
import 'package:anyway/constants.dart';
import 'package:anyway/structs/landmark.dart';
import 'package:anyway/structs/trip.dart';
import 'package:anyway/modules/landmark_map_marker.dart';
class CurrentTripMap extends StatefulWidget {
final Trip? trip;
CurrentTripMap({this.trip});
@override
State<CurrentTripMap> createState() => _CurrentTripMapState();
}
class _CurrentTripMapState extends State<CurrentTripMap> {
late GoogleMapController mapController;
CameraPosition _cameraPosition = CameraPosition(
target: LatLng(48.8566, 2.3522),
zoom: 11.0,
);
Set<Marker> mapMarkers = <Marker>{};
Set<Polyline> mapPolylines = <Polyline>{};
@override
void initState() {
super.initState();
widget.trip?.addListener(setMapMarkers);
widget.trip?.addListener(setMapRoute);
}
@override
void dispose() {
widget.trip?.removeListener(setMapMarkers);
widget.trip?.removeListener(setMapRoute);
super.dispose();
}
void _onMapCreated(GoogleMapController controller) async {
mapController = controller;
List<double>? newLocation = widget.trip?.landmarks.firstOrNull?.location;
if (newLocation != null) {
CameraUpdate update = CameraUpdate.newLatLng(LatLng(newLocation[0], newLocation[1]));
controller.moveCamera(update);
}
setMapMarkers();
setMapRoute();
}
void _onCameraIdle() {
// print(mapController.getLatLng(ScreenCoordinate(x: 0, y: 0)));
}
void setMapMarkers() async {
Iterator<(int, Landmark)> it = (widget.trip?.landmarks.toList() ?? []).indexed.iterator;
while (it.moveNext()) {
int i = it.current.$1;
Landmark landmark = it.current.$2;
MarkerId markerId = MarkerId("${landmark.uuid} - ${landmark.visited}");
List<double> location = landmark.location;
// only create a new marker, if there is no marker for this landmark
if (!mapMarkers.any((Marker marker) => marker.markerId == markerId)) {
Marker marker = Marker(
markerId: markerId,
position: LatLng(location[0], location[1]),
icon: await ThemedMarker(landmark: landmark, position: i).toBitmapDescriptor(
logicalSize: const Size(150, 150),
imageSize: const Size(150, 150),
)
);
setState(() {
mapMarkers.add(marker);
});
}
}
}
void setMapRoute() async {
List<Landmark> landmarks = widget.trip?.landmarks.toList() ?? [];
Set<Polyline> polyLines = <Polyline>{};
if (landmarks.length < 2) {
return;
}
for (Landmark landmark in landmarks) {
if (landmark.next != null) {
List<LatLng> step = [
LatLng(landmark.location[0], landmark.location[1]),
LatLng(landmark.next!.location[0], landmark.next!.location[1])
];
Polyline stepLine = Polyline(
polylineId: PolylineId('step-${landmark.uuid}'),
points: step,
color: landmark.visited || (landmark.next?.visited ?? false) ? Colors.grey : PRIMARY_COLOR,
width: 5
);
polyLines.add(stepLine);
}
}
setState(() {
mapPolylines = polyLines;
});
}
@override
Widget build(BuildContext context) {
Future<SharedPreferences> preferences = SharedPreferences.getInstance();
return FutureBuilder(
future: preferences,
builder: (context, snapshot) {
if (snapshot.hasData) {
SharedPreferences prefs = snapshot.data as SharedPreferences;
bool useLocation = prefs.getBool('useLocation') ?? true;
return _buildMap(useLocation);
} else {
return const CircularProgressIndicator();
}
},
);
}
Widget _buildMap(bool useLocation) {
return GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: _cameraPosition,
onCameraIdle: _onCameraIdle,
markers: mapMarkers,
polylines: mapPolylines,
cloudMapId: MAP_ID,
mapToolbarEnabled: false,
zoomControlsEnabled: false,
myLocationEnabled: useLocation,
myLocationButtonEnabled: false,
);
}
}