mirror of
https://github.com/Iconica-Development/flutter_google_track_and_trace.git
synced 2025-05-19 05:03:45 +02:00
update track&trace with bitmaps
This commit is contained in:
parent
38ac7476a5
commit
0f5eb37d1f
11 changed files with 238 additions and 19 deletions
BIN
example/assets/ic_custom_marker.png
Normal file
BIN
example/assets/ic_custom_marker.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
BIN
example/assets/ic_location_on.png
Normal file
BIN
example/assets/ic_location_on.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
example/assets/profile_picture.png
Normal file
BIN
example/assets/profile_picture.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 300 KiB |
|
@ -1,7 +1,9 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart' show rootBundle;
|
||||||
import 'package:google_track_trace/google_track_trace.dart';
|
import 'package:google_track_trace/google_track_trace.dart';
|
||||||
|
|
||||||
class TrackTraceDemo extends StatefulWidget {
|
class TrackTraceDemo extends StatefulWidget {
|
||||||
|
@ -16,9 +18,12 @@ class _TrackTraceDemoState extends State<TrackTraceDemo> {
|
||||||
int step = 1;
|
int step = 1;
|
||||||
int routeLength = 0;
|
int routeLength = 0;
|
||||||
late final Timer timer;
|
late final Timer timer;
|
||||||
|
BitmapDescriptor? startMarkerIcon;
|
||||||
|
BitmapDescriptor? destinationMarkerIcon;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
loadBitmapImages();
|
||||||
timer = Timer.periodic(const Duration(seconds: 2), (_) {
|
timer = Timer.periodic(const Duration(seconds: 2), (_) {
|
||||||
moveAlongRoute();
|
moveAlongRoute();
|
||||||
});
|
});
|
||||||
|
@ -39,43 +44,56 @@ class _TrackTraceDemoState extends State<TrackTraceDemo> {
|
||||||
body: GoogleTrackTraceMap(
|
body: GoogleTrackTraceMap(
|
||||||
mapStylingTheme: GoogleTrackTraceMapTheme(
|
mapStylingTheme: GoogleTrackTraceMapTheme(
|
||||||
themes: [
|
themes: [
|
||||||
|
GoogleMapThemeFeature(
|
||||||
|
featureType: 'all',
|
||||||
|
stylers: [
|
||||||
|
{'saturation': '-50'},
|
||||||
|
//{'invert_lightness': 'true'},
|
||||||
|
],
|
||||||
|
),
|
||||||
|
GoogleMapThemeFeature(
|
||||||
|
featureType: 'landscape.natural.landcover',
|
||||||
|
stylers: [
|
||||||
|
{'color': '#00ff00'},
|
||||||
|
],
|
||||||
|
),
|
||||||
GoogleMapThemeFeature(
|
GoogleMapThemeFeature(
|
||||||
featureType: 'poi',
|
featureType: 'poi',
|
||||||
stylers: [
|
stylers: [
|
||||||
{'visibility': 'off'},
|
{'visibility': 'off'},
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
GoogleMapThemeFeature(
|
||||||
|
featureType: 'poi.park',
|
||||||
|
stylers: [
|
||||||
|
{'visibility': 'on'},
|
||||||
|
],
|
||||||
|
),
|
||||||
GoogleMapThemeFeature(
|
GoogleMapThemeFeature(
|
||||||
featureType: 'transit',
|
featureType: 'transit',
|
||||||
stylers: [
|
stylers: [
|
||||||
{'visibility': 'off'},
|
{'visibility': 'off'},
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
// GoogleMapThemeFeature(
|
|
||||||
// featureType: 'water',
|
|
||||||
// stylers: [
|
|
||||||
// {'color': '#00ff00'}
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// GoogleMapThemeFeature(
|
|
||||||
// featureType: 'road',
|
|
||||||
// stylers: [
|
|
||||||
// {'color': '#000000'}
|
|
||||||
// ],
|
|
||||||
// )
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
startPosition: const Marker(
|
startPosition: Marker(
|
||||||
markerId: MarkerId('Start locatie'),
|
markerId: MarkerId('Start locatie'),
|
||||||
|
anchor: Offset(0.5, 0.5),
|
||||||
position: LatLng(52.356057, 4.897540),
|
position: LatLng(52.356057, 4.897540),
|
||||||
|
icon: startMarkerIcon ?? BitmapDescriptor.defaultMarker,
|
||||||
),
|
),
|
||||||
destinationPosition: const Marker(
|
destinationPosition: Marker(
|
||||||
markerId: MarkerId('Bestemming Locatie'),
|
markerId: MarkerId('Bestemming Locatie'),
|
||||||
|
anchor: Offset(0.5, 0.5),
|
||||||
position: LatLng(52.364709, 4.877157),
|
position: LatLng(52.364709, 4.877157),
|
||||||
|
icon: destinationMarkerIcon ?? BitmapDescriptor.defaultMarker,
|
||||||
),
|
),
|
||||||
|
buildingsEnabled: false,
|
||||||
googleAPIKey: 'AIzaSyDaxZX8TeQeVf5tW-D6A66WLl20arbWV6c',
|
googleAPIKey: 'AIzaSyDaxZX8TeQeVf5tW-D6A66WLl20arbWV6c',
|
||||||
travelMode: TravelMode.walking,
|
travelMode: TravelMode.walking,
|
||||||
mapType: MapType.normal,
|
mapType: MapType.normal,
|
||||||
|
indoorViewEnabled: false,
|
||||||
routeUpdateInterval: Duration(seconds: 30),
|
routeUpdateInterval: Duration(seconds: 30),
|
||||||
timerPrecision: TimePrecision.everySecond,
|
timerPrecision: TimePrecision.everySecond,
|
||||||
zoomGesturesEnabled: true,
|
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() {
|
void getRandomPointOnMap() {
|
||||||
// 51.989909, 6.234950 NW
|
// 51.989909, 6.234950 NW
|
||||||
// 51.939909, 6.314950 SE
|
// 51.939909, 6.314950 SE
|
||||||
|
@ -133,10 +180,12 @@ class _TrackTraceDemoState extends State<TrackTraceDemo> {
|
||||||
controller!.route!.line.length > 1) {
|
controller!.route!.line.length > 1) {
|
||||||
controller!.start = Marker(
|
controller!.start = Marker(
|
||||||
markerId: const MarkerId('Start Locatie'),
|
markerId: const MarkerId('Start Locatie'),
|
||||||
|
anchor: Offset(0.5, 0.5),
|
||||||
position: LatLng(
|
position: LatLng(
|
||||||
controller!.route!.line[step].latitude,
|
controller!.route!.line[step].latitude,
|
||||||
controller!.route!.line[step].longitude,
|
controller!.route!.line[step].longitude,
|
||||||
),
|
),
|
||||||
|
icon: startMarkerIcon ?? BitmapDescriptor.defaultMarker,
|
||||||
);
|
);
|
||||||
step++;
|
step++;
|
||||||
routeLength = controller!.route!.distance;
|
routeLength = controller!.route!.distance;
|
||||||
|
|
|
@ -134,7 +134,7 @@ packages:
|
||||||
path: ".."
|
path: ".."
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "1.0.0"
|
version: "1.0.1"
|
||||||
html:
|
html:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -60,7 +60,8 @@ flutter:
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
|
|
||||||
# To add assets to your application, add an assets section, like this:
|
# To add assets to your application, add an assets section, like this:
|
||||||
# assets:
|
assets:
|
||||||
|
- assets/
|
||||||
# - images/a_dot_burr.jpeg
|
# - images/a_dot_burr.jpeg
|
||||||
# - images/a_dot_ham.jpeg
|
# - images/a_dot_ham.jpeg
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,12 @@ import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
import 'dart:ui' as ui;
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/rendering.dart';
|
||||||
import 'package:flutter_polyline_points/flutter_polyline_points.dart';
|
import 'package:flutter_polyline_points/flutter_polyline_points.dart';
|
||||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
@ -22,8 +25,8 @@ export 'package:google_maps_flutter/google_maps_flutter.dart'
|
||||||
PolylineId,
|
PolylineId,
|
||||||
JointType,
|
JointType,
|
||||||
LatLng;
|
LatLng;
|
||||||
|
|
||||||
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';
|
part 'src/google_map_theme.dart';
|
||||||
|
part 'src/marker_generator.dart';
|
||||||
|
|
|
@ -163,7 +163,10 @@ class _GoogleTrackTraceMapState extends State<GoogleTrackTraceMap> {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
controller.mapController = ctr;
|
controller.mapController = ctr;
|
||||||
if (widget.mapStylingTheme != null) {
|
if (widget.mapStylingTheme != null) {
|
||||||
ctr.setMapStyle(widget.mapStylingTheme!.getJson());
|
ctr.setMapStyle(widget.mapStylingTheme!.getJson()).onError(
|
||||||
|
(error, stackTrace) =>
|
||||||
|
throw GoogleMapsException(error.toString()),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// No theme provided so switching to default
|
// No theme provided so switching to default
|
||||||
ctr.setMapStyle(
|
ctr.setMapStyle(
|
||||||
|
|
|
@ -52,3 +52,7 @@ class GoogleMapThemeFeature {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum GoogleMapThemeFeatureType {
|
||||||
|
featureAll,
|
||||||
|
}
|
||||||
|
|
159
lib/src/marker_generator.dart
Normal file
159
lib/src/marker_generator.dart
Normal 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));
|
||||||
|
// }
|
|
@ -1,6 +1,6 @@
|
||||||
name: google_track_trace
|
name: google_track_trace
|
||||||
description: An Iconica Flutter pluginin for Track & Trace Package
|
description: An Iconica Flutter pluginin for Track & Trace Package
|
||||||
version: 1.0.0
|
version: 1.0.1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.14.0 <3.0.0"
|
sdk: ">=2.14.0 <3.0.0"
|
||||||
|
|
Loading…
Reference in a new issue