flutter_google_track_and_trace/lib/src/google_map.dart

201 lines
6.1 KiB
Dart
Raw Normal View History

2021-09-28 08:18:14 +02:00
part of google_track_trace;
2021-09-29 10:07:56 +02:00
// typedef void MapCreatedCallback(TrackTraceController controller);
enum TimePrecision { updateOnly, everySecond, everyMinute }
2021-09-28 08:18:14 +02:00
class GoogleTrackTraceMap extends StatefulWidget {
GoogleTrackTraceMap({
Key? key,
2021-09-29 10:07:56 +02:00
required this.onMapCreated,
2021-09-28 08:18:14 +02:00
required this.startPosition,
required this.destinationPosition,
2021-09-29 10:07:56 +02:00
required this.googleAPIKey,
required this.routeUpdateInterval,
this.timerPrecision = TimePrecision.everyMinute,
2021-09-28 10:37:48 +02:00
this.travelMode = TravelMode.driving,
2021-09-29 10:07:56 +02:00
this.compassEnabled = false,
this.zoomControlsEnabled = false,
this.zoomGesturesEnabled = false,
this.mapToolbarEnabled = false,
this.mapType = MapType.normal,
this.buildingsEnabled = false,
2021-09-29 12:18:53 +02:00
this.mapMarkations =
'[{"featureType": "poi","stylers": [{"visibility": "off"}]}]',
this.line,
2021-09-28 08:18:14 +02:00
}) : assert(true),
super(key: key);
/// Callback method for when the map is ready to be used.
///
/// Used to receive a [TrackTraceController] for this [GoogleTrackTraceMap].
/// this [TrackTraceController] also contains the [GoogleMapController]
2021-09-29 10:07:56 +02:00
final void Function(TrackTraceController) onMapCreated;
2021-09-28 08:18:14 +02:00
final TravelMode travelMode;
2021-09-29 10:07:56 +02:00
final int routeUpdateInterval;
final TimePrecision timerPrecision;
final Marker startPosition;
final Marker destinationPosition;
2021-09-29 12:18:53 +02:00
Polyline? line;
2021-09-29 10:07:56 +02:00
final bool compassEnabled;
final bool zoomControlsEnabled;
final bool zoomGesturesEnabled;
final bool mapToolbarEnabled;
final bool buildingsEnabled;
final MapType mapType;
2021-09-29 12:18:53 +02:00
final String mapMarkations;
2021-09-29 10:07:56 +02:00
CameraPosition initialCameraPosition = const CameraPosition(
// doetinchem default initialCamera
target: LatLng(51.965578, 6.293439),
zoom: 12.0);
final String googleAPIKey;
2021-09-28 08:18:14 +02:00
@override
State createState() => _GoogleTrackTraceMapState();
}
class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
2021-09-29 12:18:53 +02:00
late final TrackTraceController controller;
2021-09-29 10:07:56 +02:00
DateTime lastRouteUpdate = DateTime.now();
@override
void initState() {
super.initState();
2021-09-29 12:18:53 +02:00
controller =
2021-09-29 10:07:56 +02:00
TrackTraceController(widget.startPosition, widget.destinationPosition);
2021-09-29 12:18:53 +02:00
controller.addListener(_onChange);
widget.onMapCreated(controller);
2021-09-29 10:07:56 +02:00
startRouteUpdateTimer();
startMarkerUpdateTimer();
}
@override
void dispose() {
2021-09-29 12:18:53 +02:00
controller.dispose();
2021-09-29 10:07:56 +02:00
super.dispose();
}
@override
Widget build(BuildContext context) {
return GoogleMap(
initialCameraPosition: calculateCameraPosition(
2021-09-29 12:18:53 +02:00
controller.start.position, controller.end.position),
2021-09-29 10:07:56 +02:00
onMapCreated: _onMapCreated,
compassEnabled: widget.compassEnabled,
zoomControlsEnabled: widget.zoomControlsEnabled,
zoomGesturesEnabled: widget.zoomGesturesEnabled,
mapToolbarEnabled: widget.mapToolbarEnabled,
mapType: widget.mapType,
buildingsEnabled: widget.buildingsEnabled,
markers: {
2021-09-29 12:18:53 +02:00
controller.start,
controller.end,
2021-09-29 10:07:56 +02:00
},
polylines: {
2021-09-29 12:18:53 +02:00
if (controller.route != null)
(widget.line != null)
? widget.line!.copyWith(
pointsParam: controller.route!.line
.map((e) => LatLng(e.latitude, e.longitude))
.toList())
: Polyline(
// default PolyLine if none is provided
polylineId: const PolylineId('track&trace route'),
color: Theme.of(context).primaryColor,
width: 4,
points: controller.route!.line
.map((e) => LatLng(e.latitude, e.longitude))
.toList(),
),
2021-09-29 10:07:56 +02:00
});
}
2021-09-28 08:18:14 +02:00
2021-09-29 10:07:56 +02:00
void _onChange() {
setState(() {});
}
2021-09-28 08:18:14 +02:00
2021-09-29 12:18:53 +02:00
void _onMapCreated(GoogleMapController ctr) {
2021-09-28 08:18:14 +02:00
if (mounted) {
2021-09-29 12:18:53 +02:00
controller.mapController = ctr;
ctr.setMapStyle(widget.mapMarkations); // move to dart json file
2021-09-28 08:18:14 +02:00
}
}
CameraPosition calculateCameraPosition(LatLng pointA, LatLng pointB) {
LatLng target = LatLng((pointA.latitude + pointB.latitude) / 2,
(pointA.longitude + pointB.longitude) / 2);
2021-09-29 10:07:56 +02:00
double calculatedZoom = 13.0; // TODO calculate this zoom
2021-09-29 12:18:53 +02:00
2021-09-28 08:18:14 +02:00
return CameraPosition(
target: target, zoom: calculatedZoom, tilt: 0.0, bearing: 0.0);
}
2021-09-29 12:18:53 +02:00
CameraUpdate moveCameraToCenter(LatLng pointA, LatLng pointB) {
return CameraUpdate.newLatLngBounds(
LatLngBounds(
southwest: LatLng(
min(pointA.latitude, pointB.latitude),
min(pointA.longitude, pointB.longitude),
),
northeast: LatLng(
max(pointA.latitude, pointB.latitude),
max(pointA.longitude, pointB.longitude),
),
),
50);
}
2021-09-29 10:07:56 +02:00
void startRouteUpdateTimer() {
calculateRoute(); // run at the start
Timer.periodic(Duration(seconds: widget.routeUpdateInterval), (timer) {
calculateRoute();
});
2021-09-28 08:18:14 +02:00
}
2021-09-29 10:07:56 +02:00
void startMarkerUpdateTimer() {
if (widget.timerPrecision != TimePrecision.updateOnly) {
2021-09-29 12:18:53 +02:00
int updateInterval =
(widget.timerPrecision == TimePrecision.everyMinute) ? 60 : 1;
Timer.periodic(Duration(seconds: updateInterval), (timer) {
if (controller.route != null) {
2021-09-29 13:42:13 +02:00
controller.route = TrackTraceRoute(
controller.route!.duration - updateInterval,
controller.route!.distance,
controller.route!.line);
2021-09-29 12:18:53 +02:00
}
2021-09-29 10:07:56 +02:00
});
}
2021-09-28 08:18:14 +02:00
}
2021-09-29 13:42:13 +02:00
void calculateRoute() async {
2021-09-29 12:18:53 +02:00
DirectionsRepository() //TODO refactor this away
2021-09-29 10:07:56 +02:00
.getDirections(
2021-09-29 12:18:53 +02:00
origin: controller.start.position,
destination: controller.end.position,
2021-09-29 10:07:56 +02:00
mode: widget.travelMode,
key: widget.googleAPIKey,
)
.then((value) => {
2021-09-29 12:18:53 +02:00
controller.route = TrackTraceRoute(value.totalDuration,
value.totalDistance, value.polylinePoints),
if (controller.mapController != null)
{
controller.mapController!.moveCamera(moveCameraToCenter(
controller.start.position, controller.end.position)),
},
2021-09-29 10:07:56 +02:00
setState(() {
lastRouteUpdate = DateTime.now();
})
});
2021-09-28 08:18:14 +02:00
}
}