mirror of
https://github.com/Iconica-Development/flutter_google_track_and_trace.git
synced 2025-05-19 05:03:45 +02:00
update demo to amsterdam travel
This commit is contained in:
parent
a39de81555
commit
ed11998739
4 changed files with 124 additions and 121 deletions
|
@ -17,15 +17,8 @@ class _TrackTraceDemoState extends State<TrackTraceDemo> {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
Timer.periodic(const Duration(seconds: 10), (_) {
|
||||
print('updating marker');
|
||||
getRandomPointOnMap();
|
||||
});
|
||||
|
||||
Timer.periodic(const Duration(seconds: 60), (_) {
|
||||
print('updating route');
|
||||
getRandomRoute();
|
||||
moveAlongRoute();
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
@ -34,24 +27,30 @@ class _TrackTraceDemoState extends State<TrackTraceDemo> {
|
|||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: (controller == null)
|
||||
title: (controller == null || controller!.route == null)
|
||||
? const Text('TrackTrace example')
|
||||
: Text(controller!.duration.toString() + ' seconds')),
|
||||
: Text(controller!.route!.duration.toString() +
|
||||
' seconds, afstand: ' +
|
||||
(controller!.route!.distance / 1000).toString() +
|
||||
' km')),
|
||||
body: GoogleTrackTraceMap(
|
||||
startPosition: const Marker(
|
||||
markerId: MarkerId('Start locatie'),
|
||||
position: LatLng(51.965578, 6.293439),
|
||||
position: LatLng(52.356057, 4.897540),
|
||||
),
|
||||
destinationPosition: const Marker(
|
||||
markerId: MarkerId('Eind locatie'),
|
||||
position: LatLng(51.958996, 6.296520),
|
||||
),
|
||||
markerId: MarkerId('Bestemming Locatie'),
|
||||
position: LatLng(52.364709, 4.877157)),
|
||||
googleAPIKey: 'AIzaSyDaxZX8TeQeVf5tW-D6A66WLl20arbWV6c',
|
||||
travelMode: TravelMode.walking,
|
||||
travelMode: TravelMode.bicycling,
|
||||
routeUpdateInterval: 60,
|
||||
routeLabel: 'Test route',
|
||||
timerPrecision: TimePrecision.everySecond,
|
||||
zoomGesturesEnabled: true,
|
||||
line: const Polyline(
|
||||
polylineId: PolylineId('test route'),
|
||||
color: Colors.purple,
|
||||
width: 7,
|
||||
),
|
||||
onMapCreated: (ctr) => {
|
||||
controller = ctr,
|
||||
ctr.addListener(() {
|
||||
|
@ -62,42 +61,20 @@ class _TrackTraceDemoState extends State<TrackTraceDemo> {
|
|||
);
|
||||
}
|
||||
|
||||
void updateMap() {
|
||||
controller!.current = const Marker(
|
||||
markerId: MarkerId('Huidige locatie'),
|
||||
position: LatLng(51.962578, 6.294439),
|
||||
);
|
||||
}
|
||||
|
||||
void getRandomPointOnMap() {
|
||||
// 51.989909, 6.234950
|
||||
|
||||
// 51.939909, 6.314950
|
||||
// 51.989909, 6.234950 NW
|
||||
// 51.939909, 6.314950 SE
|
||||
if (controller != null) {
|
||||
controller!.current = Marker(
|
||||
markerId: MarkerId('Huidige Locatie'),
|
||||
controller!.start = Marker(
|
||||
markerId: const MarkerId('Start Locatie'),
|
||||
position: LatLng(51.93 + Random().nextDouble() * 0.06,
|
||||
6.23 + Random().nextDouble() * 0.08));
|
||||
}
|
||||
}
|
||||
|
||||
void getRandomRoute() {
|
||||
// if (route != null) {
|
||||
// print('removing point');
|
||||
// PointLatLng point = route!.polylinePoints[1];
|
||||
// trackTraceController.startMarker = Marker(
|
||||
// markerId: MarkerId('Start locatie'),
|
||||
// position: LatLng(point.latitude, point.longitude));
|
||||
// }
|
||||
if (controller != null) {
|
||||
controller!.start = Marker(
|
||||
markerId: MarkerId('Start Locatie'),
|
||||
position: LatLng(51.93 + Random().nextDouble() * 0.06,
|
||||
6.23 + Random().nextDouble() * 0.08));
|
||||
controller!.end = Marker(
|
||||
markerId: MarkerId('Bestemming Locatie'),
|
||||
position: LatLng(51.93 + Random().nextDouble() * 0.06,
|
||||
6.23 + Random().nextDouble() * 0.08));
|
||||
void moveAlongRoute() {
|
||||
if (controller != null && controller!.route != null && controller!.route!.line.length > 1) {
|
||||
controller!.start = Marker(markerId: const MarkerId('Start Locatie'), position: LatLng(controller!.route!.line[1].latitude, controller!.route!.line[1].longitude));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,48 +1,56 @@
|
|||
part of google_track_trace;
|
||||
|
||||
class TrackTraceController extends ChangeNotifier {
|
||||
late final GoogleMapController _mapController;
|
||||
Marker startPosition;
|
||||
Marker destinationPosition;
|
||||
Marker? currentPosition;
|
||||
|
||||
int durationInSeconds = 0;
|
||||
GoogleMapController? _mapController;
|
||||
Marker _startPosition;
|
||||
Marker _destinationPosition;
|
||||
TrackTraceRoute? _route;
|
||||
|
||||
TrackTraceController(Marker start, Marker destination)
|
||||
: startPosition = start,
|
||||
destinationPosition = destination;
|
||||
: _startPosition = start,
|
||||
_destinationPosition = destination;
|
||||
|
||||
set start(Marker start) {
|
||||
startPosition = start;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
set current(Marker? current) {
|
||||
currentPosition = current;
|
||||
_startPosition = start;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
set end(Marker end) {
|
||||
destinationPosition = end;
|
||||
_destinationPosition = end;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Marker get start => startPosition;
|
||||
Marker get start => _startPosition;
|
||||
|
||||
Marker? get current => currentPosition;
|
||||
Marker get end => _destinationPosition;
|
||||
|
||||
Marker get end => destinationPosition;
|
||||
TrackTraceRoute? get route => _route;
|
||||
|
||||
set duration(int duration) {
|
||||
durationInSeconds = duration;
|
||||
set route(TrackTraceRoute? newRoute) {
|
||||
_route = newRoute;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
int get duration => durationInSeconds;
|
||||
|
||||
set mapController(GoogleMapController controller) {
|
||||
set mapController(GoogleMapController? controller) {
|
||||
_mapController = controller;
|
||||
}
|
||||
|
||||
GoogleMapController get mapController => _mapController;
|
||||
GoogleMapController? get mapController => _mapController;
|
||||
}
|
||||
|
||||
class TrackTraceRoute {
|
||||
/// route duration in seconds
|
||||
int duration = 0;
|
||||
|
||||
/// route distance in meters
|
||||
int distance = 0;
|
||||
|
||||
/// route edge points
|
||||
List<PointLatLng> line;
|
||||
|
||||
TrackTraceRoute(
|
||||
int durationValue, int distanceValue, List<PointLatLng> lineValue)
|
||||
: duration = durationValue,
|
||||
distance = distanceValue,
|
||||
line = lineValue;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ class DirectionsRepository {
|
|||
} on HttpException catch (e) {
|
||||
print(e.message);
|
||||
}
|
||||
throw GoogleMapsException('Unable to retrieve directions');
|
||||
throw GoogleMapsException('Unable to retrieve directions from Google Maps API');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,7 @@ class Directions {
|
|||
required this.totalDuration,
|
||||
});
|
||||
|
||||
/// map the json response to a [Directions] object
|
||||
factory Directions.fromMap(Map<String, dynamic> map) {
|
||||
if ((map['routes'] as List).isEmpty) {
|
||||
throw GoogleMapsException('No Routes available');
|
||||
|
@ -92,7 +93,7 @@ class GoogleMapsException implements Exception {
|
|||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Error occurred in Google Maps package:\n'
|
||||
return 'Error occurred in Track&Trace package:\n'
|
||||
'$message';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,13 +13,15 @@ class GoogleTrackTraceMap extends StatefulWidget {
|
|||
required this.routeUpdateInterval,
|
||||
this.timerPrecision = TimePrecision.everyMinute,
|
||||
this.travelMode = TravelMode.driving,
|
||||
this.routeLabel = '',
|
||||
this.compassEnabled = false,
|
||||
this.zoomControlsEnabled = false,
|
||||
this.zoomGesturesEnabled = false,
|
||||
this.mapToolbarEnabled = false,
|
||||
this.mapType = MapType.normal,
|
||||
this.buildingsEnabled = false,
|
||||
this.mapMarkations =
|
||||
'[{"featureType": "poi","stylers": [{"visibility": "off"}]}]',
|
||||
this.line,
|
||||
}) : assert(true),
|
||||
super(key: key);
|
||||
|
||||
|
@ -31,8 +33,6 @@ class GoogleTrackTraceMap extends StatefulWidget {
|
|||
|
||||
final TravelMode travelMode;
|
||||
|
||||
final String routeLabel;
|
||||
|
||||
final int routeUpdateInterval;
|
||||
|
||||
final TimePrecision timerPrecision;
|
||||
|
@ -40,6 +40,8 @@ class GoogleTrackTraceMap extends StatefulWidget {
|
|||
final Marker startPosition;
|
||||
final Marker destinationPosition;
|
||||
|
||||
Polyline? line;
|
||||
|
||||
final bool compassEnabled;
|
||||
final bool zoomControlsEnabled;
|
||||
final bool zoomGesturesEnabled;
|
||||
|
@ -47,6 +49,8 @@ class GoogleTrackTraceMap extends StatefulWidget {
|
|||
final bool buildingsEnabled;
|
||||
final MapType mapType;
|
||||
|
||||
final String mapMarkations;
|
||||
|
||||
CameraPosition initialCameraPosition = const CameraPosition(
|
||||
// doetinchem default initialCamera
|
||||
target: LatLng(51.965578, 6.293439),
|
||||
|
@ -59,25 +63,24 @@ class GoogleTrackTraceMap extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
|
||||
late final TrackTraceController trackTraceController;
|
||||
late final TrackTraceController controller;
|
||||
|
||||
Directions? route;
|
||||
DateTime lastRouteUpdate = DateTime.now();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
trackTraceController =
|
||||
controller =
|
||||
TrackTraceController(widget.startPosition, widget.destinationPosition);
|
||||
trackTraceController.addListener(_onChange);
|
||||
widget.onMapCreated(trackTraceController);
|
||||
controller.addListener(_onChange);
|
||||
widget.onMapCreated(controller);
|
||||
startRouteUpdateTimer();
|
||||
startMarkerUpdateTimer();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
trackTraceController.dispose();
|
||||
controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
@ -85,8 +88,7 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
|
|||
Widget build(BuildContext context) {
|
||||
return GoogleMap(
|
||||
initialCameraPosition: calculateCameraPosition(
|
||||
trackTraceController.start.position,
|
||||
trackTraceController.end.position),
|
||||
controller.start.position, controller.end.position),
|
||||
onMapCreated: _onMapCreated,
|
||||
compassEnabled: widget.compassEnabled,
|
||||
zoomControlsEnabled: widget.zoomControlsEnabled,
|
||||
|
@ -95,22 +97,25 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
|
|||
mapType: widget.mapType,
|
||||
buildingsEnabled: widget.buildingsEnabled,
|
||||
markers: {
|
||||
// style the markers
|
||||
trackTraceController.start,
|
||||
trackTraceController.end,
|
||||
if (trackTraceController.current != null)
|
||||
trackTraceController.current!,
|
||||
controller.start,
|
||||
controller.end,
|
||||
},
|
||||
polylines: {
|
||||
if (route != null)
|
||||
Polyline(
|
||||
polylineId: PolylineId(widget.routeLabel),
|
||||
color: Theme.of(context).primaryColor,
|
||||
width: 4,
|
||||
points: route!.polylinePoints
|
||||
.map((e) => LatLng(e.latitude, e.longitude))
|
||||
.toList(),
|
||||
),
|
||||
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(),
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -118,11 +123,10 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
|
|||
setState(() {});
|
||||
}
|
||||
|
||||
void _onMapCreated(GoogleMapController controller) {
|
||||
void _onMapCreated(GoogleMapController ctr) {
|
||||
if (mounted) {
|
||||
trackTraceController.mapController = controller;
|
||||
controller.setMapStyle(
|
||||
'[{"featureType": "poi","stylers": [{"visibility": "off"}]}]'); // move to dart json file
|
||||
controller.mapController = ctr;
|
||||
ctr.setMapStyle(widget.mapMarkations); // move to dart json file
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,6 +139,21 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
|
|||
target: target, zoom: calculatedZoom, tilt: 0.0, bearing: 0.0);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void startRouteUpdateTimer() {
|
||||
calculateRoute(); // run at the start
|
||||
Timer.periodic(Duration(seconds: widget.routeUpdateInterval), (timer) {
|
||||
|
@ -144,37 +163,35 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
|
|||
|
||||
void startMarkerUpdateTimer() {
|
||||
if (widget.timerPrecision != TimePrecision.updateOnly) {
|
||||
Timer.periodic(
|
||||
Duration(
|
||||
seconds: (widget.timerPrecision == TimePrecision.everyMinute)
|
||||
? 60
|
||||
: 1), (timer) {
|
||||
updateDurationTimer();
|
||||
int updateInterval =
|
||||
(widget.timerPrecision == TimePrecision.everyMinute) ? 60 : 1;
|
||||
Timer.periodic(Duration(seconds: updateInterval), (timer) {
|
||||
if (controller.route != null) {
|
||||
controller.route!.duration =
|
||||
controller.route!.duration - updateInterval;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void updateDurationTimer() {
|
||||
if (route != null) {
|
||||
trackTraceController.duration = route!.totalDuration -
|
||||
DateTime.now().difference(lastRouteUpdate).inSeconds;
|
||||
}
|
||||
}
|
||||
|
||||
void calculateRoute() async {
|
||||
DirectionsRepository()
|
||||
DirectionsRepository() //TODO refactor this away
|
||||
.getDirections(
|
||||
origin: trackTraceController.start.position,
|
||||
destination: trackTraceController.end.position,
|
||||
origin: controller.start.position,
|
||||
destination: controller.end.position,
|
||||
mode: widget.travelMode,
|
||||
key: widget.googleAPIKey,
|
||||
)
|
||||
.then((value) => {
|
||||
trackTraceController.duration = value.totalDuration,
|
||||
trackTraceController.mapController.moveCamera(CameraUpdate.newCameraPosition(calculateCameraPosition(trackTraceController.start.position, trackTraceController.end.position))),
|
||||
controller.route = TrackTraceRoute(value.totalDuration,
|
||||
value.totalDistance, value.polylinePoints),
|
||||
if (controller.mapController != null)
|
||||
{
|
||||
controller.mapController!.moveCamera(moveCameraToCenter(
|
||||
controller.start.position, controller.end.position)),
|
||||
},
|
||||
setState(() {
|
||||
lastRouteUpdate = DateTime.now();
|
||||
route = value;
|
||||
})
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue