mirror of
https://github.com/Iconica-Development/flutter_google_track_and_trace.git
synced 2025-05-19 05:03:45 +02:00
only update on minimum distance
This commit is contained in:
parent
b9a867eaca
commit
38ac7476a5
6 changed files with 215 additions and 68 deletions
|
@ -13,10 +13,13 @@ class TrackTraceDemo extends StatefulWidget {
|
|||
|
||||
class _TrackTraceDemoState extends State<TrackTraceDemo> {
|
||||
TrackTraceController? controller;
|
||||
int step = 1;
|
||||
int routeLength = 0;
|
||||
late final Timer timer;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
Timer.periodic(const Duration(seconds: 5), (_) {
|
||||
timer = Timer.periodic(const Duration(seconds: 2), (_) {
|
||||
moveAlongRoute();
|
||||
});
|
||||
super.initState();
|
||||
|
@ -48,6 +51,18 @@ class _TrackTraceDemoState extends State<TrackTraceDemo> {
|
|||
{'visibility': 'off'},
|
||||
],
|
||||
),
|
||||
// GoogleMapThemeFeature(
|
||||
// featureType: 'water',
|
||||
// stylers: [
|
||||
// {'color': '#00ff00'}
|
||||
// ],
|
||||
// ),
|
||||
// GoogleMapThemeFeature(
|
||||
// featureType: 'road',
|
||||
// stylers: [
|
||||
// {'color': '#000000'}
|
||||
// ],
|
||||
// )
|
||||
],
|
||||
),
|
||||
startPosition: const Marker(
|
||||
|
@ -61,18 +76,37 @@ class _TrackTraceDemoState extends State<TrackTraceDemo> {
|
|||
googleAPIKey: 'AIzaSyDaxZX8TeQeVf5tW-D6A66WLl20arbWV6c',
|
||||
travelMode: TravelMode.walking,
|
||||
mapType: MapType.normal,
|
||||
routeUpdateInterval: 60,
|
||||
routeUpdateInterval: Duration(seconds: 30),
|
||||
timerPrecision: TimePrecision.everySecond,
|
||||
zoomGesturesEnabled: true,
|
||||
scrollGesturesEnabled: true,
|
||||
line: const Polyline(
|
||||
jointType: JointType.bevel,
|
||||
polylineId: PolylineId('test route'),
|
||||
color: Color(0xFFFF7884),
|
||||
width: 3,
|
||||
),
|
||||
onArrived: () {
|
||||
timer.cancel();
|
||||
debugPrint('stopping simulation');
|
||||
},
|
||||
onTap: (value) {
|
||||
debugPrint(value.toString());
|
||||
},
|
||||
onLongPress: (value) {
|
||||
debugPrint(value.toString());
|
||||
},
|
||||
onCameraMove: (value) {
|
||||
debugPrint(value.toString());
|
||||
},
|
||||
onMapCreated: (ctr) => {
|
||||
controller = ctr,
|
||||
ctr.addListener(() {
|
||||
setState(() {});
|
||||
setState(() {
|
||||
if (ctr.route != null && ctr.route!.distance != routeLength) {
|
||||
step = 1;
|
||||
}
|
||||
});
|
||||
}),
|
||||
},
|
||||
),
|
||||
|
@ -100,10 +134,12 @@ class _TrackTraceDemoState extends State<TrackTraceDemo> {
|
|||
controller!.start = Marker(
|
||||
markerId: const MarkerId('Start Locatie'),
|
||||
position: LatLng(
|
||||
controller!.route!.line[1].latitude,
|
||||
controller!.route!.line[1].longitude,
|
||||
controller!.route!.line[step].latitude,
|
||||
controller!.route!.line[step].longitude,
|
||||
),
|
||||
);
|
||||
step++;
|
||||
routeLength = controller!.route!.distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ packages:
|
|||
path: ".."
|
||||
relative: true
|
||||
source: path
|
||||
version: "0.0.1"
|
||||
version: "1.0.0"
|
||||
html:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -12,7 +12,16 @@ import 'package:google_maps_flutter/google_maps_flutter.dart';
|
|||
import 'package:http/http.dart' as http;
|
||||
|
||||
export 'package:google_maps_flutter/google_maps_flutter.dart'
|
||||
show MapType, Marker, MarkerId, Polyline, PolylineId, LatLng;
|
||||
show
|
||||
MapType,
|
||||
Marker,
|
||||
MarkerId,
|
||||
BitmapDescriptor,
|
||||
InfoWindow,
|
||||
Polyline,
|
||||
PolylineId,
|
||||
JointType,
|
||||
LatLng;
|
||||
|
||||
part 'src/controller.dart';
|
||||
part 'src/directions_repository.dart';
|
||||
|
|
|
@ -31,6 +31,36 @@ class TrackTraceController extends ChangeNotifier {
|
|||
notifyListeners();
|
||||
}
|
||||
|
||||
void recenterCamera() {
|
||||
mapController?.moveCamera(
|
||||
CameraUpdate.newLatLngBounds(
|
||||
LatLngBounds(
|
||||
southwest: LatLng(
|
||||
min(
|
||||
_startPosition.position.latitude,
|
||||
_destinationPosition.position.latitude,
|
||||
),
|
||||
min(
|
||||
_startPosition.position.longitude,
|
||||
_destinationPosition.position.longitude,
|
||||
),
|
||||
),
|
||||
northeast: LatLng(
|
||||
max(
|
||||
_startPosition.position.latitude,
|
||||
_destinationPosition.position.latitude,
|
||||
),
|
||||
max(
|
||||
_startPosition.position.longitude,
|
||||
_destinationPosition.position.longitude,
|
||||
),
|
||||
),
|
||||
),
|
||||
50,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
mapController?.dispose();
|
||||
|
@ -40,10 +70,13 @@ class TrackTraceController extends ChangeNotifier {
|
|||
|
||||
class TrackTraceRoute {
|
||||
TrackTraceRoute(
|
||||
int durationValue, int distanceValue, List<PointLatLng> lineValue,)
|
||||
: duration = durationValue,
|
||||
int durationValue,
|
||||
int distanceValue,
|
||||
List<PointLatLng> lineValue,
|
||||
) : duration = durationValue,
|
||||
distance = distanceValue,
|
||||
line = lineValue;
|
||||
|
||||
/// route duration in seconds
|
||||
int duration = 0;
|
||||
|
||||
|
@ -51,5 +84,5 @@ TrackTraceRoute(
|
|||
int distance = 0;
|
||||
|
||||
/// route edge points
|
||||
final List<PointLatLng> line;
|
||||
List<PointLatLng> line;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
part of google_track_trace;
|
||||
|
||||
// typedef void MapCreatedCallback(TrackTraceController controller);
|
||||
enum TimePrecision { updateOnly, everySecond, everyMinute }
|
||||
|
||||
class GoogleTrackTraceMap extends StatefulWidget {
|
||||
|
@ -11,15 +10,29 @@ class GoogleTrackTraceMap extends StatefulWidget {
|
|||
required this.googleAPIKey,
|
||||
required this.routeUpdateInterval,
|
||||
Key? key,
|
||||
this.markerUpdatePrecision = 50,
|
||||
this.timerPrecision = TimePrecision.everyMinute,
|
||||
this.travelMode = TravelMode.driving,
|
||||
this.cameraTargetBounds,
|
||||
this.compassEnabled = false,
|
||||
this.rotateGesturesEnabled = false,
|
||||
this.scrollGesturesEnabled = false,
|
||||
this.zoomControlsEnabled = false,
|
||||
this.zoomGesturesEnabled = false,
|
||||
this.liteModeEnabled = false,
|
||||
this.tiltGesturesEnabled = false,
|
||||
this.myLocationEnabled = false,
|
||||
this.myLocationButtonEnabled = false,
|
||||
this.mapToolbarEnabled = false,
|
||||
this.mapType = MapType.normal,
|
||||
this.buildingsEnabled = false,
|
||||
this.indoorViewEnabled = false,
|
||||
this.trafficEnabled = false,
|
||||
this.mapStylingTheme,
|
||||
this.onTap,
|
||||
this.onArrived,
|
||||
this.onLongPress,
|
||||
this.onCameraMove,
|
||||
this.line,
|
||||
}) : super(key: key);
|
||||
|
||||
|
@ -31,8 +44,10 @@ class GoogleTrackTraceMap extends StatefulWidget {
|
|||
|
||||
final TravelMode travelMode;
|
||||
|
||||
final int routeUpdateInterval;
|
||||
final Duration routeUpdateInterval;
|
||||
|
||||
/// amount of meter the marker needs to move to update
|
||||
final int markerUpdatePrecision;
|
||||
final TimePrecision timerPrecision;
|
||||
|
||||
final Marker startPosition;
|
||||
|
@ -41,13 +56,26 @@ class GoogleTrackTraceMap extends StatefulWidget {
|
|||
final Polyline? line;
|
||||
|
||||
final bool compassEnabled;
|
||||
final bool rotateGesturesEnabled;
|
||||
final bool scrollGesturesEnabled;
|
||||
final bool liteModeEnabled;
|
||||
final bool tiltGesturesEnabled;
|
||||
final bool myLocationEnabled;
|
||||
final bool myLocationButtonEnabled;
|
||||
final bool zoomControlsEnabled;
|
||||
final bool zoomGesturesEnabled;
|
||||
final bool mapToolbarEnabled;
|
||||
final bool buildingsEnabled;
|
||||
final bool indoorViewEnabled;
|
||||
final bool trafficEnabled;
|
||||
final CameraTargetBounds? cameraTargetBounds;
|
||||
final MapType mapType;
|
||||
final GoogleTrackTraceMapTheme? mapStylingTheme;
|
||||
|
||||
final ArgumentCallback<LatLng>? onTap;
|
||||
final void Function()? onArrived;
|
||||
final ArgumentCallback<LatLng>? onLongPress;
|
||||
final CameraPositionCallback? onCameraMove;
|
||||
final String googleAPIKey;
|
||||
|
||||
@override
|
||||
|
@ -59,12 +87,17 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
|
|||
|
||||
DateTime lastRouteUpdate = DateTime.now();
|
||||
|
||||
late final Timer routeCalculateTimer;
|
||||
late final Timer markerUpdateTimer;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
controller =
|
||||
TrackTraceController(widget.startPosition, widget.destinationPosition);
|
||||
controller.addListener(_onChange);
|
||||
controller.addListener(
|
||||
() => setState(() {}),
|
||||
);
|
||||
widget.onMapCreated(controller);
|
||||
startRouteUpdateTimer();
|
||||
startMarkerUpdateTimer();
|
||||
|
@ -84,12 +117,23 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
|
|||
controller.end.position,
|
||||
),
|
||||
onMapCreated: _onMapCreated,
|
||||
onTap: widget.onTap,
|
||||
onLongPress: widget.onLongPress,
|
||||
onCameraMove: widget.onCameraMove,
|
||||
compassEnabled: widget.compassEnabled,
|
||||
rotateGesturesEnabled: widget.rotateGesturesEnabled,
|
||||
scrollGesturesEnabled: widget.scrollGesturesEnabled,
|
||||
zoomControlsEnabled: widget.zoomControlsEnabled,
|
||||
zoomGesturesEnabled: widget.zoomGesturesEnabled,
|
||||
liteModeEnabled: widget.liteModeEnabled,
|
||||
tiltGesturesEnabled: widget.tiltGesturesEnabled,
|
||||
myLocationEnabled: widget.myLocationEnabled,
|
||||
myLocationButtonEnabled: widget.myLocationButtonEnabled,
|
||||
mapToolbarEnabled: widget.mapToolbarEnabled,
|
||||
mapType: widget.mapType,
|
||||
buildingsEnabled: widget.buildingsEnabled,
|
||||
indoorViewEnabled: widget.indoorViewEnabled,
|
||||
trafficEnabled: widget.trafficEnabled,
|
||||
markers: <Marker>{
|
||||
controller.start,
|
||||
controller.end,
|
||||
|
@ -115,10 +159,6 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
|
|||
);
|
||||
}
|
||||
|
||||
void _onChange() {
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
void _onMapCreated(GoogleMapController ctr) {
|
||||
if (mounted) {
|
||||
controller.mapController = ctr;
|
||||
|
@ -130,6 +170,7 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
|
|||
'[{"featureType": "poi","stylers": [{"visibility": "off"}]}]',
|
||||
);
|
||||
}
|
||||
controller.recenterCamera();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,7 +179,6 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
|
|||
(pointA.latitude + pointB.latitude) / 2,
|
||||
(pointA.longitude + pointB.longitude) / 2,
|
||||
);
|
||||
|
||||
return CameraPosition(
|
||||
target: target,
|
||||
zoom: 13.0,
|
||||
|
@ -147,26 +187,10 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
|
|||
);
|
||||
}
|
||||
|
||||
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 timer) {
|
||||
routeCalculateTimer =
|
||||
Timer.periodic(widget.routeUpdateInterval, (Timer timer) {
|
||||
calculateRoute();
|
||||
});
|
||||
}
|
||||
|
@ -175,10 +199,14 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
|
|||
if (widget.timerPrecision != TimePrecision.updateOnly) {
|
||||
var updateInterval =
|
||||
(widget.timerPrecision == TimePrecision.everyMinute) ? 60 : 1;
|
||||
markerUpdateTimer =
|
||||
Timer.periodic(Duration(seconds: updateInterval), (timer) {
|
||||
if (controller.route != null) {
|
||||
checkDestinationCloseBy();
|
||||
controller.route = TrackTraceRoute(
|
||||
controller.route!.duration - updateInterval,
|
||||
(controller.route!.duration != 0)
|
||||
? controller.route!.duration - updateInterval
|
||||
: 0,
|
||||
controller.route!.distance,
|
||||
controller.route!.line,
|
||||
);
|
||||
|
@ -188,6 +216,7 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
|
|||
}
|
||||
|
||||
void calculateRoute() {
|
||||
if (controller.route == null || checkTargetMoved()) {
|
||||
DirectionsRepository() // TODO(freek): refactor this away
|
||||
.getDirections(
|
||||
origin: controller.start.position,
|
||||
|
@ -202,19 +231,59 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
|
|||
value.totalDistance,
|
||||
value.polylinePoints,
|
||||
),
|
||||
if (controller.mapController != null)
|
||||
{
|
||||
controller.mapController!.moveCamera(
|
||||
moveCameraToCenter(
|
||||
controller.start.position,
|
||||
controller.end.position,
|
||||
),
|
||||
),
|
||||
},
|
||||
checkDestinationCloseBy(),
|
||||
controller.recenterCamera(),
|
||||
setState(() {
|
||||
lastRouteUpdate = DateTime.now();
|
||||
})
|
||||
}),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void checkDestinationCloseBy() {
|
||||
if (calculatePointProximity(
|
||||
controller.start.position,
|
||||
controller.end.position,
|
||||
) <
|
||||
widget.markerUpdatePrecision) {
|
||||
routeCalculateTimer.cancel();
|
||||
markerUpdateTimer.cancel();
|
||||
if (controller.route != null) {
|
||||
controller.route!.line = <PointLatLng>[controller.route!.line[1]];
|
||||
controller.route!.distance = 0;
|
||||
controller.route!.duration = 0;
|
||||
}
|
||||
widget.onArrived?.call();
|
||||
}
|
||||
}
|
||||
|
||||
bool checkTargetMoved() {
|
||||
return calculatePointProximity(
|
||||
controller.start.position,
|
||||
LatLng(
|
||||
controller.route!.line[0].latitude,
|
||||
controller.route!.line[0].longitude,
|
||||
),
|
||||
) >=
|
||||
widget.markerUpdatePrecision;
|
||||
}
|
||||
|
||||
double calculatePointProximity(LatLng pointA, LatLng pointB) {
|
||||
var p = 0.017453292519943295;
|
||||
var c = cos;
|
||||
var a = 0.5 -
|
||||
c(
|
||||
(pointA.latitude - pointB.latitude) * p,
|
||||
) /
|
||||
2 +
|
||||
c(controller.route!.line[0].latitude * p) *
|
||||
c(pointA.latitude * p) *
|
||||
(1 -
|
||||
c(
|
||||
(pointA.longitude - pointB.longitude) * p,
|
||||
)) /
|
||||
2;
|
||||
return 12742 * asin(sqrt(a)) * 1000;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: google_track_trace
|
||||
description: An Iconica Flutter pluginin for Track & Trace Package
|
||||
version: 0.0.1
|
||||
version: 1.0.0
|
||||
|
||||
environment:
|
||||
sdk: ">=2.14.0 <3.0.0"
|
||||
|
|
Loading…
Reference in a new issue