@@ -23,6 +23,36 @@ part 'painter.dart';
2323part 'polygon.dart' ;
2424part 'projected_polygon.dart' ;
2525
26+ /// The method used by the painter to fill polygons and resolve overlaps &
27+ /// intersections
28+ ///
29+ /// Each method has its own advantages and disadvantages.
30+ enum PolygonPainterFillMethod {
31+ /// Uses `PathFillType.evenOdd` with `Path().addPolygon`
32+ ///
33+ /// This gives the best performance, and works on the web. However, it yields
34+ /// unintended results in certain edge cases when polygons intersect when
35+ /// [PolygonLayer.invertedFill] is used, or when polygon holes intersect with
36+ /// other holes.
37+ evenOdd,
38+
39+ /// Uses `Path.combine`
40+ ///
41+ /// This always gives the best results on non-web platforms. However, it
42+ /// always yields unintended results on the web (due to a Flutter issue), and
43+ /// has slightly worse performance.
44+ ///
45+ /// The hit to performance is unlikely to be significant or even noticable in
46+ /// many applications, but applications drawing many polygons may see a slow
47+ /// of about 2ms (as tested in the example app's stress test). Profile your
48+ /// project to determine whether switching methods is suitable, especially if
49+ /// there is no visual difference.
50+ ///
51+ /// See https://github.com/flutter/flutter/issues/124675 for the Flutter issue
52+ /// preventing this method from working on the web.
53+ pathCombine,
54+ }
55+
2656/// A polygon layer for [FlutterMap] .
2757@immutable
2858base class PolygonLayer <R extends Object >
@@ -78,15 +108,25 @@ base class PolygonLayer<R extends Object>
78108 /// Defaults to `false` .
79109 final bool drawInSingleWorld;
80110
111+ /// The method used by the painter to fill polygons and resolve overlaps &
112+ /// intersections
113+ ///
114+ /// See documentation on each value in [PolygonPainterFillMethod] for more
115+ /// advantages and disadvantages of each method.
116+ ///
117+ /// Defaults to [PolygonPainterFillMethod.evenOdd] on web &
118+ /// [PolygonPainterFillMethod.pathCombine] otherwise.
119+ final PolygonPainterFillMethod painterFillMethod;
120+
81121 /// Color to apply to the map where not covered by a polygon
82122 ///
83123 /// > [!WARNING]
84124 /// > On the web, inverted filling may not work as expected in some cases.
85125 /// > It will not match the behaviour seen on native platforms. Avoid allowing
86126 /// > polygons to intersect, and avoid using holes within polygons.
87- /// > This is due to multiple limitations/bugs within Flutter. See the
88- /// > [online documentation] (docs.fleaflet.dev/layers/polygon-layer#inverted-filling)
89- /// > for more info .
127+ /// > This is because [PolygonPainterFillMethod.evenOdd] must be used on the
128+ /// > web, which (due to Flutter issues), does not properly support this
129+ /// > functionality .
90130 final Color ? invertedFill;
91131
92132 /// {@macro fm.lhn.layerHitNotifier.usage}
@@ -101,9 +141,12 @@ base class PolygonLayer<R extends Object>
101141 this .polygonCulling = true ,
102142 this .polygonLabels = true ,
103143 this .drawLabelsLast = false ,
144+ this .drawInSingleWorld = false ,
145+ this .painterFillMethod = kIsWeb
146+ ? PolygonPainterFillMethod .evenOdd
147+ : PolygonPainterFillMethod .pathCombine,
104148 this .invertedFill,
105149 this .hitNotifier,
106- this .drawInSingleWorld = false ,
107150 super .simplificationTolerance,
108151 }) : super ();
109152
@@ -222,6 +265,7 @@ class _PolygonLayerState<R extends Object> extends State<PolygonLayer<R>>
222265 camera: camera,
223266 polygonLabels: widget.polygonLabels,
224267 drawLabelsLast: widget.drawLabelsLast,
268+ painterFillMethod: widget.painterFillMethod,
225269 invertedFill: widget.invertedFill,
226270 debugAltRenderer: widget.debugAltRenderer,
227271 hitNotifier: widget.hitNotifier,
0 commit comments