[google_maps_flutter_web] Support for Holes in Polygons (#3412)

diff --git a/AUTHORS b/AUTHORS
index 09bab9d..dabc201 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -60,3 +60,4 @@
 Chris Rutkowski <chrisrutkowski89@gmail.com>
 Juan Alvarez <juan.alvarez@resideo.com>
 Aleksandr Yurkovskiy <sanekyy@gmail.com>
+Anton Borries <mail@antonborri.es>
\ No newline at end of file
diff --git a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md
index 2d03ab2..940419a 100644
--- a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md
+++ b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 0.1.0+10
+
+* Update `package:google_maps_flutter_platform_interface` to `^1.1.0`.
+* Add support for Polygon Holes.
+
 ## 0.1.0+9
 
 * Update Flutter SDK constraint.
diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart
index 551c157..c9fd1cd 100644
--- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart
@@ -366,6 +366,11 @@
           points: rawPolygon['points']
               ?.map<LatLng>((rawPoint) => LatLng.fromJson(rawPoint))
               ?.toList(),
+          holes: rawPolygon['holes']
+              ?.map<List<LatLng>>((List hole) => hole
+                  ?.map<LatLng>((rawPoint) => LatLng.fromJson(rawPoint))
+                  ?.toList())
+              ?.toList(),
         );
       }) ??
       []);
@@ -473,9 +478,13 @@
 
 gmaps.PolygonOptions _polygonOptionsFromPolygon(
     gmaps.GMap googleMap, Polygon polygon) {
-  List<gmaps.LatLng> paths = [];
+  List<gmaps.LatLng> path = [];
   polygon.points.forEach((point) {
-    paths.add(_latLngToGmLatLng(point));
+    path.add(_latLngToGmLatLng(point));
+  });
+  List<List<gmaps.LatLng>> paths = [path];
+  polygon.holes?.forEach((hole) {
+    paths.add(hole.map((point) => _latLngToGmLatLng(point)).toList());
   });
   return gmaps.PolygonOptions()
     ..paths = paths
diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml
index b41e24c..bd87955 100644
--- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml
+++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml
@@ -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+9
+version: 0.1.0+10
 
 flutter:
   plugin:
@@ -16,7 +16,7 @@
   flutter_web_plugins:
     sdk: flutter
   meta: ^1.1.7
-  google_maps_flutter_platform_interface: ^1.0.5
+  google_maps_flutter_platform_interface: ^1.1.0
   google_maps: ^3.4.5
   stream_transform: ^1.2.0
   sanitize_html: ^1.4.1
diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration.dart
index 70d4452..302057f 100644
--- a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration.dart
@@ -166,6 +166,22 @@
                 [43.354762, -5.850824],
               ],
             },
+            {
+              'polygonId': 'polygon-2-with-holes',
+              'points': [
+                [43.355114, -5.851333],
+                [43.354797, -5.851860],
+                [43.354469, -5.851318],
+                [43.354762, -5.850824],
+              ],
+              'holes': [
+                [
+                  [41.354797, -6.851860],
+                  [41.354469, -6.851318],
+                  [41.354762, -6.850824],
+                ]
+              ]
+            },
           ],
           'polylinesToAdd': [
             {
@@ -202,6 +218,9 @@
         expect(capturedMarkers.first.infoWindow.snippet, 'snippet for test');
         expect(capturedMarkers.first.infoWindow.title, 'title for test');
         expect(capturedPolygons.first.polygonId.value, 'polygon-1');
+        expect(capturedPolygons.elementAt(1).polygonId.value,
+            'polygon-2-with-holes');
+        expect(capturedPolygons.elementAt(1).holes, isNot(null));
         expect(capturedPolylines.first.polylineId.value, 'polyline-1');
       });
 
diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration.dart
index 0c92c6a..4d5c2b1 100644
--- a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration.dart
@@ -10,6 +10,8 @@
 import 'package:integration_test/integration_test.dart';
 import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
 import 'package:google_maps_flutter_web/google_maps_flutter_web.dart';
+import 'package:google_maps/google_maps.dart' as gmaps;
+import 'package:google_maps/google_maps_geometry.dart' as geometry;
 import 'package:flutter_test/flutter_test.dart';
 
 // This value is used when comparing the results of
@@ -190,6 +192,59 @@
       expect(polygon.get('strokeColor'), '#c0ffee');
       expect(polygon.get('strokeOpacity'), closeTo(1, _acceptableDelta));
     });
+
+    testWidgets('Handle Polygons with holes', (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(28.745, -70.579),
+              LatLng(29.57, -67.514),
+              LatLng(27.339, -66.668),
+            ],
+          ],
+        ),
+      };
+
+      controller.addPolygons(polygons);
+
+      expect(controller.polygons.length, 1);
+      expect(controller.polygons, contains(PolygonId('BermudaTriangle')));
+      expect(controller.polygons, isNot(contains(PolygonId('66'))));
+    });
+
+    testWidgets('Polygon with hole has a hole', (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(28.745, -70.579),
+              LatLng(29.57, -67.514),
+              LatLng(27.339, -66.668),
+            ],
+          ],
+        ),
+      };
+
+      controller.addPolygons(polygons);
+
+      final polygon = controller.polygons.values.first.polygon;
+      final pointInHole = gmaps.LatLng(28.632, -68.401);
+
+      expect(geometry.poly.containsLocation(pointInHole, polygon), false);
+    });
   });
 
   group('PolylinesController', () {
diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/web/index.html b/packages/google_maps_flutter/google_maps_flutter_web/test/web/index.html
index 3b7e4ed..03feba1 100644
--- a/packages/google_maps_flutter/google_maps_flutter_web/test/web/index.html
+++ b/packages/google_maps_flutter/google_maps_flutter_web/test/web/index.html
@@ -5,7 +5,7 @@
 <html>
     <head>
         <title>Browser Tests</title>
-        <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
+        <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry"></script>
     </head>
     <body>
         <script src="main.dart.js"></script>