Skip to content

Commit

Permalink
[google_maps_flutter] Adds support for holes in polygon overlays to t…
Browse files Browse the repository at this point in the history
…he Google Maps plugin (flutter#1721)
  • Loading branch information
sanekyy committed Jan 13, 2021
1 parent 100c747 commit 0434f06
Show file tree
Hide file tree
Showing 14 changed files with 341 additions and 24 deletions.
4 changes: 4 additions & 0 deletions packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.1.0

* Add support for holes in Polygons.

## 1.0.10

* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,10 @@ static String interpretPolygonOptions(Object o, PolygonOptionsSink sink) {
if (points != null) {
sink.setPoints(toPoints(points));
}
final Object holes = data.get("holes");
if (holes != null) {
sink.setHoles(toHoles(holes));
}
final String polygonId = (String) data.get("polygonId");
if (polygonId == null) {
throw new IllegalArgumentException("polygonId was null");
Expand Down Expand Up @@ -576,13 +580,23 @@ private static List<LatLng> toPoints(Object o) {
final List<?> data = toList(o);
final List<LatLng> points = new ArrayList<>(data.size());

for (Object ob : data) {
final List<?> point = toList(ob);
for (Object rawPoint : data) {
final List<?> point = toList(rawPoint);
points.add(new LatLng(toFloat(point.get(0)), toFloat(point.get(1))));
}
return points;
}

private static List<List<LatLng>> toHoles(Object o) {
final List<?> data = toList(o);
final List<List<LatLng>> holes = new ArrayList<>(data.size());

for (Object rawHole : data) {
holes.add(toPoints(rawHole));
}
return holes;
}

private static List<PatternItem> toPattern(Object o) {
final List<?> data = toList(o);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ public void setPoints(List<LatLng> points) {
polygonOptions.addAll(points);
}

@Override
public void setHoles(List<List<LatLng>> holes) {
for (List<LatLng> hole : holes) {
polygonOptions.addHole(hole);
}
}

@Override
public void setConsumeTapEvents(boolean consumeTapEvents) {
this.consumeTapEvents = consumeTapEvents;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ public void setPoints(List<LatLng> points) {
polygon.setPoints(points);
}

public void setHoles(List<List<LatLng>> holes) {
polygon.setHoles(holes);
}

@Override
public void setVisible(boolean visible) {
polygon.setVisible(visible);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ interface PolygonOptionsSink {

void setPoints(List<LatLng> points);

void setHoles(List<List<LatLng>> holes);

void setVisible(boolean visible);

void setStrokeWidth(float width);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ class PlacePolygonBodyState extends State<PlacePolygonBody> {

GoogleMapController controller;
Map<PolygonId, Polygon> polygons = <PolygonId, Polygon>{};
int _polygonIdCounter = 1;
Map<PolygonId, double> polygonOffsets = <PolygonId, double>{};
int _polygonIdCounter = 0;
PolygonId selectedPolygon;

// Values when toggling polygon color
Expand Down Expand Up @@ -79,7 +80,6 @@ class PlacePolygonBodyState extends State<PlacePolygonBody> {
}

final String polygonIdVal = 'polygon_id_$_polygonIdCounter';
_polygonIdCounter++;
final PolygonId polygonId = PolygonId(polygonIdVal);

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

setState(() {
polygons[polygonId] = polygon;
polygonOffsets[polygonId] = _polygonIdCounter.ceilToDouble();
// increment _polygonIdCounter to have unique polygon id each time
_polygonIdCounter++;
});
}

Expand Down Expand Up @@ -144,6 +147,22 @@ class PlacePolygonBodyState extends State<PlacePolygonBody> {
});
}

void _addHoles() {
final Polygon polygon = polygons[selectedPolygon];
setState(() {
polygons[selectedPolygon] = polygon.copyWith(holesParam: _createHoles());
});
}

void _removeHoles() {
final Polygon polygon = polygons[selectedPolygon];
setState(() {
polygons[selectedPolygon] = polygon.copyWith(
holesParam: <List<LatLng>>[],
);
});
}

@override
Widget build(BuildContext context) {
return Column(
Expand Down Expand Up @@ -196,6 +215,22 @@ class PlacePolygonBodyState extends State<PlacePolygonBody> {
),
Column(
children: <Widget>[
TextButton(
child: const Text('add holes'),
onPressed: (selectedPolygon == null)
? null
: ((polygons[selectedPolygon].holes.isNotEmpty)
? null
: _addHoles),
),
TextButton(
child: const Text('remove holes'),
onPressed: (selectedPolygon == null)
? null
: ((polygons[selectedPolygon].holes.isEmpty)
? null
: _removeHoles),
),
TextButton(
child: const Text('change stroke width'),
onPressed:
Expand Down Expand Up @@ -235,6 +270,27 @@ class PlacePolygonBodyState extends State<PlacePolygonBody> {
return points;
}

List<List<LatLng>> _createHoles() {
final List<List<LatLng>> holes = <List<LatLng>>[];
final double offset = polygonOffsets[selectedPolygon];

final List<LatLng> hole1 = <LatLng>[];
hole1.add(_createLatLng(51.8395 + offset, -3.8814));
hole1.add(_createLatLng(52.0234 + offset, -3.9914));
hole1.add(_createLatLng(52.1351 + offset, -4.4435));
hole1.add(_createLatLng(52.0231 + offset, -4.5829));
holes.add(hole1);

final List<LatLng> hole2 = <LatLng>[];
hole2.add(_createLatLng(52.2395 + offset, -3.6814));
hole2.add(_createLatLng(52.4234 + offset, -3.7914));
hole2.add(_createLatLng(52.5351 + offset, -4.2435));
hole2.add(_createLatLng(52.4231 + offset, -4.3829));
holes.add(hole2);

return holes;
}

LatLng _createLatLng(double lat, double lng) {
return LatLng(lat, lng);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- (void)setStrokeColor:(UIColor*)color;
- (void)setStrokeWidth:(CGFloat)width;
- (void)setPoints:(NSArray<CLLocation*>*)points;
- (void)setHoles:(NSArray<NSArray<CLLocation*>*>*)holes;
- (void)setZIndex:(int)zIndex;
@end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ - (void)setPoints:(NSArray<CLLocation*>*)points {
}
_polygon.path = path;
}
- (void)setHoles:(NSArray<NSArray<CLLocation*>*>*)rawHoles {
NSMutableArray<GMSMutablePath*>* holes = [[NSMutableArray<GMSMutablePath*> alloc] init];

for (NSArray<CLLocation*>* points in rawHoles) {
GMSMutablePath* path = [GMSMutablePath path];
for (CLLocation* location in points) {
[path addCoordinate:location.coordinate];
}
[holes addObject:path];
}

_polygon.holes = holes;
}

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

static NSArray<NSArray<CLLocation*>*>* ToHoles(NSArray<NSArray*>* data) {
return [FLTGoogleMapJsonConversions toHoles:data];
}

static UIColor* ToColor(NSNumber* data) { return [FLTGoogleMapJsonConversions toColor:data]; }

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

NSArray* holes = data[@"holes"];
if (holes) {
[sink setHoles:ToHoles(holes)];
}

NSNumber* fillColor = data[@"fillColor"];
if (fillColor != nil) {
[sink setFillColor:ToColor(fillColor)];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@
+ (NSArray*)positionToJson:(CLLocationCoordinate2D)position;
+ (UIColor*)toColor:(NSNumber*)data;
+ (NSArray<CLLocation*>*)toPoints:(NSArray*)data;
+ (NSArray<NSArray<CLLocation*>*>*)toHoles:(NSArray*)data;
@end
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,14 @@ + (UIColor*)toColor:(NSNumber*)numberColor {
return points;
}

+ (NSArray<NSArray<CLLocation*>*>*)toHoles:(NSArray*)data {
NSMutableArray<NSArray<CLLocation*>*>* holes = [[[NSMutableArray alloc] init] init];
for (unsigned i = 0; i < [data count]; i++) {
NSArray<CLLocation*>* points = [FLTGoogleMapJsonConversions toPoints:data[i]];
[holes addObject:points];
}

return holes;
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
import 'package:google_maps_flutter_platform_interface/src/method_channel/method_channel_google_maps_flutter.dart';

Expand Down
4 changes: 2 additions & 2 deletions packages/google_maps_flutter/google_maps_flutter/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
name: google_maps_flutter
description: A Flutter plugin for integrating Google Maps in iOS and Android applications.
homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter
version: 1.0.10
version: 1.1.0

dependencies:
flutter:
sdk: flutter
flutter_plugin_android_lifecycle: ^1.0.0
google_maps_flutter_platform_interface: ^1.0.4
google_maps_flutter_platform_interface: ^1.1.0

dev_dependencies:
flutter_test:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,12 +202,14 @@ class FakePlatformGoogleMap {
final bool visible = polygonData['visible'];
final bool geodesic = polygonData['geodesic'];
final List<LatLng> points = _deserializePoints(polygonData['points']);
final List<List<LatLng>> holes = _deserializeHoles(polygonData['holes']);

result.add(Polygon(
polygonId: PolygonId(polygonId),
visible: visible,
geodesic: geodesic,
points: points,
holes: holes,
));
}

Expand All @@ -220,6 +222,14 @@ class FakePlatformGoogleMap {
}).toList();
}

List<List<LatLng>> _deserializeHoles(List<dynamic> holes) {
return holes.map<List<LatLng>>((dynamic hole) {
return hole.map<LatLng>((dynamic list) {
return LatLng(list[0], list[1]);
}).toList();
}).toList();
}

void updatePolylines(Map<dynamic, dynamic> polylineUpdates) {
if (polylineUpdates == null) {
return;
Expand Down

0 comments on commit 0434f06

Please sign in to comment.