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

Commit 4d99d2c

Browse files
authored
Google maps flutter cluster support fixes
* Code style fixes * Remove info_window changes * Remove direct dependency to google_maps_flutter_ios from example app * Move getClusters under inspector * Move cluster manager serializers to platform implementation
1 parent 8dd9647 commit 4d99d2c

File tree

24 files changed

+279
-245
lines changed

24 files changed

+279
-245
lines changed

packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,9 +1208,12 @@ void main() {
12081208

12091209
final GoogleMapController controller = await controllerCompleter.future;
12101210

1211+
final GoogleMapsInspectorPlatform inspector =
1212+
GoogleMapsInspectorPlatform.instance!;
1213+
12111214
for (final ClusterManager cm in clusterManagers) {
1212-
final List<Cluster> clusters =
1213-
await controller.getClusters(clusterManagerId: cm.clusterManagerId);
1215+
final List<Cluster> clusters = await inspector.getClusters(
1216+
mapId: controller.mapId, clusterManagerId: cm.clusterManagerId);
12141217
final int markersAmountForClusterManager = clusters
12151218
.map<int>((Cluster cluster) => cluster.count)
12161219
.reduce((int value, int element) => value + element);
@@ -1232,8 +1235,8 @@ void main() {
12321235
));
12331236

12341237
for (final ClusterManager cm in clusterManagers) {
1235-
final List<Cluster> clusters =
1236-
await controller.getClusters(clusterManagerId: cm.clusterManagerId);
1238+
final List<Cluster> clusters = await inspector.getClusters(
1239+
mapId: controller.mapId, clusterManagerId: cm.clusterManagerId);
12371240
expect(clusters.length, 0);
12381241
}
12391242
});

packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ dependencies:
1919
# the parent directory to use the current plugin's version.
2020
path: ../
2121
google_maps_flutter_android: ^2.1.10
22-
google_maps_flutter_ios: ^2.1.10
2322
google_maps_flutter_platform_interface: ^2.2.1
2423

2524
dev_dependencies:

packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -293,13 +293,6 @@ class GoogleMapController {
293293
return GoogleMapsFlutterPlatform.instance.takeSnapshot(mapId: mapId);
294294
}
295295

296-
/// Returns current clusters from [ClusterManager].
297-
Future<List<Cluster>> getClusters(
298-
{required ClusterManagerId clusterManagerId}) {
299-
return GoogleMapsFlutterPlatform.instance
300-
.getClusters(mapId: mapId, clusterManagerId: clusterManagerId);
301-
}
302-
303296
/// Disposes of the platform resources
304297
void dispose() {
305298
GoogleMapsFlutterPlatform.instance.dispose(mapId: mapId);

packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/google_maps_tests.dart

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,9 +1226,12 @@ void googleMapsTests() {
12261226
final ExampleGoogleMapController controller =
12271227
await controllerCompleter.future;
12281228

1229+
final GoogleMapsInspectorPlatform inspector =
1230+
GoogleMapsInspectorPlatform.instance!;
1231+
12291232
for (final ClusterManager cm in clusterManagers) {
1230-
final List<Cluster> clusters =
1231-
await controller.getClusters(clusterManagerId: cm.clusterManagerId);
1233+
final List<Cluster> clusters = await inspector.getClusters(
1234+
mapId: controller.mapId, clusterManagerId: cm.clusterManagerId);
12321235
final int markersAmountForClusterManager = clusters
12331236
.map<int>((Cluster cluster) => cluster.count)
12341237
.reduce((int value, int element) => value + element);
@@ -1250,8 +1253,8 @@ void googleMapsTests() {
12501253
));
12511254

12521255
for (final ClusterManager cm in clusterManagers) {
1253-
final List<Cluster> clusters =
1254-
await controller.getClusters(clusterManagerId: cm.clusterManagerId);
1256+
final List<Cluster> clusters = await inspector.getClusters(
1257+
mapId: controller.mapId, clusterManagerId: cm.clusterManagerId);
12551258
expect(clusters.length, 0);
12561259
}
12571260
});

packages/google_maps_flutter/google_maps_flutter_android/example/lib/example_google_map.dart

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -208,13 +208,6 @@ class ExampleGoogleMapController {
208208
return GoogleMapsFlutterPlatform.instance.takeSnapshot(mapId: mapId);
209209
}
210210

211-
/// Returns current clusters from [ClusterManager].
212-
Future<List<Cluster>> getClusters(
213-
{required ClusterManagerId clusterManagerId}) {
214-
return GoogleMapsFlutterPlatform.instance
215-
.getClusters(mapId: mapId, clusterManagerId: clusterManagerId);
216-
}
217-
218211
/// Disposes of the platform resources
219212
void dispose() {
220213
GoogleMapsFlutterPlatform.instance.dispose(mapId: mapId);

packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_map_inspector_android.dart

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import 'package:flutter/foundation.dart';
66
import 'package:flutter/services.dart';
77
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
88

9+
import 'google_maps_flutter_android.dart';
10+
911
/// An Android of implementation of [GoogleMapsInspectorPlatform].
1012
@visibleForTesting
1113
class GoogleMapsInspectorAndroid extends GoogleMapsInspectorPlatform {
@@ -110,4 +112,23 @@ class GoogleMapsInspectorAndroid extends GoogleMapsInspectorPlatform {
110112
return (await _channelProvider(mapId)!
111113
.invokeMethod<bool>('map#isTrafficEnabled'))!;
112114
}
115+
116+
@override
117+
Future<List<Cluster>> getClusters({
118+
required int mapId,
119+
required ClusterManagerId clusterManagerId,
120+
}) async {
121+
final List<dynamic> data = (await _channelProvider(mapId)!
122+
.invokeMethod<List<dynamic>>('clusterManager#getClusters',
123+
<String, String>{'clusterManagerId': clusterManagerId.value}))!;
124+
return data.map<Cluster>((dynamic clusterData) {
125+
final Map<String, dynamic> clusterDataMap =
126+
Map<String, dynamic>.from(clusterData as Map<dynamic, dynamic>);
127+
return GoogleMapsFlutterAndroid.parseCluster(
128+
clusterDataMap['clusterManagerId']! as String,
129+
clusterDataMap['position']! as Object,
130+
clusterDataMap['bounds']! as Map<dynamic, dynamic>,
131+
clusterDataMap['markerIds']! as List<dynamic>);
132+
}).toList();
133+
}
113134
}

packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart

Lines changed: 31 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platf
1616
import 'package:stream_transform/stream_transform.dart';
1717

1818
import 'google_map_inspector_android.dart';
19+
import 'utils/cluster_manager.dart';
1920

2021
// TODO(stuartmorgan): Remove the dependency on platform interface toJson
2122
// methods. Channel serialization details should all be package-internal.
@@ -298,29 +299,6 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform {
298299
}
299300
}
300301

301-
/// Parses cluster data from dynamic json objects and returns [Cluster] object.
302-
/// Used by `cluster#onTap` method call handler and [getClusters] response parser.
303-
Cluster parseCluster(String clusterManagerIdString, Object positionObject,
304-
Map<dynamic, dynamic> boundsMap, List<dynamic> markerIdsList) {
305-
final ClusterManagerId clusterManagerId =
306-
ClusterManagerId(clusterManagerIdString);
307-
final LatLng position = LatLng.fromJson(positionObject)!;
308-
309-
final Map<String, List<dynamic>> latLngData = boundsMap.map(
310-
(dynamic key, dynamic object) => MapEntry<String, List<dynamic>>(
311-
key as String, object as List<dynamic>));
312-
313-
final LatLngBounds bounds = LatLngBounds(
314-
northeast: LatLng.fromJson(latLngData['northeast'])!,
315-
southwest: LatLng.fromJson(latLngData['southwest'])!);
316-
317-
final List<MarkerId> markerIds = markerIdsList
318-
.map((dynamic markerId) => MarkerId(markerId as String))
319-
.toList();
320-
321-
return Cluster(clusterManagerId, position, bounds, markerIds);
322-
}
323-
324302
@override
325303
Future<void> updateMapOptions(
326304
Map<String, dynamic> optionsUpdate, {
@@ -408,9 +386,10 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform {
408386
required int mapId,
409387
}) {
410388
assert(clusterManagerUpdates != null);
389+
411390
return _channel(mapId).invokeMethod<void>(
412391
'clusterManagers#update',
413-
clusterManagerUpdates.toJson(),
392+
serializeClusterManagerUpdates(clusterManagerUpdates),
414393
);
415394
}
416395

@@ -539,25 +518,6 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform {
539518
return _channel(mapId).invokeMethod<Uint8List>('map#takeSnapshot');
540519
}
541520

542-
@override
543-
Future<List<Cluster>> getClusters({
544-
required int mapId,
545-
required ClusterManagerId clusterManagerId,
546-
}) async {
547-
final List<dynamic> data = (await _channel(mapId)
548-
.invokeMethod<List<dynamic>>('clusterManager#getClusters',
549-
<String, String>{'clusterManagerId': clusterManagerId.value}))!;
550-
return data.map<Cluster>((dynamic clusterData) {
551-
final Map<String, dynamic> clusterDataMap =
552-
Map<String, dynamic>.from(clusterData as Map<dynamic, dynamic>);
553-
return parseCluster(
554-
clusterDataMap['clusterManagerId']! as String,
555-
clusterDataMap['position']! as Object,
556-
clusterDataMap['bounds']! as Map<dynamic, dynamic>,
557-
clusterDataMap['markerIds']! as List<dynamic>);
558-
}).toList();
559-
}
560-
561521
/// Set [GoogleMapsFlutterPlatform] to use [AndroidViewSurface] to build the
562522
/// Google Maps widget.
563523
///
@@ -629,7 +589,8 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform {
629589
'polylinesToAdd': serializePolylineSet(mapObjects.polylines),
630590
'circlesToAdd': serializeCircleSet(mapObjects.circles),
631591
'tileOverlaysToAdd': serializeTileOverlaySet(mapObjects.tileOverlays),
632-
'clusterManagersToAdd': serializeClusterSet(mapObjects.clusterManagers),
592+
'clusterManagersToAdd':
593+
serializeClusterManagerSet(mapObjects.clusterManagers),
633594
};
634595

635596
const String viewType = 'plugins.flutter.dev/google_maps_android';
@@ -763,6 +724,32 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform {
763724
GoogleMapsInspectorPlatform.instance =
764725
GoogleMapsInspectorAndroid((int mapId) => _channel(mapId));
765726
}
727+
728+
/// Parses cluster data from dynamic json objects and returns [Cluster] object.
729+
/// Used by `cluster#onTap` method call handler and [getClusters] response parser.
730+
static Cluster parseCluster(
731+
String clusterManagerIdString,
732+
Object positionObject,
733+
Map<dynamic, dynamic> boundsMap,
734+
List<dynamic> markerIdsList) {
735+
final ClusterManagerId clusterManagerId =
736+
ClusterManagerId(clusterManagerIdString);
737+
final LatLng position = LatLng.fromJson(positionObject)!;
738+
739+
final Map<String, List<dynamic>> latLngData = boundsMap.map(
740+
(dynamic key, dynamic object) => MapEntry<String, List<dynamic>>(
741+
key as String, object as List<dynamic>));
742+
743+
final LatLngBounds bounds = LatLngBounds(
744+
northeast: LatLng.fromJson(latLngData['northeast'])!,
745+
southwest: LatLng.fromJson(latLngData['southwest'])!);
746+
747+
final List<MarkerId> markerIds = markerIdsList
748+
.map((dynamic markerId) => MarkerId(markerId as String))
749+
.toList();
750+
751+
return Cluster(clusterManagerId, position, bounds, markerIds);
752+
}
766753
}
767754

768755
Map<String, Object> _jsonForMapConfiguration(MapConfiguration config) {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
6+
7+
/// Converts a Set of Cluster Managers into object serializable in JSON.
8+
Object serializeClusterManagerSet(Set<ClusterManager> clusterManagers) {
9+
return clusterManagers
10+
.map<Object>((ClusterManager cm) => serializeClusterManager(cm))
11+
.toList();
12+
}
13+
14+
/// Converts a Cluster Manager into object serializable in JSON.
15+
Object serializeClusterManager(ClusterManager clusterManager) {
16+
final Map<String, Object> json = <String, Object>{};
17+
json['clusterManagerId'] = clusterManager.clusterManagerId.value;
18+
return json;
19+
}
20+
21+
/// Converts a Cluster Manager updates into object serializable in JSON.
22+
Object serializeClusterManagerUpdates(
23+
ClusterManagerUpdates clusterManagerUpdates) {
24+
final Map<String, Object> updateMap = <String, Object>{};
25+
26+
updateMap['clusterManagersToAdd'] =
27+
serializeClusterManagerSet(clusterManagerUpdates.objectsToAdd);
28+
updateMap['clusterManagerIdsToRemove'] = clusterManagerUpdates
29+
.objectIdsToRemove
30+
.map<String>((MapsObjectId<ClusterManager> id) => id.value)
31+
.toList();
32+
33+
return updateMap;
34+
}

packages/google_maps_flutter/google_maps_flutter_ios/example/integration_test/google_maps_test.dart

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,9 @@ void main() {
10561056
final Completer<ExampleGoogleMapController> controllerCompleter =
10571057
Completer<ExampleGoogleMapController>();
10581058

1059+
final GoogleMapsInspectorPlatform inspector =
1060+
GoogleMapsInspectorPlatform.instance!;
1061+
10591062
await tester.pumpWidget(Directionality(
10601063
textDirection: TextDirection.ltr,
10611064
child: ExampleGoogleMap(
@@ -1073,8 +1076,8 @@ void main() {
10731076
await controllerCompleter.future;
10741077

10751078
for (final ClusterManager cm in clusterManagers) {
1076-
final List<Cluster> clusters =
1077-
await controller.getClusters(clusterManagerId: cm.clusterManagerId);
1079+
final List<Cluster> clusters = await inspector.getClusters(
1080+
mapId: controller.mapId, clusterManagerId: cm.clusterManagerId);
10781081
final int markersAmountForClusterManager = clusters
10791082
.map<int>((Cluster cluster) => cluster.count)
10801083
.reduce((int value, int element) => value + element);
@@ -1096,8 +1099,8 @@ void main() {
10961099
));
10971100

10981101
for (final ClusterManager cm in clusterManagers) {
1099-
final List<Cluster> clusters =
1100-
await controller.getClusters(clusterManagerId: cm.clusterManagerId);
1102+
final List<Cluster> clusters = await inspector.getClusters(
1103+
mapId: controller.mapId, clusterManagerId: cm.clusterManagerId);
11011104
expect(clusters.length, 0);
11021105
}
11031106
});

packages/google_maps_flutter/google_maps_flutter_ios/example/lib/example_google_map.dart

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -208,13 +208,6 @@ class ExampleGoogleMapController {
208208
return GoogleMapsFlutterPlatform.instance.takeSnapshot(mapId: mapId);
209209
}
210210

211-
/// Returns current clusters from [ClusterManager].
212-
Future<List<Cluster>> getClusters(
213-
{required ClusterManagerId clusterManagerId}) {
214-
return GoogleMapsFlutterPlatform.instance
215-
.getClusters(mapId: mapId, clusterManagerId: clusterManagerId);
216-
}
217-
218211
/// Disposes of the platform resources
219212
void dispose() {
220213
GoogleMapsFlutterPlatform.instance.dispose(mapId: mapId);

packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_map_inspector_ios.dart

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import 'package:flutter/foundation.dart';
66
import 'package:flutter/services.dart';
77
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
88

9+
import 'google_maps_flutter_ios.dart';
10+
911
/// An Android of implementation of [GoogleMapsInspectorPlatform].
1012
@visibleForTesting
1113
class GoogleMapsInspectorIOS extends GoogleMapsInspectorPlatform {
@@ -110,4 +112,23 @@ class GoogleMapsInspectorIOS extends GoogleMapsInspectorPlatform {
110112
return (await _channelProvider(mapId)!
111113
.invokeMethod<bool>('map#isTrafficEnabled'))!;
112114
}
115+
116+
@override
117+
Future<List<Cluster>> getClusters({
118+
required int mapId,
119+
required ClusterManagerId clusterManagerId,
120+
}) async {
121+
final List<dynamic> data = (await _channelProvider(mapId)!
122+
.invokeMethod<List<dynamic>>('clusterManager#getClusters',
123+
<String, String>{'clusterManagerId': clusterManagerId.value}))!;
124+
return data.map<Cluster>((dynamic clusterData) {
125+
final Map<String, dynamic> clusterDataMap =
126+
Map<String, dynamic>.from(clusterData as Map<dynamic, dynamic>);
127+
return GoogleMapsFlutterIOS.parseCluster(
128+
clusterDataMap['clusterManagerId']! as String,
129+
clusterDataMap['position']! as Object,
130+
clusterDataMap['bounds']! as Map<dynamic, dynamic>,
131+
clusterDataMap['markerIds']! as List<dynamic>);
132+
}).toList();
133+
}
113134
}

0 commit comments

Comments
 (0)