From bcc20a911e4368de28c24ee2a103b2be488a3c83 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 18 Oct 2023 15:47:49 +0200 Subject: [PATCH 1/6] fix: radius and opacity --- lib/src/layer/circle_layer.dart | 71 +++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 16 deletions(-) diff --git a/lib/src/layer/circle_layer.dart b/lib/src/layer/circle_layer.dart index e8b3e9330..1308c3334 100644 --- a/lib/src/layer/circle_layer.dart +++ b/lib/src/layer/circle_layer.dart @@ -65,7 +65,8 @@ class CirclePainter extends CustomPainter { // Let's calculate all the points grouped by color and radius final points = >>{}; - final pointsBorder = >>{}; + final pointsFilledBorder = >>{}; + final pointsBorder = >>>{}; for (final circle in circles) { final offset = map.getOffsetFromOrigin(circle.point); double radius = circle.radius; @@ -79,30 +80,64 @@ class CirclePainter extends CustomPainter { points[circle.color]![radius]!.add(offset); if (circle.borderStrokeWidth > 0) { - double radiusBorder = circle.radius + circle.borderStrokeWidth; - if (circle.useRadiusInMeter) { - final rBorder = distance.offset(circle.point, radiusBorder, 180); - final deltaBorder = offset - map.getOffsetFromOrigin(rBorder); - radiusBorder = deltaBorder.distance; + // Check if color have some transparency or not + // As drawPoints is more efficient than drawCircle + if (circle.color.alpha == 0xFF) { + double radiusBorder = circle.radius + circle.borderStrokeWidth; + if (circle.useRadiusInMeter) { + final rBorder = distance.offset(circle.point, radiusBorder, 180); + final deltaBorder = offset - map.getOffsetFromOrigin(rBorder); + radiusBorder = deltaBorder.distance; + } + pointsFilledBorder[circle.borderColor] ??= {}; + pointsFilledBorder[circle.borderColor]![radiusBorder] ??= []; + pointsFilledBorder[circle.borderColor]![radiusBorder]!.add(offset); + } else { + double realRadius = circle.radius; + if (circle.useRadiusInMeter) { + final rBorder = distance.offset(circle.point, realRadius, 180); + final deltaBorder = offset - map.getOffsetFromOrigin(rBorder); + realRadius = deltaBorder.distance; + } + pointsBorder[circle.borderColor] ??= {}; + pointsBorder[circle.borderColor]![circle.borderStrokeWidth] ??= {}; + pointsBorder[circle.borderColor]![circle.borderStrokeWidth]![ + realRadius] ??= []; + pointsBorder[circle.borderColor]![circle.borderStrokeWidth]![ + realRadius]! + .add(offset); } - pointsBorder[circle.borderColor] ??= {}; - pointsBorder[circle.borderColor]![radiusBorder] ??= []; - pointsBorder[circle.borderColor]![radiusBorder]!.add(offset); } } // Now that all the points are grouped, let's draw them - // First by border in order to be under the circle for (final color in pointsBorder.keys) { + final paint = Paint() + ..style = PaintingStyle.stroke + ..color = color; + for (final borderWidth in pointsBorder[color]!.keys) { + final pointsByRadius = pointsBorder[color]![borderWidth]!; + final radiusPaint = paint..strokeWidth = borderWidth; + for (final radius in pointsByRadius.keys) { + final pointsByRadiusColor = pointsByRadius[radius]!; + for (final offset in pointsByRadiusColor) { + _paintCircle(canvas, offset, radius, radiusPaint); + } + } + } + } + + // Then the filled border in order to be under the circle + for (final color in pointsFilledBorder.keys) { final paint = Paint() ..strokeCap = StrokeCap.round ..isAntiAlias = false ..color = color; - final pointsByRadius = pointsBorder[color]!; + final pointsByRadius = pointsFilledBorder[color]!; for (final radius in pointsByRadius.keys) { final pointsByRadiusColor = pointsByRadius[radius]!; - final radiusPaint = paint..strokeWidth = radius; - _paintCircle(canvas, pointsByRadiusColor, radiusPaint); + final radiusPaint = paint..strokeWidth = radius * 2; + _paintPoints(canvas, pointsByRadiusColor, radiusPaint); } } @@ -115,16 +150,20 @@ class CirclePainter extends CustomPainter { final pointsByRadius = points[color]!; for (final radius in pointsByRadius.keys) { final pointsByRadiusColor = pointsByRadius[radius]!; - final radiusPaint = paint..strokeWidth = radius; - _paintCircle(canvas, pointsByRadiusColor, radiusPaint); + final radiusPaint = paint..strokeWidth = radius * 2; + _paintPoints(canvas, pointsByRadiusColor, radiusPaint); } } } - void _paintCircle(Canvas canvas, List offsets, Paint paint) { + void _paintPoints(Canvas canvas, List offsets, Paint paint) { canvas.drawPoints(PointMode.points, offsets, paint); } + void _paintCircle(Canvas canvas, Offset offset, double radius, Paint paint) { + canvas.drawCircle(offset, radius, paint); + } + @override bool shouldRepaint(CirclePainter oldDelegate) => false; } From 928ce4dc5a683bcc61f9d66c9eaad69a6d40ea08 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 18 Oct 2023 16:47:18 +0200 Subject: [PATCH 2/6] fix: avoid useless LayoutBuilder --- lib/src/layer/circle_layer.dart | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/lib/src/layer/circle_layer.dart b/lib/src/layer/circle_layer.dart index 1308c3334..cd3ca1574 100644 --- a/lib/src/layer/circle_layer.dart +++ b/lib/src/layer/circle_layer.dart @@ -37,14 +37,10 @@ class CircleLayer extends StatelessWidget { Widget build(BuildContext context) { final map = MapCamera.of(context); return MobileLayerTransformer( - child: LayoutBuilder( - builder: (context, bc) { - final size = Size(bc.maxWidth, bc.maxHeight); - return CustomPaint( - painter: CirclePainter(circles, map), - size: size, - ); - }, + child: CustomPaint( + painter: CirclePainter(circles, map), + size: Size(map.size.x, map.size.y), + isComplex: true, ), ); } @@ -101,11 +97,8 @@ class CirclePainter extends CustomPainter { } pointsBorder[circle.borderColor] ??= {}; pointsBorder[circle.borderColor]![circle.borderStrokeWidth] ??= {}; - pointsBorder[circle.borderColor]![circle.borderStrokeWidth]![ - realRadius] ??= []; - pointsBorder[circle.borderColor]![circle.borderStrokeWidth]![ - realRadius]! - .add(offset); + pointsBorder[circle.borderColor]![circle.borderStrokeWidth]![realRadius] ??= []; + pointsBorder[circle.borderColor]![circle.borderStrokeWidth]![realRadius]!.add(offset); } } } From 48eded297923a23248d5ab17262b8ae0eb651ef3 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 18 Oct 2023 16:55:44 +0200 Subject: [PATCH 3/6] refactor: allocate paint once per types --- lib/src/layer/circle_layer.dart | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/lib/src/layer/circle_layer.dart b/lib/src/layer/circle_layer.dart index cd3ca1574..79d7966f4 100644 --- a/lib/src/layer/circle_layer.dart +++ b/lib/src/layer/circle_layer.dart @@ -104,10 +104,9 @@ class CirclePainter extends CustomPainter { } // Now that all the points are grouped, let's draw them + final paintBorder = Paint()..style = PaintingStyle.stroke; for (final color in pointsBorder.keys) { - final paint = Paint() - ..style = PaintingStyle.stroke - ..color = color; + final paint = paintBorder..color = color; for (final borderWidth in pointsBorder[color]!.keys) { final pointsByRadius = pointsBorder[color]![borderWidth]!; final radiusPaint = paint..strokeWidth = borderWidth; @@ -121,11 +120,9 @@ class CirclePainter extends CustomPainter { } // Then the filled border in order to be under the circle + final paintPoint = Paint()..isAntiAlias = false; for (final color in pointsFilledBorder.keys) { - final paint = Paint() - ..strokeCap = StrokeCap.round - ..isAntiAlias = false - ..color = color; + final paint = paintPoint..color = color; final pointsByRadius = pointsFilledBorder[color]!; for (final radius in pointsByRadius.keys) { final pointsByRadiusColor = pointsByRadius[radius]!; @@ -136,10 +133,7 @@ class CirclePainter extends CustomPainter { // And then the circle for (final color in points.keys) { - final paint = Paint() - ..isAntiAlias = false - ..strokeCap = StrokeCap.round - ..color = color; + final paint = paintPoint..color = color; final pointsByRadius = points[color]!; for (final radius in pointsByRadius.keys) { final pointsByRadiusColor = pointsByRadius[radius]!; From 697e96758a37fff94441ce2e8595cdfeff71b165 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 18 Oct 2023 22:24:44 +0200 Subject: [PATCH 4/6] fix: rounded circle --- lib/src/layer/circle_layer.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/src/layer/circle_layer.dart b/lib/src/layer/circle_layer.dart index 79d7966f4..57474d2cf 100644 --- a/lib/src/layer/circle_layer.dart +++ b/lib/src/layer/circle_layer.dart @@ -120,7 +120,9 @@ class CirclePainter extends CustomPainter { } // Then the filled border in order to be under the circle - final paintPoint = Paint()..isAntiAlias = false; + final paintPoint = Paint() + ..isAntiAlias = false + ..strokeCap = StrokeCap.round; for (final color in pointsFilledBorder.keys) { final paint = paintPoint..color = color; final pointsByRadius = pointsFilledBorder[color]!; From a6030c430a936ecc2d613d00f07b966d76f900af Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 18 Oct 2023 22:30:26 +0200 Subject: [PATCH 5/6] fix: lint --- lib/src/layer/circle_layer.dart | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/src/layer/circle_layer.dart b/lib/src/layer/circle_layer.dart index 57474d2cf..6c5fba047 100644 --- a/lib/src/layer/circle_layer.dart +++ b/lib/src/layer/circle_layer.dart @@ -97,8 +97,11 @@ class CirclePainter extends CustomPainter { } pointsBorder[circle.borderColor] ??= {}; pointsBorder[circle.borderColor]![circle.borderStrokeWidth] ??= {}; - pointsBorder[circle.borderColor]![circle.borderStrokeWidth]![realRadius] ??= []; - pointsBorder[circle.borderColor]![circle.borderStrokeWidth]![realRadius]!.add(offset); + pointsBorder[circle.borderColor]![circle.borderStrokeWidth]![ + realRadius] ??= []; + pointsBorder[circle.borderColor]![circle.borderStrokeWidth]![ + realRadius]! + .add(offset); } } } From 97dc61ba68fd5de2bcf1f32a5d40b87784020c85 Mon Sep 17 00:00:00 2001 From: JaffaKetchup Date: Wed, 18 Oct 2023 22:12:09 +0100 Subject: [PATCH 6/6] feat(example>circles): added additional marker to Dorney Lake (useful measuring/testing device) --- example/lib/pages/circle.dart | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/example/lib/pages/circle.dart b/example/lib/pages/circle.dart index bfd7bac1d..d818fac9b 100644 --- a/example/lib/pages/circle.dart +++ b/example/lib/pages/circle.dart @@ -12,12 +12,21 @@ class CirclePage extends StatelessWidget { Widget build(BuildContext context) { final circleMarkers = [ CircleMarker( - point: const LatLng(51.5, -0.09), - color: Colors.blue.withOpacity(0.7), - borderStrokeWidth: 2, - useRadiusInMeter: true, - radius: 2000 // 2000 meters | 2 km - ), + point: const LatLng(51.5, -0.09), + color: Colors.blue.withOpacity(0.7), + borderColor: Colors.black, + borderStrokeWidth: 2, + useRadiusInMeter: true, + radius: 2000, // 2000 meters + ), + CircleMarker( + point: const LatLng(51.4937, -0.6638), // Dorney Lake is ~2km long + color: Colors.green.withOpacity(0.9), + borderColor: Colors.black, + borderStrokeWidth: 2, + useRadiusInMeter: true, + radius: 1000, // 1000 meters + ), ]; return Scaffold(