Skip to content

Commit

Permalink
Merge branch 'master' into fix/#1684_initial-camera-fit
Browse files Browse the repository at this point in the history
  • Loading branch information
JaffaKetchup committed Oct 23, 2023
2 parents a1c493a + d9c9210 commit 63ee1db
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 38 deletions.
21 changes: 15 additions & 6 deletions example/lib/pages/circle.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,21 @@ class CirclePage extends StatelessWidget {
Widget build(BuildContext context) {
final circleMarkers = <CircleMarker>[
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(
Expand Down
2 changes: 2 additions & 0 deletions lib/flutter_map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ library flutter_map;
export 'package:flutter_map/src/geo/crs.dart';
export 'package:flutter_map/src/geo/latlng_bounds.dart';
export 'package:flutter_map/src/gestures/interactive_flag.dart';
export 'package:flutter_map/src/gestures/latlng_tween.dart';
export 'package:flutter_map/src/gestures/map_events.dart';
export 'package:flutter_map/src/gestures/multi_finger_gesture.dart';
export 'package:flutter_map/src/gestures/positioned_tap_detector_2.dart';
export 'package:flutter_map/src/layer/attribution_layer/rich/animation.dart';
export 'package:flutter_map/src/layer/attribution_layer/rich/source.dart';
export 'package:flutter_map/src/layer/attribution_layer/rich/widget.dart';
Expand Down
95 changes: 63 additions & 32 deletions lib/src/layer/circle_layer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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,
),
);
}
Expand All @@ -65,7 +61,8 @@ class CirclePainter extends CustomPainter {

// Let's calculate all the points grouped by color and radius
final points = <Color, Map<double, List<Offset>>>{};
final pointsBorder = <Color, Map<double, List<Offset>>>{};
final pointsFilledBorder = <Color, Map<double, List<Offset>>>{};
final pointsBorder = <Color, Map<double, Map<double, List<Offset>>>>{};
for (final circle in circles) {
final offset = map.getOffsetFromOrigin(circle.point);
double radius = circle.radius;
Expand All @@ -79,52 +76,86 @@ 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
final paintBorder = Paint()..style = PaintingStyle.stroke;
for (final color in pointsBorder.keys) {
final paint = Paint()
..strokeCap = StrokeCap.round
..isAntiAlias = false
..color = color;
final pointsByRadius = pointsBorder[color]!;
final paint = paintBorder..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
final paintPoint = Paint()
..isAntiAlias = false
..strokeCap = StrokeCap.round;
for (final color in pointsFilledBorder.keys) {
final paint = paintPoint..color = 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);
}
}

// 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]!;
final radiusPaint = paint..strokeWidth = radius;
_paintCircle(canvas, pointsByRadiusColor, radiusPaint);
final radiusPaint = paint..strokeWidth = radius * 2;
_paintPoints(canvas, pointsByRadiusColor, radiusPaint);
}
}
}

void _paintCircle(Canvas canvas, List<Offset> offsets, Paint paint) {
void _paintPoints(Canvas canvas, List<Offset> 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;
}

0 comments on commit 63ee1db

Please sign in to comment.