Skip to content

Commit

Permalink
[google_maps_flutter_web] Reverse Hole winding when needed (flutter#3440
Browse files Browse the repository at this point in the history
)

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]>
  • Loading branch information
ABausG and Anton Borries authored Jan 21, 2021
1 parent 07cf89a commit c923ef8
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.1.1

* Auto-reverse holes if they're the same direction as the polygon. [Issue](https://github.com/flutter/flutter/issues/74096).

## 0.1.0+10

* Update `package:google_maps_flutter_platform_interface` to `^1.1.0`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -482,9 +482,23 @@ gmaps.PolygonOptions _polygonOptionsFromPolygon(
polygon.points.forEach((point) {
path.add(_latLngToGmLatLng(point));
});
final polygonDirection = _isPolygonClockwise(path);
List<List<gmaps.LatLng>> paths = [path];
int holeIndex = 0;
polygon.holes?.forEach((hole) {
paths.add(hole.map((point) => _latLngToGmLatLng(point)).toList());
List<gmaps.LatLng> holePath =
hole.map((point) => _latLngToGmLatLng(point)).toList();
if (_isPolygonClockwise(holePath) == polygonDirection) {
holePath = holePath.reversed.toList();
if (kDebugMode) {
print(
'Hole [$holeIndex] in Polygon [${polygon.polygonId.value}] has been reversed.'
' Ensure holes in polygons are "wound in the opposite direction to the outer path."'
' More info: https://github.com/flutter/flutter/issues/74096');
}
}
paths.add(holePath);
holeIndex++;
});
return gmaps.PolygonOptions()
..paths = paths
Expand All @@ -498,6 +512,20 @@ gmaps.PolygonOptions _polygonOptionsFromPolygon(
..geodesic = polygon.geodesic;
}

/// Calculates the direction of a given Polygon
/// based on: https://stackoverflow.com/a/1165943
///
/// returns [true] if clockwise [false] if counterclockwise
bool _isPolygonClockwise(List<gmaps.LatLng> path) {
var direction = 0.0;
for (var i = 0; i < path.length; i++) {
direction = direction +
((path[(i + 1) % path.length].lat - path[i].lat) *
(path[(i + 1) % path.length].lng + path[i].lng));
}
return direction >= 0;
}

gmaps.PolylineOptions _polylineOptionsFromPolyline(
gmaps.GMap googleMap, Polyline polyline) {
List<gmaps.LatLng> paths = [];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: google_maps_flutter_web
description: Web platform implementation of google_maps_flutter
homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter
version: 0.1.0+10
version: 0.1.1

flutter:
plugin:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,39 @@ void main() {

expect(geometry.poly.containsLocation(pointInHole, polygon), false);
});

testWidgets('Hole Path gets reversed to display correctly',
(WidgetTester tester) async {
final polygons = {
Polygon(
polygonId: PolygonId('BermudaTriangle'),
points: [
LatLng(25.774, -80.19),
LatLng(18.466, -66.118),
LatLng(32.321, -64.757),
],
holes: [
[
LatLng(27.339, -66.668),
LatLng(29.57, -67.514),
LatLng(28.745, -70.579),
],
],
),
};

controller.addPolygons(polygons);

expect(
controller.polygons.values.first.polygon.paths.getAt(1).getAt(0).lat,
28.745);
expect(
controller.polygons.values.first.polygon.paths.getAt(1).getAt(1).lat,
29.57);
expect(
controller.polygons.values.first.polygon.paths.getAt(1).getAt(2).lat,
27.339);
});
});

group('PolylinesController', () {
Expand Down

0 comments on commit c923ef8

Please sign in to comment.