Skip to content

Commit 0434f06

Browse files
authored
[google_maps_flutter] Adds support for holes in polygon overlays to the Google Maps plugin (flutter#1721)
1 parent 100c747 commit 0434f06

14 files changed

+341
-24
lines changed

packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 1.1.0
2+
3+
* Add support for holes in Polygons.
4+
15
## 1.0.10
26

37
* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets.

packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,10 @@ static String interpretPolygonOptions(Object o, PolygonOptionsSink sink) {
468468
if (points != null) {
469469
sink.setPoints(toPoints(points));
470470
}
471+
final Object holes = data.get("holes");
472+
if (holes != null) {
473+
sink.setHoles(toHoles(holes));
474+
}
471475
final String polygonId = (String) data.get("polygonId");
472476
if (polygonId == null) {
473477
throw new IllegalArgumentException("polygonId was null");
@@ -576,13 +580,23 @@ private static List<LatLng> toPoints(Object o) {
576580
final List<?> data = toList(o);
577581
final List<LatLng> points = new ArrayList<>(data.size());
578582

579-
for (Object ob : data) {
580-
final List<?> point = toList(ob);
583+
for (Object rawPoint : data) {
584+
final List<?> point = toList(rawPoint);
581585
points.add(new LatLng(toFloat(point.get(0)), toFloat(point.get(1))));
582586
}
583587
return points;
584588
}
585589

590+
private static List<List<LatLng>> toHoles(Object o) {
591+
final List<?> data = toList(o);
592+
final List<List<LatLng>> holes = new ArrayList<>(data.size());
593+
594+
for (Object rawHole : data) {
595+
holes.add(toPoints(rawHole));
596+
}
597+
return holes;
598+
}
599+
586600
private static List<PatternItem> toPattern(Object o) {
587601
final List<?> data = toList(o);
588602

packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonBuilder.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ public void setPoints(List<LatLng> points) {
4141
polygonOptions.addAll(points);
4242
}
4343

44+
@Override
45+
public void setHoles(List<List<LatLng>> holes) {
46+
for (List<LatLng> hole : holes) {
47+
polygonOptions.addHole(hole);
48+
}
49+
}
50+
4451
@Override
4552
public void setConsumeTapEvents(boolean consumeTapEvents) {
4653
this.consumeTapEvents = consumeTapEvents;

packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonController.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ public void setPoints(List<LatLng> points) {
5252
polygon.setPoints(points);
5353
}
5454

55+
public void setHoles(List<List<LatLng>> holes) {
56+
polygon.setHoles(holes);
57+
}
58+
5559
@Override
5660
public void setVisible(boolean visible) {
5761
polygon.setVisible(visible);

packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonOptionsSink.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ interface PolygonOptionsSink {
2020

2121
void setPoints(List<LatLng> points);
2222

23+
void setHoles(List<List<LatLng>> holes);
24+
2325
void setVisible(boolean visible);
2426

2527
void setStrokeWidth(float width);

packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ class PlacePolygonBodyState extends State<PlacePolygonBody> {
3030

3131
GoogleMapController controller;
3232
Map<PolygonId, Polygon> polygons = <PolygonId, Polygon>{};
33-
int _polygonIdCounter = 1;
33+
Map<PolygonId, double> polygonOffsets = <PolygonId, double>{};
34+
int _polygonIdCounter = 0;
3435
PolygonId selectedPolygon;
3536

3637
// Values when toggling polygon color
@@ -79,7 +80,6 @@ class PlacePolygonBodyState extends State<PlacePolygonBody> {
7980
}
8081

8182
final String polygonIdVal = 'polygon_id_$_polygonIdCounter';
82-
_polygonIdCounter++;
8383
final PolygonId polygonId = PolygonId(polygonIdVal);
8484

8585
final Polygon polygon = Polygon(
@@ -96,6 +96,9 @@ class PlacePolygonBodyState extends State<PlacePolygonBody> {
9696

9797
setState(() {
9898
polygons[polygonId] = polygon;
99+
polygonOffsets[polygonId] = _polygonIdCounter.ceilToDouble();
100+
// increment _polygonIdCounter to have unique polygon id each time
101+
_polygonIdCounter++;
99102
});
100103
}
101104

@@ -144,6 +147,22 @@ class PlacePolygonBodyState extends State<PlacePolygonBody> {
144147
});
145148
}
146149

150+
void _addHoles() {
151+
final Polygon polygon = polygons[selectedPolygon];
152+
setState(() {
153+
polygons[selectedPolygon] = polygon.copyWith(holesParam: _createHoles());
154+
});
155+
}
156+
157+
void _removeHoles() {
158+
final Polygon polygon = polygons[selectedPolygon];
159+
setState(() {
160+
polygons[selectedPolygon] = polygon.copyWith(
161+
holesParam: <List<LatLng>>[],
162+
);
163+
});
164+
}
165+
147166
@override
148167
Widget build(BuildContext context) {
149168
return Column(
@@ -196,6 +215,22 @@ class PlacePolygonBodyState extends State<PlacePolygonBody> {
196215
),
197216
Column(
198217
children: <Widget>[
218+
TextButton(
219+
child: const Text('add holes'),
220+
onPressed: (selectedPolygon == null)
221+
? null
222+
: ((polygons[selectedPolygon].holes.isNotEmpty)
223+
? null
224+
: _addHoles),
225+
),
226+
TextButton(
227+
child: const Text('remove holes'),
228+
onPressed: (selectedPolygon == null)
229+
? null
230+
: ((polygons[selectedPolygon].holes.isEmpty)
231+
? null
232+
: _removeHoles),
233+
),
199234
TextButton(
200235
child: const Text('change stroke width'),
201236
onPressed:
@@ -235,6 +270,27 @@ class PlacePolygonBodyState extends State<PlacePolygonBody> {
235270
return points;
236271
}
237272

273+
List<List<LatLng>> _createHoles() {
274+
final List<List<LatLng>> holes = <List<LatLng>>[];
275+
final double offset = polygonOffsets[selectedPolygon];
276+
277+
final List<LatLng> hole1 = <LatLng>[];
278+
hole1.add(_createLatLng(51.8395 + offset, -3.8814));
279+
hole1.add(_createLatLng(52.0234 + offset, -3.9914));
280+
hole1.add(_createLatLng(52.1351 + offset, -4.4435));
281+
hole1.add(_createLatLng(52.0231 + offset, -4.5829));
282+
holes.add(hole1);
283+
284+
final List<LatLng> hole2 = <LatLng>[];
285+
hole2.add(_createLatLng(52.2395 + offset, -3.6814));
286+
hole2.add(_createLatLng(52.4234 + offset, -3.7914));
287+
hole2.add(_createLatLng(52.5351 + offset, -4.2435));
288+
hole2.add(_createLatLng(52.4231 + offset, -4.3829));
289+
holes.add(hole2);
290+
291+
return holes;
292+
}
293+
238294
LatLng _createLatLng(double lat, double lng) {
239295
return LatLng(lat, lng);
240296
}

packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
- (void)setStrokeColor:(UIColor*)color;
1414
- (void)setStrokeWidth:(CGFloat)width;
1515
- (void)setPoints:(NSArray<CLLocation*>*)points;
16+
- (void)setHoles:(NSArray<NSArray<CLLocation*>*>*)holes;
1617
- (void)setZIndex:(int)zIndex;
1718
@end
1819

packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,19 @@ - (void)setPoints:(NSArray<CLLocation*>*)points {
4545
}
4646
_polygon.path = path;
4747
}
48+
- (void)setHoles:(NSArray<NSArray<CLLocation*>*>*)rawHoles {
49+
NSMutableArray<GMSMutablePath*>* holes = [[NSMutableArray<GMSMutablePath*> alloc] init];
50+
51+
for (NSArray<CLLocation*>* points in rawHoles) {
52+
GMSMutablePath* path = [GMSMutablePath path];
53+
for (CLLocation* location in points) {
54+
[path addCoordinate:location.coordinate];
55+
}
56+
[holes addObject:path];
57+
}
58+
59+
_polygon.holes = holes;
60+
}
4861

4962
- (void)setFillColor:(UIColor*)color {
5063
_polygon.fillColor = color;
@@ -65,6 +78,10 @@ - (void)setStrokeWidth:(CGFloat)width {
6578
return [FLTGoogleMapJsonConversions toPoints:data];
6679
}
6780

81+
static NSArray<NSArray<CLLocation*>*>* ToHoles(NSArray<NSArray*>* data) {
82+
return [FLTGoogleMapJsonConversions toHoles:data];
83+
}
84+
6885
static UIColor* ToColor(NSNumber* data) { return [FLTGoogleMapJsonConversions toColor:data]; }
6986

7087
static void InterpretPolygonOptions(NSDictionary* data, id<FLTGoogleMapPolygonOptionsSink> sink,
@@ -89,6 +106,11 @@ static void InterpretPolygonOptions(NSDictionary* data, id<FLTGoogleMapPolygonOp
89106
[sink setPoints:ToPoints(points)];
90107
}
91108

109+
NSArray* holes = data[@"holes"];
110+
if (holes) {
111+
[sink setHoles:ToHoles(holes)];
112+
}
113+
92114
NSNumber* fillColor = data[@"fillColor"];
93115
if (fillColor != nil) {
94116
[sink setFillColor:ToColor(fillColor)];

packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@
1515
+ (NSArray*)positionToJson:(CLLocationCoordinate2D)position;
1616
+ (UIColor*)toColor:(NSNumber*)data;
1717
+ (NSArray<CLLocation*>*)toPoints:(NSArray*)data;
18+
+ (NSArray<NSArray<CLLocation*>*>*)toHoles:(NSArray*)data;
1819
@end

packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.m

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,14 @@ + (UIColor*)toColor:(NSNumber*)numberColor {
5858
return points;
5959
}
6060

61+
+ (NSArray<NSArray<CLLocation*>*>*)toHoles:(NSArray*)data {
62+
NSMutableArray<NSArray<CLLocation*>*>* holes = [[[NSMutableArray alloc] init] init];
63+
for (unsigned i = 0; i < [data count]; i++) {
64+
NSArray<CLLocation*>* points = [FLTGoogleMapJsonConversions toPoints:data[i]];
65+
[holes addObject:points];
66+
}
67+
68+
return holes;
69+
}
70+
6171
@end

packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import 'package:flutter/foundation.dart';
1313
import 'package:flutter/gestures.dart';
1414
import 'package:flutter/material.dart';
1515
import 'package:flutter/services.dart';
16-
1716
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
1817
import 'package:google_maps_flutter_platform_interface/src/method_channel/method_channel_google_maps_flutter.dart';
1918

packages/google_maps_flutter/google_maps_flutter/pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
name: google_maps_flutter
22
description: A Flutter plugin for integrating Google Maps in iOS and Android applications.
33
homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter
4-
version: 1.0.10
4+
version: 1.1.0
55

66
dependencies:
77
flutter:
88
sdk: flutter
99
flutter_plugin_android_lifecycle: ^1.0.0
10-
google_maps_flutter_platform_interface: ^1.0.4
10+
google_maps_flutter_platform_interface: ^1.1.0
1111

1212
dev_dependencies:
1313
flutter_test:

packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,14 @@ class FakePlatformGoogleMap {
202202
final bool visible = polygonData['visible'];
203203
final bool geodesic = polygonData['geodesic'];
204204
final List<LatLng> points = _deserializePoints(polygonData['points']);
205+
final List<List<LatLng>> holes = _deserializeHoles(polygonData['holes']);
205206

206207
result.add(Polygon(
207208
polygonId: PolygonId(polygonId),
208209
visible: visible,
209210
geodesic: geodesic,
210211
points: points,
212+
holes: holes,
211213
));
212214
}
213215

@@ -220,6 +222,14 @@ class FakePlatformGoogleMap {
220222
}).toList();
221223
}
222224

225+
List<List<LatLng>> _deserializeHoles(List<dynamic> holes) {
226+
return holes.map<List<LatLng>>((dynamic hole) {
227+
return hole.map<LatLng>((dynamic list) {
228+
return LatLng(list[0], list[1]);
229+
}).toList();
230+
}).toList();
231+
}
232+
223233
void updatePolylines(Map<dynamic, dynamic> polylineUpdates) {
224234
if (polylineUpdates == null) {
225235
return;

0 commit comments

Comments
 (0)