update track&trace with bitmaps

This commit is contained in:
Freek van de Ven 2021-10-05 21:09:19 +02:00
parent 38ac7476a5
commit 0f5eb37d1f
11 changed files with 238 additions and 19 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

View file

@ -1,7 +1,9 @@
import 'dart:async';
import 'dart:math';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:google_track_trace/google_track_trace.dart';
class TrackTraceDemo extends StatefulWidget {
@ -16,9 +18,12 @@ class _TrackTraceDemoState extends State<TrackTraceDemo> {
int step = 1;
int routeLength = 0;
late final Timer timer;
BitmapDescriptor? startMarkerIcon;
BitmapDescriptor? destinationMarkerIcon;
@override
void initState() {
loadBitmapImages();
timer = Timer.periodic(const Duration(seconds: 2), (_) {
moveAlongRoute();
});
@ -39,43 +44,56 @@ class _TrackTraceDemoState extends State<TrackTraceDemo> {
body: GoogleTrackTraceMap(
mapStylingTheme: GoogleTrackTraceMapTheme(
themes: [
GoogleMapThemeFeature(
featureType: 'all',
stylers: [
{'saturation': '-50'},
//{'invert_lightness': 'true'},
],
),
GoogleMapThemeFeature(
featureType: 'landscape.natural.landcover',
stylers: [
{'color': '#00ff00'},
],
),
GoogleMapThemeFeature(
featureType: 'poi',
stylers: [
{'visibility': 'off'},
],
),
GoogleMapThemeFeature(
featureType: 'poi.park',
stylers: [
{'visibility': 'on'},
],
),
GoogleMapThemeFeature(
featureType: 'transit',
stylers: [
{'visibility': 'off'},
],
),
// GoogleMapThemeFeature(
// featureType: 'water',
// stylers: [
// {'color': '#00ff00'}
// ],
// ),
// GoogleMapThemeFeature(
// featureType: 'road',
// stylers: [
// {'color': '#000000'}
// ],
// )
],
),
startPosition: const Marker(
startPosition: Marker(
markerId: MarkerId('Start locatie'),
anchor: Offset(0.5, 0.5),
position: LatLng(52.356057, 4.897540),
icon: startMarkerIcon ?? BitmapDescriptor.defaultMarker,
),
destinationPosition: const Marker(
destinationPosition: Marker(
markerId: MarkerId('Bestemming Locatie'),
anchor: Offset(0.5, 0.5),
position: LatLng(52.364709, 4.877157),
icon: destinationMarkerIcon ?? BitmapDescriptor.defaultMarker,
),
buildingsEnabled: false,
googleAPIKey: 'AIzaSyDaxZX8TeQeVf5tW-D6A66WLl20arbWV6c',
travelMode: TravelMode.walking,
mapType: MapType.normal,
indoorViewEnabled: false,
routeUpdateInterval: Duration(seconds: 30),
timerPrecision: TimePrecision.everySecond,
zoomGesturesEnabled: true,
@ -113,6 +131,35 @@ class _TrackTraceDemoState extends State<TrackTraceDemo> {
);
}
void loadBitmapImages() {
rootBundle.load('assets/profile_picture.png').then((value) {
convertBytesToCustomBitmapDescriptor(
value.buffer.asUint8List(),
size: 80,
addBorder: true,
borderColor: Colors.grey,
title: 'Alex',
titleBackgroundColor: Color(0xffff7884),
).then((bitmap) {
startMarkerIcon = bitmap;
BitmapDescriptor.fromAssetImage(
ImageConfiguration(size: Size(100, 100)),
'assets/ic_location_on.png',
).then((value) {
setState(() {
destinationMarkerIcon = value;
controller?.end = Marker(
anchor: Offset(0.5, 0.5),
markerId: MarkerId('Bestemming Locatie'),
position: LatLng(52.364709, 4.877157),
icon: value,
);
});
});
});
});
}
void getRandomPointOnMap() {
// 51.989909, 6.234950 NW
// 51.939909, 6.314950 SE
@ -133,10 +180,12 @@ class _TrackTraceDemoState extends State<TrackTraceDemo> {
controller!.route!.line.length > 1) {
controller!.start = Marker(
markerId: const MarkerId('Start Locatie'),
anchor: Offset(0.5, 0.5),
position: LatLng(
controller!.route!.line[step].latitude,
controller!.route!.line[step].longitude,
),
icon: startMarkerIcon ?? BitmapDescriptor.defaultMarker,
);
step++;
routeLength = controller!.route!.distance;

View file

@ -134,7 +134,7 @@ packages:
path: ".."
relative: true
source: path
version: "1.0.0"
version: "1.0.1"
html:
dependency: transitive
description:

View file

@ -60,7 +60,8 @@ flutter:
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
assets:
- assets/
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg

View file

@ -4,9 +4,12 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_polyline_points/flutter_polyline_points.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:http/http.dart' as http;
@ -22,8 +25,8 @@ export 'package:google_maps_flutter/google_maps_flutter.dart'
PolylineId,
JointType,
LatLng;
part 'src/controller.dart';
part 'src/directions_repository.dart';
part 'src/google_map.dart';
part 'src/google_map_theme.dart';
part 'src/marker_generator.dart';

View file

@ -163,7 +163,10 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
if (mounted) {
controller.mapController = ctr;
if (widget.mapStylingTheme != null) {
ctr.setMapStyle(widget.mapStylingTheme!.getJson());
ctr.setMapStyle(widget.mapStylingTheme!.getJson()).onError(
(error, stackTrace) =>
throw GoogleMapsException(error.toString()),
);
} else {
// No theme provided so switching to default
ctr.setMapStyle(

View file

@ -52,3 +52,7 @@ class GoogleMapThemeFeature {
};
}
}
enum GoogleMapThemeFeatureType {
featureAll,
}

View file

@ -0,0 +1,159 @@
part of google_track_trace;
Future<BitmapDescriptor> convertBytesToCustomBitmapDescriptor(
Uint8List image, {
int size = 150,
bool addBorder = false,
Color borderColor = Colors.white,
double borderSize = 10,
String? title,
Color titleColor = Colors.white,
Color titleBackgroundColor = Colors.black,
}) async {
var pictureRecorder = ui.PictureRecorder();
var canvas = Canvas(pictureRecorder);
var paint = Paint()..color;
var textPainter = TextPainter(
textDirection: TextDirection.ltr,
);
var radius = size / 2;
//make canvas clip path to prevent image drawing over the circle
var clipPath = Path()
..addRRect(
RRect.fromRectAndRadius(
Rect.fromLTWH(0, 0, size.toDouble(), size.toDouble()),
Radius.circular(100),
),
)
..addRRect(
RRect.fromRectAndRadius(
Rect.fromLTWH(0, size * 8 / 10, size.toDouble(), size * 3 / 10),
Radius.circular(100),
),
);
canvas.clipPath(clipPath);
//paintImage
var imageUint8List = image;
var codec = await ui.instantiateImageCodec(imageUint8List);
var imageFI = await codec.getNextFrame();
paintImage(
canvas: canvas,
rect: Rect.fromLTWH(0, 0, size.toDouble(), size.toDouble()),
image: imageFI.image,
);
if (addBorder) {
//draw Border
paint
..color = borderColor
..style = PaintingStyle.stroke
..strokeWidth = borderSize;
canvas.drawCircle(Offset(radius, radius), radius, paint);
}
if (title != null) {
var displayedTitle = '';
if (title.length > 9) {
displayedTitle = title.substring(0, 9);
} else {
displayedTitle = title;
}
//draw Title background
paint
..color = titleBackgroundColor
..style = PaintingStyle.fill;
canvas.drawRRect(
RRect.fromRectAndRadius(
Rect.fromLTWH(0, size * 8 / 10, size.toDouble(), size * 3 / 10),
Radius.circular(100),
),
paint,
);
//draw Title
textPainter
..text = TextSpan(
text: displayedTitle,
style: TextStyle(
fontSize: radius / 2.5,
fontWeight: FontWeight.bold,
color: titleColor,
),
)
..layout()
..paint(
canvas,
Offset(
radius - textPainter.width / 2,
size * 9.5 / 10 - textPainter.height / 2,
),
);
}
//convert canvas as PNG bytes
var _image =
await pictureRecorder.endRecording().toImage(size, (size * 1.1).toInt());
var data = await _image.toByteData(format: ui.ImageByteFormat.png);
//convert PNG bytes as BitmapDescriptor
return BitmapDescriptor.fromBytes(data!.buffer.asUint8List());
}
/// https://medium.com/@JBXBergDev/how-to-use-googlemap-markers-with-flutter-material-icons-38c4c975e928
Future<BitmapDescriptor> createBitmapDescriptorFromIconData(
IconData iconData,
double markerSize,
Color iconColor,
Color circleColor,
Color backgroundColor,
) async {
var pictureRecorder = ui.PictureRecorder();
//var canvas = Canvas(pictureRecorder);
//_paintCircleFill(canvas, backgroundColor);
//_paintCircleStroke(canvas, circleColor);
//_paintIcon(canvas, iconColor, iconData);
var picture = pictureRecorder.endRecording();
var image = await picture.toImage(markerSize.round(), markerSize.round());
var bytes = await image.toByteData(format: ui.ImageByteFormat.png);
return BitmapDescriptor.fromBytes(bytes!.buffer.asUint8List());
}
/// Paints the icon background
// void _paintCircleFill(Canvas canvas, Color color) {
// final paint = Paint()
// ..style = PaintingStyle.fill
// ..color = color;
// canvas.drawCircle(Offset(_circleOffset, _circleOffset),
//_fillCircleWidth, paint);
// }
// /// Paints a circle around the icon
// void _paintCircleStroke(Canvas canvas, Color color) {
// final paint = Paint()
// ..style = PaintingStyle.stroke
// ..color = color
// ..strokeWidth = _circleStrokeWidth;
// canvas.drawCircle(Offset(_circleOffset, _circleOffset),
//_outlineCircleWidth, paint);
// }
// /// Paints the icon
// void _paintIcon(Canvas canvas, Color color, IconData iconData) {
// final textPainter = TextPainter(textDirection: TextDirection.ltr);
// textPainter.text = TextSpan(
// text: String.fromCharCode(iconData.codePoint),
// style: TextStyle(
// letterSpacing: 0.0,
// fontSize: _iconSize,
// fontFamily: iconData.fontFamily,
// color: color,
// )
// );
// textPainter.layout();
// textPainter.paint(canvas, Offset(_iconOffset, _iconOffset));
// }

View file

@ -1,6 +1,6 @@
name: google_track_trace
description: An Iconica Flutter pluginin for Track & Trace Package
version: 1.0.0
version: 1.0.1
environment:
sdk: ">=2.14.0 <3.0.0"