Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit c923ef8

Browse files
ABausGAnton Borries
and
Anton Borries
authored
[google_maps_flutter_web] Reverse Hole winding when needed (#3440)
The Web Version needs the holes in a polygon to be defined in the opposite direction to their parent polygon. This change automatically reverses the definition of a hole, when needed. In debug mode, it'll let the user know that the holes need to be wound differently. Co-authored-by: Anton Borries <[email protected]>
1 parent 07cf89a commit c923ef8

File tree

4 files changed

+67
-2
lines changed

4 files changed

+67
-2
lines changed

packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.1.1
2+
3+
* Auto-reverse holes if they're the same direction as the polygon. [Issue](https://github.com/flutter/flutter/issues/74096).
4+
15
## 0.1.0+10
26

37
* Update `package:google_maps_flutter_platform_interface` to `^1.1.0`.

packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,9 +482,23 @@ gmaps.PolygonOptions _polygonOptionsFromPolygon(
482482
polygon.points.forEach((point) {
483483
path.add(_latLngToGmLatLng(point));
484484
});
485+
final polygonDirection = _isPolygonClockwise(path);
485486
List<List<gmaps.LatLng>> paths = [path];
487+
int holeIndex = 0;
486488
polygon.holes?.forEach((hole) {
487-
paths.add(hole.map((point) => _latLngToGmLatLng(point)).toList());
489+
List<gmaps.LatLng> holePath =
490+
hole.map((point) => _latLngToGmLatLng(point)).toList();
491+
if (_isPolygonClockwise(holePath) == polygonDirection) {
492+
holePath = holePath.reversed.toList();
493+
if (kDebugMode) {
494+
print(
495+
'Hole [$holeIndex] in Polygon [${polygon.polygonId.value}] has been reversed.'
496+
' Ensure holes in polygons are "wound in the opposite direction to the outer path."'
497+
' More info: https://github.com/flutter/flutter/issues/74096');
498+
}
499+
}
500+
paths.add(holePath);
501+
holeIndex++;
488502
});
489503
return gmaps.PolygonOptions()
490504
..paths = paths
@@ -498,6 +512,20 @@ gmaps.PolygonOptions _polygonOptionsFromPolygon(
498512
..geodesic = polygon.geodesic;
499513
}
500514

515+
/// Calculates the direction of a given Polygon
516+
/// based on: https://stackoverflow.com/a/1165943
517+
///
518+
/// returns [true] if clockwise [false] if counterclockwise
519+
bool _isPolygonClockwise(List<gmaps.LatLng> path) {
520+
var direction = 0.0;
521+
for (var i = 0; i < path.length; i++) {
522+
direction = direction +
523+
((path[(i + 1) % path.length].lat - path[i].lat) *
524+
(path[(i + 1) % path.length].lng + path[i].lng));
525+
}
526+
return direction >= 0;
527+
}
528+
501529
gmaps.PolylineOptions _polylineOptionsFromPolyline(
502530
gmaps.GMap googleMap, Polyline polyline) {
503531
List<gmaps.LatLng> paths = [];

packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: google_maps_flutter_web
22
description: Web platform implementation of google_maps_flutter
33
homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter
4-
version: 0.1.0+10
4+
version: 0.1.1
55

66
flutter:
77
plugin:

packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration.dart

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,39 @@ void main() {
245245

246246
expect(geometry.poly.containsLocation(pointInHole, polygon), false);
247247
});
248+
249+
testWidgets('Hole Path gets reversed to display correctly',
250+
(WidgetTester tester) async {
251+
final polygons = {
252+
Polygon(
253+
polygonId: PolygonId('BermudaTriangle'),
254+
points: [
255+
LatLng(25.774, -80.19),
256+
LatLng(18.466, -66.118),
257+
LatLng(32.321, -64.757),
258+
],
259+
holes: [
260+
[
261+
LatLng(27.339, -66.668),
262+
LatLng(29.57, -67.514),
263+
LatLng(28.745, -70.579),
264+
],
265+
],
266+
),
267+
};
268+
269+
controller.addPolygons(polygons);
270+
271+
expect(
272+
controller.polygons.values.first.polygon.paths.getAt(1).getAt(0).lat,
273+
28.745);
274+
expect(
275+
controller.polygons.values.first.polygon.paths.getAt(1).getAt(1).lat,
276+
29.57);
277+
expect(
278+
controller.polygons.values.first.polygon.paths.getAt(1).getAt(2).lat,
279+
27.339);
280+
});
248281
});
249282

250283
group('PolylinesController', () {

0 commit comments

Comments
 (0)