Skip to content

Commit

Permalink
perf: pre-project polylines, and improve simplification & culling (fl…
Browse files Browse the repository at this point in the history
  • Loading branch information
ignatz committed Jan 23, 2024
1 parent 0f5342f commit 712ee36
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 148 deletions.
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

0 comments on commit 712ee36

Please sign in to comment.