Skip to content

Commit 117f254

Browse files
Fixed CircleMarker's incorrect appearance and size (#1692)
Co-authored-by: JaffaKetchup <github@jaffaketchup.dev>
1 parent 0a08527 commit 117f254

File tree

2 files changed

+78
-38
lines changed

2 files changed

+78
-38
lines changed

example/lib/pages/circle.dart

+15-6
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,21 @@ class CirclePage extends StatelessWidget {
1212
Widget build(BuildContext context) {
1313
final circleMarkers = <CircleMarker>[
1414
CircleMarker(
15-
point: const LatLng(51.5, -0.09),
16-
color: Colors.blue.withOpacity(0.7),
17-
borderStrokeWidth: 2,
18-
useRadiusInMeter: true,
19-
radius: 2000 // 2000 meters | 2 km
20-
),
15+
point: const LatLng(51.5, -0.09),
16+
color: Colors.blue.withOpacity(0.7),
17+
borderColor: Colors.black,
18+
borderStrokeWidth: 2,
19+
useRadiusInMeter: true,
20+
radius: 2000, // 2000 meters
21+
),
22+
CircleMarker(
23+
point: const LatLng(51.4937, -0.6638), // Dorney Lake is ~2km long
24+
color: Colors.green.withOpacity(0.9),
25+
borderColor: Colors.black,
26+
borderStrokeWidth: 2,
27+
useRadiusInMeter: true,
28+
radius: 1000, // 1000 meters
29+
),
2130
];
2231

2332
return Scaffold(

lib/src/layer/circle_layer.dart

+63-32
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,10 @@ class CircleLayer extends StatelessWidget {
3737
Widget build(BuildContext context) {
3838
final map = MapCamera.of(context);
3939
return MobileLayerTransformer(
40-
child: LayoutBuilder(
41-
builder: (context, bc) {
42-
final size = Size(bc.maxWidth, bc.maxHeight);
43-
return CustomPaint(
44-
painter: CirclePainter(circles, map),
45-
size: size,
46-
);
47-
},
40+
child: CustomPaint(
41+
painter: CirclePainter(circles, map),
42+
size: Size(map.size.x, map.size.y),
43+
isComplex: true,
4844
),
4945
);
5046
}
@@ -65,7 +61,8 @@ class CirclePainter extends CustomPainter {
6561

6662
// Let's calculate all the points grouped by color and radius
6763
final points = <Color, Map<double, List<Offset>>>{};
68-
final pointsBorder = <Color, Map<double, List<Offset>>>{};
64+
final pointsFilledBorder = <Color, Map<double, List<Offset>>>{};
65+
final pointsBorder = <Color, Map<double, Map<double, List<Offset>>>>{};
6966
for (final circle in circles) {
7067
final offset = map.getOffsetFromOrigin(circle.point);
7168
double radius = circle.radius;
@@ -79,52 +76,86 @@ class CirclePainter extends CustomPainter {
7976
points[circle.color]![radius]!.add(offset);
8077

8178
if (circle.borderStrokeWidth > 0) {
82-
double radiusBorder = circle.radius + circle.borderStrokeWidth;
83-
if (circle.useRadiusInMeter) {
84-
final rBorder = distance.offset(circle.point, radiusBorder, 180);
85-
final deltaBorder = offset - map.getOffsetFromOrigin(rBorder);
86-
radiusBorder = deltaBorder.distance;
79+
// Check if color have some transparency or not
80+
// As drawPoints is more efficient than drawCircle
81+
if (circle.color.alpha == 0xFF) {
82+
double radiusBorder = circle.radius + circle.borderStrokeWidth;
83+
if (circle.useRadiusInMeter) {
84+
final rBorder = distance.offset(circle.point, radiusBorder, 180);
85+
final deltaBorder = offset - map.getOffsetFromOrigin(rBorder);
86+
radiusBorder = deltaBorder.distance;
87+
}
88+
pointsFilledBorder[circle.borderColor] ??= {};
89+
pointsFilledBorder[circle.borderColor]![radiusBorder] ??= [];
90+
pointsFilledBorder[circle.borderColor]![radiusBorder]!.add(offset);
91+
} else {
92+
double realRadius = circle.radius;
93+
if (circle.useRadiusInMeter) {
94+
final rBorder = distance.offset(circle.point, realRadius, 180);
95+
final deltaBorder = offset - map.getOffsetFromOrigin(rBorder);
96+
realRadius = deltaBorder.distance;
97+
}
98+
pointsBorder[circle.borderColor] ??= {};
99+
pointsBorder[circle.borderColor]![circle.borderStrokeWidth] ??= {};
100+
pointsBorder[circle.borderColor]![circle.borderStrokeWidth]![
101+
realRadius] ??= [];
102+
pointsBorder[circle.borderColor]![circle.borderStrokeWidth]![
103+
realRadius]!
104+
.add(offset);
87105
}
88-
pointsBorder[circle.borderColor] ??= {};
89-
pointsBorder[circle.borderColor]![radiusBorder] ??= [];
90-
pointsBorder[circle.borderColor]![radiusBorder]!.add(offset);
91106
}
92107
}
93108

94109
// Now that all the points are grouped, let's draw them
95-
// First by border in order to be under the circle
110+
final paintBorder = Paint()..style = PaintingStyle.stroke;
96111
for (final color in pointsBorder.keys) {
97-
final paint = Paint()
98-
..strokeCap = StrokeCap.round
99-
..isAntiAlias = false
100-
..color = color;
101-
final pointsByRadius = pointsBorder[color]!;
112+
final paint = paintBorder..color = color;
113+
for (final borderWidth in pointsBorder[color]!.keys) {
114+
final pointsByRadius = pointsBorder[color]![borderWidth]!;
115+
final radiusPaint = paint..strokeWidth = borderWidth;
116+
for (final radius in pointsByRadius.keys) {
117+
final pointsByRadiusColor = pointsByRadius[radius]!;
118+
for (final offset in pointsByRadiusColor) {
119+
_paintCircle(canvas, offset, radius, radiusPaint);
120+
}
121+
}
122+
}
123+
}
124+
125+
// Then the filled border in order to be under the circle
126+
final paintPoint = Paint()
127+
..isAntiAlias = false
128+
..strokeCap = StrokeCap.round;
129+
for (final color in pointsFilledBorder.keys) {
130+
final paint = paintPoint..color = color;
131+
final pointsByRadius = pointsFilledBorder[color]!;
102132
for (final radius in pointsByRadius.keys) {
103133
final pointsByRadiusColor = pointsByRadius[radius]!;
104-
final radiusPaint = paint..strokeWidth = radius;
105-
_paintCircle(canvas, pointsByRadiusColor, radiusPaint);
134+
final radiusPaint = paint..strokeWidth = radius * 2;
135+
_paintPoints(canvas, pointsByRadiusColor, radiusPaint);
106136
}
107137
}
108138

109139
// And then the circle
110140
for (final color in points.keys) {
111-
final paint = Paint()
112-
..isAntiAlias = false
113-
..strokeCap = StrokeCap.round
114-
..color = color;
141+
final paint = paintPoint..color = color;
115142
final pointsByRadius = points[color]!;
116143
for (final radius in pointsByRadius.keys) {
117144
final pointsByRadiusColor = pointsByRadius[radius]!;
118-
final radiusPaint = paint..strokeWidth = radius;
119-
_paintCircle(canvas, pointsByRadiusColor, radiusPaint);
145+
final radiusPaint = paint..strokeWidth = radius * 2;
146+
_paintPoints(canvas, pointsByRadiusColor, radiusPaint);
120147
}
121148
}
122149
}
123150

124-
void _paintCircle(Canvas canvas, List<Offset> offsets, Paint paint) {
151+
void _paintPoints(Canvas canvas, List<Offset> offsets, Paint paint) {
125152
canvas.drawPoints(PointMode.points, offsets, paint);
126153
}
127154

155+
void _paintCircle(Canvas canvas, Offset offset, double radius, Paint paint) {
156+
canvas.drawCircle(offset, radius, paint);
157+
}
158+
128159
@override
129160
bool shouldRepaint(CirclePainter oldDelegate) => false;
130161
}

0 commit comments

Comments
 (0)