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

[google_maps_flutter] Adds support for holes in polygon overlays to the Google Maps plugin #1721

Merged
merged 62 commits into from
Jan 13, 2021
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
76d56ca
Adds support for holes in polygon overlays to the Google Maps plugin
sanekyy Jun 10, 2019
8826721
Add name and contact info to the AUTHORS file
sanekyy Jun 10, 2019
9252dc4
fix holes generating in example
sanekyy Jun 17, 2019
a4eeab5
Merge branch 'master' into polygon_holes
sanekyy Jun 17, 2019
1b26908
merge with upstream/master
sanekyy Jun 17, 2019
01bd55c
Merge remote-tracking branch 'upstream/master' into polygon_holes
sanekyy Jun 20, 2019
69d3889
Merge remote-tracking branch 'upstream/master' into polygon_holes
sanekyy Jun 20, 2019
18137c2
change version to 0.5.19
sanekyy Jun 20, 2019
a86e25f
Merge remote-tracking branch 'upstream/master' into polygon_holes
sanekyy Jun 21, 2019
e866736
change version to 0.5.20
sanekyy Jun 21, 2019
0d404b4
Merge remote-tracking branch 'upstream/master' into polygon_holes
sanekyy Jun 25, 2019
32ee443
fix format
sanekyy Jun 27, 2019
71c45b5
Merge remote-tracking branch 'upstream/master'
sanekyy Jun 27, 2019
4f24a58
Merge branch 'polygon_holes'
sanekyy Jun 27, 2019
5233c0d
fix format
sanekyy Jun 27, 2019
a952a34
Merge remote-tracking branch 'upstream/master'
sanekyy Jul 5, 2019
1faf0d4
Merge branch 'master' into polygon_holes
sanekyy Jul 5, 2019
b4ae7bf
Merge remote-tracking branch 'upstream/master'
sanekyy Jul 11, 2019
49d08b3
Merge branch 'master' into polygon_holes
sanekyy Jul 11, 2019
b526132
Merge remote-tracking branch 'upstream/master'
sanekyy Jul 20, 2019
2d55631
Merge branch 'master' into polygon_holes
sanekyy Jul 20, 2019
7871f33
Merge remote-tracking branch 'upstream/master'
sanekyy Jul 26, 2019
185f67b
Merge branch 'master' into polygon_holes
sanekyy Jul 26, 2019
14136d5
Merge remote-tracking branch 'upstream/master'
sanekyy Sep 4, 2019
4283ce0
Merge branch 'master' into polygon_holes
sanekyy Sep 4, 2019
af1c9b0
add additional documentation about what is a hole
sanekyy Sep 4, 2019
0461f32
Merge remote-tracking branch 'upstream/master' into polygon_holes
sanekyy Sep 10, 2019
13dd5cf
Merge remote-tracking branch 'upstream/master' into polygon_holes
sanekyy Dec 21, 2019
c563086
fix polygon compare
sanekyy Dec 23, 2019
2516df5
apply format
sanekyy Dec 23, 2019
38ca9e9
add collection package to dependencies
sanekyy Dec 23, 2019
df66101
fix version
sanekyy Dec 23, 2019
c515201
fix collection dependency version
sanekyy Dec 23, 2019
47e5f60
Merge remote-tracking branch 'upstream/master' into polygon_holes
sanekyy Jan 14, 2020
6b970c8
Merge remote-tracking branch 'upstream/master' into polygon_holes
sanekyy Jan 24, 2020
1b2c8ef
Merge remote-tracking branch 'upstream/master' into polygon_holes
sanekyy Feb 1, 2020
cfd96b6
Merge remote-tracking branch 'upstream/master' into polygon_holes
sanekyy Feb 17, 2020
d2c06dc
Update packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md
sanekyy Feb 21, 2020
d377276
renaming
sanekyy Feb 21, 2020
17b0e6f
add comment
sanekyy Feb 21, 2020
9f83f73
Merge remote-tracking branch 'upstream/master' into polygon_holes
sanekyy Feb 21, 2020
dd9e6e5
Merge remote-tracking branch 'origin/polygon_holes' into polygon_holes
sanekyy Feb 21, 2020
8d3d94f
use explicit return type List<dynamic> instead of dynamic
sanekyy Feb 21, 2020
c69d178
Merge remote-tracking branch 'upstream/master' into polygon_holes
sanekyy Mar 18, 2020
0d2a84c
Merge remote-tracking branch 'upstream/master' into polygon_holes
sanekyy Mar 31, 2020
aa140a0
Merge remote-tracking branch 'upstream/master' into polygon_holes
sanekyy May 2, 2020
a603d00
fix issues after merge upstream
sanekyy May 2, 2020
1496272
fix serializing, add tests
sanekyy May 2, 2020
63cbca9
workaround for success build checks in PR
sanekyy May 2, 2020
2a8837d
cleanup
sanekyy May 3, 2020
fedafd7
bump google_maps_flutter_platform_interface version
sanekyy May 3, 2020
33e926e
fix collection package version
sanekyy May 3, 2020
4553a61
Merge branch 'master' into polygon_holes
sanekyy Jul 23, 2020
6ef0253
Merge remote-tracking branch 'upstream/master' into polygon_holes
sanekyy Aug 13, 2020
f4673a3
Merge remote-tracking branch 'origin/polygon_holes' into polygon_holes
sanekyy Aug 13, 2020
b082a41
fix merge issues
sanekyy Aug 13, 2020
9dea297
Merge remote-tracking branch 'upstream/master' into polygon_holes
sanekyy Oct 5, 2020
9802260
remove empty line
sanekyy Oct 5, 2020
7a9b266
1.0.3 -> 1.1.0
sanekyy Oct 5, 2020
febcd31
Merge remote-tracking branch 'upstream/master' into polygon_holes
sanekyy Jan 13, 2021
a5e6a5c
bump google_maps_flutter_platform_interface version
sanekyy Jan 13, 2021
d1480e1
Fix deprecated `FlatButton`
Jan 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@ Jonathan Younger <jonathan@daikini.com>
Jose Sanchez <josesm82@gmail.com>
Debkanchan Samadder <debu.samadder@gmail.com>
Audrius Karosevicius <audrius.karosevicius@gmail.com>
Lukasz Piliszczuk <lukasz@intheloup.io>
Lukasz Piliszczuk <lukasz@intheloup.io>
Aleksandr Yurkovskiy <sanekyy@gmail.com>
4 changes: 4 additions & 0 deletions packages/google_maps_flutter/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.5.21

* Add support for holes in Polygons

## 0.5.20

* Add map toolbar support
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,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 @@ -539,6 +543,16 @@ private static List<LatLng> toPoints(Object o) {
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 ob : data) {
holes.add(toPoints(ob));
}
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 @@ -35,6 +35,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 @@ -46,6 +46,10 @@ public void setPoints(List<LatLng> points) {
polygon.setPoints(points);
}

public void setHoles(List<List<LatLng>> holes) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens if the holes lie outside the polygon? does the google maps api throw some error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation from https://developers.google.com/maps/documentation/android-sdk/shapes:

If the hole intersects the outline of the polygon, the polygon will be rendered without any fill.

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 @@ -16,6 +16,8 @@ interface PolygonOptionsSink {

void setPoints(List<LatLng> points);

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

void setVisible(boolean visible);

void setStrokeWidth(float width);
Expand Down
55 changes: 55 additions & 0 deletions packages/google_maps_flutter/example/lib/place_polygon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class PlacePolygonBodyState extends State<PlacePolygonBody> {

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

Expand Down Expand Up @@ -90,6 +91,7 @@ class PlacePolygonBodyState extends State<PlacePolygonBody> {

setState(() {
polygons[polygonId] = polygon;
polygonOffsets[polygonId] = _polygonIdCounter.ceilToDouble();
});
}

Expand Down Expand Up @@ -138,6 +140,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 @@ -190,6 +208,22 @@ class PlacePolygonBodyState extends State<PlacePolygonBody> {
),
Column(
children: <Widget>[
FlatButton(
child: const Text('add holes'),
onPressed: (selectedPolygon == null)
? null
: ((polygons[selectedPolygon].holes.isNotEmpty)
? null
: _addHoles),
),
FlatButton(
child: const Text('remove holes'),
onPressed: (selectedPolygon == null)
? null
: ((polygons[selectedPolygon].holes.isEmpty)
? null
: _removeHoles),
),
FlatButton(
child: const Text('change stroke width'),
onPressed:
Expand Down Expand Up @@ -229,6 +263,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) {
[sink setFillColor:ToColor(fillColor)];
Expand Down
1 change: 1 addition & 0 deletions packages/google_maps_flutter/ios/Classes/JsonConversions.h
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
10 changes: 10 additions & 0 deletions packages/google_maps_flutter/ios/Classes/JsonConversions.m
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
24 changes: 24 additions & 0 deletions packages/google_maps_flutter/lib/src/polygon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class Polygon {
this.fillColor = Colors.black,
this.geodesic = false,
this.points = const <LatLng>[],
this.holes = const <List<LatLng>>[],
this.strokeColor = Colors.black,
this.strokeWidth = 10,
this.visible = true,
Expand Down Expand Up @@ -67,6 +68,11 @@ class Polygon {
/// default; to form a closed polygon, the start and end points must be the same.
final List<LatLng> points;

/// The vertices of the holes to be cut out of polygon.
///
/// Line segments of each points of hole are drawn inside polygon between consecutive hole points.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional documentation as to what a hole is would be helpful. Also something about the sequence in which the lat lngs are supposed to be input. Something along the lines of:

To create an empty area within a polygon, you need to create two paths, one inside the other. To create the hole, the coordinates defining the inner path must be in the opposite order to those defining the outer path. For example, if the coordinates of the outer path are in clockwise order then the inner path must be counter-clockwise.

I copied it over from https://developers.google.com/maps/documentation/javascript/shapes#polygon_hole

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

final List<List<LatLng>> holes;

/// True if the marker is visible.
final bool visible;

Expand Down Expand Up @@ -96,6 +102,7 @@ class Polygon {
Color fillColorParam,
bool geodesicParam,
List<LatLng> pointsParam,
List<List<LatLng>> holesParam,
Color strokeColorParam,
int strokeWidthParam,
bool visibleParam,
Expand All @@ -108,6 +115,7 @@ class Polygon {
fillColor: fillColorParam ?? fillColor,
geodesic: geodesicParam ?? geodesic,
points: pointsParam ?? points,
holes: holesParam ?? holes,
strokeColor: strokeColorParam ?? strokeColor,
strokeWidth: strokeWidthParam ?? strokeWidth,
visible: visibleParam ?? visible,
Expand Down Expand Up @@ -138,6 +146,10 @@ class Polygon {
json['points'] = _pointsToJson();
}

if (holes != null) {
json['holes'] = _holesToJson();
}

return json;
}

Expand All @@ -159,6 +171,18 @@ class Polygon {
}
return result;
}

dynamic _holesToJson() {
final List<dynamic> result = <dynamic>[];
for (final List<LatLng> hole in holes) {
final List<dynamic> jsonHole = <dynamic>[];
for (final LatLng point in hole) {
jsonHole.add(point._toJson());
}
result.add(jsonHole);
}
return result;
}
}

Map<PolygonId, Polygon> _keyByPolygonId(Iterable<Polygon> polygons) {
Expand Down