Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: pre-project polylines, and improve simplification & culling #1805

Merged
merged 9 commits into from
Jan 23, 2024
2 changes: 1 addition & 1 deletion lib/src/layer/polygon_layer/polygon_layer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class _PolygonLayerState extends State<PolygonLayer> {

final projected = _cachedProjectedPolygons ??= List.generate(
widget.polygons.length,
(i) => _ProjectedPolygon.fromPolygon(
(i) => _ProjectedPolygon._fromPolygon(
camera.crs.projection,
widget.polygons[i],
),
Expand Down
2 changes: 1 addition & 1 deletion lib/src/layer/polygon_layer/projected_polygon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class _ProjectedPolygon {
this.holePoints,
});

_ProjectedPolygon.fromPolygon(Projection projection, Polygon polygon)
_ProjectedPolygon._fromPolygon(Projection projection, Polygon polygon)
: this._(
polygon: polygon,
points: List<DoublePoint>.generate(
Expand Down
37 changes: 16 additions & 21 deletions lib/src/layer/polyline_layer/painter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ part of 'polyline_layer.dart';
/// [CustomPainter] for [Polygon]s.
class _PolylinePainter<R extends Object> extends CustomPainter {
/// Reference to the list of [Polyline]s.
final List<Polyline<R>> polylines;
final List<_ProjectedPolyline> polylines;

/// Reference to the [MapCamera].
final MapCamera camera;
Expand All @@ -20,18 +20,6 @@ class _PolylinePainter<R extends Object> extends CustomPainter {
required this.minimumHitbox,
});

List<Offset> getOffsets(Offset origin, List<LatLng> points) => List.generate(
points.length,
(index) => getOffset(origin, points[index]),
growable: false,
);

Offset getOffset(Offset origin, LatLng point) {
// Critically create as little garbage as possible. This is called on every frame.
final projected = camera.project(point);
return Offset(projected.x - origin.dx, projected.y - origin.dy);
}

@override
bool? hitTest(Offset position) {
if (hitNotifier == null) return null;
Expand All @@ -41,8 +29,11 @@ class _PolylinePainter<R extends Object> extends CustomPainter {
final origin =
camera.project(camera.center).toOffset() - camera.size.toOffset() / 2;

for (final polyline in polylines.reversed) {
if (polyline.hitValue == null) continue;
for (final projectedPolyline in polylines.reversed) {
final polyline = projectedPolyline.polyline as Polyline<R>;
if (polyline.hitValue == null) {
continue;
}

// TODO: For efficiency we'd ideally filter by bounding box here. However
// we'd need to compute an extended bounding box that accounts account for
Expand All @@ -51,11 +42,11 @@ class _PolylinePainter<R extends Object> extends CustomPainter {
// continue;
// }

final offsets = getOffsets(origin, polyline.points);
final offsets = getOffsetsXY(camera, origin, projectedPolyline.points);
final strokeWidth = polyline.useStrokeWidthInMeter
? _metersToStrokeWidth(
origin,
polyline.points.first,
_unproject(projectedPolyline.points.first),
offsets.first,
polyline.strokeWidth,
)
Expand Down Expand Up @@ -141,8 +132,9 @@ class _PolylinePainter<R extends Object> extends CustomPainter {
final origin =
camera.project(camera.center).toOffset() - camera.size.toOffset() / 2;

for (final polyline in polylines) {
final offsets = getOffsets(origin, polyline.points);
for (final projectedPolyline in polylines) {
final polyline = projectedPolyline.polyline;
final offsets = getOffsetsXY(camera, origin, projectedPolyline.points);
if (offsets.isEmpty) {
continue;
}
Expand All @@ -159,7 +151,7 @@ class _PolylinePainter<R extends Object> extends CustomPainter {
if (polyline.useStrokeWidthInMeter) {
strokeWidth = _metersToStrokeWidth(
origin,
polyline.points.first,
_unproject(projectedPolyline.points.first),
offsets.first,
polyline.strokeWidth,
);
Expand Down Expand Up @@ -281,10 +273,13 @@ class _PolylinePainter<R extends Object> extends CustomPainter {
double strokeWidthInMeters,
) {
final r = _distance.offset(p0, strokeWidthInMeters, 180);
final delta = o0 - getOffset(origin, r);
final delta = o0 - getOffset(camera, origin, r);
return delta.distance;
}

LatLng _unproject(DoublePoint p0) =>
camera.crs.projection.unprojectXY(p0.x, p0.y);

@override
bool shouldRepaint(_PolylinePainter<R> oldDelegate) => false;
}
Expand Down
15 changes: 0 additions & 15 deletions lib/src/layer/polyline_layer/polyline.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,21 +52,6 @@ class Polyline<R extends Object> {
this.hitValue,
});

Polyline<R> copyWithNewPoints(List<LatLng> points) => Polyline<R>(
points: points,
strokeWidth: strokeWidth,
color: color,
borderStrokeWidth: borderStrokeWidth,
borderColor: borderColor,
gradientColors: gradientColors,
colorsStop: colorsStop,
isDotted: isDotted,
strokeCap: strokeCap,
strokeJoin: strokeJoin,
useStrokeWidthInMeter: useStrokeWidthInMeter,
hitValue: hitValue,
);

@override
bool operator ==(Object other) =>
identical(this, other) ||
Expand Down
Loading
Loading