add Strong Map Styling

This commit is contained in:
Freek van de Ven 2021-09-30 12:34:43 +02:00
parent 54fa43ebbf
commit b9a867eaca
6 changed files with 161 additions and 70 deletions

View file

@ -137,7 +137,7 @@ linter:
prefer_equal_for_default_values: true prefer_equal_for_default_values: true
prefer_expression_function_bodies: false prefer_expression_function_bodies: false
prefer_final_fields: true prefer_final_fields: true
prefer_final_in_for_each: true prefer_final_in_for_each: false
prefer_final_locals: false prefer_final_locals: false
prefer_final_parameters: false prefer_final_parameters: false
prefer_for_elements_to_map_fromIterable: true prefer_for_elements_to_map_fromIterable: true

View file

@ -137,7 +137,7 @@ linter:
prefer_equal_for_default_values: true prefer_equal_for_default_values: true
prefer_expression_function_bodies: false prefer_expression_function_bodies: false
prefer_final_fields: true prefer_final_fields: true
prefer_final_in_for_each: true prefer_final_in_for_each: false
prefer_final_locals: false prefer_final_locals: false
prefer_final_parameters: false prefer_final_parameters: false
prefer_for_elements_to_map_fromIterable: true prefer_for_elements_to_map_fromIterable: true

View file

@ -34,6 +34,22 @@ class _TrackTraceDemoState extends State<TrackTraceDemo> {
), ),
), ),
body: GoogleTrackTraceMap( body: GoogleTrackTraceMap(
mapStylingTheme: GoogleTrackTraceMapTheme(
themes: [
GoogleMapThemeFeature(
featureType: 'poi',
stylers: [
{'visibility': 'off'},
],
),
GoogleMapThemeFeature(
featureType: 'transit',
stylers: [
{'visibility': 'off'},
],
),
],
),
startPosition: const Marker( startPosition: const Marker(
markerId: MarkerId('Start locatie'), markerId: MarkerId('Start locatie'),
position: LatLng(52.356057, 4.897540), position: LatLng(52.356057, 4.897540),
@ -43,15 +59,15 @@ class _TrackTraceDemoState extends State<TrackTraceDemo> {
position: LatLng(52.364709, 4.877157), position: LatLng(52.364709, 4.877157),
), ),
googleAPIKey: 'AIzaSyDaxZX8TeQeVf5tW-D6A66WLl20arbWV6c', googleAPIKey: 'AIzaSyDaxZX8TeQeVf5tW-D6A66WLl20arbWV6c',
travelMode: TravelMode.bicycling, travelMode: TravelMode.walking,
mapType: MapType.satellite, mapType: MapType.normal,
routeUpdateInterval: 60, routeUpdateInterval: 60,
timerPrecision: TimePrecision.everySecond, timerPrecision: TimePrecision.everySecond,
zoomGesturesEnabled: true, zoomGesturesEnabled: true,
line: const Polyline( line: const Polyline(
polylineId: PolylineId('test route'), polylineId: PolylineId('test route'),
color: Colors.purple, color: Color(0xFFFF7884),
width: 5, width: 3,
), ),
onMapCreated: (ctr) => { onMapCreated: (ctr) => {
controller = ctr, controller = ctr,

View file

@ -17,3 +17,4 @@ export 'package:google_maps_flutter/google_maps_flutter.dart'
part 'src/controller.dart'; part 'src/controller.dart';
part 'src/directions_repository.dart'; part 'src/directions_repository.dart';
part 'src/google_map.dart'; part 'src/google_map.dart';
part 'src/google_map_theme.dart';

View file

@ -19,10 +19,9 @@ class GoogleTrackTraceMap extends StatefulWidget {
this.mapToolbarEnabled = false, this.mapToolbarEnabled = false,
this.mapType = MapType.normal, this.mapType = MapType.normal,
this.buildingsEnabled = false, this.buildingsEnabled = false,
this.mapMarkations = this.mapStylingTheme,
'[{"featureType": "poi","stylers": [{"visibility": "off"}]}]',
this.line, this.line,
}) : super(key: key); }) : super(key: key);
/// Callback method for when the map is ready to be used. /// Callback method for when the map is ready to be used.
/// ///
@ -47,8 +46,7 @@ class GoogleTrackTraceMap extends StatefulWidget {
final bool mapToolbarEnabled; final bool mapToolbarEnabled;
final bool buildingsEnabled; final bool buildingsEnabled;
final MapType mapType; final MapType mapType;
final GoogleTrackTraceMapTheme? mapStylingTheme;
final String mapMarkations;
final String googleAPIKey; final String googleAPIKey;
@ -81,36 +79,40 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GoogleMap( return GoogleMap(
initialCameraPosition: calculateCameraPosition( initialCameraPosition: calculateCameraPosition(
controller.start.position, controller.end.position,), controller.start.position,
onMapCreated: _onMapCreated, controller.end.position,
compassEnabled: widget.compassEnabled, ),
zoomControlsEnabled: widget.zoomControlsEnabled, onMapCreated: _onMapCreated,
zoomGesturesEnabled: widget.zoomGesturesEnabled, compassEnabled: widget.compassEnabled,
mapToolbarEnabled: widget.mapToolbarEnabled, zoomControlsEnabled: widget.zoomControlsEnabled,
mapType: widget.mapType, zoomGesturesEnabled: widget.zoomGesturesEnabled,
buildingsEnabled: widget.buildingsEnabled, mapToolbarEnabled: widget.mapToolbarEnabled,
markers: <Marker>{ mapType: widget.mapType,
controller.start, buildingsEnabled: widget.buildingsEnabled,
controller.end, markers: <Marker>{
}, controller.start,
polylines: <Polyline>{ controller.end,
if (controller.route != null) },
(widget.line != null) polylines: <Polyline>{
? widget.line!.copyWith( if (controller.route != null)
pointsParam: controller.route!.line (widget.line != null)
.map((PointLatLng e) => LatLng(e.latitude, e.longitude)) ? widget.line!.copyWith(
.toList(),) pointsParam: controller.route!.line
: Polyline( .map((PointLatLng e) => LatLng(e.latitude, e.longitude))
// default PolyLine if none is provided .toList(),
polylineId: const PolylineId('track&trace route'), )
color: Theme.of(context).primaryColor, : Polyline(
width: 4, // default PolyLine if none is provided
points: controller.route!.line polylineId: const PolylineId('track&trace route'),
.map((PointLatLng e) => LatLng(e.latitude, e.longitude)) color: Theme.of(context).primaryColor,
.toList(), width: 4,
), points: controller.route!.line
},); .map((PointLatLng e) => LatLng(e.latitude, e.longitude))
.toList(),
),
},
);
} }
void _onChange() { void _onChange() {
@ -120,7 +122,14 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
void _onMapCreated(GoogleMapController ctr) { void _onMapCreated(GoogleMapController ctr) {
if (mounted) { if (mounted) {
controller.mapController = ctr; controller.mapController = ctr;
ctr.setMapStyle(widget.mapMarkations); // move to dart json file if (widget.mapStylingTheme != null) {
ctr.setMapStyle(widget.mapStylingTheme!.getJson());
} else {
// No theme provided so switching to default
ctr.setMapStyle(
'[{"featureType": "poi","stylers": [{"visibility": "off"}]}]',
);
}
} }
} }
@ -140,23 +149,24 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
CameraUpdate moveCameraToCenter(LatLng pointA, LatLng pointB) { CameraUpdate moveCameraToCenter(LatLng pointA, LatLng pointB) {
return CameraUpdate.newLatLngBounds( return CameraUpdate.newLatLngBounds(
LatLngBounds( LatLngBounds(
southwest: LatLng( southwest: LatLng(
min(pointA.latitude, pointB.latitude), min(pointA.latitude, pointB.latitude),
min(pointA.longitude, pointB.longitude), min(pointA.longitude, pointB.longitude),
),
northeast: LatLng(
max(pointA.latitude, pointB.latitude),
max(pointA.longitude, pointB.longitude),
),
), ),
50,); northeast: LatLng(
max(pointA.latitude, pointB.latitude),
max(pointA.longitude, pointB.longitude),
),
),
50,
);
} }
void startRouteUpdateTimer() { void startRouteUpdateTimer() {
calculateRoute(); // run at the start calculateRoute(); // run at the start
Timer.periodic(Duration(seconds: widget.routeUpdateInterval), Timer.periodic(Duration(seconds: widget.routeUpdateInterval),
(Timer timer) { (Timer timer) {
calculateRoute(); calculateRoute();
}); });
} }
@ -168,15 +178,16 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
Timer.periodic(Duration(seconds: updateInterval), (timer) { Timer.periodic(Duration(seconds: updateInterval), (timer) {
if (controller.route != null) { if (controller.route != null) {
controller.route = TrackTraceRoute( controller.route = TrackTraceRoute(
controller.route!.duration - updateInterval, controller.route!.duration - updateInterval,
controller.route!.distance, controller.route!.distance,
controller.route!.line,); controller.route!.line,
);
} }
}); });
} }
} }
void calculateRoute(){ void calculateRoute() {
DirectionsRepository() // TODO(freek): refactor this away DirectionsRepository() // TODO(freek): refactor this away
.getDirections( .getDirections(
origin: controller.start.position, origin: controller.start.position,
@ -184,17 +195,26 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
mode: widget.travelMode, mode: widget.travelMode,
key: widget.googleAPIKey, key: widget.googleAPIKey,
) )
.then((value) => { .then(
controller.route = TrackTraceRoute(value.totalDuration, (value) => {
value.totalDistance, value.polylinePoints,), controller.route = TrackTraceRoute(
if (controller.mapController != null) value.totalDuration,
{ value.totalDistance,
controller.mapController!.moveCamera(moveCameraToCenter( value.polylinePoints,
controller.start.position, controller.end.position,),), ),
}, if (controller.mapController != null)
setState(() { {
lastRouteUpdate = DateTime.now(); controller.mapController!.moveCamera(
}) moveCameraToCenter(
},); controller.start.position,
controller.end.position,
),
),
},
setState(() {
lastRouteUpdate = DateTime.now();
})
},
);
} }
} }

View file

@ -0,0 +1,54 @@
part of google_track_trace;
/// Styling object for the Google maps Style
///
/// Contains a List of features with stylers applied to them
/// Full documentation on all the possible style:
/// https://developers.google.com/maps/documentation/javascript/style-reference
/// ```dart
/// GoogleTrackTraceMapTheme(
/// themes: [
/// GoogleMapThemeFeature(
/// featureType: 'poi',
/// stylers: [
/// {'visibility': 'off'},
/// ],
/// ),
/// ],
/// ),
/// ```
class GoogleTrackTraceMapTheme {
GoogleTrackTraceMapTheme({
required this.themes,
});
final List<GoogleMapThemeFeature> themes;
String getJson() {
var sb = StringBuffer('[');
for (var property in themes) {
sb..write(jsonEncode(property.toJson()))
..write(',');
}
sb.write(']');
return sb.toString();
}
}
class GoogleMapThemeFeature {
GoogleMapThemeFeature({
required this.stylers,
this.featureType,
this.elementType,
});
final String? featureType;
final String? elementType;
final List<Map<String, String>> stylers;
Map toJson() {
return {
if(featureType != null) 'featureType': featureType,
if(elementType != null) 'elementType': elementType,
'stylers': stylers,
};
}
}