Skip to content

Commit

Permalink
Interpret tolerance as pixel tolerance.
Browse files Browse the repository at this point in the history
  • Loading branch information
ignatz committed Jan 17, 2024
1 parent 1990204 commit 4e9ede3
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 52 deletions.
87 changes: 44 additions & 43 deletions lib/src/layer/polygon_layer/polygon_layer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,12 @@ class PolygonLayer extends StatefulWidget {
/// Defaults to `true`.
final bool polygonCulling;

/// Distance between two mergeable polygon points, in decimal degrees scaled
/// to floored zoom
/// Distance between two neighboring polygon points, in logical pixels scaled
/// to floored zoom.
///
/// Increasing results in a more jagged, less accurate simplification, with
/// improved performance; and vice versa.
///
/// Note that this value is internally scaled using the current map zoom, to
/// optimize visual performance in conjunction with improved performance with
/// culling.
/// Increasing this value results in points further apart being collapsed and
/// thus more simplified polygons. Higher values improve performance at the
/// cost of visual fidelity and vice versa.
///
/// Defaults to 0.5. Set to 0 to disable simplification.
final double simplificationTolerance;
Expand Down Expand Up @@ -67,7 +64,6 @@ class PolygonLayer extends StatefulWidget {

class _PolygonLayerState extends State<PolygonLayer> {
List<_ProjectedPolygon>? _cachedProjectedPolygons;
double? _effectiveTolerance;
final _cachedSimplifiedPolygons = <int, List<_ProjectedPolygon>>{};

@override
Expand All @@ -83,7 +79,6 @@ class _PolygonLayerState extends State<PolygonLayer> {

_cachedSimplifiedPolygons.clear();
_cachedProjectedPolygons = null;
_effectiveTolerance = null;
}

@override
Expand All @@ -98,17 +93,15 @@ class _PolygonLayerState extends State<PolygonLayer> {
),
growable: false,
);
final simplificationTolerance = _effectiveTolerance ??=
getEffectiveSimplificationTolerance(
camera.crs.projection, widget.simplificationTolerance);

final zoom = camera.zoom.floor();

final simplified = widget.simplificationTolerance == 0
? projected
: _cachedSimplifiedPolygons[zoom] ??= _computeZoomLevelSimplification(
camera.crs,
projected,
simplificationTolerance,
widget.simplificationTolerance,
zoom,
);

Expand All @@ -134,36 +127,44 @@ class _PolygonLayerState extends State<PolygonLayer> {
}

static List<_ProjectedPolygon> _computeZoomLevelSimplification(
Crs crs,
List<_ProjectedPolygon> polygons,
double tolerance,
double pixelTolerance,
int zoom,
) =>
List<_ProjectedPolygon>.generate(
polygons.length,
(i) {
final polygon = polygons[i];
final holes = polygon.holePoints;

return _ProjectedPolygon._(
polygon: polygon.polygon,
points: simplifyPoints(
polygon.points,
tolerance / math.pow(2, zoom),
highestQuality: true,
),
holePoints: holes == null
? null
: List<List<DoublePoint>>.generate(
holes.length,
(j) => simplifyPoints(
holes[j],
tolerance / math.pow(2, zoom),
highestQuality: true,
),
growable: false,
) {
final tolerance = getEffectiveSimplificationTolerance(
crs,
zoom,
pixelTolerance,
);

return List<_ProjectedPolygon>.generate(
polygons.length,
(i) {
final polygon = polygons[i];
final holes = polygon.holePoints;

return _ProjectedPolygon._(
polygon: polygon.polygon,
points: simplifyPoints(
polygon.points,
tolerance,
highestQuality: true,
),
holePoints: holes == null
? null
: List<List<DoublePoint>>.generate(
holes.length,
(j) => simplifyPoints(
holes[j],
tolerance,
highestQuality: true,
),
);
},
growable: false,
);
growable: false,
),
);
},
growable: false,
);
}
}
25 changes: 16 additions & 9 deletions lib/src/misc/simplify.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// implementation based on
// https://github.com/mourner/simplify-js/blob/master/simplify.js
import 'dart:math' as math;

import 'package:flutter_map/src/geo/crs.dart';
import 'package:latlong2/latlong.dart';

Expand Down Expand Up @@ -158,15 +160,20 @@ List<DoublePoint> simplifyPoints(
}

double getEffectiveSimplificationTolerance(
Projection projection,
double tolerance, {
LatLng point = const LatLng(45, 90),
}) {
if (tolerance <= 0) return 0;
Crs crs,
int zoom,
double pixelTolerance,
) {
if (pixelTolerance <= 0) return 0;

final p0 = projection.project(point);
final p1 = projection
.project(LatLng(point.latitude + tolerance, point.longitude + tolerance));
final (x0, y0) = crs.untransform(0, 0, crs.scale(zoom.toDouble()));
final (x1, y1) = crs.untransform(
pixelTolerance,
pixelTolerance,
crs.scale(zoom.toDouble()),
);

return p0.distanceTo(p1);
final dx = x1 - x0;
final dy = y1 - y0;
return math.sqrt(dx * dx + dy * dy);
}

0 comments on commit 4e9ede3

Please sign in to comment.