diff --git a/packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md index e48f90c9073..c2c7aec6aa7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.14.0 + +* Updates map configuration and platform view creation parameters to use Pigeon. + ## 2.13.0 * Adds support for heatmap layers. diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/CirclesController.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/CirclesController.java index 734e36c809e..8b28fe6aada 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/CirclesController.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/CirclesController.java @@ -32,16 +32,6 @@ void setGoogleMap(GoogleMap googleMap) { this.googleMap = googleMap; } - void addJsonCircles(List circlesToAdd) { - if (circlesToAdd != null) { - for (Object circleToAdd : circlesToAdd) { - @SuppressWarnings("unchecked") - Map circleMap = (Map) circleToAdd; - addJsonCircle(circleMap); - } - } - } - void addCircles(@NonNull List circlesToAdd) { for (Messages.PlatformCircle circleToAdd : circlesToAdd) { addJsonCircle(circleToAdd.getJson()); diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/ClusterManagersController.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/ClusterManagersController.java index 448d34aebb1..cd81eba7940 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/ClusterManagersController.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/ClusterManagersController.java @@ -78,17 +78,6 @@ private void initListenersForClusterManager( clusterManager.setOnClusterItemClickListener(clusterItemClickListener); } - /** Adds new ClusterManagers to the controller. */ - void addJsonClusterManagers(@NonNull List clusterManagersToAdd) { - for (Object clusterToAdd : clusterManagersToAdd) { - String clusterManagerId = getClusterManagerId(clusterToAdd); - if (clusterManagerId == null) { - throw new IllegalArgumentException("clusterManagerId was null"); - } - addClusterManager(clusterManagerId); - } - } - /** Adds new ClusterManagers to the controller. */ void addClusterManagers(@NonNull List clusterManagersToAdd) { for (Messages.PlatformClusterManager clusterToAdd : clusterManagersToAdd) { diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java index 825bb504abb..01285d9ca70 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java @@ -4,6 +4,12 @@ package io.flutter.plugins.googlemaps; +import static com.google.android.gms.maps.GoogleMap.MAP_TYPE_HYBRID; +import static com.google.android.gms.maps.GoogleMap.MAP_TYPE_NONE; +import static com.google.android.gms.maps.GoogleMap.MAP_TYPE_NORMAL; +import static com.google.android.gms.maps.GoogleMap.MAP_TYPE_SATELLITE; +import static com.google.android.gms.maps.GoogleMap.MAP_TYPE_TERRAIN; + import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; @@ -44,7 +50,6 @@ /** Conversions between JSON-like values and GoogleMaps data types. */ class Convert { // These constants must match the corresponding constants in serialization.dart - public static final String HEATMAPS_TO_ADD_KEY = "heatmapsToAdd"; public static final String HEATMAP_ID_KEY = "heatmapId"; public static final String HEATMAP_DATA_KEY = "data"; public static final String HEATMAP_GRADIENT_KEY = "gradient"; @@ -313,6 +318,16 @@ private static boolean toBoolean(Object o) { return (Boolean) o; } + static @NonNull CameraPosition cameraPositionFromPigeon( + @NonNull Messages.PlatformCameraPosition position) { + final CameraPosition.Builder builder = CameraPosition.builder(); + builder.bearing(position.getBearing().floatValue()); + builder.target(latLngFromPigeon(position.getTarget())); + builder.tilt(position.getTilt().floatValue()); + builder.zoom(position.getZoom().floatValue()); + return builder.build(); + } + static CameraPosition toCameraPosition(Object o) { final Map data = toMap(o); final CameraPosition.Builder builder = CameraPosition.builder(); @@ -364,14 +379,30 @@ private static float toFloat(Object o) { return ((Number) o).floatValue(); } - private static Float toFloatWrapper(Object o) { - return (o == null) ? null : toFloat(o); + private static @Nullable Float nullableDoubleToFloat(@Nullable Double d) { + return (d == null) ? null : d.floatValue(); } private static int toInt(Object o) { return ((Number) o).intValue(); } + static int toMapType(@NonNull Messages.PlatformMapType type) { + switch (type) { + case NONE: + return MAP_TYPE_NONE; + case NORMAL: + return MAP_TYPE_NORMAL; + case SATELLITE: + return MAP_TYPE_SATELLITE; + case TERRAIN: + return MAP_TYPE_TERRAIN; + case HYBRID: + return MAP_TYPE_HYBRID; + } + return MAP_TYPE_NORMAL; + } + static @Nullable MapsInitializer.Renderer toMapRendererType( @Nullable Messages.PlatformRendererType type) { if (type == null) { @@ -396,13 +427,6 @@ private static int toInt(Object o) { .build(); } - static Object latLngBoundsToJson(LatLngBounds latLngBounds) { - final Map arguments = new HashMap<>(2); - arguments.put("southwest", latLngToJson(latLngBounds.southwest)); - arguments.put("northeast", latLngToJson(latLngBounds.northeast)); - return arguments; - } - static Messages.PlatformLatLngBounds latLngBoundsToPigeon(LatLngBounds latLngBounds) { return new Messages.PlatformLatLngBounds.Builder() .setNortheast(latLngToPigeon(latLngBounds.northeast)) @@ -410,35 +434,10 @@ static Messages.PlatformLatLngBounds latLngBoundsToPigeon(LatLngBounds latLngBou .build(); } - static Object markerIdToJson(String markerId) { - if (markerId == null) { - return null; - } - final Map data = new HashMap<>(1); - data.put("markerId", markerId); - return data; - } - - static Object polygonIdToJson(String polygonId) { - if (polygonId == null) { - return null; - } - final Map data = new HashMap<>(1); - data.put("polygonId", polygonId); - return data; - } - - static Object polylineIdToJson(String polylineId) { - if (polylineId == null) { - return null; - } - final Map data = new HashMap<>(1); - data.put("polylineId", polylineId); - return data; - } - - static Object latLngToJson(LatLng latLng) { - return Arrays.asList(latLng.latitude, latLng.longitude); + static @NonNull LatLngBounds latLngBoundsFromPigeon( + @NonNull Messages.PlatformLatLngBounds bounds) { + return new LatLngBounds( + latLngFromPigeon(bounds.getSouthwest()), latLngFromPigeon(bounds.getNortheast())); } static Messages.PlatformLatLng latLngToPigeon(LatLng latLng) { @@ -571,92 +570,90 @@ private static String toString(Object o) { return (String) o; } - static void interpretGoogleMapOptions(Object o, GoogleMapOptionsSink sink) { - final Map data = toMap(o); - final Object cameraTargetBounds = data.get("cameraTargetBounds"); + static void interpretMapConfiguration( + @NonNull Messages.PlatformMapConfiguration config, @NonNull GoogleMapOptionsSink sink) { + final Messages.PlatformCameraTargetBounds cameraTargetBounds = config.getCameraTargetBounds(); if (cameraTargetBounds != null) { - final List targetData = toList(cameraTargetBounds); - sink.setCameraTargetBounds(toLatLngBounds(targetData.get(0))); + final @Nullable Messages.PlatformLatLngBounds bounds = cameraTargetBounds.getBounds(); + sink.setCameraTargetBounds(bounds == null ? null : latLngBoundsFromPigeon(bounds)); } - final Object compassEnabled = data.get("compassEnabled"); + final Boolean compassEnabled = config.getCompassEnabled(); if (compassEnabled != null) { - sink.setCompassEnabled(toBoolean(compassEnabled)); + sink.setCompassEnabled(compassEnabled); } - final Object mapToolbarEnabled = data.get("mapToolbarEnabled"); + final Boolean mapToolbarEnabled = config.getMapToolbarEnabled(); if (mapToolbarEnabled != null) { - sink.setMapToolbarEnabled(toBoolean(mapToolbarEnabled)); + sink.setMapToolbarEnabled(mapToolbarEnabled); } - final Object mapType = data.get("mapType"); + final Messages.PlatformMapType mapType = config.getMapType(); if (mapType != null) { - sink.setMapType(toInt(mapType)); + sink.setMapType(toMapType(mapType)); } - final Object minMaxZoomPreference = data.get("minMaxZoomPreference"); + final Messages.PlatformZoomRange minMaxZoomPreference = config.getMinMaxZoomPreference(); if (minMaxZoomPreference != null) { - final List zoomPreferenceData = toList(minMaxZoomPreference); - sink.setMinMaxZoomPreference( // - toFloatWrapper(zoomPreferenceData.get(0)), // - toFloatWrapper(zoomPreferenceData.get(1))); + sink.setMinMaxZoomPreference( + nullableDoubleToFloat(minMaxZoomPreference.getMin()), + nullableDoubleToFloat(minMaxZoomPreference.getMax())); } - final Object padding = data.get("padding"); + final Messages.PlatformEdgeInsets padding = config.getPadding(); if (padding != null) { - final List paddingData = toList(padding); sink.setPadding( - toFloat(paddingData.get(0)), - toFloat(paddingData.get(1)), - toFloat(paddingData.get(2)), - toFloat(paddingData.get(3))); + padding.getTop().floatValue(), + padding.getLeft().floatValue(), + padding.getBottom().floatValue(), + padding.getRight().floatValue()); } - final Object rotateGesturesEnabled = data.get("rotateGesturesEnabled"); + final Boolean rotateGesturesEnabled = config.getRotateGesturesEnabled(); if (rotateGesturesEnabled != null) { - sink.setRotateGesturesEnabled(toBoolean(rotateGesturesEnabled)); + sink.setRotateGesturesEnabled(rotateGesturesEnabled); } - final Object scrollGesturesEnabled = data.get("scrollGesturesEnabled"); + final Boolean scrollGesturesEnabled = config.getScrollGesturesEnabled(); if (scrollGesturesEnabled != null) { - sink.setScrollGesturesEnabled(toBoolean(scrollGesturesEnabled)); + sink.setScrollGesturesEnabled(scrollGesturesEnabled); } - final Object tiltGesturesEnabled = data.get("tiltGesturesEnabled"); + final Boolean tiltGesturesEnabled = config.getTiltGesturesEnabled(); if (tiltGesturesEnabled != null) { - sink.setTiltGesturesEnabled(toBoolean(tiltGesturesEnabled)); + sink.setTiltGesturesEnabled(tiltGesturesEnabled); } - final Object trackCameraPosition = data.get("trackCameraPosition"); + final Boolean trackCameraPosition = config.getTrackCameraPosition(); if (trackCameraPosition != null) { - sink.setTrackCameraPosition(toBoolean(trackCameraPosition)); + sink.setTrackCameraPosition(trackCameraPosition); } - final Object zoomGesturesEnabled = data.get("zoomGesturesEnabled"); + final Boolean zoomGesturesEnabled = config.getZoomGesturesEnabled(); if (zoomGesturesEnabled != null) { - sink.setZoomGesturesEnabled(toBoolean(zoomGesturesEnabled)); + sink.setZoomGesturesEnabled(zoomGesturesEnabled); } - final Object liteModeEnabled = data.get("liteModeEnabled"); + final Boolean liteModeEnabled = config.getLiteModeEnabled(); if (liteModeEnabled != null) { - sink.setLiteModeEnabled(toBoolean(liteModeEnabled)); + sink.setLiteModeEnabled(liteModeEnabled); } - final Object myLocationEnabled = data.get("myLocationEnabled"); + final Boolean myLocationEnabled = config.getMyLocationEnabled(); if (myLocationEnabled != null) { - sink.setMyLocationEnabled(toBoolean(myLocationEnabled)); + sink.setMyLocationEnabled(myLocationEnabled); } - final Object zoomControlsEnabled = data.get("zoomControlsEnabled"); + final Boolean zoomControlsEnabled = config.getZoomControlsEnabled(); if (zoomControlsEnabled != null) { - sink.setZoomControlsEnabled(toBoolean(zoomControlsEnabled)); + sink.setZoomControlsEnabled(zoomControlsEnabled); } - final Object myLocationButtonEnabled = data.get("myLocationButtonEnabled"); + final Boolean myLocationButtonEnabled = config.getMyLocationButtonEnabled(); if (myLocationButtonEnabled != null) { - sink.setMyLocationButtonEnabled(toBoolean(myLocationButtonEnabled)); + sink.setMyLocationButtonEnabled(myLocationButtonEnabled); } - final Object indoorEnabled = data.get("indoorEnabled"); + final Boolean indoorEnabled = config.getIndoorViewEnabled(); if (indoorEnabled != null) { - sink.setIndoorEnabled(toBoolean(indoorEnabled)); + sink.setIndoorEnabled(indoorEnabled); } - final Object trafficEnabled = data.get("trafficEnabled"); + final Boolean trafficEnabled = config.getTrafficEnabled(); if (trafficEnabled != null) { - sink.setTrafficEnabled(toBoolean(trafficEnabled)); + sink.setTrafficEnabled(trafficEnabled); } - final Object buildingsEnabled = data.get("buildingsEnabled"); + final Boolean buildingsEnabled = config.getBuildingsEnabled(); if (buildingsEnabled != null) { - sink.setBuildingsEnabled(toBoolean(buildingsEnabled)); + sink.setBuildingsEnabled(buildingsEnabled); } - final Object style = data.get("style"); + final String style = config.getStyle(); if (style != null) { - sink.setMapStyle(toString(style)); + sink.setMapStyle(style); } } @@ -869,7 +866,7 @@ static String interpretCircleOptions(Map data, CircleOptionsSink sink /** * Set the options in the given heatmap object to the given sink. * - * @param o the object expected to be a Map containing the heatmap options. The options map is + * @param data the object expected to be a Map containing the heatmap options. The options map is * expected to have the following structure: *
{@code
    * {
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java
index 1273a21f664..c7abcb2ff94 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java
+++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java
@@ -6,13 +6,13 @@
 
 import android.content.Context;
 import android.graphics.Rect;
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import com.google.android.gms.maps.GoogleMapOptions;
 import com.google.android.gms.maps.model.CameraPosition;
 import com.google.android.gms.maps.model.LatLngBounds;
 import io.flutter.plugin.common.BinaryMessenger;
 import java.util.List;
-import java.util.Map;
 
 class GoogleMapBuilder implements GoogleMapOptionsSink {
   private final GoogleMapOptions options = new GoogleMapOptions();
@@ -22,13 +22,13 @@ class GoogleMapBuilder implements GoogleMapOptionsSink {
   private boolean indoorEnabled = true;
   private boolean trafficEnabled = false;
   private boolean buildingsEnabled = true;
-  private Object initialMarkers;
-  private Object initialClusterManagers;
-  private Object initialPolygons;
-  private Object initialPolylines;
-  private Object initialCircles;
-  private Object initialHeatmaps;
-  private List> initialTileOverlays;
+  private List initialMarkers;
+  private List initialClusterManagers;
+  private List initialPolygons;
+  private List initialPolylines;
+  private List initialCircles;
+  private List initialHeatmaps;
+  private List initialTileOverlays;
   private Rect padding = new Rect(0, 0, 0, 0);
   private @Nullable String style;
 
@@ -162,37 +162,38 @@ public void setMyLocationButtonEnabled(boolean myLocationButtonEnabled) {
   }
 
   @Override
-  public void setInitialMarkers(Object initialMarkers) {
+  public void setInitialMarkers(@NonNull List initialMarkers) {
     this.initialMarkers = initialMarkers;
   }
 
   @Override
-  public void setInitialClusterManagers(Object initialClusterManagers) {
+  public void setInitialClusterManagers(
+      @NonNull List initialClusterManagers) {
     this.initialClusterManagers = initialClusterManagers;
   }
 
   @Override
-  public void setInitialPolygons(Object initialPolygons) {
+  public void setInitialPolygons(@NonNull List initialPolygons) {
     this.initialPolygons = initialPolygons;
   }
 
   @Override
-  public void setInitialPolylines(Object initialPolylines) {
+  public void setInitialPolylines(@NonNull List initialPolylines) {
     this.initialPolylines = initialPolylines;
   }
 
   @Override
-  public void setInitialCircles(Object initialCircles) {
+  public void setInitialCircles(@NonNull List initialCircles) {
     this.initialCircles = initialCircles;
   }
 
   @Override
-  public void setInitialHeatmaps(Object initialHeatmaps) {
+  public void setInitialHeatmaps(@NonNull List initialHeatmaps) {
     this.initialHeatmaps = initialHeatmaps;
   }
 
-  @Override
-  public void setInitialTileOverlays(List> initialTileOverlays) {
+  public void setInitialTileOverlays(
+      @NonNull List initialTileOverlays) {
     this.initialTileOverlays = initialTileOverlays;
   }
 
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java
index 4cb5e3b57af..9327669e927 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java
+++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java
@@ -51,7 +51,6 @@
 import java.io.ByteArrayOutputStream;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 
@@ -96,13 +95,13 @@ class GoogleMapController
   private final TileOverlaysController tileOverlaysController;
   private MarkerManager markerManager;
   private MarkerManager.Collection markerCollection;
-  private List initialMarkers;
-  private List initialClusterManagers;
-  private List initialPolygons;
-  private List initialPolylines;
-  private List initialCircles;
-  private List initialHeatmaps;
-  private List> initialTileOverlays;
+  private @Nullable List initialMarkers;
+  private @Nullable List initialClusterManagers;
+  private @Nullable List initialPolygons;
+  private @Nullable List initialPolylines;
+  private @Nullable List initialCircles;
+  private @Nullable List initialHeatmaps;
+  private @Nullable List initialTileOverlays;
   // Null except between initialization and onMapReady.
   private @Nullable String initialMapStyle;
   private boolean lastSetStyleSucceeded;
@@ -624,22 +623,23 @@ public void setZoomControlsEnabled(boolean zoomControlsEnabled) {
   }
 
   @Override
-  public void setInitialMarkers(Object initialMarkers) {
-    ArrayList markers = (ArrayList) initialMarkers;
-    this.initialMarkers = markers != null ? new ArrayList<>(markers) : null;
+  public void setInitialMarkers(@NonNull List initialMarkers) {
+    this.initialMarkers = initialMarkers;
     if (googleMap != null) {
       updateInitialMarkers();
     }
   }
 
   private void updateInitialMarkers() {
-    markersController.addJsonMarkers(initialMarkers);
+    if (initialMarkers != null) {
+      markersController.addMarkers(initialMarkers);
+    }
   }
 
   @Override
-  public void setInitialClusterManagers(Object initialClusterManagers) {
-    ArrayList clusterManagers = (ArrayList) initialClusterManagers;
-    this.initialClusterManagers = clusterManagers != null ? new ArrayList<>(clusterManagers) : null;
+  public void setInitialClusterManagers(
+      @NonNull List initialClusterManagers) {
+    this.initialClusterManagers = initialClusterManagers;
     if (googleMap != null) {
       updateInitialClusterManagers();
     }
@@ -647,64 +647,69 @@ public void setInitialClusterManagers(Object initialClusterManagers) {
 
   private void updateInitialClusterManagers() {
     if (initialClusterManagers != null) {
-      clusterManagersController.addJsonClusterManagers(initialClusterManagers);
+      clusterManagersController.addClusterManagers(initialClusterManagers);
     }
   }
 
   @Override
-  public void setInitialPolygons(Object initialPolygons) {
-    ArrayList polygons = (ArrayList) initialPolygons;
-    this.initialPolygons = polygons != null ? new ArrayList<>(polygons) : null;
+  public void setInitialPolygons(@NonNull List initialPolygons) {
+    this.initialPolygons = initialPolygons;
     if (googleMap != null) {
       updateInitialPolygons();
     }
   }
 
   private void updateInitialPolygons() {
-    polygonsController.addJsonPolygons(initialPolygons);
+    if (initialPolygons != null) {
+      polygonsController.addPolygons(initialPolygons);
+    }
   }
 
   @Override
-  public void setInitialPolylines(Object initialPolylines) {
-    ArrayList polylines = (ArrayList) initialPolylines;
-    this.initialPolylines = polylines != null ? new ArrayList<>(polylines) : null;
+  public void setInitialPolylines(@NonNull List initialPolylines) {
+    this.initialPolylines = initialPolylines;
     if (googleMap != null) {
       updateInitialPolylines();
     }
   }
 
   private void updateInitialPolylines() {
-    polylinesController.addJsonPolylines(initialPolylines);
+    if (initialPolylines != null) {
+      polylinesController.addPolylines(initialPolylines);
+    }
   }
 
   @Override
-  public void setInitialCircles(Object initialCircles) {
-    ArrayList circles = (ArrayList) initialCircles;
-    this.initialCircles = circles != null ? new ArrayList<>(circles) : null;
+  public void setInitialCircles(@NonNull List initialCircles) {
+    this.initialCircles = initialCircles;
     if (googleMap != null) {
       updateInitialCircles();
     }
   }
 
   @Override
-  public void setInitialHeatmaps(Object initialHeatmaps) {
-    List heatmaps = (List) initialHeatmaps;
-    this.initialHeatmaps = heatmaps != null ? new ArrayList<>(heatmaps) : null;
+  public void setInitialHeatmaps(@NonNull List initialHeatmaps) {
+    this.initialHeatmaps = initialHeatmaps;
     if (googleMap != null) {
       updateInitialHeatmaps();
     }
   }
 
   private void updateInitialCircles() {
-    circlesController.addJsonCircles(initialCircles);
+    if (initialCircles != null) {
+      circlesController.addCircles(initialCircles);
+    }
   }
 
   private void updateInitialHeatmaps() {
-    heatmapsController.addJsonHeatmaps(initialHeatmaps);
+    if (initialHeatmaps != null) {
+      heatmapsController.addHeatmaps(initialHeatmaps);
+    }
   }
 
   @Override
-  public void setInitialTileOverlays(List> initialTileOverlays) {
+  public void setInitialTileOverlays(
+      @NonNull List initialTileOverlays) {
     this.initialTileOverlays = initialTileOverlays;
     if (googleMap != null) {
       updateInitialTileOverlays();
@@ -712,7 +717,9 @@ public void setInitialTileOverlays(List> initialTileOverlays) {
   }
 
   private void updateInitialTileOverlays() {
-    tileOverlaysController.addJsonTileOverlays(initialTileOverlays);
+    if (initialTileOverlays != null) {
+      tileOverlaysController.addTileOverlays(initialTileOverlays);
+    }
   }
 
   @SuppressLint("MissingPermission")
@@ -809,7 +816,7 @@ public void waitForMap(@NonNull Messages.VoidResult result) {
 
   @Override
   public void updateMapConfiguration(@NonNull Messages.PlatformMapConfiguration configuration) {
-    Convert.interpretGoogleMapOptions(configuration.getJson(), this);
+    Convert.interpretMapConfiguration(configuration, this);
   }
 
   @Override
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java
index 81ab3ec7207..c1a3496e7f4 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java
+++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java
@@ -4,18 +4,14 @@
 
 package io.flutter.plugins.googlemaps;
 
-import static io.flutter.plugins.googlemaps.Convert.HEATMAPS_TO_ADD_KEY;
-
 import android.content.Context;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import com.google.android.gms.maps.model.CameraPosition;
 import io.flutter.plugin.common.BinaryMessenger;
-import io.flutter.plugin.common.StandardMessageCodec;
 import io.flutter.plugin.platform.PlatformView;
 import io.flutter.plugin.platform.PlatformViewFactory;
-import java.util.List;
-import java.util.Map;
+import java.util.Objects;
 
 public class GoogleMapFactory extends PlatformViewFactory {
 
@@ -25,50 +21,35 @@ public class GoogleMapFactory extends PlatformViewFactory {
 
   GoogleMapFactory(
       BinaryMessenger binaryMessenger, Context context, LifecycleProvider lifecycleProvider) {
-    super(StandardMessageCodec.INSTANCE);
+    super(Messages.MapsApi.getCodec());
 
     this.binaryMessenger = binaryMessenger;
     this.lifecycleProvider = lifecycleProvider;
     this.googleMapInitializer = new GoogleMapInitializer(context, binaryMessenger);
   }
 
-  @SuppressWarnings("unchecked")
   @Override
   @NonNull
   public PlatformView create(@NonNull Context context, int id, @Nullable Object args) {
-    Map params = (Map) args;
+    final Messages.PlatformMapViewCreationParams params =
+        Objects.requireNonNull((Messages.PlatformMapViewCreationParams) args);
     final GoogleMapBuilder builder = new GoogleMapBuilder();
 
-    final Object options = params.get("options");
-    Convert.interpretGoogleMapOptions(options, builder);
-    if (params.containsKey("initialCameraPosition")) {
-      CameraPosition position = Convert.toCameraPosition(params.get("initialCameraPosition"));
-      builder.setInitialCameraPosition(position);
-    }
-    if (params.containsKey("clusterManagersToAdd")) {
-      builder.setInitialClusterManagers(params.get("clusterManagersToAdd"));
-    }
-    if (params.containsKey("markersToAdd")) {
-      builder.setInitialMarkers(params.get("markersToAdd"));
-    }
-    if (params.containsKey("polygonsToAdd")) {
-      builder.setInitialPolygons(params.get("polygonsToAdd"));
-    }
-    if (params.containsKey("polylinesToAdd")) {
-      builder.setInitialPolylines(params.get("polylinesToAdd"));
-    }
-    if (params.containsKey("circlesToAdd")) {
-      builder.setInitialCircles(params.get("circlesToAdd"));
-    }
-    if (params.containsKey(HEATMAPS_TO_ADD_KEY)) {
-      builder.setInitialHeatmaps(params.get(HEATMAPS_TO_ADD_KEY));
-    }
-    if (params.containsKey("tileOverlaysToAdd")) {
-      builder.setInitialTileOverlays((List>) params.get("tileOverlaysToAdd"));
-    }
-    final Object cloudMapId = ((Map) options).get("cloudMapId");
+    final Messages.PlatformMapConfiguration mapConfig = params.getMapConfiguration();
+    Convert.interpretMapConfiguration(mapConfig, builder);
+    CameraPosition position = Convert.cameraPositionFromPigeon(params.getInitialCameraPosition());
+    builder.setInitialCameraPosition(position);
+    builder.setInitialClusterManagers(params.getInitialClusterManagers());
+    builder.setInitialMarkers(params.getInitialMarkers());
+    builder.setInitialPolygons(params.getInitialPolygons());
+    builder.setInitialPolylines(params.getInitialPolylines());
+    builder.setInitialCircles(params.getInitialCircles());
+    builder.setInitialHeatmaps(params.getInitialHeatmaps());
+    builder.setInitialTileOverlays(params.getInitialTileOverlays());
+
+    final String cloudMapId = mapConfig.getCloudMapId();
     if (cloudMapId != null) {
-      builder.setMapId((String) cloudMapId);
+      builder.setMapId(cloudMapId);
     }
 
     return builder.build(id, context, binaryMessenger, lifecycleProvider);
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java
index b353da6f65f..457508e83c5 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java
+++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java
@@ -4,10 +4,10 @@
 
 package io.flutter.plugins.googlemaps;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import com.google.android.gms.maps.model.LatLngBounds;
 import java.util.List;
-import java.util.Map;
 
 /** Receiver of GoogleMap configuration options. */
 interface GoogleMapOptionsSink {
@@ -47,19 +47,20 @@ interface GoogleMapOptionsSink {
 
   void setBuildingsEnabled(boolean buildingsEnabled);
 
-  void setInitialMarkers(Object initialMarkers);
+  void setInitialMarkers(@NonNull List initialMarkers);
 
-  void setInitialClusterManagers(Object initialClusterManagers);
+  void setInitialClusterManagers(
+      @NonNull List initialClusterManagers);
 
-  void setInitialPolygons(Object initialPolygons);
+  void setInitialPolygons(@NonNull List initialPolygons);
 
-  void setInitialPolylines(Object initialPolylines);
+  void setInitialPolylines(@NonNull List initialPolylines);
 
-  void setInitialCircles(Object initialCircles);
+  void setInitialCircles(@NonNull List initialCircles);
 
-  void setInitialHeatmaps(Object initialHeatmaps);
+  void setInitialHeatmaps(@NonNull List initialHeatmaps);
 
-  void setInitialTileOverlays(List> initialTileOverlays);
+  void setInitialTileOverlays(@NonNull List initialTileOverlays);
 
   void setMapStyle(@Nullable String style);
 }
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/HeatmapsController.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/HeatmapsController.java
index 2bbc685365c..4bb85fbbe8f 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/HeatmapsController.java
+++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/HeatmapsController.java
@@ -33,17 +33,6 @@ void setGoogleMap(GoogleMap googleMap) {
     this.googleMap = googleMap;
   }
 
-  /** Adds heatmaps to the map from json data. */
-  void addJsonHeatmaps(List heatmapsToAdd) {
-    if (heatmapsToAdd != null) {
-      for (Object heatmapToAdd : heatmapsToAdd) {
-        @SuppressWarnings("unchecked")
-        Map heatmapMap = (Map) heatmapToAdd;
-        addJsonHeatmap(heatmapMap);
-      }
-    }
-  }
-
   /** Adds heatmaps to the map. */
   void addHeatmaps(@NonNull List heatmapsToAdd) {
     for (Messages.PlatformHeatmap heatmapToAdd : heatmapsToAdd) {
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/MarkersController.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/MarkersController.java
index d6546cc621b..6edee43be2d 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/MarkersController.java
+++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/MarkersController.java
@@ -44,16 +44,6 @@ void setCollection(MarkerManager.Collection markerCollection) {
     this.markerCollection = markerCollection;
   }
 
-  void addJsonMarkers(List markersToAdd) {
-    if (markersToAdd != null) {
-      for (Object markerToAdd : markersToAdd) {
-        @SuppressWarnings("unchecked")
-        Map markerMap = (Map) markerToAdd;
-        addJsonMarker(markerMap);
-      }
-    }
-  }
-
   void addMarkers(@NonNull List markersToAdd) {
     for (Messages.PlatformMarker markerToAdd : markersToAdd) {
       addJsonMarker(markerToAdd.getJson());
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Messages.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Messages.java
index 32fc6eaf6cb..c51fdd5166a 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Messages.java
+++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Messages.java
@@ -74,6 +74,21 @@ protected static FlutterError createConnectionError(@NonNull String channelName)
   @Retention(CLASS)
   @interface CanIgnoreReturnValue {}
 
+  /** Pigeon equivalent of MapType */
+  public enum PlatformMapType {
+    NONE(0),
+    NORMAL(1),
+    SATELLITE(2),
+    TERRAIN(3),
+    HYBRID(4);
+
+    final int index;
+
+    private PlatformMapType(final int index) {
+      this.index = index;
+    }
+  }
+
   public enum PlatformRendererType {
     LEGACY(0),
     LATEST(1);
@@ -958,6 +973,155 @@ ArrayList toList() {
     }
   }
 
+  /**
+   * Pigeon equivalent of Flutter's EdgeInsets.
+   *
+   * 

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformEdgeInsets { + private @NonNull Double top; + + public @NonNull Double getTop() { + return top; + } + + public void setTop(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"top\" is null."); + } + this.top = setterArg; + } + + private @NonNull Double bottom; + + public @NonNull Double getBottom() { + return bottom; + } + + public void setBottom(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"bottom\" is null."); + } + this.bottom = setterArg; + } + + private @NonNull Double left; + + public @NonNull Double getLeft() { + return left; + } + + public void setLeft(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"left\" is null."); + } + this.left = setterArg; + } + + private @NonNull Double right; + + public @NonNull Double getRight() { + return right; + } + + public void setRight(@NonNull Double setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"right\" is null."); + } + this.right = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformEdgeInsets() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformEdgeInsets that = (PlatformEdgeInsets) o; + return top.equals(that.top) + && bottom.equals(that.bottom) + && left.equals(that.left) + && right.equals(that.right); + } + + @Override + public int hashCode() { + return Objects.hash(top, bottom, left, right); + } + + public static final class Builder { + + private @Nullable Double top; + + @CanIgnoreReturnValue + public @NonNull Builder setTop(@NonNull Double setterArg) { + this.top = setterArg; + return this; + } + + private @Nullable Double bottom; + + @CanIgnoreReturnValue + public @NonNull Builder setBottom(@NonNull Double setterArg) { + this.bottom = setterArg; + return this; + } + + private @Nullable Double left; + + @CanIgnoreReturnValue + public @NonNull Builder setLeft(@NonNull Double setterArg) { + this.left = setterArg; + return this; + } + + private @Nullable Double right; + + @CanIgnoreReturnValue + public @NonNull Builder setRight(@NonNull Double setterArg) { + this.right = setterArg; + return this; + } + + public @NonNull PlatformEdgeInsets build() { + PlatformEdgeInsets pigeonReturn = new PlatformEdgeInsets(); + pigeonReturn.setTop(top); + pigeonReturn.setBottom(bottom); + pigeonReturn.setLeft(left); + pigeonReturn.setRight(right); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList(4); + toListResult.add(top); + toListResult.add(bottom); + toListResult.add(left); + toListResult.add(right); + return toListResult; + } + + static @NonNull PlatformEdgeInsets fromList(@NonNull ArrayList __pigeon_list) { + PlatformEdgeInsets pigeonResult = new PlatformEdgeInsets(); + Object top = __pigeon_list.get(0); + pigeonResult.setTop((Double) top); + Object bottom = __pigeon_list.get(1); + pigeonResult.setBottom((Double) bottom); + Object left = __pigeon_list.get(2); + pigeonResult.setLeft((Double) left); + Object right = __pigeon_list.get(3); + pigeonResult.setRight((Double) right); + return pigeonResult; + } + } + /** * Pigeon equivalent of LatLng. * @@ -1169,48 +1333,700 @@ public void setClusterManagerId(@NonNull String setterArg) { this.clusterManagerId = setterArg; } - private @NonNull PlatformLatLng position; + private @NonNull PlatformLatLng position; + + public @NonNull PlatformLatLng getPosition() { + return position; + } + + public void setPosition(@NonNull PlatformLatLng setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"position\" is null."); + } + this.position = setterArg; + } + + private @NonNull PlatformLatLngBounds bounds; + + public @NonNull PlatformLatLngBounds getBounds() { + return bounds; + } + + public void setBounds(@NonNull PlatformLatLngBounds setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"bounds\" is null."); + } + this.bounds = setterArg; + } + + private @NonNull List markerIds; + + public @NonNull List getMarkerIds() { + return markerIds; + } + + public void setMarkerIds(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"markerIds\" is null."); + } + this.markerIds = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformCluster() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformCluster that = (PlatformCluster) o; + return clusterManagerId.equals(that.clusterManagerId) + && position.equals(that.position) + && bounds.equals(that.bounds) + && markerIds.equals(that.markerIds); + } + + @Override + public int hashCode() { + return Objects.hash(clusterManagerId, position, bounds, markerIds); + } + + public static final class Builder { + + private @Nullable String clusterManagerId; + + @CanIgnoreReturnValue + public @NonNull Builder setClusterManagerId(@NonNull String setterArg) { + this.clusterManagerId = setterArg; + return this; + } + + private @Nullable PlatformLatLng position; + + @CanIgnoreReturnValue + public @NonNull Builder setPosition(@NonNull PlatformLatLng setterArg) { + this.position = setterArg; + return this; + } + + private @Nullable PlatformLatLngBounds bounds; + + @CanIgnoreReturnValue + public @NonNull Builder setBounds(@NonNull PlatformLatLngBounds setterArg) { + this.bounds = setterArg; + return this; + } + + private @Nullable List markerIds; + + @CanIgnoreReturnValue + public @NonNull Builder setMarkerIds(@NonNull List setterArg) { + this.markerIds = setterArg; + return this; + } + + public @NonNull PlatformCluster build() { + PlatformCluster pigeonReturn = new PlatformCluster(); + pigeonReturn.setClusterManagerId(clusterManagerId); + pigeonReturn.setPosition(position); + pigeonReturn.setBounds(bounds); + pigeonReturn.setMarkerIds(markerIds); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList(4); + toListResult.add(clusterManagerId); + toListResult.add(position); + toListResult.add(bounds); + toListResult.add(markerIds); + return toListResult; + } + + static @NonNull PlatformCluster fromList(@NonNull ArrayList __pigeon_list) { + PlatformCluster pigeonResult = new PlatformCluster(); + Object clusterManagerId = __pigeon_list.get(0); + pigeonResult.setClusterManagerId((String) clusterManagerId); + Object position = __pigeon_list.get(1); + pigeonResult.setPosition((PlatformLatLng) position); + Object bounds = __pigeon_list.get(2); + pigeonResult.setBounds((PlatformLatLngBounds) bounds); + Object markerIds = __pigeon_list.get(3); + pigeonResult.setMarkerIds((List) markerIds); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of CameraTargetBounds. + * + *

As with the Dart version, it exists to distinguish between not setting a a target, and + * having an explicitly unbounded target (null [bounds]). + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformCameraTargetBounds { + private @Nullable PlatformLatLngBounds bounds; + + public @Nullable PlatformLatLngBounds getBounds() { + return bounds; + } + + public void setBounds(@Nullable PlatformLatLngBounds setterArg) { + this.bounds = setterArg; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformCameraTargetBounds that = (PlatformCameraTargetBounds) o; + return Objects.equals(bounds, that.bounds); + } + + @Override + public int hashCode() { + return Objects.hash(bounds); + } + + public static final class Builder { + + private @Nullable PlatformLatLngBounds bounds; + + @CanIgnoreReturnValue + public @NonNull Builder setBounds(@Nullable PlatformLatLngBounds setterArg) { + this.bounds = setterArg; + return this; + } + + public @NonNull PlatformCameraTargetBounds build() { + PlatformCameraTargetBounds pigeonReturn = new PlatformCameraTargetBounds(); + pigeonReturn.setBounds(bounds); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList(1); + toListResult.add(bounds); + return toListResult; + } + + static @NonNull PlatformCameraTargetBounds fromList(@NonNull ArrayList __pigeon_list) { + PlatformCameraTargetBounds pigeonResult = new PlatformCameraTargetBounds(); + Object bounds = __pigeon_list.get(0); + pigeonResult.setBounds((PlatformLatLngBounds) bounds); + return pigeonResult; + } + } + + /** + * Information passed to the platform view creation. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformMapViewCreationParams { + private @NonNull PlatformCameraPosition initialCameraPosition; + + public @NonNull PlatformCameraPosition getInitialCameraPosition() { + return initialCameraPosition; + } + + public void setInitialCameraPosition(@NonNull PlatformCameraPosition setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"initialCameraPosition\" is null."); + } + this.initialCameraPosition = setterArg; + } + + private @NonNull PlatformMapConfiguration mapConfiguration; + + public @NonNull PlatformMapConfiguration getMapConfiguration() { + return mapConfiguration; + } + + public void setMapConfiguration(@NonNull PlatformMapConfiguration setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"mapConfiguration\" is null."); + } + this.mapConfiguration = setterArg; + } + + private @NonNull List initialCircles; + + public @NonNull List getInitialCircles() { + return initialCircles; + } + + public void setInitialCircles(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"initialCircles\" is null."); + } + this.initialCircles = setterArg; + } + + private @NonNull List initialMarkers; + + public @NonNull List getInitialMarkers() { + return initialMarkers; + } + + public void setInitialMarkers(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"initialMarkers\" is null."); + } + this.initialMarkers = setterArg; + } + + private @NonNull List initialPolygons; + + public @NonNull List getInitialPolygons() { + return initialPolygons; + } + + public void setInitialPolygons(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"initialPolygons\" is null."); + } + this.initialPolygons = setterArg; + } + + private @NonNull List initialPolylines; + + public @NonNull List getInitialPolylines() { + return initialPolylines; + } + + public void setInitialPolylines(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"initialPolylines\" is null."); + } + this.initialPolylines = setterArg; + } + + private @NonNull List initialHeatmaps; + + public @NonNull List getInitialHeatmaps() { + return initialHeatmaps; + } + + public void setInitialHeatmaps(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"initialHeatmaps\" is null."); + } + this.initialHeatmaps = setterArg; + } + + private @NonNull List initialTileOverlays; + + public @NonNull List getInitialTileOverlays() { + return initialTileOverlays; + } + + public void setInitialTileOverlays(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"initialTileOverlays\" is null."); + } + this.initialTileOverlays = setterArg; + } + + private @NonNull List initialClusterManagers; + + public @NonNull List getInitialClusterManagers() { + return initialClusterManagers; + } + + public void setInitialClusterManagers(@NonNull List setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"initialClusterManagers\" is null."); + } + this.initialClusterManagers = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + PlatformMapViewCreationParams() {} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PlatformMapViewCreationParams that = (PlatformMapViewCreationParams) o; + return initialCameraPosition.equals(that.initialCameraPosition) + && mapConfiguration.equals(that.mapConfiguration) + && initialCircles.equals(that.initialCircles) + && initialMarkers.equals(that.initialMarkers) + && initialPolygons.equals(that.initialPolygons) + && initialPolylines.equals(that.initialPolylines) + && initialHeatmaps.equals(that.initialHeatmaps) + && initialTileOverlays.equals(that.initialTileOverlays) + && initialClusterManagers.equals(that.initialClusterManagers); + } + + @Override + public int hashCode() { + return Objects.hash( + initialCameraPosition, + mapConfiguration, + initialCircles, + initialMarkers, + initialPolygons, + initialPolylines, + initialHeatmaps, + initialTileOverlays, + initialClusterManagers); + } + + public static final class Builder { + + private @Nullable PlatformCameraPosition initialCameraPosition; + + @CanIgnoreReturnValue + public @NonNull Builder setInitialCameraPosition(@NonNull PlatformCameraPosition setterArg) { + this.initialCameraPosition = setterArg; + return this; + } + + private @Nullable PlatformMapConfiguration mapConfiguration; + + @CanIgnoreReturnValue + public @NonNull Builder setMapConfiguration(@NonNull PlatformMapConfiguration setterArg) { + this.mapConfiguration = setterArg; + return this; + } + + private @Nullable List initialCircles; + + @CanIgnoreReturnValue + public @NonNull Builder setInitialCircles(@NonNull List setterArg) { + this.initialCircles = setterArg; + return this; + } + + private @Nullable List initialMarkers; + + @CanIgnoreReturnValue + public @NonNull Builder setInitialMarkers(@NonNull List setterArg) { + this.initialMarkers = setterArg; + return this; + } + + private @Nullable List initialPolygons; + + @CanIgnoreReturnValue + public @NonNull Builder setInitialPolygons(@NonNull List setterArg) { + this.initialPolygons = setterArg; + return this; + } + + private @Nullable List initialPolylines; + + @CanIgnoreReturnValue + public @NonNull Builder setInitialPolylines(@NonNull List setterArg) { + this.initialPolylines = setterArg; + return this; + } + + private @Nullable List initialHeatmaps; + + @CanIgnoreReturnValue + public @NonNull Builder setInitialHeatmaps(@NonNull List setterArg) { + this.initialHeatmaps = setterArg; + return this; + } + + private @Nullable List initialTileOverlays; + + @CanIgnoreReturnValue + public @NonNull Builder setInitialTileOverlays(@NonNull List setterArg) { + this.initialTileOverlays = setterArg; + return this; + } + + private @Nullable List initialClusterManagers; + + @CanIgnoreReturnValue + public @NonNull Builder setInitialClusterManagers( + @NonNull List setterArg) { + this.initialClusterManagers = setterArg; + return this; + } + + public @NonNull PlatformMapViewCreationParams build() { + PlatformMapViewCreationParams pigeonReturn = new PlatformMapViewCreationParams(); + pigeonReturn.setInitialCameraPosition(initialCameraPosition); + pigeonReturn.setMapConfiguration(mapConfiguration); + pigeonReturn.setInitialCircles(initialCircles); + pigeonReturn.setInitialMarkers(initialMarkers); + pigeonReturn.setInitialPolygons(initialPolygons); + pigeonReturn.setInitialPolylines(initialPolylines); + pigeonReturn.setInitialHeatmaps(initialHeatmaps); + pigeonReturn.setInitialTileOverlays(initialTileOverlays); + pigeonReturn.setInitialClusterManagers(initialClusterManagers); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList(9); + toListResult.add(initialCameraPosition); + toListResult.add(mapConfiguration); + toListResult.add(initialCircles); + toListResult.add(initialMarkers); + toListResult.add(initialPolygons); + toListResult.add(initialPolylines); + toListResult.add(initialHeatmaps); + toListResult.add(initialTileOverlays); + toListResult.add(initialClusterManagers); + return toListResult; + } + + static @NonNull PlatformMapViewCreationParams fromList( + @NonNull ArrayList __pigeon_list) { + PlatformMapViewCreationParams pigeonResult = new PlatformMapViewCreationParams(); + Object initialCameraPosition = __pigeon_list.get(0); + pigeonResult.setInitialCameraPosition((PlatformCameraPosition) initialCameraPosition); + Object mapConfiguration = __pigeon_list.get(1); + pigeonResult.setMapConfiguration((PlatformMapConfiguration) mapConfiguration); + Object initialCircles = __pigeon_list.get(2); + pigeonResult.setInitialCircles((List) initialCircles); + Object initialMarkers = __pigeon_list.get(3); + pigeonResult.setInitialMarkers((List) initialMarkers); + Object initialPolygons = __pigeon_list.get(4); + pigeonResult.setInitialPolygons((List) initialPolygons); + Object initialPolylines = __pigeon_list.get(5); + pigeonResult.setInitialPolylines((List) initialPolylines); + Object initialHeatmaps = __pigeon_list.get(6); + pigeonResult.setInitialHeatmaps((List) initialHeatmaps); + Object initialTileOverlays = __pigeon_list.get(7); + pigeonResult.setInitialTileOverlays((List) initialTileOverlays); + Object initialClusterManagers = __pigeon_list.get(8); + pigeonResult.setInitialClusterManagers((List) initialClusterManagers); + return pigeonResult; + } + } + + /** + * Pigeon equivalent of MapConfiguration. + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class PlatformMapConfiguration { + private @Nullable Boolean compassEnabled; + + public @Nullable Boolean getCompassEnabled() { + return compassEnabled; + } + + public void setCompassEnabled(@Nullable Boolean setterArg) { + this.compassEnabled = setterArg; + } + + private @Nullable PlatformCameraTargetBounds cameraTargetBounds; + + public @Nullable PlatformCameraTargetBounds getCameraTargetBounds() { + return cameraTargetBounds; + } + + public void setCameraTargetBounds(@Nullable PlatformCameraTargetBounds setterArg) { + this.cameraTargetBounds = setterArg; + } + + private @Nullable PlatformMapType mapType; + + public @Nullable PlatformMapType getMapType() { + return mapType; + } + + public void setMapType(@Nullable PlatformMapType setterArg) { + this.mapType = setterArg; + } + + private @Nullable PlatformZoomRange minMaxZoomPreference; + + public @Nullable PlatformZoomRange getMinMaxZoomPreference() { + return minMaxZoomPreference; + } + + public void setMinMaxZoomPreference(@Nullable PlatformZoomRange setterArg) { + this.minMaxZoomPreference = setterArg; + } + + private @Nullable Boolean mapToolbarEnabled; + + public @Nullable Boolean getMapToolbarEnabled() { + return mapToolbarEnabled; + } + + public void setMapToolbarEnabled(@Nullable Boolean setterArg) { + this.mapToolbarEnabled = setterArg; + } + + private @Nullable Boolean rotateGesturesEnabled; + + public @Nullable Boolean getRotateGesturesEnabled() { + return rotateGesturesEnabled; + } + + public void setRotateGesturesEnabled(@Nullable Boolean setterArg) { + this.rotateGesturesEnabled = setterArg; + } + + private @Nullable Boolean scrollGesturesEnabled; + + public @Nullable Boolean getScrollGesturesEnabled() { + return scrollGesturesEnabled; + } + + public void setScrollGesturesEnabled(@Nullable Boolean setterArg) { + this.scrollGesturesEnabled = setterArg; + } + + private @Nullable Boolean tiltGesturesEnabled; + + public @Nullable Boolean getTiltGesturesEnabled() { + return tiltGesturesEnabled; + } + + public void setTiltGesturesEnabled(@Nullable Boolean setterArg) { + this.tiltGesturesEnabled = setterArg; + } + + private @Nullable Boolean trackCameraPosition; + + public @Nullable Boolean getTrackCameraPosition() { + return trackCameraPosition; + } + + public void setTrackCameraPosition(@Nullable Boolean setterArg) { + this.trackCameraPosition = setterArg; + } + + private @Nullable Boolean zoomControlsEnabled; + + public @Nullable Boolean getZoomControlsEnabled() { + return zoomControlsEnabled; + } + + public void setZoomControlsEnabled(@Nullable Boolean setterArg) { + this.zoomControlsEnabled = setterArg; + } + + private @Nullable Boolean zoomGesturesEnabled; + + public @Nullable Boolean getZoomGesturesEnabled() { + return zoomGesturesEnabled; + } + + public void setZoomGesturesEnabled(@Nullable Boolean setterArg) { + this.zoomGesturesEnabled = setterArg; + } + + private @Nullable Boolean myLocationEnabled; + + public @Nullable Boolean getMyLocationEnabled() { + return myLocationEnabled; + } + + public void setMyLocationEnabled(@Nullable Boolean setterArg) { + this.myLocationEnabled = setterArg; + } + + private @Nullable Boolean myLocationButtonEnabled; + + public @Nullable Boolean getMyLocationButtonEnabled() { + return myLocationButtonEnabled; + } + + public void setMyLocationButtonEnabled(@Nullable Boolean setterArg) { + this.myLocationButtonEnabled = setterArg; + } + + private @Nullable PlatformEdgeInsets padding; + + public @Nullable PlatformEdgeInsets getPadding() { + return padding; + } + + public void setPadding(@Nullable PlatformEdgeInsets setterArg) { + this.padding = setterArg; + } + + private @Nullable Boolean indoorViewEnabled; + + public @Nullable Boolean getIndoorViewEnabled() { + return indoorViewEnabled; + } + + public void setIndoorViewEnabled(@Nullable Boolean setterArg) { + this.indoorViewEnabled = setterArg; + } + + private @Nullable Boolean trafficEnabled; + + public @Nullable Boolean getTrafficEnabled() { + return trafficEnabled; + } + + public void setTrafficEnabled(@Nullable Boolean setterArg) { + this.trafficEnabled = setterArg; + } + + private @Nullable Boolean buildingsEnabled; + + public @Nullable Boolean getBuildingsEnabled() { + return buildingsEnabled; + } + + public void setBuildingsEnabled(@Nullable Boolean setterArg) { + this.buildingsEnabled = setterArg; + } + + private @Nullable Boolean liteModeEnabled; - public @NonNull PlatformLatLng getPosition() { - return position; + public @Nullable Boolean getLiteModeEnabled() { + return liteModeEnabled; } - public void setPosition(@NonNull PlatformLatLng setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"position\" is null."); - } - this.position = setterArg; + public void setLiteModeEnabled(@Nullable Boolean setterArg) { + this.liteModeEnabled = setterArg; } - private @NonNull PlatformLatLngBounds bounds; + private @Nullable String cloudMapId; - public @NonNull PlatformLatLngBounds getBounds() { - return bounds; + public @Nullable String getCloudMapId() { + return cloudMapId; } - public void setBounds(@NonNull PlatformLatLngBounds setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"bounds\" is null."); - } - this.bounds = setterArg; + public void setCloudMapId(@Nullable String setterArg) { + this.cloudMapId = setterArg; } - private @NonNull List markerIds; + private @Nullable String style; - public @NonNull List getMarkerIds() { - return markerIds; + public @Nullable String getStyle() { + return style; } - public void setMarkerIds(@NonNull List setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"markerIds\" is null."); - } - this.markerIds = setterArg; + public void setStyle(@Nullable String setterArg) { + this.style = setterArg; } - /** Constructor is non-public to enforce null safety; use Builder. */ - PlatformCluster() {} - @Override public boolean equals(Object o) { if (this == o) { @@ -1219,158 +2035,311 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) { return false; } - PlatformCluster that = (PlatformCluster) o; - return clusterManagerId.equals(that.clusterManagerId) - && position.equals(that.position) - && bounds.equals(that.bounds) - && markerIds.equals(that.markerIds); + PlatformMapConfiguration that = (PlatformMapConfiguration) o; + return Objects.equals(compassEnabled, that.compassEnabled) + && Objects.equals(cameraTargetBounds, that.cameraTargetBounds) + && Objects.equals(mapType, that.mapType) + && Objects.equals(minMaxZoomPreference, that.minMaxZoomPreference) + && Objects.equals(mapToolbarEnabled, that.mapToolbarEnabled) + && Objects.equals(rotateGesturesEnabled, that.rotateGesturesEnabled) + && Objects.equals(scrollGesturesEnabled, that.scrollGesturesEnabled) + && Objects.equals(tiltGesturesEnabled, that.tiltGesturesEnabled) + && Objects.equals(trackCameraPosition, that.trackCameraPosition) + && Objects.equals(zoomControlsEnabled, that.zoomControlsEnabled) + && Objects.equals(zoomGesturesEnabled, that.zoomGesturesEnabled) + && Objects.equals(myLocationEnabled, that.myLocationEnabled) + && Objects.equals(myLocationButtonEnabled, that.myLocationButtonEnabled) + && Objects.equals(padding, that.padding) + && Objects.equals(indoorViewEnabled, that.indoorViewEnabled) + && Objects.equals(trafficEnabled, that.trafficEnabled) + && Objects.equals(buildingsEnabled, that.buildingsEnabled) + && Objects.equals(liteModeEnabled, that.liteModeEnabled) + && Objects.equals(cloudMapId, that.cloudMapId) + && Objects.equals(style, that.style); } @Override public int hashCode() { - return Objects.hash(clusterManagerId, position, bounds, markerIds); + return Objects.hash( + compassEnabled, + cameraTargetBounds, + mapType, + minMaxZoomPreference, + mapToolbarEnabled, + rotateGesturesEnabled, + scrollGesturesEnabled, + tiltGesturesEnabled, + trackCameraPosition, + zoomControlsEnabled, + zoomGesturesEnabled, + myLocationEnabled, + myLocationButtonEnabled, + padding, + indoorViewEnabled, + trafficEnabled, + buildingsEnabled, + liteModeEnabled, + cloudMapId, + style); } public static final class Builder { - private @Nullable String clusterManagerId; + private @Nullable Boolean compassEnabled; @CanIgnoreReturnValue - public @NonNull Builder setClusterManagerId(@NonNull String setterArg) { - this.clusterManagerId = setterArg; + public @NonNull Builder setCompassEnabled(@Nullable Boolean setterArg) { + this.compassEnabled = setterArg; return this; } - private @Nullable PlatformLatLng position; + private @Nullable PlatformCameraTargetBounds cameraTargetBounds; @CanIgnoreReturnValue - public @NonNull Builder setPosition(@NonNull PlatformLatLng setterArg) { - this.position = setterArg; + public @NonNull Builder setCameraTargetBounds( + @Nullable PlatformCameraTargetBounds setterArg) { + this.cameraTargetBounds = setterArg; return this; } - private @Nullable PlatformLatLngBounds bounds; + private @Nullable PlatformMapType mapType; @CanIgnoreReturnValue - public @NonNull Builder setBounds(@NonNull PlatformLatLngBounds setterArg) { - this.bounds = setterArg; + public @NonNull Builder setMapType(@Nullable PlatformMapType setterArg) { + this.mapType = setterArg; return this; } - private @Nullable List markerIds; + private @Nullable PlatformZoomRange minMaxZoomPreference; @CanIgnoreReturnValue - public @NonNull Builder setMarkerIds(@NonNull List setterArg) { - this.markerIds = setterArg; + public @NonNull Builder setMinMaxZoomPreference(@Nullable PlatformZoomRange setterArg) { + this.minMaxZoomPreference = setterArg; return this; } - public @NonNull PlatformCluster build() { - PlatformCluster pigeonReturn = new PlatformCluster(); - pigeonReturn.setClusterManagerId(clusterManagerId); - pigeonReturn.setPosition(position); - pigeonReturn.setBounds(bounds); - pigeonReturn.setMarkerIds(markerIds); - return pigeonReturn; + private @Nullable Boolean mapToolbarEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setMapToolbarEnabled(@Nullable Boolean setterArg) { + this.mapToolbarEnabled = setterArg; + return this; } - } - @NonNull - ArrayList toList() { - ArrayList toListResult = new ArrayList(4); - toListResult.add(clusterManagerId); - toListResult.add(position); - toListResult.add(bounds); - toListResult.add(markerIds); - return toListResult; - } + private @Nullable Boolean rotateGesturesEnabled; - static @NonNull PlatformCluster fromList(@NonNull ArrayList __pigeon_list) { - PlatformCluster pigeonResult = new PlatformCluster(); - Object clusterManagerId = __pigeon_list.get(0); - pigeonResult.setClusterManagerId((String) clusterManagerId); - Object position = __pigeon_list.get(1); - pigeonResult.setPosition((PlatformLatLng) position); - Object bounds = __pigeon_list.get(2); - pigeonResult.setBounds((PlatformLatLngBounds) bounds); - Object markerIds = __pigeon_list.get(3); - pigeonResult.setMarkerIds((List) markerIds); - return pigeonResult; - } - } + @CanIgnoreReturnValue + public @NonNull Builder setRotateGesturesEnabled(@Nullable Boolean setterArg) { + this.rotateGesturesEnabled = setterArg; + return this; + } - /** - * Pigeon equivalent of MapConfiguration. - * - *

Generated class from Pigeon that represents data sent in messages. - */ - public static final class PlatformMapConfiguration { - /** - * The configuration options, as JSON. This should only be set from _jsonForMapConfiguration, - * and the native code must interpret it according to the internal implementation details of - * that method. - */ - private @NonNull Map json; + private @Nullable Boolean scrollGesturesEnabled; - public @NonNull Map getJson() { - return json; - } + @CanIgnoreReturnValue + public @NonNull Builder setScrollGesturesEnabled(@Nullable Boolean setterArg) { + this.scrollGesturesEnabled = setterArg; + return this; + } - public void setJson(@NonNull Map setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"json\" is null."); + private @Nullable Boolean tiltGesturesEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setTiltGesturesEnabled(@Nullable Boolean setterArg) { + this.tiltGesturesEnabled = setterArg; + return this; } - this.json = setterArg; - } - /** Constructor is non-public to enforce null safety; use Builder. */ - PlatformMapConfiguration() {} + private @Nullable Boolean trackCameraPosition; - @Override - public boolean equals(Object o) { - if (this == o) { - return true; + @CanIgnoreReturnValue + public @NonNull Builder setTrackCameraPosition(@Nullable Boolean setterArg) { + this.trackCameraPosition = setterArg; + return this; } - if (o == null || getClass() != o.getClass()) { - return false; + + private @Nullable Boolean zoomControlsEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setZoomControlsEnabled(@Nullable Boolean setterArg) { + this.zoomControlsEnabled = setterArg; + return this; } - PlatformMapConfiguration that = (PlatformMapConfiguration) o; - return json.equals(that.json); - } - @Override - public int hashCode() { - return Objects.hash(json); - } + private @Nullable Boolean zoomGesturesEnabled; - public static final class Builder { + @CanIgnoreReturnValue + public @NonNull Builder setZoomGesturesEnabled(@Nullable Boolean setterArg) { + this.zoomGesturesEnabled = setterArg; + return this; + } - private @Nullable Map json; + private @Nullable Boolean myLocationEnabled; @CanIgnoreReturnValue - public @NonNull Builder setJson(@NonNull Map setterArg) { - this.json = setterArg; + public @NonNull Builder setMyLocationEnabled(@Nullable Boolean setterArg) { + this.myLocationEnabled = setterArg; + return this; + } + + private @Nullable Boolean myLocationButtonEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setMyLocationButtonEnabled(@Nullable Boolean setterArg) { + this.myLocationButtonEnabled = setterArg; + return this; + } + + private @Nullable PlatformEdgeInsets padding; + + @CanIgnoreReturnValue + public @NonNull Builder setPadding(@Nullable PlatformEdgeInsets setterArg) { + this.padding = setterArg; + return this; + } + + private @Nullable Boolean indoorViewEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setIndoorViewEnabled(@Nullable Boolean setterArg) { + this.indoorViewEnabled = setterArg; + return this; + } + + private @Nullable Boolean trafficEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setTrafficEnabled(@Nullable Boolean setterArg) { + this.trafficEnabled = setterArg; + return this; + } + + private @Nullable Boolean buildingsEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setBuildingsEnabled(@Nullable Boolean setterArg) { + this.buildingsEnabled = setterArg; + return this; + } + + private @Nullable Boolean liteModeEnabled; + + @CanIgnoreReturnValue + public @NonNull Builder setLiteModeEnabled(@Nullable Boolean setterArg) { + this.liteModeEnabled = setterArg; + return this; + } + + private @Nullable String cloudMapId; + + @CanIgnoreReturnValue + public @NonNull Builder setCloudMapId(@Nullable String setterArg) { + this.cloudMapId = setterArg; + return this; + } + + private @Nullable String style; + + @CanIgnoreReturnValue + public @NonNull Builder setStyle(@Nullable String setterArg) { + this.style = setterArg; return this; } public @NonNull PlatformMapConfiguration build() { PlatformMapConfiguration pigeonReturn = new PlatformMapConfiguration(); - pigeonReturn.setJson(json); + pigeonReturn.setCompassEnabled(compassEnabled); + pigeonReturn.setCameraTargetBounds(cameraTargetBounds); + pigeonReturn.setMapType(mapType); + pigeonReturn.setMinMaxZoomPreference(minMaxZoomPreference); + pigeonReturn.setMapToolbarEnabled(mapToolbarEnabled); + pigeonReturn.setRotateGesturesEnabled(rotateGesturesEnabled); + pigeonReturn.setScrollGesturesEnabled(scrollGesturesEnabled); + pigeonReturn.setTiltGesturesEnabled(tiltGesturesEnabled); + pigeonReturn.setTrackCameraPosition(trackCameraPosition); + pigeonReturn.setZoomControlsEnabled(zoomControlsEnabled); + pigeonReturn.setZoomGesturesEnabled(zoomGesturesEnabled); + pigeonReturn.setMyLocationEnabled(myLocationEnabled); + pigeonReturn.setMyLocationButtonEnabled(myLocationButtonEnabled); + pigeonReturn.setPadding(padding); + pigeonReturn.setIndoorViewEnabled(indoorViewEnabled); + pigeonReturn.setTrafficEnabled(trafficEnabled); + pigeonReturn.setBuildingsEnabled(buildingsEnabled); + pigeonReturn.setLiteModeEnabled(liteModeEnabled); + pigeonReturn.setCloudMapId(cloudMapId); + pigeonReturn.setStyle(style); return pigeonReturn; } } @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(1); - toListResult.add(json); + ArrayList toListResult = new ArrayList(20); + toListResult.add(compassEnabled); + toListResult.add(cameraTargetBounds); + toListResult.add(mapType); + toListResult.add(minMaxZoomPreference); + toListResult.add(mapToolbarEnabled); + toListResult.add(rotateGesturesEnabled); + toListResult.add(scrollGesturesEnabled); + toListResult.add(tiltGesturesEnabled); + toListResult.add(trackCameraPosition); + toListResult.add(zoomControlsEnabled); + toListResult.add(zoomGesturesEnabled); + toListResult.add(myLocationEnabled); + toListResult.add(myLocationButtonEnabled); + toListResult.add(padding); + toListResult.add(indoorViewEnabled); + toListResult.add(trafficEnabled); + toListResult.add(buildingsEnabled); + toListResult.add(liteModeEnabled); + toListResult.add(cloudMapId); + toListResult.add(style); return toListResult; } static @NonNull PlatformMapConfiguration fromList(@NonNull ArrayList __pigeon_list) { PlatformMapConfiguration pigeonResult = new PlatformMapConfiguration(); - Object json = __pigeon_list.get(0); - pigeonResult.setJson((Map) json); + Object compassEnabled = __pigeon_list.get(0); + pigeonResult.setCompassEnabled((Boolean) compassEnabled); + Object cameraTargetBounds = __pigeon_list.get(1); + pigeonResult.setCameraTargetBounds((PlatformCameraTargetBounds) cameraTargetBounds); + Object mapType = __pigeon_list.get(2); + pigeonResult.setMapType((PlatformMapType) mapType); + Object minMaxZoomPreference = __pigeon_list.get(3); + pigeonResult.setMinMaxZoomPreference((PlatformZoomRange) minMaxZoomPreference); + Object mapToolbarEnabled = __pigeon_list.get(4); + pigeonResult.setMapToolbarEnabled((Boolean) mapToolbarEnabled); + Object rotateGesturesEnabled = __pigeon_list.get(5); + pigeonResult.setRotateGesturesEnabled((Boolean) rotateGesturesEnabled); + Object scrollGesturesEnabled = __pigeon_list.get(6); + pigeonResult.setScrollGesturesEnabled((Boolean) scrollGesturesEnabled); + Object tiltGesturesEnabled = __pigeon_list.get(7); + pigeonResult.setTiltGesturesEnabled((Boolean) tiltGesturesEnabled); + Object trackCameraPosition = __pigeon_list.get(8); + pigeonResult.setTrackCameraPosition((Boolean) trackCameraPosition); + Object zoomControlsEnabled = __pigeon_list.get(9); + pigeonResult.setZoomControlsEnabled((Boolean) zoomControlsEnabled); + Object zoomGesturesEnabled = __pigeon_list.get(10); + pigeonResult.setZoomGesturesEnabled((Boolean) zoomGesturesEnabled); + Object myLocationEnabled = __pigeon_list.get(11); + pigeonResult.setMyLocationEnabled((Boolean) myLocationEnabled); + Object myLocationButtonEnabled = __pigeon_list.get(12); + pigeonResult.setMyLocationButtonEnabled((Boolean) myLocationButtonEnabled); + Object padding = __pigeon_list.get(13); + pigeonResult.setPadding((PlatformEdgeInsets) padding); + Object indoorViewEnabled = __pigeon_list.get(14); + pigeonResult.setIndoorViewEnabled((Boolean) indoorViewEnabled); + Object trafficEnabled = __pigeon_list.get(15); + pigeonResult.setTrafficEnabled((Boolean) trafficEnabled); + Object buildingsEnabled = __pigeon_list.get(16); + pigeonResult.setBuildingsEnabled((Boolean) buildingsEnabled); + Object liteModeEnabled = __pigeon_list.get(17); + pigeonResult.setLiteModeEnabled((Boolean) liteModeEnabled); + Object cloudMapId = __pigeon_list.get(18); + pigeonResult.setCloudMapId((String) cloudMapId); + Object style = __pigeon_list.get(19); + pigeonResult.setStyle((String) style); return pigeonResult; } } @@ -1626,35 +2595,26 @@ ArrayList toList() { *

Generated class from Pigeon that represents data sent in messages. */ public static final class PlatformZoomRange { - private @NonNull Double min; + private @Nullable Double min; - public @NonNull Double getMin() { + public @Nullable Double getMin() { return min; } - public void setMin(@NonNull Double setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"min\" is null."); - } + public void setMin(@Nullable Double setterArg) { this.min = setterArg; } - private @NonNull Double max; + private @Nullable Double max; - public @NonNull Double getMax() { + public @Nullable Double getMax() { return max; } - public void setMax(@NonNull Double setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"max\" is null."); - } + public void setMax(@Nullable Double setterArg) { this.max = setterArg; } - /** Constructor is non-public to enforce null safety; use Builder. */ - PlatformZoomRange() {} - @Override public boolean equals(Object o) { if (this == o) { @@ -1664,7 +2624,7 @@ public boolean equals(Object o) { return false; } PlatformZoomRange that = (PlatformZoomRange) o; - return min.equals(that.min) && max.equals(that.max); + return Objects.equals(min, that.min) && Objects.equals(max, that.max); } @Override @@ -1677,7 +2637,7 @@ public static final class Builder { private @Nullable Double min; @CanIgnoreReturnValue - public @NonNull Builder setMin(@NonNull Double setterArg) { + public @NonNull Builder setMin(@Nullable Double setterArg) { this.min = setterArg; return this; } @@ -1685,7 +2645,7 @@ public static final class Builder { private @Nullable Double max; @CanIgnoreReturnValue - public @NonNull Builder setMax(@NonNull Double setterArg) { + public @NonNull Builder setMax(@Nullable Double setterArg) { this.max = setterArg; return this; } @@ -1745,22 +2705,39 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { case (byte) 138: return PlatformTileOverlay.fromList((ArrayList) readValue(buffer)); case (byte) 139: - return PlatformLatLng.fromList((ArrayList) readValue(buffer)); + return PlatformEdgeInsets.fromList((ArrayList) readValue(buffer)); case (byte) 140: - return PlatformLatLngBounds.fromList((ArrayList) readValue(buffer)); + return PlatformLatLng.fromList((ArrayList) readValue(buffer)); case (byte) 141: - return PlatformCluster.fromList((ArrayList) readValue(buffer)); + return PlatformLatLngBounds.fromList((ArrayList) readValue(buffer)); case (byte) 142: - return PlatformMapConfiguration.fromList((ArrayList) readValue(buffer)); + return PlatformCluster.fromList((ArrayList) readValue(buffer)); case (byte) 143: - return PlatformPoint.fromList((ArrayList) readValue(buffer)); + return PlatformCameraTargetBounds.fromList((ArrayList) readValue(buffer)); case (byte) 144: - return PlatformTileLayer.fromList((ArrayList) readValue(buffer)); + return PlatformMapViewCreationParams.fromList((ArrayList) readValue(buffer)); case (byte) 145: - return PlatformZoomRange.fromList((ArrayList) readValue(buffer)); + return PlatformMapConfiguration.fromList((ArrayList) readValue(buffer)); case (byte) 146: - Object value = readValue(buffer); - return value == null ? null : PlatformRendererType.values()[(int) value]; + return PlatformPoint.fromList((ArrayList) readValue(buffer)); + case (byte) 147: + return PlatformTileLayer.fromList((ArrayList) readValue(buffer)); + case (byte) 148: + return PlatformZoomRange.fromList((ArrayList) readValue(buffer)); + case (byte) 149: + // Manual edit to fix https://github.com/flutter/flutter/issues/150108 + // the way the generator will fix it once the PR lands. + { + Object value = readValue(buffer); + return value == null ? null : PlatformMapType.values()[(int) value]; + } + case (byte) 150: + // Manual edit to fix https://github.com/flutter/flutter/issues/150108 + // the way the generator will fix it once the PR lands. + { + Object value = readValue(buffer); + return value == null ? null : PlatformRendererType.values()[(int) value]; + } default: return super.readValueOfType(type, buffer); } @@ -1798,29 +2775,41 @@ protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { } else if (value instanceof PlatformTileOverlay) { stream.write(138); writeValue(stream, ((PlatformTileOverlay) value).toList()); - } else if (value instanceof PlatformLatLng) { + } else if (value instanceof PlatformEdgeInsets) { stream.write(139); + writeValue(stream, ((PlatformEdgeInsets) value).toList()); + } else if (value instanceof PlatformLatLng) { + stream.write(140); writeValue(stream, ((PlatformLatLng) value).toList()); } else if (value instanceof PlatformLatLngBounds) { - stream.write(140); + stream.write(141); writeValue(stream, ((PlatformLatLngBounds) value).toList()); } else if (value instanceof PlatformCluster) { - stream.write(141); + stream.write(142); writeValue(stream, ((PlatformCluster) value).toList()); + } else if (value instanceof PlatformCameraTargetBounds) { + stream.write(143); + writeValue(stream, ((PlatformCameraTargetBounds) value).toList()); + } else if (value instanceof PlatformMapViewCreationParams) { + stream.write(144); + writeValue(stream, ((PlatformMapViewCreationParams) value).toList()); } else if (value instanceof PlatformMapConfiguration) { - stream.write(142); + stream.write(145); writeValue(stream, ((PlatformMapConfiguration) value).toList()); } else if (value instanceof PlatformPoint) { - stream.write(143); + stream.write(146); writeValue(stream, ((PlatformPoint) value).toList()); } else if (value instanceof PlatformTileLayer) { - stream.write(144); + stream.write(147); writeValue(stream, ((PlatformTileLayer) value).toList()); } else if (value instanceof PlatformZoomRange) { - stream.write(145); + stream.write(148); writeValue(stream, ((PlatformZoomRange) value).toList()); + } else if (value instanceof PlatformMapType) { + stream.write(149); + writeValue(stream, value == null ? null : ((PlatformMapType) value).index); } else if (value instanceof PlatformRendererType) { - stream.write(146); + stream.write(150); writeValue(stream, value == null ? null : ((PlatformRendererType) value).index); } else { super.writeValue(stream, value); @@ -3049,6 +4038,61 @@ public void error(Throwable error) { } } } + /** + * Dummy interface to force generation of the platform view creation params, which are not used in + * any Pigeon calls, only the platform view creation call made internally by Flutter. + * + *

Generated interface from Pigeon that represents a handler of messages from Flutter. + */ + public interface MapsPlatformViewApi { + + void createView(@Nullable PlatformMapViewCreationParams type); + + /** The codec used by MapsPlatformViewApi. */ + static @NonNull MessageCodec getCodec() { + return PigeonCodec.INSTANCE; + } + /** + * Sets up an instance of `MapsPlatformViewApi` to handle messages through the + * `binaryMessenger`. + */ + static void setUp(@NonNull BinaryMessenger binaryMessenger, @Nullable MapsPlatformViewApi api) { + setUp(binaryMessenger, "", api); + } + + static void setUp( + @NonNull BinaryMessenger binaryMessenger, + @NonNull String messageChannelSuffix, + @Nullable MapsPlatformViewApi api) { + messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix; + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.google_maps_flutter_android.MapsPlatformViewApi.createView" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + PlatformMapViewCreationParams typeArg = (PlatformMapViewCreationParams) args.get(0); + try { + api.createView(typeArg); + wrapped.add(0, null); + } catch (Throwable exception) { + ArrayList wrappedError = wrapError(exception); + wrapped = wrappedError; + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + } + } /** * Inspector API only intended for use in integration tests. * diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/PolygonsController.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/PolygonsController.java index 23626edeb70..57d7a6a5271 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/PolygonsController.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/PolygonsController.java @@ -32,16 +32,6 @@ void setGoogleMap(GoogleMap googleMap) { this.googleMap = googleMap; } - void addJsonPolygons(List polygonsToAdd) { - if (polygonsToAdd != null) { - for (Object polygonToAdd : polygonsToAdd) { - @SuppressWarnings("unchecked") - Map polygonMap = (Map) polygonToAdd; - addJsonPolygon(polygonMap); - } - } - } - void addPolygons(@NonNull List polygonsToAdd) { for (Messages.PlatformPolygon polygonToAdd : polygonsToAdd) { addJsonPolygon(polygonToAdd.getJson()); diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/PolylinesController.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/PolylinesController.java index cd388f1eae0..646f14c4497 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/PolylinesController.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/PolylinesController.java @@ -36,16 +36,6 @@ void setGoogleMap(GoogleMap googleMap) { this.googleMap = googleMap; } - void addJsonPolylines(List polylinesToAdd) { - if (polylinesToAdd != null) { - for (Object polylineToAdd : polylinesToAdd) { - @SuppressWarnings("unchecked") - Map polylineMap = (Map) polylineToAdd; - addJsonPolyline(polylineMap); - } - } - } - void addPolylines(@NonNull List polylinesToAdd) { for (Messages.PlatformPolyline polylineToAdd : polylinesToAdd) { addJsonPolyline(polylineToAdd.getJson()); diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaysController.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaysController.java index 1d44e56b51a..fcc5c212d8d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaysController.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaysController.java @@ -29,15 +29,6 @@ void setGoogleMap(GoogleMap googleMap) { this.googleMap = googleMap; } - void addJsonTileOverlays(List> tileOverlaysToAdd) { - if (tileOverlaysToAdd == null) { - return; - } - for (Map tileOverlayToAdd : tileOverlaysToAdd) { - addJsonTileOverlay(tileOverlayToAdd); - } - } - void addTileOverlays(@NonNull List tileOverlaysToAdd) { for (Messages.PlatformTileOverlay tileOverlayToAdd : tileOverlaysToAdd) { @SuppressWarnings("unchecked") diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/ClusterManagersControllerTest.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/ClusterManagersControllerTest.java index 4133392e310..cee54cb685b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/ClusterManagersControllerTest.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/ClusterManagersControllerTest.java @@ -37,7 +37,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentMatchers; import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; @@ -49,81 +48,22 @@ public class ClusterManagersControllerTest { private ClusterManagersController controller; private GoogleMap googleMap; private MarkerManager markerManager; - private MarkerManager.Collection markerCollection; private AssetManager assetManager; private final float density = 1; @Before public void setUp() { - MockitoAnnotations.openMocks(this); context = ApplicationProvider.getApplicationContext(); assetManager = context.getAssets(); flutterApi = spy(new MapsCallbackApi(mock(BinaryMessenger.class))); controller = spy(new ClusterManagersController(flutterApi, context)); googleMap = mock(GoogleMap.class); markerManager = new MarkerManager(googleMap); - markerCollection = markerManager.newCollection(); controller.init(googleMap, markerManager); } @Test - @SuppressWarnings("unchecked") - public void AddJsonClusterManagersAndMarkers() throws InterruptedException { - final String clusterManagerId = "cm_1"; - final String markerId1 = "mid_1"; - final String markerId2 = "mid_2"; - - final LatLng latLng1 = new LatLng(1.1, 2.2); - final LatLng latLng2 = new LatLng(3.3, 4.4); - - final List location1 = new ArrayList<>(); - location1.add(latLng1.latitude); - location1.add(latLng1.longitude); - - final List location2 = new ArrayList<>(); - location2.add(latLng2.latitude); - location2.add(latLng2.longitude); - - when(googleMap.getCameraPosition()) - .thenReturn(CameraPosition.builder().target(new LatLng(0, 0)).build()); - Map initialClusterManager = new HashMap<>(); - initialClusterManager.put("clusterManagerId", clusterManagerId); - List clusterManagersToAdd = new ArrayList<>(); - clusterManagersToAdd.add(initialClusterManager); - controller.addJsonClusterManagers(clusterManagersToAdd); - - MarkerBuilder markerBuilder1 = new MarkerBuilder(markerId1, clusterManagerId); - MarkerBuilder markerBuilder2 = new MarkerBuilder(markerId2, clusterManagerId); - - final Map markerData1 = - createMarkerData(markerId1, location1, clusterManagerId); - final Map markerData2 = - createMarkerData(markerId2, location2, clusterManagerId); - - Convert.interpretMarkerOptions(markerData1, markerBuilder1, assetManager, density); - Convert.interpretMarkerOptions(markerData2, markerBuilder2, assetManager, density); - - controller.addItem(markerBuilder1); - controller.addItem(markerBuilder2); - - Set> clusters = - controller.getClustersWithClusterManagerId(clusterManagerId); - assertEquals("Amount of clusters should be 1", 1, clusters.size()); - - Cluster cluster = clusters.iterator().next(); - assertNotNull("Cluster position should not be null", cluster.getPosition()); - Set markerIds = new HashSet<>(); - for (MarkerBuilder marker : cluster.getItems()) { - markerIds.add(marker.markerId()); - } - assertTrue("Marker IDs should contain markerId1", markerIds.contains(markerId1)); - assertTrue("Marker IDs should contain markerId2", markerIds.contains(markerId2)); - assertEquals("Cluster should contain exactly 2 markers", 2, cluster.getSize()); - } - - @Test - @SuppressWarnings("unchecked") - public void AddClusterManagersAndMarkers() throws InterruptedException { + public void AddClusterManagersAndMarkers() { final String clusterManagerId = "cm_1"; final String markerId1 = "mid_1"; final String markerId2 = "mid_2"; @@ -177,8 +117,7 @@ public void AddClusterManagersAndMarkers() throws InterruptedException { } @Test - @SuppressWarnings("unchecked") - public void OnClusterClickCallsMethodChannel() throws InterruptedException { + public void OnClusterClickCallsMethodChannel() { String clusterManagerId = "cm_1"; LatLng clusterPosition = new LatLng(43.00, -87.90); LatLng markerPosition1 = new LatLng(43.05, -87.95); diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/ConvertTest.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/ConvertTest.java index 156b8ce60e8..1efab354086 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/ConvertTest.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/ConvertTest.java @@ -4,6 +4,7 @@ package io.flutter.plugins.googlemaps; +import static com.google.android.gms.maps.GoogleMap.MAP_TYPE_HYBRID; import static io.flutter.plugins.googlemaps.Convert.HEATMAP_DATA_KEY; import static io.flutter.plugins.googlemaps.Convert.HEATMAP_GRADIENT_COLORS_KEY; import static io.flutter.plugins.googlemaps.Convert.HEATMAP_GRADIENT_COLOR_MAP_SIZE_KEY; @@ -16,7 +17,9 @@ import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; import android.content.res.AssetManager; @@ -29,6 +32,7 @@ import androidx.annotation.NonNull; import com.google.android.gms.maps.model.BitmapDescriptor; import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.LatLngBounds; import com.google.maps.android.clustering.algo.StaticCluster; import com.google.maps.android.geometry.Point; import com.google.maps.android.heatmaps.Gradient; @@ -64,10 +68,12 @@ public class ConvertTest { @Mock private FlutterInjectorWrapper flutterInjectorWrapper; + @Mock private GoogleMapOptionsSink optionsSink; + AutoCloseable mockCloseable; // A 1x1 pixel (#8080ff) PNG image encoded in base64 - private String base64Image = generateBase64Image(); + private final String base64Image = generateBase64Image(); @Before public void before() { @@ -83,7 +89,7 @@ public void tearDown() throws Exception { public void ConvertToPointsConvertsThePointsWithFullPrecision() { double latitude = 43.03725568057; double longitude = -87.90466904649; - ArrayList point = new ArrayList(); + ArrayList point = new ArrayList<>(); point.add(latitude); point.add(longitude); ArrayList> pointsList = new ArrayList<>(); @@ -247,7 +253,7 @@ public void GetBitmapFromAssetNoScaling() throws Exception { } @Test - public void GetBitmapFromBytesAuto() throws Exception { + public void GetBitmapFromBytesAuto() { byte[] bmpData = Base64.decode(base64Image, Base64.DEFAULT); Map assetDetails = new HashMap<>(); @@ -264,7 +270,7 @@ public void GetBitmapFromBytesAuto() throws Exception { } @Test - public void GetBitmapFromBytesAutoAndWidth() throws Exception { + public void GetBitmapFromBytesAutoAndWidth() { byte[] bmpData = Base64.decode(base64Image, Base64.DEFAULT); Map assetDetails = new HashMap<>(); @@ -282,7 +288,7 @@ public void GetBitmapFromBytesAutoAndWidth() throws Exception { } @Test - public void GetBitmapFromBytesAutoAndHeight() throws Exception { + public void GetBitmapFromBytesAutoAndHeight() { byte[] bmpData = Base64.decode(base64Image, Base64.DEFAULT); Map assetDetails = new HashMap<>(); @@ -300,7 +306,7 @@ public void GetBitmapFromBytesAutoAndHeight() throws Exception { } @Test - public void GetBitmapFromBytesNoScaling() throws Exception { + public void GetBitmapFromBytesNoScaling() { byte[] bmpData = Base64.decode(base64Image, Base64.DEFAULT); Map assetDetails = new HashMap<>(); @@ -317,7 +323,7 @@ public void GetBitmapFromBytesNoScaling() throws Exception { } @Test(expected = IllegalArgumentException.class) // Expecting an IllegalArgumentException - public void GetBitmapFromBytesThrowsErrorIfInvalidImageData() throws Exception { + public void GetBitmapFromBytesThrowsErrorIfInvalidImageData() { String invalidBase64Image = "not valid image data"; byte[] bmpData = Base64.decode(invalidBase64Image, Base64.DEFAULT); @@ -338,6 +344,214 @@ public void GetBitmapFromBytesThrowsErrorIfInvalidImageData() throws Exception { fail("Expected an IllegalArgumentException to be thrown"); } + @Test + public void interpretMapConfiguration_handlesNulls() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().build(); + Convert.interpretMapConfiguration(config, optionsSink); + verifyNoInteractions(optionsSink); + } + + @Test + public void interpretMapConfiguration_handlesCompassEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setCompassEnabled(false).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setCompassEnabled(false); + } + + @Test + public void interpretMapConfiguration_handlesMapToolbarEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setMapToolbarEnabled(true).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setMapToolbarEnabled(true); + } + + @Test + public void interpretMapConfiguration_handlesRotateGesturesEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setRotateGesturesEnabled(false).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setRotateGesturesEnabled(false); + } + + @Test + public void interpretMapConfiguration_handlesScrollGesturesEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setScrollGesturesEnabled(true).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setScrollGesturesEnabled(true); + } + + @Test + public void interpretMapConfiguration_handlesTiltGesturesEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setTiltGesturesEnabled(false).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setTiltGesturesEnabled(false); + } + + @Test + public void interpretMapConfiguration_handlesTrackCameraPosition() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setTrackCameraPosition(true).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setTrackCameraPosition(true); + } + + @Test + public void interpretMapConfiguration_handlesZoomControlsEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setZoomControlsEnabled(false).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setZoomControlsEnabled(false); + } + + @Test + public void interpretMapConfiguration_handlesZoomGesturesEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setZoomGesturesEnabled(true).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setZoomGesturesEnabled(true); + } + + @Test + public void interpretMapConfiguration_handlesMyLocationEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setMyLocationEnabled(false).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setMyLocationEnabled(false); + } + + @Test + public void interpretMapConfiguration_handlesMyLocationButtonEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setMyLocationButtonEnabled(true).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setMyLocationButtonEnabled(true); + } + + @Test + public void interpretMapConfiguration_handlesIndoorViewEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setIndoorViewEnabled(false).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setIndoorEnabled(false); + } + + @Test + public void interpretMapConfiguration_handlesTrafficEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setTrafficEnabled(true).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setTrafficEnabled(true); + } + + @Test + public void interpretMapConfiguration_handlesBuildingsEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setBuildingsEnabled(false).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setBuildingsEnabled(false); + } + + @Test + public void interpretMapConfiguration_handlesLiteModeEnabled() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setLiteModeEnabled(true).build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setLiteModeEnabled(true); + } + + @Test + public void interpretMapConfiguration_handlesStyle() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder().setStyle("foo").build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setMapStyle("foo"); + } + + @Test + public void interpretMapConfiguration_handlesUnboundedCameraTargetBounds() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder() + .setCameraTargetBounds(new Messages.PlatformCameraTargetBounds.Builder().build()) + .build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setCameraTargetBounds(null); + } + + @Test + public void interpretMapConfiguration_handlesBoundedCameraTargetBounds() { + LatLngBounds bounds = new LatLngBounds(new LatLng(10, 20), new LatLng(30, 40)); + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder() + .setCameraTargetBounds( + new Messages.PlatformCameraTargetBounds.Builder() + .setBounds( + new Messages.PlatformLatLngBounds.Builder() + .setSouthwest( + new Messages.PlatformLatLng.Builder() + .setLatitude(bounds.southwest.latitude) + .setLongitude(bounds.southwest.longitude) + .build()) + .setNortheast( + new Messages.PlatformLatLng.Builder() + .setLatitude(bounds.northeast.latitude) + .setLongitude(bounds.northeast.longitude) + .build()) + .build()) + .build()) + .build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setCameraTargetBounds(bounds); + } + + @Test + public void interpretMapConfiguration_handlesMapType() { + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder() + .setMapType(Messages.PlatformMapType.HYBRID) + .build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setMapType(MAP_TYPE_HYBRID); + } + + @Test + public void interpretMapConfiguration_handlesPadding() { + final double top = 1.0; + final double bottom = 2.0; + final double left = 3.0; + final double right = 4.0; + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder() + .setPadding( + new Messages.PlatformEdgeInsets.Builder() + .setTop(top) + .setBottom(bottom) + .setLeft(left) + .setRight(right) + .build()) + .build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)) + .setPadding((float) top, (float) left, (float) bottom, (float) right); + } + + @Test + public void interpretMapConfiguration_handlesMinMaxZoomPreference() { + final double min = 1.0; + final double max = 2.0; + final Messages.PlatformMapConfiguration config = + new Messages.PlatformMapConfiguration.Builder() + .setMinMaxZoomPreference( + new Messages.PlatformZoomRange.Builder().setMin(min).setMax(max).build()) + .build(); + Convert.interpretMapConfiguration(config, optionsSink); + verify(optionsSink, times(1)).setMinMaxZoomPreference((float) min, (float) max); + } + private static final SphericalMercatorProjection sProjection = new SphericalMercatorProjection(1); @Test() @@ -465,8 +679,7 @@ private InputStream buildImageInputStream() { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); fakeBitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream); byte[] byteArray = byteArrayOutputStream.toByteArray(); - InputStream fakeStream = new ByteArrayInputStream(byteArray); - return fakeStream; + return new ByteArrayInputStream(byteArray); } // Helper method to generate 1x1 pixel base64 encoded png test image @@ -487,9 +700,7 @@ private String generateBase64Image() { byte[] pngBytes = outputStream.toByteArray(); // Encode the PNG bytes as a base64 string - String base64Image = Base64.encodeToString(pngBytes, Base64.DEFAULT); - - return base64Image; + return Base64.encodeToString(pngBytes, Base64.DEFAULT); } } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/GoogleMapControllerTest.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/GoogleMapControllerTest.java index 2295ec1a757..c0d54ba1958 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/GoogleMapControllerTest.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/GoogleMapControllerTest.java @@ -6,7 +6,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; @@ -22,9 +21,7 @@ import com.google.maps.android.clustering.ClusterManager; import io.flutter.plugin.common.BinaryMessenger; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -105,19 +102,19 @@ public void tearDown() throws Exception { } @Test - public void DisposeReleaseTheMap() throws InterruptedException { + public void DisposeReleaseTheMap() { GoogleMapController googleMapController = getGoogleMapController(); googleMapController.onMapReady(mockGoogleMap); - assertTrue(googleMapController != null); + assertNotNull(googleMapController); googleMapController.dispose(); assertNull(googleMapController.getView()); } @Test - public void OnDestroyReleaseTheMap() throws InterruptedException { + public void OnDestroyReleaseTheMap() { GoogleMapController googleMapController = getGoogleMapController(); googleMapController.onMapReady(mockGoogleMap); - assertTrue(googleMapController != null); + assertNotNull(googleMapController); googleMapController.onDestroy(activity); assertNull(googleMapController.getView()); } @@ -196,15 +193,15 @@ public void OnMapReadySetsClusterItemRenderedListener() { @Test public void SetInitialClusterManagers() { GoogleMapController googleMapController = getGoogleMapControllerWithMockedDependencies(); - Map initialClusterManager = new HashMap<>(); - initialClusterManager.put("clusterManagerId", "cm_1"); - List initialClusterManagers = new ArrayList<>(); + Messages.PlatformClusterManager initialClusterManager = + new Messages.PlatformClusterManager.Builder().setIdentifier("cm_1").build(); + List initialClusterManagers = new ArrayList<>(); initialClusterManagers.add(initialClusterManager); googleMapController.setInitialClusterManagers(initialClusterManagers); googleMapController.onMapReady(mockGoogleMap); // Verify if the ClusterManagersController.addClusterManagers method is called with initial cluster managers. - verify(mockClusterManagersController, times(1)).addJsonClusterManagers(any()); + verify(mockClusterManagersController, times(1)).addClusterManagers(any()); } @Test @@ -229,12 +226,12 @@ public void OnClusterItemClickCallsMarkersController() { public void SetInitialHeatmaps() { GoogleMapController googleMapController = getGoogleMapControllerWithMockedDependencies(); - List initialHeatmaps = List.of(Map.of("heatmapId", "hm_1")); + List initialHeatmaps = List.of(new Messages.PlatformHeatmap()); googleMapController.setInitialHeatmaps(initialHeatmaps); googleMapController.onMapReady(mockGoogleMap); // Verify if the HeatmapsController.addHeatmaps method is called with initial heatmaps. - verify(mockHeatmapsController, times(1)).addJsonHeatmaps(initialHeatmaps); + verify(mockHeatmapsController, times(1)).addHeatmaps(initialHeatmaps); } @Test diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/HeatmapsControllerTest.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/HeatmapsControllerTest.java index e087ba38683..752472c4286 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/HeatmapsControllerTest.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/HeatmapsControllerTest.java @@ -47,11 +47,13 @@ public void setUp() { @Test(expected = IllegalArgumentException.class) public void controller_AddHeatmapThrowsErrorIfHeatmapIdIsNull() { - final Map heatmapOptions = new HashMap<>(); + final Map heatmapOptions = new HashMap<>(); - final List heatmaps = Collections.singletonList(heatmapOptions); + final List heatmaps = + Collections.singletonList( + new Messages.PlatformHeatmap.Builder().setJson(heatmapOptions).build()); try { - controller.addJsonHeatmaps(heatmaps); + controller.addHeatmaps(heatmaps); } catch (IllegalArgumentException e) { assertEquals("heatmapId was null", e.getMessage()); throw e; @@ -74,8 +76,10 @@ public void controller_AddChangeAndRemoveHeatmap() { heatmapOptions1.put(HEATMAP_ID_KEY, googleHeatmapId); heatmapOptions1.put(HEATMAP_DATA_KEY, heatmapData); - final List heatmaps = Collections.singletonList(heatmapOptions1); - controller.addJsonHeatmaps(heatmaps); + final List heatmaps = + Collections.singletonList( + new Messages.PlatformHeatmap.Builder().setJson(heatmapOptions1).build()); + controller.addHeatmaps(heatmaps); Mockito.verify(googleMap, times(1)) .addTileOverlay( @@ -88,15 +92,8 @@ public void controller_AddChangeAndRemoveHeatmap() { heatmapOptions2.put(HEATMAP_OPACITY_KEY, opacity); final List heatmapUpdates = - Collections.singletonList(heatmapOptions2) - .stream() - .map( - json -> { - final Messages.PlatformHeatmap platformHeatmap = new Messages.PlatformHeatmap(); - platformHeatmap.setJson(json); - return platformHeatmap; - }) - .toList(); + Collections.singletonList( + new Messages.PlatformHeatmap.Builder().setJson(heatmapOptions2).build()); controller.changeHeatmaps(heatmapUpdates); Mockito.verify(heatmap, times(1)).setOpacity(opacity); diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/MarkersControllerTest.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/MarkersControllerTest.java index 820ef50c451..1a50fbc9f7a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/MarkersControllerTest.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/MarkersControllerTest.java @@ -24,7 +24,6 @@ import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugins.googlemaps.Messages.MapsCallbackApi; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -34,7 +33,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; @@ -53,7 +51,6 @@ public class MarkersControllerTest { @Before public void setUp() { - MockitoAnnotations.openMocks(this); assetManager = ApplicationProvider.getApplicationContext().getAssets(); context = ApplicationProvider.getApplicationContext(); flutterApi = spy(new MapsCallbackApi(mock(BinaryMessenger.class))); @@ -77,11 +74,13 @@ public void controller_OnMarkerDragStart() { when(googleMap.addMarker(any(MarkerOptions.class))).thenReturn(marker); final LatLng latLng = new LatLng(1.1, 2.2); - final Map markerOptions = new HashMap<>(); + final Map markerOptions = new HashMap<>(); markerOptions.put("markerId", googleMarkerId); - final List markers = Arrays.asList(markerOptions); - controller.addJsonMarkers(markers); + final List markers = + Collections.singletonList( + new Messages.PlatformMarker.Builder().setJson(markerOptions).build()); + controller.addMarkers(markers); controller.onMarkerDragStart(googleMarkerId, latLng); Mockito.verify(flutterApi) @@ -98,11 +97,13 @@ public void controller_OnMarkerDragEnd() { when(googleMap.addMarker(any(MarkerOptions.class))).thenReturn(marker); final LatLng latLng = new LatLng(1.1, 2.2); - final Map markerOptions = new HashMap<>(); + final Map markerOptions = new HashMap<>(); markerOptions.put("markerId", googleMarkerId); - final List markers = Arrays.asList(markerOptions); - controller.addJsonMarkers(markers); + final List markers = + Collections.singletonList( + new Messages.PlatformMarker.Builder().setJson(markerOptions).build()); + controller.addMarkers(markers); controller.onMarkerDragEnd(googleMarkerId, latLng); Mockito.verify(flutterApi) @@ -119,11 +120,13 @@ public void controller_OnMarkerDrag() { when(googleMap.addMarker(any(MarkerOptions.class))).thenReturn(marker); final LatLng latLng = new LatLng(1.1, 2.2); - final Map markerOptions = new HashMap<>(); + final Map markerOptions = new HashMap<>(); markerOptions.put("markerId", googleMarkerId); - final List markers = Arrays.asList(markerOptions); - controller.addJsonMarkers(markers); + final List markers = + Collections.singletonList( + new Messages.PlatformMarker.Builder().setJson(markerOptions).build()); + controller.addMarkers(markers); controller.onMarkerDrag(googleMarkerId, latLng); Mockito.verify(flutterApi) @@ -132,11 +135,13 @@ public void controller_OnMarkerDrag() { @Test(expected = IllegalArgumentException.class) public void controller_AddMarkerThrowsErrorIfMarkerIdIsNull() { - final Map markerOptions = new HashMap<>(); + final Map markerOptions = new HashMap<>(); - final List markers = Arrays.asList(markerOptions); + final List markers = + Collections.singletonList( + new Messages.PlatformMarker.Builder().setJson(markerOptions).build()); try { - controller.addJsonMarkers(markers); + controller.addMarkers(markers); } catch (IllegalArgumentException e) { assertEquals("markerId was null", e.getMessage()); throw e; @@ -162,10 +167,12 @@ public void controller_AddChangeAndRemoveMarkerWithClusterManagerId() { markerOptions1.put("position", location1); markerOptions1.put("clusterManagerId", clusterManagerId); - final List markers = Arrays.asList(markerOptions1); + final List markers = + Collections.singletonList( + new Messages.PlatformMarker.Builder().setJson(markerOptions1).build()); // Add marker and capture the markerBuilder - controller.addJsonMarkers(markers); + controller.addMarkers(markers); ArgumentCaptor captor = ArgumentCaptor.forClass(MarkerBuilder.class); Mockito.verify(clusterManagersController, times(1)).addItem(captor.capture()); MarkerBuilder capturedMarkerBuilder = captor.getValue(); @@ -192,7 +199,7 @@ public void controller_AddChangeAndRemoveMarkerWithClusterManagerId() { Mockito.verify(marker, times(1)).setPosition(latLng2); // Remove marker - controller.removeMarkers(Arrays.asList(googleMarkerId)); + controller.removeMarkers(Collections.singletonList(googleMarkerId)); Mockito.verify(clusterManagersController, times(1)) .removeItem( @@ -212,11 +219,13 @@ public void controller_AddChangeAndRemoveMarkerWithoutClusterManagerId() { when(marker.getId()).thenReturn(googleMarkerId); when(googleMap.addMarker(any(MarkerOptions.class))).thenReturn(marker); - final Map markerOptions1 = new HashMap<>(); + final Map markerOptions1 = new HashMap<>(); markerOptions1.put("markerId", googleMarkerId); - final List markers = Arrays.asList(markerOptions1); - controller.addJsonMarkers(markers); + final List markers = + Collections.singletonList( + new Messages.PlatformMarker.Builder().setJson(markerOptions1).build()); + controller.addMarkers(markers); // clusterManagersController should not be called when adding the marker Mockito.verify(clusterManagersController, times(0)).addItem(any()); @@ -234,7 +243,7 @@ public void controller_AddChangeAndRemoveMarkerWithoutClusterManagerId() { controller.changeMarkers(markerUpdates); Mockito.verify(marker, times(1)).setAlpha(alpha); - controller.removeMarkers(Arrays.asList(googleMarkerId)); + controller.removeMarkers(Collections.singletonList(googleMarkerId)); // clusterManagersController should not be called when removing the marker Mockito.verify(clusterManagersController, times(0)).removeItem(any()); diff --git a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart index 214acc41ed2..f8b4f158ec9 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart @@ -15,7 +15,6 @@ import 'package:stream_transform/stream_transform.dart'; import 'google_map_inspector_android.dart'; import 'messages.g.dart'; import 'serialization.dart'; -import 'utils/cluster_manager_utils.dart'; // TODO(stuartmorgan): Remove the dependency on platform interface toJson // methods. Channel serialization details should all be package-internal. @@ -225,8 +224,8 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { MapConfiguration configuration, { required int mapId, }) { - return updateMapOptions(_jsonForMapConfiguration(configuration), - mapId: mapId); + return _hostApi(mapId).updateMapConfiguration( + _platformMapConfigurationFromMapConfiguration(configuration)); } @override @@ -234,8 +233,8 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { Map optionsUpdate, { required int mapId, }) { - return _hostApi(mapId) - .updateMapConfiguration(PlatformMapConfiguration(json: optionsUpdate)); + return _hostApi(mapId).updateMapConfiguration( + _platformMapConfigurationFromOptionsJson(optionsUpdate)); } @override @@ -503,25 +502,32 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { Widget _buildView( int creationId, PlatformViewCreatedCallback onPlatformViewCreated, { + required PlatformMapConfiguration mapConfiguration, required MapWidgetConfiguration widgetConfiguration, MapObjects mapObjects = const MapObjects(), - Map mapOptions = const {}, }) { - // TODO(stuartmorgan): Convert this to Pigeon-generated structures once - // https://github.com/flutter/flutter/issues/150631 is fixed. - final Map creationParams = { - 'initialCameraPosition': - widgetConfiguration.initialCameraPosition.toMap(), - 'options': mapOptions, - 'markersToAdd': serializeMarkerSet(mapObjects.markers), - 'polygonsToAdd': serializePolygonSet(mapObjects.polygons), - 'polylinesToAdd': serializePolylineSet(mapObjects.polylines), - 'circlesToAdd': serializeCircleSet(mapObjects.circles), - 'heatmapsToAdd': mapObjects.heatmaps.map(serializeHeatmap).toList(), - 'tileOverlaysToAdd': serializeTileOverlaySet(mapObjects.tileOverlays), - 'clusterManagersToAdd': - serializeClusterManagerSet(mapObjects.clusterManagers), - }; + final PlatformMapViewCreationParams creationParams = + PlatformMapViewCreationParams( + initialCameraPosition: _platformCameraPositionFromCameraPosition( + widgetConfiguration.initialCameraPosition), + mapConfiguration: mapConfiguration, + initialMarkers: + mapObjects.markers.map(_platformMarkerFromMarker).toList(), + initialPolygons: + mapObjects.polygons.map(_platformPolygonFromPolygon).toList(), + initialPolylines: + mapObjects.polylines.map(_platformPolylineFromPolyline).toList(), + initialCircles: + mapObjects.circles.map(_platformCircleFromCircle).toList(), + initialHeatmaps: + mapObjects.heatmaps.map(_platformHeatmapFromHeatmap).toList(), + initialTileOverlays: mapObjects.tileOverlays + .map(_platformTileOverlayFromTileOverlay) + .toList(), + initialClusterManagers: mapObjects.clusterManagers + .map(_platformClusterManagerFromClusterManager) + .toList(), + ); const String viewType = 'plugins.flutter.dev/google_maps_android'; if (useAndroidViewSurface) { @@ -544,7 +550,7 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { viewType: viewType, layoutDirection: widgetConfiguration.textDirection, creationParams: creationParams, - creationParamsCodec: const StandardMessageCodec(), + creationParamsCodec: MapsApi.pigeonChannelCodec, onFocus: () => params.onFocusChanged(true), ); controller.addOnPlatformViewCreatedListener( @@ -565,7 +571,7 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { gestureRecognizers: widgetConfiguration.gestureRecognizers, layoutDirection: widgetConfiguration.textDirection, creationParams: creationParams, - creationParamsCodec: const StandardMessageCodec(), + creationParamsCodec: MapsApi.pigeonChannelCodec, ); } } @@ -583,7 +589,8 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { onPlatformViewCreated, widgetConfiguration: widgetConfiguration, mapObjects: mapObjects, - mapOptions: _jsonForMapConfiguration(mapConfiguration), + mapConfiguration: + _platformMapConfigurationFromMapConfiguration(mapConfiguration), ); } @@ -615,7 +622,7 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { circles: circles, clusterManagers: clusterManagers, tileOverlays: tileOverlays), - mapOptions: mapOptions, + mapConfiguration: _platformMapConfigurationFromOptionsJson(mapOptions), ); } @@ -692,10 +699,7 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { } static PlatformHeatmap _platformHeatmapFromHeatmap(Heatmap heatmap) { - // This cast is not ideal, but the Java code already assumes this format. - // See the TODOs at the top of this file and on the 'json' field in - // messages.dart. - return PlatformHeatmap(json: heatmap.toJson() as Map); + return PlatformHeatmap(json: serializeHeatmap(heatmap)); } static PlatformClusterManager _platformClusterManagerFromClusterManager( @@ -886,52 +890,200 @@ PlatformTile _platformTileFromTile(Tile tile) { return PlatformTile(width: tile.width, height: tile.height, data: tile.data); } -Map _jsonForMapConfiguration(MapConfiguration config) { - final EdgeInsets? padding = config.padding; - return { - if (config.compassEnabled != null) 'compassEnabled': config.compassEnabled!, - if (config.mapToolbarEnabled != null) - 'mapToolbarEnabled': config.mapToolbarEnabled!, - if (config.cameraTargetBounds != null) - 'cameraTargetBounds': config.cameraTargetBounds!.toJson(), - if (config.mapType != null) 'mapType': config.mapType!.index, - if (config.minMaxZoomPreference != null) - 'minMaxZoomPreference': config.minMaxZoomPreference!.toJson(), - if (config.rotateGesturesEnabled != null) - 'rotateGesturesEnabled': config.rotateGesturesEnabled!, - if (config.scrollGesturesEnabled != null) - 'scrollGesturesEnabled': config.scrollGesturesEnabled!, - if (config.tiltGesturesEnabled != null) - 'tiltGesturesEnabled': config.tiltGesturesEnabled!, - if (config.zoomControlsEnabled != null) - 'zoomControlsEnabled': config.zoomControlsEnabled!, - if (config.zoomGesturesEnabled != null) - 'zoomGesturesEnabled': config.zoomGesturesEnabled!, - if (config.liteModeEnabled != null) - 'liteModeEnabled': config.liteModeEnabled!, - if (config.trackCameraPosition != null) - 'trackCameraPosition': config.trackCameraPosition!, - if (config.myLocationEnabled != null) - 'myLocationEnabled': config.myLocationEnabled!, - if (config.myLocationButtonEnabled != null) - 'myLocationButtonEnabled': config.myLocationButtonEnabled!, - if (padding != null) - 'padding': [ - padding.top, - padding.left, - padding.bottom, - padding.right, - ], - if (config.indoorViewEnabled != null) - 'indoorEnabled': config.indoorViewEnabled!, - if (config.trafficEnabled != null) 'trafficEnabled': config.trafficEnabled!, - if (config.buildingsEnabled != null) - 'buildingsEnabled': config.buildingsEnabled!, - if (config.cloudMapId != null) 'cloudMapId': config.cloudMapId!, - if (config.style != null) 'style': config.style!, +PlatformLatLng _platformLatLngFromLatLng(LatLng latLng) { + return PlatformLatLng(latitude: latLng.latitude, longitude: latLng.longitude); +} + +PlatformLatLngBounds? _platformLatLngBoundsFromLatLngBounds( + LatLngBounds? bounds) { + if (bounds == null) { + return null; + } + return PlatformLatLngBounds( + northeast: _platformLatLngFromLatLng(bounds.northeast), + southwest: _platformLatLngFromLatLng(bounds.southwest)); +} + +PlatformCameraTargetBounds? _platformCameraTargetBoundsFromCameraTargetBounds( + CameraTargetBounds? bounds) { + return bounds == null + ? null + : PlatformCameraTargetBounds( + bounds: _platformLatLngBoundsFromLatLngBounds(bounds.bounds)); +} + +PlatformMapType? _platformMapTypeFromMapType(MapType? type) { + switch (type) { + case null: + return null; + case MapType.none: + return PlatformMapType.none; + case MapType.normal: + return PlatformMapType.normal; + case MapType.satellite: + return PlatformMapType.satellite; + case MapType.terrain: + return PlatformMapType.terrain; + case MapType.hybrid: + return PlatformMapType.hybrid; + } + // The enum comes from a different package, which could get a new value at + // any time, so provide a fallback that ensures this won't break when used + // with a version that contains new values. This is deliberately outside + // the switch rather than a `default` so that the linter will flag the + // switch as needing an update. + // ignore: dead_code + return PlatformMapType.normal; +} + +PlatformZoomRange? _platformZoomRangeFromMinMaxZoomPreference( + MinMaxZoomPreference? zoomPref) { + return zoomPref == null + ? null + : PlatformZoomRange(min: zoomPref.minZoom, max: zoomPref.maxZoom); +} + +PlatformEdgeInsets? _platformEdgeInsetsFromEdgeInsets(EdgeInsets? insets) { + return insets == null + ? null + : PlatformEdgeInsets( + top: insets.top, + bottom: insets.bottom, + left: insets.left, + right: insets.right); +} + +PlatformMapConfiguration _platformMapConfigurationFromMapConfiguration( + MapConfiguration config) { + return PlatformMapConfiguration( + compassEnabled: config.compassEnabled, + cameraTargetBounds: _platformCameraTargetBoundsFromCameraTargetBounds( + config.cameraTargetBounds), + mapType: _platformMapTypeFromMapType(config.mapType), + minMaxZoomPreference: + _platformZoomRangeFromMinMaxZoomPreference(config.minMaxZoomPreference), + mapToolbarEnabled: config.mapToolbarEnabled, + rotateGesturesEnabled: config.rotateGesturesEnabled, + scrollGesturesEnabled: config.scrollGesturesEnabled, + tiltGesturesEnabled: config.tiltGesturesEnabled, + trackCameraPosition: config.trackCameraPosition, + zoomControlsEnabled: config.zoomControlsEnabled, + zoomGesturesEnabled: config.zoomGesturesEnabled, + myLocationEnabled: config.myLocationEnabled, + myLocationButtonEnabled: config.myLocationButtonEnabled, + padding: _platformEdgeInsetsFromEdgeInsets(config.padding), + indoorViewEnabled: config.indoorViewEnabled, + trafficEnabled: config.trafficEnabled, + buildingsEnabled: config.buildingsEnabled, + liteModeEnabled: config.liteModeEnabled, + cloudMapId: config.cloudMapId, + style: config.style, + ); +} + +// For supporting the deprecated updateMapOptions API. +PlatformMapConfiguration _platformMapConfigurationFromOptionsJson( + Map options) { + // All of these hard-coded values and structures come from + // google_maps_flutter_platform_interface/lib/src/types/utils/map_configuration_serialization.dart + // to support this legacy API that relied on cross-package magic strings. + final List? padding = + (options['padding'] as List?)?.cast(); + final int? mapType = options['mapType'] as int?; + return PlatformMapConfiguration( + compassEnabled: options['compassEnabled'] as bool?, + cameraTargetBounds: _platformCameraTargetBoundsFromCameraTargetBoundsJson( + options['cameraTargetBounds']), + mapType: mapType == null ? null : _platformMapTypeFromMapTypeIndex(mapType), + minMaxZoomPreference: _platformZoomRangeFromMinMaxZoomPreferenceJson( + options['minMaxZoomPreference']), + mapToolbarEnabled: options['mapToolbarEnabled'] as bool?, + rotateGesturesEnabled: options['rotateGesturesEnabled'] as bool?, + scrollGesturesEnabled: options['scrollGesturesEnabled'] as bool?, + tiltGesturesEnabled: options['tiltGesturesEnabled'] as bool?, + trackCameraPosition: options['trackCameraPosition'] as bool?, + zoomControlsEnabled: options['zoomControlsEnabled'] as bool?, + zoomGesturesEnabled: options['zoomGesturesEnabled'] as bool?, + myLocationEnabled: options['myLocationEnabled'] as bool?, + myLocationButtonEnabled: options['myLocationButtonEnabled'] as bool?, + padding: padding == null + ? null + : PlatformEdgeInsets( + top: padding[0], + left: padding[1], + bottom: padding[2], + right: padding[3]), + indoorViewEnabled: options['indoorEnabled'] as bool?, + trafficEnabled: options['trafficEnabled'] as bool?, + buildingsEnabled: options['buildingsEnabled'] as bool?, + liteModeEnabled: options['liteModeEnabled'] as bool?, + cloudMapId: options['cloudMapId'] as String?, + style: options['style'] as String?, + ); +} + +PlatformCameraPosition _platformCameraPositionFromCameraPosition( + CameraPosition position) { + return PlatformCameraPosition( + bearing: position.bearing, + target: _platformLatLngFromLatLng(position.target), + tilt: position.tilt, + zoom: position.zoom); +} + +PlatformMapType _platformMapTypeFromMapTypeIndex(int index) { + // This is inherently fragile, but see comment in updateMapOptions. + return switch (index) { + 0 => PlatformMapType.none, + 1 => PlatformMapType.normal, + 2 => PlatformMapType.satellite, + 3 => PlatformMapType.terrain, + 4 => PlatformMapType.hybrid, + // For a new, unsupported type, just use normal. + _ => PlatformMapType.normal, }; } +PlatformLatLng _platformLatLngFromLatLngJson(Object latLngJson) { + // See `LatLng.toJson`. + final List list = (latLngJson as List).cast(); + return PlatformLatLng(latitude: list[0], longitude: list[1]); +} + +PlatformLatLngBounds? _platformLatLngBoundsFromLatLngBoundsJson( + Object? boundsJson) { + if (boundsJson == null) { + return null; + } + // See `LatLngBounds.toJson`. + final List boundsList = (boundsJson as List).cast(); + return PlatformLatLngBounds( + southwest: _platformLatLngFromLatLngJson(boundsList[0]), + northeast: _platformLatLngFromLatLngJson(boundsList[1])); +} + +PlatformCameraTargetBounds? + _platformCameraTargetBoundsFromCameraTargetBoundsJson(Object? targetJson) { + if (targetJson == null) { + return null; + } + // See `CameraTargetBounds.toJson`. + return PlatformCameraTargetBounds( + bounds: _platformLatLngBoundsFromLatLngBoundsJson( + (targetJson as List)[0])); +} + +PlatformZoomRange? _platformZoomRangeFromMinMaxZoomPreferenceJson( + Object? zoomPrefsJson) { + if (zoomPrefsJson == null) { + return null; + } + // See `MinMaxZoomPreference.toJson`. + final List minMaxZoom = + (zoomPrefsJson as List).cast(); + return PlatformZoomRange(min: minMaxZoom[0], max: minMaxZoom[1]); +} + /// Update specification for a set of [TileOverlay]s. // TODO(stuartmorgan): Fix the missing export of this class in the platform // interface, and remove this copy. diff --git a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/messages.g.dart b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/messages.g.dart index 676b8f48b86..92c53604baa 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/messages.g.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/messages.g.dart @@ -29,6 +29,15 @@ List wrapResponse( return [error.code, error.message, error.details]; } +/// Pigeon equivalent of MapType +enum PlatformMapType { + none, + normal, + satellite, + terrain, + hybrid, +} + enum PlatformRendererType { legacy, latest, @@ -300,6 +309,43 @@ class PlatformTileOverlay { } } +/// Pigeon equivalent of Flutter's EdgeInsets. +class PlatformEdgeInsets { + PlatformEdgeInsets({ + required this.top, + required this.bottom, + required this.left, + required this.right, + }); + + double top; + + double bottom; + + double left; + + double right; + + Object encode() { + return [ + top, + bottom, + left, + right, + ]; + } + + static PlatformEdgeInsets decode(Object result) { + result as List; + return PlatformEdgeInsets( + top: result[0]! as double, + bottom: result[1]! as double, + left: result[2]! as double, + right: result[3]! as double, + ); + } +} + /// Pigeon equivalent of LatLng. class PlatformLatLng { PlatformLatLng({ @@ -391,27 +437,209 @@ class PlatformCluster { } } +/// Pigeon equivalent of CameraTargetBounds. +/// +/// As with the Dart version, it exists to distinguish between not setting a +/// a target, and having an explicitly unbounded target (null [bounds]). +class PlatformCameraTargetBounds { + PlatformCameraTargetBounds({ + this.bounds, + }); + + PlatformLatLngBounds? bounds; + + Object encode() { + return [ + bounds, + ]; + } + + static PlatformCameraTargetBounds decode(Object result) { + result as List; + return PlatformCameraTargetBounds( + bounds: result[0] as PlatformLatLngBounds?, + ); + } +} + +/// Information passed to the platform view creation. +class PlatformMapViewCreationParams { + PlatformMapViewCreationParams({ + required this.initialCameraPosition, + required this.mapConfiguration, + required this.initialCircles, + required this.initialMarkers, + required this.initialPolygons, + required this.initialPolylines, + required this.initialHeatmaps, + required this.initialTileOverlays, + required this.initialClusterManagers, + }); + + PlatformCameraPosition initialCameraPosition; + + PlatformMapConfiguration mapConfiguration; + + List initialCircles; + + List initialMarkers; + + List initialPolygons; + + List initialPolylines; + + List initialHeatmaps; + + List initialTileOverlays; + + List initialClusterManagers; + + Object encode() { + return [ + initialCameraPosition, + mapConfiguration, + initialCircles, + initialMarkers, + initialPolygons, + initialPolylines, + initialHeatmaps, + initialTileOverlays, + initialClusterManagers, + ]; + } + + static PlatformMapViewCreationParams decode(Object result) { + result as List; + return PlatformMapViewCreationParams( + initialCameraPosition: result[0]! as PlatformCameraPosition, + mapConfiguration: result[1]! as PlatformMapConfiguration, + initialCircles: (result[2] as List?)!.cast(), + initialMarkers: (result[3] as List?)!.cast(), + initialPolygons: (result[4] as List?)!.cast(), + initialPolylines: + (result[5] as List?)!.cast(), + initialHeatmaps: (result[6] as List?)!.cast(), + initialTileOverlays: + (result[7] as List?)!.cast(), + initialClusterManagers: + (result[8] as List?)!.cast(), + ); + } +} + /// Pigeon equivalent of MapConfiguration. class PlatformMapConfiguration { PlatformMapConfiguration({ - required this.json, + this.compassEnabled, + this.cameraTargetBounds, + this.mapType, + this.minMaxZoomPreference, + this.mapToolbarEnabled, + this.rotateGesturesEnabled, + this.scrollGesturesEnabled, + this.tiltGesturesEnabled, + this.trackCameraPosition, + this.zoomControlsEnabled, + this.zoomGesturesEnabled, + this.myLocationEnabled, + this.myLocationButtonEnabled, + this.padding, + this.indoorViewEnabled, + this.trafficEnabled, + this.buildingsEnabled, + this.liteModeEnabled, + this.cloudMapId, + this.style, }); - /// The configuration options, as JSON. This should only be set from - /// _jsonForMapConfiguration, and the native code must interpret it according - /// to the internal implementation details of that method. - Map json; + bool? compassEnabled; + + PlatformCameraTargetBounds? cameraTargetBounds; + + PlatformMapType? mapType; + + PlatformZoomRange? minMaxZoomPreference; + + bool? mapToolbarEnabled; + + bool? rotateGesturesEnabled; + + bool? scrollGesturesEnabled; + + bool? tiltGesturesEnabled; + + bool? trackCameraPosition; + + bool? zoomControlsEnabled; + + bool? zoomGesturesEnabled; + + bool? myLocationEnabled; + + bool? myLocationButtonEnabled; + + PlatformEdgeInsets? padding; + + bool? indoorViewEnabled; + + bool? trafficEnabled; + + bool? buildingsEnabled; + + bool? liteModeEnabled; + + String? cloudMapId; + + String? style; Object encode() { return [ - json, + compassEnabled, + cameraTargetBounds, + mapType, + minMaxZoomPreference, + mapToolbarEnabled, + rotateGesturesEnabled, + scrollGesturesEnabled, + tiltGesturesEnabled, + trackCameraPosition, + zoomControlsEnabled, + zoomGesturesEnabled, + myLocationEnabled, + myLocationButtonEnabled, + padding, + indoorViewEnabled, + trafficEnabled, + buildingsEnabled, + liteModeEnabled, + cloudMapId, + style, ]; } static PlatformMapConfiguration decode(Object result) { result as List; return PlatformMapConfiguration( - json: (result[0] as Map?)!.cast(), + compassEnabled: result[0] as bool?, + cameraTargetBounds: result[1] as PlatformCameraTargetBounds?, + mapType: result[2] as PlatformMapType?, + minMaxZoomPreference: result[3] as PlatformZoomRange?, + mapToolbarEnabled: result[4] as bool?, + rotateGesturesEnabled: result[5] as bool?, + scrollGesturesEnabled: result[6] as bool?, + tiltGesturesEnabled: result[7] as bool?, + trackCameraPosition: result[8] as bool?, + zoomControlsEnabled: result[9] as bool?, + zoomGesturesEnabled: result[10] as bool?, + myLocationEnabled: result[11] as bool?, + myLocationButtonEnabled: result[12] as bool?, + padding: result[13] as PlatformEdgeInsets?, + indoorViewEnabled: result[14] as bool?, + trafficEnabled: result[15] as bool?, + buildingsEnabled: result[16] as bool?, + liteModeEnabled: result[17] as bool?, + cloudMapId: result[18] as String?, + style: result[19] as String?, ); } } @@ -483,13 +711,13 @@ class PlatformTileLayer { /// Possible outcomes of launching a URL. class PlatformZoomRange { PlatformZoomRange({ - required this.min, - required this.max, + this.min, + this.max, }); - double min; + double? min; - double max; + double? max; Object encode() { return [ @@ -501,8 +729,8 @@ class PlatformZoomRange { static PlatformZoomRange decode(Object result) { result as List; return PlatformZoomRange( - min: result[0]! as double, - max: result[1]! as double, + min: result[0] as double?, + max: result[1] as double?, ); } } @@ -541,29 +769,41 @@ class _PigeonCodec extends StandardMessageCodec { } else if (value is PlatformTileOverlay) { buffer.putUint8(138); writeValue(buffer, value.encode()); - } else if (value is PlatformLatLng) { + } else if (value is PlatformEdgeInsets) { buffer.putUint8(139); writeValue(buffer, value.encode()); - } else if (value is PlatformLatLngBounds) { + } else if (value is PlatformLatLng) { buffer.putUint8(140); writeValue(buffer, value.encode()); - } else if (value is PlatformCluster) { + } else if (value is PlatformLatLngBounds) { buffer.putUint8(141); writeValue(buffer, value.encode()); - } else if (value is PlatformMapConfiguration) { + } else if (value is PlatformCluster) { buffer.putUint8(142); writeValue(buffer, value.encode()); - } else if (value is PlatformPoint) { + } else if (value is PlatformCameraTargetBounds) { buffer.putUint8(143); writeValue(buffer, value.encode()); - } else if (value is PlatformTileLayer) { + } else if (value is PlatformMapViewCreationParams) { buffer.putUint8(144); writeValue(buffer, value.encode()); - } else if (value is PlatformZoomRange) { + } else if (value is PlatformMapConfiguration) { buffer.putUint8(145); writeValue(buffer, value.encode()); - } else if (value is PlatformRendererType) { + } else if (value is PlatformPoint) { buffer.putUint8(146); + writeValue(buffer, value.encode()); + } else if (value is PlatformTileLayer) { + buffer.putUint8(147); + writeValue(buffer, value.encode()); + } else if (value is PlatformZoomRange) { + buffer.putUint8(148); + writeValue(buffer, value.encode()); + } else if (value is PlatformMapType) { + buffer.putUint8(149); + writeValue(buffer, value.index); + } else if (value is PlatformRendererType) { + buffer.putUint8(150); writeValue(buffer, value.index); } else { super.writeValue(buffer, value); @@ -594,20 +834,29 @@ class _PigeonCodec extends StandardMessageCodec { case 138: return PlatformTileOverlay.decode(readValue(buffer)!); case 139: - return PlatformLatLng.decode(readValue(buffer)!); + return PlatformEdgeInsets.decode(readValue(buffer)!); case 140: - return PlatformLatLngBounds.decode(readValue(buffer)!); + return PlatformLatLng.decode(readValue(buffer)!); case 141: - return PlatformCluster.decode(readValue(buffer)!); + return PlatformLatLngBounds.decode(readValue(buffer)!); case 142: - return PlatformMapConfiguration.decode(readValue(buffer)!); + return PlatformCluster.decode(readValue(buffer)!); case 143: - return PlatformPoint.decode(readValue(buffer)!); + return PlatformCameraTargetBounds.decode(readValue(buffer)!); case 144: - return PlatformTileLayer.decode(readValue(buffer)!); + return PlatformMapViewCreationParams.decode(readValue(buffer)!); case 145: - return PlatformZoomRange.decode(readValue(buffer)!); + return PlatformMapConfiguration.decode(readValue(buffer)!); case 146: + return PlatformPoint.decode(readValue(buffer)!); + case 147: + return PlatformTileLayer.decode(readValue(buffer)!); + case 148: + return PlatformZoomRange.decode(readValue(buffer)!); + case 149: + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformMapType.values[value]; + case 150: final int? value = readValue(buffer) as int?; return value == null ? null : PlatformRendererType.values[value]; default: @@ -1782,6 +2031,49 @@ class MapsInitializerApi { } } +/// Dummy interface to force generation of the platform view creation params, +/// which are not used in any Pigeon calls, only the platform view creation +/// call made internally by Flutter. +class MapsPlatformViewApi { + /// Constructor for [MapsPlatformViewApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + MapsPlatformViewApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String __pigeon_messageChannelSuffix; + + Future createView(PlatformMapViewCreationParams? type) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.google_maps_flutter_android.MapsPlatformViewApi.createView$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([type]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } +} + /// Inspector API only intended for use in integration tests. class MapsInspectorApi { /// Constructor for [MapsInspectorApi]. The [binaryMessenger] named argument is diff --git a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/serialization.dart b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/serialization.dart index 8858a6e481b..fee4828fe71 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/serialization.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/serialization.dart @@ -23,7 +23,7 @@ void _addIfNonNull(Map map, String fieldName, Object? value) { } /// Serialize [Heatmap] -Object serializeHeatmap(Heatmap heatmap) { +Map serializeHeatmap(Heatmap heatmap) { final Map json = {}; _addIfNonNull(json, _heatmapIdKey, heatmap.heatmapId.value); diff --git a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/utils/cluster_manager_utils.dart b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/utils/cluster_manager_utils.dart deleted file mode 100644 index 1aab89354a0..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/utils/cluster_manager_utils.dart +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; - -/// Converts a Set of Cluster Managers into object serializable in JSON. -Object serializeClusterManagerSet(Set clusterManagers) { - return clusterManagers - .map((ClusterManager cm) => _serializeClusterManager(cm)) - .toList(); -} - -/// Converts a Cluster Manager into object serializable in JSON. -Object _serializeClusterManager(ClusterManager clusterManager) { - final Map json = {}; - json['clusterManagerId'] = clusterManager.clusterManagerId.value; - return json; -} diff --git a/packages/google_maps_flutter/google_maps_flutter_android/pigeons/messages.dart b/packages/google_maps_flutter/google_maps_flutter_android/pigeons/messages.dart index 7cf0afbea28..205ce4191b7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/pigeons/messages.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/pigeons/messages.dart @@ -11,6 +11,15 @@ import 'package:pigeon/pigeon.dart'; copyrightHeader: 'pigeons/copyright.txt', )) +/// Pigeon equivalent of MapType +enum PlatformMapType { + none, + normal, + satellite, + terrain, + hybrid, +} + // Pigeon equivalent of the Java MapsInitializer.Renderer. enum PlatformRendererType { legacy, latest } @@ -132,6 +141,21 @@ class PlatformTileOverlay { final Map json; } +/// Pigeon equivalent of Flutter's EdgeInsets. +class PlatformEdgeInsets { + PlatformEdgeInsets({ + required this.top, + required this.bottom, + required this.left, + required this.right, + }); + + final double top; + final double bottom; + final double left; + final double right; +} + /// Pigeon equivalent of LatLng. class PlatformLatLng { PlatformLatLng({required this.latitude, required this.longitude}); @@ -166,16 +190,89 @@ class PlatformCluster { final List markerIds; } +/// Pigeon equivalent of CameraTargetBounds. +/// +/// As with the Dart version, it exists to distinguish between not setting a +/// a target, and having an explicitly unbounded target (null [bounds]). +class PlatformCameraTargetBounds { + PlatformCameraTargetBounds({required this.bounds}); + + final PlatformLatLngBounds? bounds; +} + +/// Information passed to the platform view creation. +class PlatformMapViewCreationParams { + PlatformMapViewCreationParams({ + required this.initialCameraPosition, + required this.mapConfiguration, + required this.initialCircles, + required this.initialMarkers, + required this.initialPolygons, + required this.initialPolylines, + required this.initialHeatmaps, + required this.initialTileOverlays, + required this.initialClusterManagers, + }); + + final PlatformCameraPosition initialCameraPosition; + final PlatformMapConfiguration mapConfiguration; + // TODO(stuartmorgan): Make the generic types non-nullable once supported. + // https://github.com/flutter/flutter/issues/97848 + // The consuming code treats the entries as non-nullable. + final List initialCircles; + final List initialMarkers; + final List initialPolygons; + final List initialPolylines; + final List initialHeatmaps; + final List initialTileOverlays; + final List initialClusterManagers; +} + /// Pigeon equivalent of MapConfiguration. class PlatformMapConfiguration { - PlatformMapConfiguration({required this.json}); + PlatformMapConfiguration({ + required this.compassEnabled, + required this.cameraTargetBounds, + required this.mapType, + required this.minMaxZoomPreference, + required this.mapToolbarEnabled, + required this.rotateGesturesEnabled, + required this.scrollGesturesEnabled, + required this.tiltGesturesEnabled, + required this.trackCameraPosition, + required this.zoomControlsEnabled, + required this.zoomGesturesEnabled, + required this.myLocationEnabled, + required this.myLocationButtonEnabled, + required this.padding, + required this.indoorViewEnabled, + required this.trafficEnabled, + required this.buildingsEnabled, + required this.liteModeEnabled, + required this.cloudMapId, + required this.style, + }); - /// The configuration options, as JSON. This should only be set from - /// _jsonForMapConfiguration, and the native code must interpret it according - /// to the internal implementation details of that method. - // TODO(stuartmorgan): Replace this with structured data. This exists only to - // allow incremental migration to Pigeon. - final Map json; + final bool? compassEnabled; + final PlatformCameraTargetBounds? cameraTargetBounds; + final PlatformMapType? mapType; + final PlatformZoomRange? minMaxZoomPreference; + final bool? mapToolbarEnabled; + final bool? rotateGesturesEnabled; + final bool? scrollGesturesEnabled; + final bool? tiltGesturesEnabled; + final bool? trackCameraPosition; + final bool? zoomControlsEnabled; + final bool? zoomGesturesEnabled; + final bool? myLocationEnabled; + final bool? myLocationButtonEnabled; + final PlatformEdgeInsets? padding; + final bool? indoorViewEnabled; + final bool? trafficEnabled; + final bool? buildingsEnabled; + final bool? liteModeEnabled; + final String? cloudMapId; + final String? style; } /// Pigeon representation of an x,y coordinate. @@ -205,8 +302,8 @@ class PlatformTileLayer { class PlatformZoomRange { PlatformZoomRange({required this.min, required this.max}); - final double min; - final double max; + final double? min; + final double? max; } /// Interface for non-test interactions with the native SDK. @@ -388,6 +485,15 @@ abstract class MapsInitializerApi { PlatformRendererType? type); } +/// Dummy interface to force generation of the platform view creation params, +/// which are not used in any Pigeon calls, only the platform view creation +/// call made internally by Flutter. +@HostApi() +abstract class MapsPlatformViewApi { + // This is never actually called. + void createView(PlatformMapViewCreationParams? type); +} + /// Inspector API only intended for use in integration tests. @HostApi() abstract class MapsInspectorApi { diff --git a/packages/google_maps_flutter/google_maps_flutter_android/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_android/pubspec.yaml index 82068018bc7..56c520593ff 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_android/pubspec.yaml @@ -2,7 +2,7 @@ name: google_maps_flutter_android description: Android implementation of the google_maps_flutter plugin. repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 2.13.0 +version: 2.14.0 environment: sdk: ^3.4.0 diff --git a/packages/google_maps_flutter/google_maps_flutter_android/test/google_maps_flutter_android_test.dart b/packages/google_maps_flutter/google_maps_flutter_android/test/google_maps_flutter_android_test.dart index 5e3943b26ab..b6808bc61ee 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/test/google_maps_flutter_android_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/test/google_maps_flutter_android_test.dart @@ -209,10 +209,12 @@ void main() { setUpMockMap(mapId: mapId); // Set some arbitrary options. - const MapConfiguration config = MapConfiguration( + final CameraTargetBounds cameraBounds = CameraTargetBounds(LatLngBounds( + southwest: const LatLng(10, 20), northeast: const LatLng(30, 40))); + final MapConfiguration config = MapConfiguration( compassEnabled: true, - liteModeEnabled: false, mapType: MapType.terrain, + cameraTargetBounds: cameraBounds, ); await maps.updateMapConfiguration(config, mapId: mapId); @@ -220,16 +222,21 @@ void main() { verify(api.updateMapConfiguration(captureAny)); final PlatformMapConfiguration passedConfig = verification.captured[0] as PlatformMapConfiguration; - final Map passedConfigJson = - passedConfig.json as Map; // Each set option should be present. - expect(passedConfigJson['compassEnabled'], true); - expect(passedConfigJson['liteModeEnabled'], false); - expect(passedConfigJson['mapType'], MapType.terrain.index); + expect(passedConfig.compassEnabled, true); + expect(passedConfig.mapType, PlatformMapType.terrain); + expect(passedConfig.cameraTargetBounds?.bounds?.northeast.latitude, + cameraBounds.bounds?.northeast.latitude); + expect(passedConfig.cameraTargetBounds?.bounds?.northeast.longitude, + cameraBounds.bounds?.northeast.longitude); + expect(passedConfig.cameraTargetBounds?.bounds?.southwest.latitude, + cameraBounds.bounds?.southwest.latitude); + expect(passedConfig.cameraTargetBounds?.bounds?.southwest.longitude, + cameraBounds.bounds?.southwest.longitude); // Spot-check that unset options are not be present. - expect(passedConfigJson['myLocationEnabled'], isNull); - expect(passedConfigJson['cameraTargetBounds'], isNull); - expect(passedConfigJson['padding'], isNull); + expect(passedConfig.myLocationEnabled, isNull); + expect(passedConfig.minMaxZoomPreference, isNull); + expect(passedConfig.padding, isNull); }); test('updateMapOptions passes expected arguments', () async { @@ -238,10 +245,12 @@ void main() { setUpMockMap(mapId: mapId); // Set some arbitrary options. + final CameraTargetBounds cameraBounds = CameraTargetBounds(LatLngBounds( + southwest: const LatLng(10, 20), northeast: const LatLng(30, 40))); final Map config = { 'compassEnabled': true, - 'liteModeEnabled': false, 'mapType': MapType.terrain.index, + 'cameraTargetBounds': cameraBounds.toJson(), }; await maps.updateMapOptions(config, mapId: mapId); @@ -249,16 +258,21 @@ void main() { verify(api.updateMapConfiguration(captureAny)); final PlatformMapConfiguration passedConfig = verification.captured[0] as PlatformMapConfiguration; - final Map passedConfigJson = - passedConfig.json as Map; // Each set option should be present. - expect(passedConfigJson['compassEnabled'], true); - expect(passedConfigJson['liteModeEnabled'], false); - expect(passedConfigJson['mapType'], MapType.terrain.index); + expect(passedConfig.compassEnabled, true); + expect(passedConfig.mapType, PlatformMapType.terrain); + expect(passedConfig.cameraTargetBounds?.bounds?.northeast.latitude, + cameraBounds.bounds?.northeast.latitude); + expect(passedConfig.cameraTargetBounds?.bounds?.northeast.longitude, + cameraBounds.bounds?.northeast.longitude); + expect(passedConfig.cameraTargetBounds?.bounds?.southwest.latitude, + cameraBounds.bounds?.southwest.latitude); + expect(passedConfig.cameraTargetBounds?.bounds?.southwest.longitude, + cameraBounds.bounds?.southwest.longitude); // Spot-check that unset options are not be present. - expect(passedConfigJson['myLocationEnabled'], isNull); - expect(passedConfigJson['cameraTargetBounds'], isNull); - expect(passedConfigJson['padding'], isNull); + expect(passedConfig.myLocationEnabled, isNull); + expect(passedConfig.minMaxZoomPreference, isNull); + expect(passedConfig.padding, isNull); }); test('updateCircles passes expected arguments', () async { @@ -645,17 +659,15 @@ void main() { methodCall.arguments as Map); if (args.containsKey('params')) { final Uint8List paramsUint8List = args['params'] as Uint8List; - const StandardMessageCodec codec = StandardMessageCodec(); final ByteData byteData = ByteData.sublistView(paramsUint8List); - final Map creationParams = - Map.from( - codec.decodeMessage(byteData) as Map); - if (creationParams.containsKey('options')) { - final Map options = Map.from( - creationParams['options'] as Map); - if (options.containsKey('cloudMapId')) { - passedCloudMapIdCompleter - .complete(options['cloudMapId'] as String); + final PlatformMapViewCreationParams? creationParams = + MapsApi.pigeonChannelCodec.decodeMessage(byteData) + as PlatformMapViewCreationParams?; + if (creationParams != null) { + final String? passedMapId = + creationParams.mapConfiguration.cloudMapId; + if (passedMapId != null) { + passedCloudMapIdCompleter.complete(passedMapId); } } } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md index db97cfdbaf8..3e2202dcab5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md @@ -1,5 +1,6 @@ -## NEXT +## 2.13.0 +* Updates map configuration and platform view creation parameters to use Pigeon. * Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 2.12.0 diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/FGMClusterManagersControllerTests.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/FGMClusterManagersControllerTests.m index 97607bf63ca..6fdcccf468d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/FGMClusterManagersControllerTests.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/FGMClusterManagersControllerTests.m @@ -43,18 +43,10 @@ - (void)testClustering { [FGMPlatformClusterManager makeWithIdentifier:clusterManagerId]; [clusterManagersController addClusterManagers:@[ clusterManagerToAdd ]]; - // Add cluster managers in JSON format. - NSString *JSONClusterManagerId = @"json_cm"; - NSDictionary *JSONclusterManagerToAdd = @{@"clusterManagerId" : JSONClusterManagerId}; - [clusterManagersController addJSONClusterManagers:@[ JSONclusterManagerToAdd ]]; - // Verify that cluster managers are available GMUClusterManager *clusterManager = [clusterManagersController clusterManagerWithIdentifier:clusterManagerId]; XCTAssertNotNil(clusterManager, @"Cluster Manager should not be nil"); - GMUClusterManager *JSONClusterManager = - [clusterManagersController clusterManagerWithIdentifier:JSONClusterManagerId]; - XCTAssertNotNil(JSONClusterManager, @"Cluster Manager should not be nil"); // Add markers NSString *markerId1 = @"m1"; @@ -65,11 +57,13 @@ - (void)testClustering { @"position" : @[ @0, @0 ], @"clusterManagerId" : clusterManagerId }]; - NSDictionary *marker2 = - @{@"markerId" : markerId2, @"position" : @[ @0, @0 ], @"clusterManagerId" : clusterManagerId}; + FGMPlatformMarker *marker2 = [FGMPlatformMarker makeWithJson:@{ + @"markerId" : markerId2, + @"position" : @[ @0, @0 ], + @"clusterManagerId" : clusterManagerId + }]; - [markersController addMarkers:@[ marker1 ]]; - [markersController addJSONMarkers:@[ marker2 ]]; + [markersController addMarkers:@[ marker1, marker2 ]]; FlutterError *error = nil; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m index 42e3fde2552..8179ec697a5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m @@ -152,6 +152,25 @@ - (void)testCameraPostionFromDictionary { XCTAssertEqualWithAccuracy(cameraPosition.viewingAngle, 5, accuracy); } +- (void)testGetCameraPostionForPigeonCameraPosition { + FGMPlatformCameraPosition *pigeonCameraPosition = [FGMPlatformCameraPosition + makeWithBearing:1.0 + target:[FGMPlatformLatLng makeWithLatitude:2.0 longitude:3.0] + tilt:4.0 + zoom:5.0]; + + GMSCameraPosition *cameraPosition = + FGMGetCameraPositionForPigeonCameraPosition(pigeonCameraPosition); + + XCTAssertEqualWithAccuracy(cameraPosition.target.latitude, pigeonCameraPosition.target.latitude, + DBL_EPSILON); + XCTAssertEqualWithAccuracy(cameraPosition.target.longitude, pigeonCameraPosition.target.longitude, + DBL_EPSILON); + XCTAssertEqualWithAccuracy(cameraPosition.zoom, pigeonCameraPosition.zoom, DBL_EPSILON); + XCTAssertEqualWithAccuracy(cameraPosition.bearing, pigeonCameraPosition.bearing, DBL_EPSILON); + XCTAssertEqualWithAccuracy(cameraPosition.viewingAngle, pigeonCameraPosition.tilt, DBL_EPSILON); +} + - (void)testCGPointForPigeonPoint { FGMPlatformPoint *pigeonPoint = [FGMPlatformPoint makeWithX:1.0 y:2.0]; @@ -175,12 +194,12 @@ - (void)testCoordinateBoundsFromLatLongs { XCTAssertEqualWithAccuracy(bounds.northEast.longitude, 4, accuracy); } -- (void)testMapViewTypeFromTypeValue { - XCTAssertEqual(kGMSTypeNormal, [FLTGoogleMapJSONConversions mapViewTypeFromTypeValue:@1]); - XCTAssertEqual(kGMSTypeSatellite, [FLTGoogleMapJSONConversions mapViewTypeFromTypeValue:@2]); - XCTAssertEqual(kGMSTypeTerrain, [FLTGoogleMapJSONConversions mapViewTypeFromTypeValue:@3]); - XCTAssertEqual(kGMSTypeHybrid, [FLTGoogleMapJSONConversions mapViewTypeFromTypeValue:@4]); - XCTAssertEqual(kGMSTypeNone, [FLTGoogleMapJSONConversions mapViewTypeFromTypeValue:@5]); +- (void)testMapViewTypeFromPigeonType { + XCTAssertEqual(kGMSTypeNormal, FGMGetMapViewTypeForPigeonMapType(FGMPlatformMapTypeNormal)); + XCTAssertEqual(kGMSTypeSatellite, FGMGetMapViewTypeForPigeonMapType(FGMPlatformMapTypeSatellite)); + XCTAssertEqual(kGMSTypeTerrain, FGMGetMapViewTypeForPigeonMapType(FGMPlatformMapTypeTerrain)); + XCTAssertEqual(kGMSTypeHybrid, FGMGetMapViewTypeForPigeonMapType(FGMPlatformMapTypeHybrid)); + XCTAssertEqual(kGMSTypeNone, FGMGetMapViewTypeForPigeonMapType(FGMPlatformMapTypeNone)); } - (void)testCameraUpdateFromArrayNewCameraPosition { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/GoogleMapsTests.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/GoogleMapsTests.m index b3ac89e2441..c175550dd2c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/GoogleMapsTests.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/ios/RunnerTests/GoogleMapsTests.m @@ -40,10 +40,11 @@ - (void)testFrameObserver { initWithFrame:frame camera:[[GMSCameraPosition alloc] initWithLatitude:0 longitude:0 zoom:0]]; #pragma clang diagnostic pop - FLTGoogleMapController *controller = [[FLTGoogleMapController alloc] initWithMapView:mapView - viewIdentifier:0 - arguments:nil - registrar:registrar]; + FLTGoogleMapController *controller = + [[FLTGoogleMapController alloc] initWithMapView:mapView + viewIdentifier:0 + creationParameters:[self emptyCreationParameters] + registrar:registrar]; for (NSInteger i = 0; i < 10; ++i) { [controller view]; @@ -85,4 +86,24 @@ - (void)testHandleResultTileDownsamplesWideGamutImages { XCTAssert(bitsPerComponent == 8); } +/// Creates an empty creation paramaters object for tests where the values don't matter, just that +/// there's a valid object to pass in. +- (FGMPlatformMapViewCreationParams *)emptyCreationParameters { + return [FGMPlatformMapViewCreationParams + makeWithInitialCameraPosition:[FGMPlatformCameraPosition + makeWithBearing:0.0 + target:[FGMPlatformLatLng makeWithLatitude:0.0 + longitude:0.0] + tilt:0.0 + zoom:0.0] + mapConfiguration:[[FGMPlatformMapConfiguration alloc] init] + initialCircles:@[] + initialMarkers:@[] + initialPolygons:@[] + initialPolylines:@[] + initialHeatmaps:@[] + initialTileOverlays:@[] + initialClusterManagers:@[]]; +} + @end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/ios/RunnerTests/GoogleMapsTests.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/ios/RunnerTests/GoogleMapsTests.m index b3ac89e2441..c175550dd2c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/ios/RunnerTests/GoogleMapsTests.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios15/ios/RunnerTests/GoogleMapsTests.m @@ -40,10 +40,11 @@ - (void)testFrameObserver { initWithFrame:frame camera:[[GMSCameraPosition alloc] initWithLatitude:0 longitude:0 zoom:0]]; #pragma clang diagnostic pop - FLTGoogleMapController *controller = [[FLTGoogleMapController alloc] initWithMapView:mapView - viewIdentifier:0 - arguments:nil - registrar:registrar]; + FLTGoogleMapController *controller = + [[FLTGoogleMapController alloc] initWithMapView:mapView + viewIdentifier:0 + creationParameters:[self emptyCreationParameters] + registrar:registrar]; for (NSInteger i = 0; i < 10; ++i) { [controller view]; @@ -85,4 +86,24 @@ - (void)testHandleResultTileDownsamplesWideGamutImages { XCTAssert(bitsPerComponent == 8); } +/// Creates an empty creation paramaters object for tests where the values don't matter, just that +/// there's a valid object to pass in. +- (FGMPlatformMapViewCreationParams *)emptyCreationParameters { + return [FGMPlatformMapViewCreationParams + makeWithInitialCameraPosition:[FGMPlatformCameraPosition + makeWithBearing:0.0 + target:[FGMPlatformLatLng makeWithLatitude:0.0 + longitude:0.0] + tilt:0.0 + zoom:0.0] + mapConfiguration:[[FGMPlatformMapConfiguration alloc] init] + initialCircles:@[] + initialMarkers:@[] + initialPolygons:@[] + initialPolylines:@[] + initialHeatmaps:@[] + initialTileOverlays:@[] + initialClusterManagers:@[]]; +} + @end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/example_google_map.dart b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/example_google_map.dart index fcf24452c87..a8e19e29e7d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/example_google_map.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/example_google_map.dart @@ -224,7 +224,6 @@ class ExampleGoogleMap extends StatefulWidget { this.onMapCreated, this.gestureRecognizers = const >{}, this.compassEnabled = true, - this.mapToolbarEnabled = true, this.cameraTargetBounds = CameraTargetBounds.unbounded, this.mapType = MapType.normal, this.minMaxZoomPreference = MinMaxZoomPreference.unbounded, @@ -232,7 +231,6 @@ class ExampleGoogleMap extends StatefulWidget { this.scrollGesturesEnabled = true, this.zoomControlsEnabled = true, this.zoomGesturesEnabled = true, - this.liteModeEnabled = false, this.tiltGesturesEnabled = true, this.myLocationEnabled = false, this.myLocationButtonEnabled = true, @@ -269,9 +267,6 @@ class ExampleGoogleMap extends StatefulWidget { /// True if the map should show a compass when rotated. final bool compassEnabled; - /// True if the map should show a toolbar when you interact with the map. Android only. - final bool mapToolbarEnabled; - /// Geographical bounding box for the camera target. final CameraTargetBounds cameraTargetBounds; @@ -299,9 +294,6 @@ class ExampleGoogleMap extends StatefulWidget { /// True if the map view should respond to zoom gestures. final bool zoomGesturesEnabled; - /// True if the map view should be in lite mode. Android only. - final bool liteModeEnabled; - /// True if the map view should respond to tilt gestures. final bool tiltGesturesEnabled; @@ -556,7 +548,6 @@ class _ExampleGoogleMapState extends State { MapConfiguration _configurationFromMapWidget(ExampleGoogleMap map) { return MapConfiguration( compassEnabled: map.compassEnabled, - mapToolbarEnabled: map.mapToolbarEnabled, cameraTargetBounds: map.cameraTargetBounds, mapType: map.mapType, minMaxZoomPreference: map.minMaxZoomPreference, @@ -566,7 +557,6 @@ MapConfiguration _configurationFromMapWidget(ExampleGoogleMap map) { trackCameraPosition: map.onCameraMove != null, zoomControlsEnabled: map.zoomControlsEnabled, zoomGesturesEnabled: map.zoomGesturesEnabled, - liteModeEnabled: map.liteModeEnabled, myLocationEnabled: map.myLocationEnabled, myLocationButtonEnabled: map.myLocationButtonEnabled, padding: map.padding, diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/lite_mode.dart b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/lite_mode.dart index f7bead951f5..a70ff98a4e7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/lite_mode.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/lite_mode.dart @@ -37,7 +37,6 @@ class _LiteModeBody extends StatelessWidget { height: 300.0, child: ExampleGoogleMap( initialCameraPosition: _kInitialPosition, - liteModeEnabled: true, ), ), ), diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/map_ui.dart b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/map_ui.dart index 105676da9ed..0038ec6f339 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/map_ui.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/map_ui.dart @@ -45,7 +45,6 @@ class MapUiBodyState extends State { bool _isMapCreated = false; final bool _isMoving = false; bool _compassEnabled = true; - bool _mapToolbarEnabled = true; CameraTargetBounds _cameraTargetBounds = CameraTargetBounds.unbounded; MinMaxZoomPreference _minMaxZoomPreference = MinMaxZoomPreference.unbounded; MapType _mapType = MapType.normal; @@ -83,17 +82,6 @@ class MapUiBodyState extends State { ); } - Widget _mapToolbarToggler() { - return TextButton( - child: Text('${_mapToolbarEnabled ? 'disable' : 'enable'} map toolbar'), - onPressed: () { - setState(() { - _mapToolbarEnabled = !_mapToolbarEnabled; - }); - }, - ); - } - Widget _latLngBoundsToggler() { return TextButton( child: Text( @@ -265,7 +253,6 @@ class MapUiBodyState extends State { onMapCreated: onMapCreated, initialCameraPosition: _kInitialPosition, compassEnabled: _compassEnabled, - mapToolbarEnabled: _mapToolbarEnabled, cameraTargetBounds: _cameraTargetBounds, minMaxZoomPreference: _minMaxZoomPreference, mapType: _mapType, @@ -308,7 +295,6 @@ class MapUiBodyState extends State { Text('camera tilt: ${_position.tilt}'), Text(_isMoving ? '(Camera moving)' : '(Camera idle)'), _compassToggler(), - _mapToolbarToggler(), _latLngBoundsToggler(), _mapTypeCycler(), _zoomBoundsToggler(), diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FGMClusterManagersController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FGMClusterManagersController.h index 9e5f6f16ae6..346a1ab9f1c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FGMClusterManagersController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FGMClusterManagersController.h @@ -20,11 +20,6 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithMapView:(GMSMapView *)mapView callbackHandler:(FGMMapsCallbackApi *)callbackHandler; -/// Creates cluster managers and initializes them form JSON data. -/// -/// @param clusterManagersToAdd Array of cluster managers JSON data to add. -- (void)addJSONClusterManagers:(NSArray *)clusterManagersToAdd; - /// Creates cluster managers and initializes them. /// /// @param clusterManagersToAdd Array of cluster managers to add. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FGMClusterManagersController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FGMClusterManagersController.m index d9fcb6a9db8..26db81693bd 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FGMClusterManagersController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FGMClusterManagersController.m @@ -33,13 +33,6 @@ - (instancetype)initWithMapView:(GMSMapView *)mapView return self; } -- (void)addJSONClusterManagers:(NSArray *)clusterManagersToAdd { - for (NSDictionary *clusterDict in clusterManagersToAdd) { - NSString *identifier = clusterDict[@"clusterManagerId"]; - [self addClusterManager:identifier]; - } -} - - (void)addClusterManagers:(NSArray *)clusterManagersToAdd { for (FGMPlatformClusterManager *clusterManager in clusterManagersToAdd) { NSString *identifier = clusterManager.identifier; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapHeatmapController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapHeatmapController.h index 0c3407504a7..fb516ad99e7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapHeatmapController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapHeatmapController.h @@ -54,9 +54,6 @@ NS_ASSUME_NONNULL_BEGIN /// Initializes the controller with a GMSMapView. - (instancetype)initWithMapView:(GMSMapView *)mapView; -/// Adds heatmaps to the map from JSON data. -- (void)addJSONHeatmaps:(NSArray *> *)heatmapsToAdd; - /// Adds heatmaps to the map. - (void)addHeatmaps:(NSArray *)heatmapsToAdd; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapHeatmapController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapHeatmapController.m index 38b6b35ce55..e3f6aab0274 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapHeatmapController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapHeatmapController.m @@ -106,18 +106,6 @@ - (instancetype)initWithMapView:(GMSMapView *)mapView { return self; } -- (void)addJSONHeatmaps:(NSArray *> *)heatmapsToAdd { - for (NSDictionary *heatmap in heatmapsToAdd) { - NSString *heatmapId = [FLTHeatmapsController identifierForHeatmap:heatmap]; - GMUHeatmapTileLayer *heatmapTileLayer = [[GMUHeatmapTileLayer alloc] init]; - FLTGoogleMapHeatmapController *controller = - [[FLTGoogleMapHeatmapController alloc] initWithHeatmapTileLayer:heatmapTileLayer - mapView:_mapView - options:heatmap]; - _heatmapIdToController[heatmapId] = controller; - } -} - - (void)addHeatmaps:(NSArray *)heatmapsToAdd { for (FGMPlatformHeatmap *heatmap in heatmapsToAdd) { NSString *heatmapId = [FLTHeatmapsController identifierForHeatmap:heatmap.json]; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapJSONConversions.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapJSONConversions.h index d6a7992e979..ba68ca7a5b5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapJSONConversions.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapJSONConversions.h @@ -26,6 +26,10 @@ extern CLLocationCoordinate2D FGMGetCoordinateForPigeonLatLng(FGMPlatformLatLng /// Converts a CLLocationCoordinate2D to its Pigeon representation. extern FGMPlatformLatLng *FGMGetPigeonLatLngForCoordinate(CLLocationCoordinate2D coord); +/// Creates a GMSCoordinateBounds from its Pigeon representation. +extern GMSCoordinateBounds *FGMGetCoordinateBoundsForPigeonLatLngBounds( + FGMPlatformLatLngBounds *bounds); + /// Converts a GMSCoordinateBounds to its Pigeon representation. extern FGMPlatformLatLngBounds *FGMGetPigeonLatLngBoundsForCoordinateBounds( GMSCoordinateBounds *bounds); @@ -34,6 +38,13 @@ extern FGMPlatformLatLngBounds *FGMGetPigeonLatLngBoundsForCoordinateBounds( extern FGMPlatformCameraPosition *FGMGetPigeonCameraPositionForPosition( GMSCameraPosition *position); +/// Creates a GMSCameraPosition from its Pigeon representation. +extern GMSCameraPosition *FGMGetCameraPositionForPigeonCameraPosition( + FGMPlatformCameraPosition *position); + +/// Creates a GMSMapViewType from its Pigeon representation. +extern GMSMapViewType FGMGetMapViewTypeForPigeonMapType(FGMPlatformMapType type); + /// Converts a GMUStaticCluster to its Pigeon representation. extern FGMPlatformCluster *FGMGetPigeonCluster(GMUStaticCluster *cluster, NSString *clusterManagerIdentifier); @@ -61,7 +72,6 @@ extern NSString *const kHeatmapGradientColorMapSizeKey; + (NSArray *> *)holesFromPointsArray:(NSArray *)data; + (nullable GMSCameraPosition *)cameraPostionFromDictionary:(nullable NSDictionary *)channelValue; + (GMSCoordinateBounds *)coordinateBoundsFromLatLongs:(NSArray *)latlongs; -+ (GMSMapViewType)mapViewTypeFromTypeValue:(NSNumber *)value; + (nullable GMSCameraUpdate *)cameraUpdateFromArray:(NSArray *)channelValue; + (nullable GMUWeightedLatLng *)weightedLatLngFromArray:(NSArray *)data; + (NSArray *)arrayFromWeightedLatLng:(GMUWeightedLatLng *)weightedLatLng; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapJSONConversions.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapJSONConversions.m index 6542c998c83..99439c48dd2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapJSONConversions.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapJSONConversions.m @@ -27,6 +27,12 @@ CLLocationCoordinate2D FGMGetCoordinateForPigeonLatLng(FGMPlatformLatLng *latLng return [FGMPlatformLatLng makeWithLatitude:coord.latitude longitude:coord.longitude]; } +GMSCoordinateBounds *FGMGetCoordinateBoundsForPigeonLatLngBounds(FGMPlatformLatLngBounds *bounds) { + return [[GMSCoordinateBounds alloc] + initWithCoordinate:FGMGetCoordinateForPigeonLatLng(bounds.northeast) + coordinate:FGMGetCoordinateForPigeonLatLng(bounds.southwest)]; +} + FGMPlatformLatLngBounds *FGMGetPigeonLatLngBoundsForCoordinateBounds(GMSCoordinateBounds *bounds) { return [FGMPlatformLatLngBounds makeWithNortheast:FGMGetPigeonLatLngForCoordinate(bounds.northEast) @@ -40,6 +46,29 @@ CLLocationCoordinate2D FGMGetCoordinateForPigeonLatLng(FGMPlatformLatLng *latLng zoom:position.zoom]; } +GMSCameraPosition *FGMGetCameraPositionForPigeonCameraPosition( + FGMPlatformCameraPosition *position) { + return [GMSCameraPosition cameraWithTarget:FGMGetCoordinateForPigeonLatLng(position.target) + zoom:position.zoom + bearing:position.bearing + viewingAngle:position.tilt]; +} + +extern GMSMapViewType FGMGetMapViewTypeForPigeonMapType(FGMPlatformMapType type) { + switch (type) { + case FGMPlatformMapTypeNone: + return kGMSTypeNone; + case FGMPlatformMapTypeNormal: + return kGMSTypeNormal; + case FGMPlatformMapTypeSatellite: + return kGMSTypeSatellite; + case FGMPlatformMapTypeTerrain: + return kGMSTypeTerrain; + case FGMPlatformMapTypeHybrid: + return kGMSTypeHybrid; + } +} + FGMPlatformCluster *FGMGetPigeonCluster(GMUStaticCluster *cluster, NSString *clusterManagerIdentifier) { NSMutableArray *markerIDs = [[NSMutableArray alloc] initWithCapacity:cluster.items.count]; @@ -140,11 +169,6 @@ + (GMSCoordinateBounds *)coordinateBoundsFromLatLongs:(NSArray *)latlongs { coordinate:[FLTGoogleMapJSONConversions locationFromLatLong:latlongs[1]]]; } -+ (GMSMapViewType)mapViewTypeFromTypeValue:(NSNumber *)typeValue { - int value = [typeValue intValue]; - return (GMSMapViewType)(value == 0 ? 5 : value); -} - + (nullable GMSCameraUpdate *)cameraUpdateFromArray:(NSArray *)channelValue { NSString *update = channelValue[0]; if ([update isEqualToString:@"newCameraPosition"]) { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.h index e375f7df6e1..223de202bfc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.h @@ -30,7 +30,6 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithMapView:(GMSMapView *)mapView callbackHandler:(FGMMapsCallbackApi *)callbackHandler registrar:(NSObject *)registrar; -- (void)addJSONTileOverlays:(NSArray *> *)tileOverlaysToAdd; - (void)addTileOverlays:(NSArray *)tileOverlaysToAdd; - (void)changeTileOverlays:(NSArray *)tileOverlaysToChange; - (void)removeTileOverlayWithIdentifiers:(NSArray *)identifiers; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.m index 10523124980..9897cd93da6 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.m @@ -180,20 +180,6 @@ - (instancetype)initWithMapView:(GMSMapView *)mapView return self; } -- (void)addJSONTileOverlays:(NSArray *> *)tileOverlaysToAdd { - for (NSDictionary *tileOverlay in tileOverlaysToAdd) { - NSString *identifier = [FLTTileOverlaysController identifierForTileOverlay:tileOverlay]; - FLTTileProviderController *tileProvider = - [[FLTTileProviderController alloc] initWithTileOverlayIdentifier:identifier - callbackHandler:self.callbackHandler]; - FLTGoogleMapTileOverlayController *controller = - [[FLTGoogleMapTileOverlayController alloc] initWithTileLayer:tileProvider - mapView:self.mapView - options:tileOverlay]; - self.tileOverlayIdentifierToController[identifier] = controller; - } -} - - (void)addTileOverlays:(NSArray *)tileOverlaysToAdd { for (FGMPlatformTileOverlay *tileOverlay in tileOverlaysToAdd) { NSString *identifier = [FLTTileOverlaysController identifierForTileOverlay:tileOverlay.json]; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapCircleController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapCircleController.h index a53199f077d..c40340e08db 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapCircleController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapCircleController.h @@ -21,7 +21,6 @@ - (instancetype)initWithMapView:(GMSMapView *)mapView callbackHandler:(FGMMapsCallbackApi *)callbackHandler registrar:(NSObject *)registrar; -- (void)addJSONCircles:(NSArray *> *)circlesToAdd; - (void)addCircles:(NSArray *)circlesToAdd; - (void)changeCircles:(NSArray *)circlesToChange; - (void)removeCirclesWithIdentifiers:(NSArray *)identifiers; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapCircleController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapCircleController.m index ae4c9c2f9ba..ca71d315022 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapCircleController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapCircleController.m @@ -125,21 +125,6 @@ - (instancetype)initWithMapView:(GMSMapView *)mapView return self; } -- (void)addJSONCircles:(NSArray *> *)circlesToAdd { - for (NSDictionary *circle in circlesToAdd) { - CLLocationCoordinate2D position = [FLTCirclesController getPosition:circle]; - CLLocationDistance radius = [FLTCirclesController getRadius:circle]; - NSString *circleId = [FLTCirclesController getCircleId:circle]; - FLTGoogleMapCircleController *controller = - [[FLTGoogleMapCircleController alloc] initCircleWithPosition:position - radius:radius - circleId:circleId - mapView:self.mapView - options:circle]; - self.circleIdToController[circleId] = controller; - } -} - - (void)addCircles:(NSArray *)circlesToAdd { for (FGMPlatformCircle *circle in circlesToAdd) { CLLocationCoordinate2D position = [FLTCirclesController getPosition:circle.json]; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.h index 3b785c81df3..a2b75d74c75 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.h @@ -18,7 +18,7 @@ NS_ASSUME_NONNULL_BEGIN @interface FLTGoogleMapController : NSObject - (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId - arguments:(nullable id)args + creationParameters:(FGMPlatformMapViewCreationParams *)creationParameters registrar:(NSObject *)registrar; - (void)showAtOrigin:(CGPoint)origin; - (void)hide; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m index df49a63902f..8f913c46421 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m @@ -34,7 +34,7 @@ - (instancetype)initWithRegistrar:(NSObject *)registrar } - (NSObject *)createArgsCodec { - return [FlutterStandardMessageCodec sharedInstance]; + return FGMGetMessagesCodec(); } - (NSObject *)createWithFrame:(CGRect)frame @@ -46,7 +46,7 @@ - (instancetype)initWithRegistrar:(NSObject *)registrar return [[FLTGoogleMapController alloc] initWithFrame:frame viewIdentifier:viewId - arguments:args + creationParameters:args registrar:self.registrar]; } @@ -145,27 +145,30 @@ @implementation FLTGoogleMapController - (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId - arguments:(id _Nullable)args + creationParameters:(FGMPlatformMapViewCreationParams *)creationParameters registrar:(NSObject *)registrar { GMSCameraPosition *camera = - [FLTGoogleMapJSONConversions cameraPostionFromDictionary:args[@"initialCameraPosition"]]; + FGMGetCameraPositionForPigeonCameraPosition(creationParameters.initialCameraPosition); GMSMapViewOptions *options = [[GMSMapViewOptions alloc] init]; options.frame = frame; options.camera = camera; - NSString *cloudMapId = args[@"options"][@"cloudMapId"]; + NSString *cloudMapId = creationParameters.mapConfiguration.cloudMapId; if (cloudMapId) { options.mapID = [GMSMapID mapIDWithIdentifier:cloudMapId]; } GMSMapView *mapView = [[GMSMapView alloc] initWithOptions:options]; - return [self initWithMapView:mapView viewIdentifier:viewId arguments:args registrar:registrar]; + return [self initWithMapView:mapView + viewIdentifier:viewId + creationParameters:creationParameters + registrar:registrar]; } - (instancetype)initWithMapView:(GMSMapView *_Nonnull)mapView viewIdentifier:(int64_t)viewId - arguments:(id _Nullable)args + creationParameters:(FGMPlatformMapViewCreationParams *)creationParameters registrar:(NSObject *_Nonnull)registrar { if (self = [super init]) { _mapView = mapView; @@ -173,7 +176,7 @@ - (instancetype)initWithMapView:(GMSMapView *_Nonnull)mapView _mapView.accessibilityElementsHidden = NO; // TODO(cyanglaz): avoid sending message to self in the middle of the init method. // https://github.com/flutter/flutter/issues/104121 - [self interpretMapOptions:args[@"options"]]; + [self interpretMapConfiguration:creationParameters.mapConfiguration]; NSString *pigeonSuffix = [NSString stringWithFormat:@"%lld", viewId]; _dartCallbackHandler = [[FGMMapsCallbackApi alloc] initWithBinaryMessenger:registrar.messenger messageChannelSuffix:pigeonSuffix]; @@ -201,35 +204,13 @@ - (instancetype)initWithMapView:(GMSMapView *_Nonnull)mapView [[FLTTileOverlaysController alloc] initWithMapView:_mapView callbackHandler:_dartCallbackHandler registrar:registrar]; - - id clusterManagersToAdd = args[@"clusterManagersToAdd"]; - if ([clusterManagersToAdd isKindOfClass:[NSArray class]]) { - [_clusterManagersController addJSONClusterManagers:clusterManagersToAdd]; - } - id markersToAdd = args[@"markersToAdd"]; - if ([markersToAdd isKindOfClass:[NSArray class]]) { - [_markersController addJSONMarkers:markersToAdd]; - } - id polygonsToAdd = args[@"polygonsToAdd"]; - if ([polygonsToAdd isKindOfClass:[NSArray class]]) { - [_polygonsController addJSONPolygons:polygonsToAdd]; - } - id polylinesToAdd = args[@"polylinesToAdd"]; - if ([polylinesToAdd isKindOfClass:[NSArray class]]) { - [_polylinesController addJSONPolylines:polylinesToAdd]; - } - id circlesToAdd = args[@"circlesToAdd"]; - if ([circlesToAdd isKindOfClass:[NSArray class]]) { - [_circlesController addJSONCircles:circlesToAdd]; - } - id heatmapsToAdd = args[kHeatmapsToAddKey]; - if ([heatmapsToAdd isKindOfClass:[NSArray class]]) { - [_heatmapsController addJSONHeatmaps:heatmapsToAdd]; - } - id tileOverlaysToAdd = args[@"tileOverlaysToAdd"]; - if ([tileOverlaysToAdd isKindOfClass:[NSArray class]]) { - [_tileOverlaysController addJSONTileOverlays:tileOverlaysToAdd]; - } + [_clusterManagersController addClusterManagers:creationParameters.initialClusterManagers]; + [_markersController addMarkers:creationParameters.initialMarkers]; + [_polygonsController addPolygons:creationParameters.initialPolygons]; + [_polylinesController addPolylines:creationParameters.initialPolylines]; + [_circlesController addCircles:creationParameters.initialCircles]; + [_heatmapsController addHeatmaps:creationParameters.initialHeatmaps]; + [_tileOverlaysController addTileOverlays:creationParameters.initialTileOverlays]; // Invoke clustering after markers are added. [_clusterManagersController invokeClusteringForEachClusterManager]; @@ -457,79 +438,74 @@ - (void)mapView:(GMSMapView *)mapView didLongPressAtCoordinate:(CLLocationCoordi }]; } -- (void)interpretMapOptions:(NSDictionary *)data { - NSArray *cameraTargetBounds = FGMGetValueOrNilFromDict(data, @"cameraTargetBounds"); +- (void)interpretMapConfiguration:(FGMPlatformMapConfiguration *)config { + FGMPlatformCameraTargetBounds *cameraTargetBounds = config.cameraTargetBounds; if (cameraTargetBounds) { - [self - setCameraTargetBounds:cameraTargetBounds.count > 0 && cameraTargetBounds[0] != [NSNull null] - ? [FLTGoogleMapJSONConversions - coordinateBoundsFromLatLongs:cameraTargetBounds.firstObject] - : nil]; + [self setCameraTargetBounds:cameraTargetBounds.bounds + ? FGMGetCoordinateBoundsForPigeonLatLngBounds( + cameraTargetBounds.bounds) + : nil]; } - NSNumber *compassEnabled = FGMGetValueOrNilFromDict(data, @"compassEnabled"); + NSNumber *compassEnabled = config.compassEnabled; if (compassEnabled) { - [self setCompassEnabled:[compassEnabled boolValue]]; + [self setCompassEnabled:compassEnabled.boolValue]; } - id indoorEnabled = FGMGetValueOrNilFromDict(data, @"indoorEnabled"); + NSNumber *indoorEnabled = config.indoorViewEnabled; if (indoorEnabled) { - [self setIndoorEnabled:[indoorEnabled boolValue]]; + [self setIndoorEnabled:indoorEnabled.boolValue]; } - id trafficEnabled = FGMGetValueOrNilFromDict(data, @"trafficEnabled"); + NSNumber *trafficEnabled = config.trafficEnabled; if (trafficEnabled) { - [self setTrafficEnabled:[trafficEnabled boolValue]]; + [self setTrafficEnabled:trafficEnabled.boolValue]; } - id buildingsEnabled = FGMGetValueOrNilFromDict(data, @"buildingsEnabled"); + NSNumber *buildingsEnabled = config.buildingsEnabled; if (buildingsEnabled) { - [self setBuildingsEnabled:[buildingsEnabled boolValue]]; + [self setBuildingsEnabled:buildingsEnabled.boolValue]; } - id mapType = FGMGetValueOrNilFromDict(data, @"mapType"); + FGMPlatformMapTypeBox *mapType = config.mapType; if (mapType) { - [self setMapType:[FLTGoogleMapJSONConversions mapViewTypeFromTypeValue:mapType]]; + [self setMapType:FGMGetMapViewTypeForPigeonMapType(mapType.value)]; } - NSArray *zoomData = FGMGetValueOrNilFromDict(data, @"minMaxZoomPreference"); + FGMPlatformZoomRange *zoomData = config.minMaxZoomPreference; if (zoomData) { - float minZoom = (zoomData[0] == [NSNull null]) ? kGMSMinZoomLevel : [zoomData[0] floatValue]; - float maxZoom = (zoomData[1] == [NSNull null]) ? kGMSMaxZoomLevel : [zoomData[1] floatValue]; + float minZoom = zoomData.min ? zoomData.min.floatValue : kGMSMinZoomLevel; + float maxZoom = zoomData.max ? zoomData.max.floatValue : kGMSMaxZoomLevel; [self setMinZoom:minZoom maxZoom:maxZoom]; } - NSArray *paddingData = FGMGetValueOrNilFromDict(data, @"padding"); - if (paddingData) { - float top = (paddingData[0] == [NSNull null]) ? 0 : [paddingData[0] floatValue]; - float left = (paddingData[1] == [NSNull null]) ? 0 : [paddingData[1] floatValue]; - float bottom = (paddingData[2] == [NSNull null]) ? 0 : [paddingData[2] floatValue]; - float right = (paddingData[3] == [NSNull null]) ? 0 : [paddingData[3] floatValue]; - [self setPaddingTop:top left:left bottom:bottom right:right]; + FGMPlatformEdgeInsets *padding = config.padding; + if (padding) { + [self setPaddingTop:padding.top left:padding.left bottom:padding.bottom right:padding.right]; } - NSNumber *rotateGesturesEnabled = FGMGetValueOrNilFromDict(data, @"rotateGesturesEnabled"); + NSNumber *rotateGesturesEnabled = config.rotateGesturesEnabled; if (rotateGesturesEnabled) { - [self setRotateGesturesEnabled:[rotateGesturesEnabled boolValue]]; + [self setRotateGesturesEnabled:rotateGesturesEnabled.boolValue]; } - NSNumber *scrollGesturesEnabled = FGMGetValueOrNilFromDict(data, @"scrollGesturesEnabled"); + NSNumber *scrollGesturesEnabled = config.scrollGesturesEnabled; if (scrollGesturesEnabled) { - [self setScrollGesturesEnabled:[scrollGesturesEnabled boolValue]]; + [self setScrollGesturesEnabled:scrollGesturesEnabled.boolValue]; } - NSNumber *tiltGesturesEnabled = FGMGetValueOrNilFromDict(data, @"tiltGesturesEnabled"); + NSNumber *tiltGesturesEnabled = config.tiltGesturesEnabled; if (tiltGesturesEnabled) { - [self setTiltGesturesEnabled:[tiltGesturesEnabled boolValue]]; + [self setTiltGesturesEnabled:tiltGesturesEnabled.boolValue]; } - NSNumber *trackCameraPosition = FGMGetValueOrNilFromDict(data, @"trackCameraPosition"); + NSNumber *trackCameraPosition = config.trackCameraPosition; if (trackCameraPosition) { - [self setTrackCameraPosition:[trackCameraPosition boolValue]]; + [self setTrackCameraPosition:trackCameraPosition.boolValue]; } - NSNumber *zoomGesturesEnabled = FGMGetValueOrNilFromDict(data, @"zoomGesturesEnabled"); + NSNumber *zoomGesturesEnabled = config.zoomGesturesEnabled; if (zoomGesturesEnabled) { - [self setZoomGesturesEnabled:[zoomGesturesEnabled boolValue]]; + [self setZoomGesturesEnabled:zoomGesturesEnabled.boolValue]; } - NSNumber *myLocationEnabled = FGMGetValueOrNilFromDict(data, @"myLocationEnabled"); + NSNumber *myLocationEnabled = config.myLocationEnabled; if (myLocationEnabled) { - [self setMyLocationEnabled:[myLocationEnabled boolValue]]; + [self setMyLocationEnabled:myLocationEnabled.boolValue]; } - NSNumber *myLocationButtonEnabled = FGMGetValueOrNilFromDict(data, @"myLocationButtonEnabled"); + NSNumber *myLocationButtonEnabled = config.myLocationButtonEnabled; if (myLocationButtonEnabled) { - [self setMyLocationButtonEnabled:[myLocationButtonEnabled boolValue]]; + [self setMyLocationButtonEnabled:myLocationButtonEnabled.boolValue]; } - NSString *style = FGMGetValueOrNilFromDict(data, @"style"); + NSString *style = config.style; if (style) { [self setMapStyle:style]; } @@ -577,7 +553,7 @@ - (void)updateHeatmapsByAdding:(nonnull NSArray *)toAdd - (void)updateWithMapConfiguration:(nonnull FGMPlatformMapConfiguration *)configuration error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { - [self.controller interpretMapOptions:configuration.json]; + [self.controller interpretMapConfiguration:configuration]; } - (void)updateMarkersByAdding:(nonnull NSArray *)toAdd @@ -842,8 +818,8 @@ - (nullable NSNumber *)isTrafficEnabledWithError: - (nullable FGMPlatformZoomRange *)zoomRange: (FlutterError *_Nullable __autoreleasing *_Nonnull)error { - return [FGMPlatformZoomRange makeWithMin:self.controller.mapView.minZoom - max:self.controller.mapView.maxZoom]; + return [FGMPlatformZoomRange makeWithMin:@(self.controller.mapView.minZoom) + max:@(self.controller.mapView.maxZoom)]; } @end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController_Test.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController_Test.h index 1377b68e9b6..da4da303ff7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController_Test.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController_Test.h @@ -13,11 +13,11 @@ NS_ASSUME_NONNULL_BEGIN /// /// @param mapView A map view that will be displayed by the controller /// @param viewId A unique identifier for the controller. -/// @param args Parameters for initialising the map view. +/// @param creationParameters Parameters for initialising the map view. /// @param registrar The plugin registrar passed from Flutter. - (instancetype)initWithMapView:(GMSMapView *)mapView viewIdentifier:(int64_t)viewId - arguments:(id _Nullable)args + creationParameters:(FGMPlatformMapViewCreationParams *)creationParameters registrar:(NSObject *)registrar; @end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapMarkerController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapMarkerController.h index 95b834c5f71..3b090a3ed02 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapMarkerController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapMarkerController.h @@ -29,7 +29,6 @@ NS_ASSUME_NONNULL_BEGIN callbackHandler:(FGMMapsCallbackApi *)callbackHandler clusterManagersController:(nullable FGMClusterManagersController *)clusterManagersController registrar:(NSObject *)registrar; -- (void)addJSONMarkers:(NSArray *> *)markersToAdd; - (void)addMarkers:(NSArray *)markersToAdd; - (void)changeMarkers:(NSArray *)markersToChange; - (void)removeMarkersWithIdentifiers:(NSArray *)identifiers; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapMarkerController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapMarkerController.m index f4e14942735..648ac9f3733 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapMarkerController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapMarkerController.m @@ -472,12 +472,6 @@ - (instancetype)initWithMapView:(GMSMapView *)mapView return self; } -- (void)addJSONMarkers:(NSArray *> *)markersToAdd { - for (NSDictionary *marker in markersToAdd) { - [self addJSONMarker:marker]; - } -} - - (void)addMarkers:(NSArray *)markersToAdd { for (FGMPlatformMarker *marker in markersToAdd) { [self addJSONMarker:marker.json]; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolygonController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolygonController.h index 4d1b0fd5f00..afc8024d2b5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolygonController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolygonController.h @@ -19,7 +19,6 @@ - (instancetype)initWithMapView:(GMSMapView *)mapView callbackHandler:(FGMMapsCallbackApi *)callbackHandler registrar:(NSObject *)registrar; -- (void)addJSONPolygons:(NSArray *> *)polygonsToAdd; - (void)addPolygons:(NSArray *)polygonsToAdd; - (void)changePolygons:(NSArray *)polygonsToChange; - (void)removePolygonWithIdentifiers:(NSArray *)identifiers; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolygonController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolygonController.m index 19380aad6d0..a66b7f5d39d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolygonController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolygonController.m @@ -140,19 +140,6 @@ - (instancetype)initWithMapView:(GMSMapView *)mapView return self; } -- (void)addJSONPolygons:(NSArray *> *)polygonsToAdd { - for (NSDictionary *polygon in polygonsToAdd) { - GMSMutablePath *path = [FLTPolygonsController getPath:polygon]; - NSString *identifier = polygon[@"polygonId"]; - FLTGoogleMapPolygonController *controller = - [[FLTGoogleMapPolygonController alloc] initWithPath:path - identifier:identifier - mapView:self.mapView]; - [controller interpretPolygonOptions:polygon registrar:self.registrar]; - self.polygonIdentifierToController[identifier] = controller; - } -} - - (void)addPolygons:(NSArray *)polygonsToAdd { for (FGMPlatformPolygon *polygon in polygonsToAdd) { GMSMutablePath *path = [FLTPolygonsController getPath:polygon.json]; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolylineController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolylineController.h index 8557be961e4..da86f41b819 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolylineController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolylineController.h @@ -25,7 +25,6 @@ - (instancetype)initWithMapView:(GMSMapView *)mapView callbackHandler:(FGMMapsCallbackApi *)callbackHandler registrar:(NSObject *)registrar; -- (void)addJSONPolylines:(NSArray *> *)polylinesToAdd; - (void)addPolylines:(NSArray *)polylinesToAdd; - (void)changePolylines:(NSArray *)polylinesToChange; - (void)removePolylineWithIdentifiers:(NSArray *)identifiers; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolylineController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolylineController.m index 51cec3baae1..44a31b18b53 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolylineController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapPolylineController.m @@ -136,19 +136,6 @@ - (instancetype)initWithMapView:(GMSMapView *)mapView return self; } -- (void)addJSONPolylines:(NSArray *> *)polylinesToAdd { - for (NSDictionary *polyline in polylinesToAdd) { - GMSMutablePath *path = [FLTPolylinesController pathForPolyline:polyline]; - NSString *identifier = polyline[@"polylineId"]; - FLTGoogleMapPolylineController *controller = - [[FLTGoogleMapPolylineController alloc] initWithPath:path - identifier:identifier - mapView:self.mapView]; - [controller interpretPolylineOptions:polyline registrar:self.registrar]; - self.polylineIdentifierToController[identifier] = controller; - } -} - - (void)addPolylines:(NSArray *)polylinesToAdd { for (FGMPlatformPolyline *polyline in polylinesToAdd) { GMSMutablePath *path = [FLTPolylinesController pathForPolyline:polyline.json]; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.h index 070c24e90e5..5f983e2650e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.h @@ -13,19 +13,37 @@ NS_ASSUME_NONNULL_BEGIN +/// Pigeon equivalent of MapType +typedef NS_ENUM(NSUInteger, FGMPlatformMapType) { + FGMPlatformMapTypeNone = 0, + FGMPlatformMapTypeNormal = 1, + FGMPlatformMapTypeSatellite = 2, + FGMPlatformMapTypeTerrain = 3, + FGMPlatformMapTypeHybrid = 4, +}; + +/// Wrapper for FGMPlatformMapType to allow for nullability. +@interface FGMPlatformMapTypeBox : NSObject +@property(nonatomic, assign) FGMPlatformMapType value; +- (instancetype)initWithValue:(FGMPlatformMapType)value; +@end + @class FGMPlatformCameraPosition; @class FGMPlatformCameraUpdate; @class FGMPlatformCircle; @class FGMPlatformHeatmap; +@class FGMPlatformCluster; @class FGMPlatformClusterManager; @class FGMPlatformMarker; @class FGMPlatformPolygon; @class FGMPlatformPolyline; @class FGMPlatformTile; @class FGMPlatformTileOverlay; +@class FGMPlatformEdgeInsets; @class FGMPlatformLatLng; @class FGMPlatformLatLngBounds; -@class FGMPlatformCluster; +@class FGMPlatformCameraTargetBounds; +@class FGMPlatformMapViewCreationParams; @class FGMPlatformMapConfiguration; @class FGMPlatformPoint; @class FGMPlatformTileLayer; @@ -78,6 +96,20 @@ NS_ASSUME_NONNULL_BEGIN @property(nonatomic, strong) id json; @end +/// Pigeon equivalent of Cluster. +@interface FGMPlatformCluster : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithClusterManagerId:(NSString *)clusterManagerId + position:(FGMPlatformLatLng *)position + bounds:(FGMPlatformLatLngBounds *)bounds + markerIds:(NSArray *)markerIds; +@property(nonatomic, copy) NSString *clusterManagerId; +@property(nonatomic, strong) FGMPlatformLatLng *position; +@property(nonatomic, strong) FGMPlatformLatLngBounds *bounds; +@property(nonatomic, copy) NSArray *markerIds; +@end + /// Pigeon equivalent of the ClusterManager class. @interface FGMPlatformClusterManager : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. @@ -142,6 +174,17 @@ NS_ASSUME_NONNULL_BEGIN @property(nonatomic, strong) id json; @end +/// Pigeon equivalent of Flutter's EdgeInsets. +@interface FGMPlatformEdgeInsets : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithTop:(double)top bottom:(double)bottom left:(double)left right:(double)right; +@property(nonatomic, assign) double top; +@property(nonatomic, assign) double bottom; +@property(nonatomic, assign) double left; +@property(nonatomic, assign) double right; +@end + /// Pigeon equivalent of LatLng. @interface FGMPlatformLatLng : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. @@ -161,29 +204,76 @@ NS_ASSUME_NONNULL_BEGIN @property(nonatomic, strong) FGMPlatformLatLng *southwest; @end -/// Pigeon equivalent of Cluster. -@interface FGMPlatformCluster : NSObject +/// Pigeon equivalent of CameraTargetBounds. +/// +/// As with the Dart version, it exists to distinguish between not setting a +/// a target, and having an explicitly unbounded target (null [bounds]). +@interface FGMPlatformCameraTargetBounds : NSObject ++ (instancetype)makeWithBounds:(nullable FGMPlatformLatLngBounds *)bounds; +@property(nonatomic, strong, nullable) FGMPlatformLatLngBounds *bounds; +@end + +/// Information passed to the platform view creation. +@interface FGMPlatformMapViewCreationParams : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)makeWithClusterManagerId:(NSString *)clusterManagerId - position:(FGMPlatformLatLng *)position - bounds:(FGMPlatformLatLngBounds *)bounds - markerIds:(NSArray *)markerIds; -@property(nonatomic, copy) NSString *clusterManagerId; -@property(nonatomic, strong) FGMPlatformLatLng *position; -@property(nonatomic, strong) FGMPlatformLatLngBounds *bounds; -@property(nonatomic, copy) NSArray *markerIds; ++ (instancetype) + makeWithInitialCameraPosition:(FGMPlatformCameraPosition *)initialCameraPosition + mapConfiguration:(FGMPlatformMapConfiguration *)mapConfiguration + initialCircles:(NSArray *)initialCircles + initialMarkers:(NSArray *)initialMarkers + initialPolygons:(NSArray *)initialPolygons + initialPolylines:(NSArray *)initialPolylines + initialHeatmaps:(NSArray *)initialHeatmaps + initialTileOverlays:(NSArray *)initialTileOverlays + initialClusterManagers:(NSArray *)initialClusterManagers; +@property(nonatomic, strong) FGMPlatformCameraPosition *initialCameraPosition; +@property(nonatomic, strong) FGMPlatformMapConfiguration *mapConfiguration; +@property(nonatomic, copy) NSArray *initialCircles; +@property(nonatomic, copy) NSArray *initialMarkers; +@property(nonatomic, copy) NSArray *initialPolygons; +@property(nonatomic, copy) NSArray *initialPolylines; +@property(nonatomic, copy) NSArray *initialHeatmaps; +@property(nonatomic, copy) NSArray *initialTileOverlays; +@property(nonatomic, copy) NSArray *initialClusterManagers; @end /// Pigeon equivalent of MapConfiguration. @interface FGMPlatformMapConfiguration : NSObject -/// `init` unavailable to enforce nonnull fields, see the `make` class method. -- (instancetype)init NS_UNAVAILABLE; -+ (instancetype)makeWithJson:(id)json; -/// The configuration options, as JSON. This should only be set from -/// _jsonForMapConfiguration, and the native code must interpret it according -/// to the internal implementation details of that method. -@property(nonatomic, strong) id json; ++ (instancetype)makeWithCompassEnabled:(nullable NSNumber *)compassEnabled + cameraTargetBounds:(nullable FGMPlatformCameraTargetBounds *)cameraTargetBounds + mapType:(nullable FGMPlatformMapTypeBox *)mapType + minMaxZoomPreference:(nullable FGMPlatformZoomRange *)minMaxZoomPreference + rotateGesturesEnabled:(nullable NSNumber *)rotateGesturesEnabled + scrollGesturesEnabled:(nullable NSNumber *)scrollGesturesEnabled + tiltGesturesEnabled:(nullable NSNumber *)tiltGesturesEnabled + trackCameraPosition:(nullable NSNumber *)trackCameraPosition + zoomGesturesEnabled:(nullable NSNumber *)zoomGesturesEnabled + myLocationEnabled:(nullable NSNumber *)myLocationEnabled + myLocationButtonEnabled:(nullable NSNumber *)myLocationButtonEnabled + padding:(nullable FGMPlatformEdgeInsets *)padding + indoorViewEnabled:(nullable NSNumber *)indoorViewEnabled + trafficEnabled:(nullable NSNumber *)trafficEnabled + buildingsEnabled:(nullable NSNumber *)buildingsEnabled + cloudMapId:(nullable NSString *)cloudMapId + style:(nullable NSString *)style; +@property(nonatomic, strong, nullable) NSNumber *compassEnabled; +@property(nonatomic, strong, nullable) FGMPlatformCameraTargetBounds *cameraTargetBounds; +@property(nonatomic, strong, nullable) FGMPlatformMapTypeBox *mapType; +@property(nonatomic, strong, nullable) FGMPlatformZoomRange *minMaxZoomPreference; +@property(nonatomic, strong, nullable) NSNumber *rotateGesturesEnabled; +@property(nonatomic, strong, nullable) NSNumber *scrollGesturesEnabled; +@property(nonatomic, strong, nullable) NSNumber *tiltGesturesEnabled; +@property(nonatomic, strong, nullable) NSNumber *trackCameraPosition; +@property(nonatomic, strong, nullable) NSNumber *zoomGesturesEnabled; +@property(nonatomic, strong, nullable) NSNumber *myLocationEnabled; +@property(nonatomic, strong, nullable) NSNumber *myLocationButtonEnabled; +@property(nonatomic, strong, nullable) FGMPlatformEdgeInsets *padding; +@property(nonatomic, strong, nullable) NSNumber *indoorViewEnabled; +@property(nonatomic, strong, nullable) NSNumber *trafficEnabled; +@property(nonatomic, strong, nullable) NSNumber *buildingsEnabled; +@property(nonatomic, copy, nullable) NSString *cloudMapId; +@property(nonatomic, copy, nullable) NSString *style; @end /// Pigeon representation of an x,y coordinate. @@ -211,11 +301,9 @@ NS_ASSUME_NONNULL_BEGIN /// Pigeon equivalent of MinMaxZoomPreference. @interface FGMPlatformZoomRange : NSObject -/// `init` unavailable to enforce nonnull fields, see the `make` class method. -- (instancetype)init NS_UNAVAILABLE; -+ (instancetype)makeWithMin:(double)min max:(double)max; -@property(nonatomic, assign) double min; -@property(nonatomic, assign) double max; ++ (instancetype)makeWithMin:(nullable NSNumber *)min max:(nullable NSNumber *)max; +@property(nonatomic, strong, nullable) NSNumber *min; +@property(nonatomic, strong, nullable) NSNumber *max; @end /// The codec used by all APIs. @@ -388,6 +476,21 @@ extern void SetUpFGMMapsApiWithSuffix(id binaryMessenger FlutterError *_Nullable))completion; @end +/// Dummy interface to force generation of the platform view creation params, +/// which are not used in any Pigeon calls, only the platform view creation +/// call made internally by Flutter. +@protocol FGMMapsPlatformViewApi +- (void)createViewType:(nullable FGMPlatformMapViewCreationParams *)type + error:(FlutterError *_Nullable *_Nonnull)error; +@end + +extern void SetUpFGMMapsPlatformViewApi(id binaryMessenger, + NSObject *_Nullable api); + +extern void SetUpFGMMapsPlatformViewApiWithSuffix(id binaryMessenger, + NSObject *_Nullable api, + NSString *messageChannelSuffix); + /// Inspector API only intended for use in integration tests. @protocol FGMMapsInspectorApi /// @return `nil` only when `error != nil`. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.m index 27c32b8b4ca..dd99108301a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.m @@ -39,6 +39,17 @@ static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) { return (result == [NSNull null]) ? nil : result; } +/// Pigeon equivalent of MapType +@implementation FGMPlatformMapTypeBox +- (instancetype)initWithValue:(FGMPlatformMapType)value { + self = [super init]; + if (self) { + _value = value; + } + return self; +} +@end + @interface FGMPlatformCameraPosition () + (FGMPlatformCameraPosition *)fromList:(NSArray *)list; + (nullable FGMPlatformCameraPosition *)nullableFromList:(NSArray *)list; @@ -63,6 +74,12 @@ + (nullable FGMPlatformHeatmap *)nullableFromList:(NSArray *)list; - (NSArray *)toList; @end +@interface FGMPlatformCluster () ++ (FGMPlatformCluster *)fromList:(NSArray *)list; ++ (nullable FGMPlatformCluster *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + @interface FGMPlatformClusterManager () + (FGMPlatformClusterManager *)fromList:(NSArray *)list; + (nullable FGMPlatformClusterManager *)nullableFromList:(NSArray *)list; @@ -99,6 +116,12 @@ + (nullable FGMPlatformTileOverlay *)nullableFromList:(NSArray *)list; - (NSArray *)toList; @end +@interface FGMPlatformEdgeInsets () ++ (FGMPlatformEdgeInsets *)fromList:(NSArray *)list; ++ (nullable FGMPlatformEdgeInsets *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + @interface FGMPlatformLatLng () + (FGMPlatformLatLng *)fromList:(NSArray *)list; + (nullable FGMPlatformLatLng *)nullableFromList:(NSArray *)list; @@ -111,9 +134,15 @@ + (nullable FGMPlatformLatLngBounds *)nullableFromList:(NSArray *)list; - (NSArray *)toList; @end -@interface FGMPlatformCluster () -+ (FGMPlatformCluster *)fromList:(NSArray *)list; -+ (nullable FGMPlatformCluster *)nullableFromList:(NSArray *)list; +@interface FGMPlatformCameraTargetBounds () ++ (FGMPlatformCameraTargetBounds *)fromList:(NSArray *)list; ++ (nullable FGMPlatformCameraTargetBounds *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformMapViewCreationParams () ++ (FGMPlatformMapViewCreationParams *)fromList:(NSArray *)list; ++ (nullable FGMPlatformMapViewCreationParams *)nullableFromList:(NSArray *)list; - (NSArray *)toList; @end @@ -237,6 +266,39 @@ + (nullable FGMPlatformHeatmap *)nullableFromList:(NSArray *)list { } @end +@implementation FGMPlatformCluster ++ (instancetype)makeWithClusterManagerId:(NSString *)clusterManagerId + position:(FGMPlatformLatLng *)position + bounds:(FGMPlatformLatLngBounds *)bounds + markerIds:(NSArray *)markerIds { + FGMPlatformCluster *pigeonResult = [[FGMPlatformCluster alloc] init]; + pigeonResult.clusterManagerId = clusterManagerId; + pigeonResult.position = position; + pigeonResult.bounds = bounds; + pigeonResult.markerIds = markerIds; + return pigeonResult; +} ++ (FGMPlatformCluster *)fromList:(NSArray *)list { + FGMPlatformCluster *pigeonResult = [[FGMPlatformCluster alloc] init]; + pigeonResult.clusterManagerId = GetNullableObjectAtIndex(list, 0); + pigeonResult.position = GetNullableObjectAtIndex(list, 1); + pigeonResult.bounds = GetNullableObjectAtIndex(list, 2); + pigeonResult.markerIds = GetNullableObjectAtIndex(list, 3); + return pigeonResult; +} ++ (nullable FGMPlatformCluster *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformCluster fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + self.clusterManagerId ?: [NSNull null], + self.position ?: [NSNull null], + self.bounds ?: [NSNull null], + self.markerIds ?: [NSNull null], + ]; +} +@end + @implementation FGMPlatformClusterManager + (instancetype)makeWithIdentifier:(NSString *)identifier { FGMPlatformClusterManager *pigeonResult = [[FGMPlatformClusterManager alloc] init]; @@ -371,6 +433,39 @@ + (nullable FGMPlatformTileOverlay *)nullableFromList:(NSArray *)list { } @end +@implementation FGMPlatformEdgeInsets ++ (instancetype)makeWithTop:(double)top + bottom:(double)bottom + left:(double)left + right:(double)right { + FGMPlatformEdgeInsets *pigeonResult = [[FGMPlatformEdgeInsets alloc] init]; + pigeonResult.top = top; + pigeonResult.bottom = bottom; + pigeonResult.left = left; + pigeonResult.right = right; + return pigeonResult; +} ++ (FGMPlatformEdgeInsets *)fromList:(NSArray *)list { + FGMPlatformEdgeInsets *pigeonResult = [[FGMPlatformEdgeInsets alloc] init]; + pigeonResult.top = [GetNullableObjectAtIndex(list, 0) doubleValue]; + pigeonResult.bottom = [GetNullableObjectAtIndex(list, 1) doubleValue]; + pigeonResult.left = [GetNullableObjectAtIndex(list, 2) doubleValue]; + pigeonResult.right = [GetNullableObjectAtIndex(list, 3) doubleValue]; + return pigeonResult; +} ++ (nullable FGMPlatformEdgeInsets *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformEdgeInsets fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + @(self.top), + @(self.bottom), + @(self.left), + @(self.right), + ]; +} +@end + @implementation FGMPlatformLatLng + (instancetype)makeWithLatitude:(double)latitude longitude:(double)longitude { FGMPlatformLatLng *pigeonResult = [[FGMPlatformLatLng alloc] init]; @@ -420,48 +515,138 @@ + (nullable FGMPlatformLatLngBounds *)nullableFromList:(NSArray *)list { } @end -@implementation FGMPlatformCluster -+ (instancetype)makeWithClusterManagerId:(NSString *)clusterManagerId - position:(FGMPlatformLatLng *)position - bounds:(FGMPlatformLatLngBounds *)bounds - markerIds:(NSArray *)markerIds { - FGMPlatformCluster *pigeonResult = [[FGMPlatformCluster alloc] init]; - pigeonResult.clusterManagerId = clusterManagerId; - pigeonResult.position = position; +@implementation FGMPlatformCameraTargetBounds ++ (instancetype)makeWithBounds:(nullable FGMPlatformLatLngBounds *)bounds { + FGMPlatformCameraTargetBounds *pigeonResult = [[FGMPlatformCameraTargetBounds alloc] init]; pigeonResult.bounds = bounds; - pigeonResult.markerIds = markerIds; return pigeonResult; } -+ (FGMPlatformCluster *)fromList:(NSArray *)list { - FGMPlatformCluster *pigeonResult = [[FGMPlatformCluster alloc] init]; - pigeonResult.clusterManagerId = GetNullableObjectAtIndex(list, 0); - pigeonResult.position = GetNullableObjectAtIndex(list, 1); - pigeonResult.bounds = GetNullableObjectAtIndex(list, 2); - pigeonResult.markerIds = GetNullableObjectAtIndex(list, 3); ++ (FGMPlatformCameraTargetBounds *)fromList:(NSArray *)list { + FGMPlatformCameraTargetBounds *pigeonResult = [[FGMPlatformCameraTargetBounds alloc] init]; + pigeonResult.bounds = GetNullableObjectAtIndex(list, 0); return pigeonResult; } -+ (nullable FGMPlatformCluster *)nullableFromList:(NSArray *)list { - return (list) ? [FGMPlatformCluster fromList:list] : nil; ++ (nullable FGMPlatformCameraTargetBounds *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformCameraTargetBounds fromList:list] : nil; } - (NSArray *)toList { return @[ - self.clusterManagerId ?: [NSNull null], - self.position ?: [NSNull null], self.bounds ?: [NSNull null], - self.markerIds ?: [NSNull null], + ]; +} +@end + +@implementation FGMPlatformMapViewCreationParams ++ (instancetype) + makeWithInitialCameraPosition:(FGMPlatformCameraPosition *)initialCameraPosition + mapConfiguration:(FGMPlatformMapConfiguration *)mapConfiguration + initialCircles:(NSArray *)initialCircles + initialMarkers:(NSArray *)initialMarkers + initialPolygons:(NSArray *)initialPolygons + initialPolylines:(NSArray *)initialPolylines + initialHeatmaps:(NSArray *)initialHeatmaps + initialTileOverlays:(NSArray *)initialTileOverlays + initialClusterManagers:(NSArray *)initialClusterManagers { + FGMPlatformMapViewCreationParams *pigeonResult = [[FGMPlatformMapViewCreationParams alloc] init]; + pigeonResult.initialCameraPosition = initialCameraPosition; + pigeonResult.mapConfiguration = mapConfiguration; + pigeonResult.initialCircles = initialCircles; + pigeonResult.initialMarkers = initialMarkers; + pigeonResult.initialPolygons = initialPolygons; + pigeonResult.initialPolylines = initialPolylines; + pigeonResult.initialHeatmaps = initialHeatmaps; + pigeonResult.initialTileOverlays = initialTileOverlays; + pigeonResult.initialClusterManagers = initialClusterManagers; + return pigeonResult; +} ++ (FGMPlatformMapViewCreationParams *)fromList:(NSArray *)list { + FGMPlatformMapViewCreationParams *pigeonResult = [[FGMPlatformMapViewCreationParams alloc] init]; + pigeonResult.initialCameraPosition = GetNullableObjectAtIndex(list, 0); + pigeonResult.mapConfiguration = GetNullableObjectAtIndex(list, 1); + pigeonResult.initialCircles = GetNullableObjectAtIndex(list, 2); + pigeonResult.initialMarkers = GetNullableObjectAtIndex(list, 3); + pigeonResult.initialPolygons = GetNullableObjectAtIndex(list, 4); + pigeonResult.initialPolylines = GetNullableObjectAtIndex(list, 5); + pigeonResult.initialHeatmaps = GetNullableObjectAtIndex(list, 6); + pigeonResult.initialTileOverlays = GetNullableObjectAtIndex(list, 7); + pigeonResult.initialClusterManagers = GetNullableObjectAtIndex(list, 8); + return pigeonResult; +} ++ (nullable FGMPlatformMapViewCreationParams *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformMapViewCreationParams fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + self.initialCameraPosition ?: [NSNull null], + self.mapConfiguration ?: [NSNull null], + self.initialCircles ?: [NSNull null], + self.initialMarkers ?: [NSNull null], + self.initialPolygons ?: [NSNull null], + self.initialPolylines ?: [NSNull null], + self.initialHeatmaps ?: [NSNull null], + self.initialTileOverlays ?: [NSNull null], + self.initialClusterManagers ?: [NSNull null], ]; } @end @implementation FGMPlatformMapConfiguration -+ (instancetype)makeWithJson:(id)json { ++ (instancetype)makeWithCompassEnabled:(nullable NSNumber *)compassEnabled + cameraTargetBounds:(nullable FGMPlatformCameraTargetBounds *)cameraTargetBounds + mapType:(nullable FGMPlatformMapTypeBox *)mapType + minMaxZoomPreference:(nullable FGMPlatformZoomRange *)minMaxZoomPreference + rotateGesturesEnabled:(nullable NSNumber *)rotateGesturesEnabled + scrollGesturesEnabled:(nullable NSNumber *)scrollGesturesEnabled + tiltGesturesEnabled:(nullable NSNumber *)tiltGesturesEnabled + trackCameraPosition:(nullable NSNumber *)trackCameraPosition + zoomGesturesEnabled:(nullable NSNumber *)zoomGesturesEnabled + myLocationEnabled:(nullable NSNumber *)myLocationEnabled + myLocationButtonEnabled:(nullable NSNumber *)myLocationButtonEnabled + padding:(nullable FGMPlatformEdgeInsets *)padding + indoorViewEnabled:(nullable NSNumber *)indoorViewEnabled + trafficEnabled:(nullable NSNumber *)trafficEnabled + buildingsEnabled:(nullable NSNumber *)buildingsEnabled + cloudMapId:(nullable NSString *)cloudMapId + style:(nullable NSString *)style { FGMPlatformMapConfiguration *pigeonResult = [[FGMPlatformMapConfiguration alloc] init]; - pigeonResult.json = json; + pigeonResult.compassEnabled = compassEnabled; + pigeonResult.cameraTargetBounds = cameraTargetBounds; + pigeonResult.mapType = mapType; + pigeonResult.minMaxZoomPreference = minMaxZoomPreference; + pigeonResult.rotateGesturesEnabled = rotateGesturesEnabled; + pigeonResult.scrollGesturesEnabled = scrollGesturesEnabled; + pigeonResult.tiltGesturesEnabled = tiltGesturesEnabled; + pigeonResult.trackCameraPosition = trackCameraPosition; + pigeonResult.zoomGesturesEnabled = zoomGesturesEnabled; + pigeonResult.myLocationEnabled = myLocationEnabled; + pigeonResult.myLocationButtonEnabled = myLocationButtonEnabled; + pigeonResult.padding = padding; + pigeonResult.indoorViewEnabled = indoorViewEnabled; + pigeonResult.trafficEnabled = trafficEnabled; + pigeonResult.buildingsEnabled = buildingsEnabled; + pigeonResult.cloudMapId = cloudMapId; + pigeonResult.style = style; return pigeonResult; } + (FGMPlatformMapConfiguration *)fromList:(NSArray *)list { FGMPlatformMapConfiguration *pigeonResult = [[FGMPlatformMapConfiguration alloc] init]; - pigeonResult.json = GetNullableObjectAtIndex(list, 0); + pigeonResult.compassEnabled = GetNullableObjectAtIndex(list, 0); + pigeonResult.cameraTargetBounds = GetNullableObjectAtIndex(list, 1); + pigeonResult.mapType = GetNullableObjectAtIndex(list, 2); + pigeonResult.minMaxZoomPreference = GetNullableObjectAtIndex(list, 3); + pigeonResult.rotateGesturesEnabled = GetNullableObjectAtIndex(list, 4); + pigeonResult.scrollGesturesEnabled = GetNullableObjectAtIndex(list, 5); + pigeonResult.tiltGesturesEnabled = GetNullableObjectAtIndex(list, 6); + pigeonResult.trackCameraPosition = GetNullableObjectAtIndex(list, 7); + pigeonResult.zoomGesturesEnabled = GetNullableObjectAtIndex(list, 8); + pigeonResult.myLocationEnabled = GetNullableObjectAtIndex(list, 9); + pigeonResult.myLocationButtonEnabled = GetNullableObjectAtIndex(list, 10); + pigeonResult.padding = GetNullableObjectAtIndex(list, 11); + pigeonResult.indoorViewEnabled = GetNullableObjectAtIndex(list, 12); + pigeonResult.trafficEnabled = GetNullableObjectAtIndex(list, 13); + pigeonResult.buildingsEnabled = GetNullableObjectAtIndex(list, 14); + pigeonResult.cloudMapId = GetNullableObjectAtIndex(list, 15); + pigeonResult.style = GetNullableObjectAtIndex(list, 16); return pigeonResult; } + (nullable FGMPlatformMapConfiguration *)nullableFromList:(NSArray *)list { @@ -469,7 +654,23 @@ + (nullable FGMPlatformMapConfiguration *)nullableFromList:(NSArray *)list { } - (NSArray *)toList { return @[ - self.json ?: [NSNull null], + self.compassEnabled ?: [NSNull null], + self.cameraTargetBounds ?: [NSNull null], + self.mapType ?: [NSNull null], + self.minMaxZoomPreference ?: [NSNull null], + self.rotateGesturesEnabled ?: [NSNull null], + self.scrollGesturesEnabled ?: [NSNull null], + self.tiltGesturesEnabled ?: [NSNull null], + self.trackCameraPosition ?: [NSNull null], + self.zoomGesturesEnabled ?: [NSNull null], + self.myLocationEnabled ?: [NSNull null], + self.myLocationButtonEnabled ?: [NSNull null], + self.padding ?: [NSNull null], + self.indoorViewEnabled ?: [NSNull null], + self.trafficEnabled ?: [NSNull null], + self.buildingsEnabled ?: [NSNull null], + self.cloudMapId ?: [NSNull null], + self.style ?: [NSNull null], ]; } @end @@ -532,7 +733,7 @@ + (nullable FGMPlatformTileLayer *)nullableFromList:(NSArray *)list { @end @implementation FGMPlatformZoomRange -+ (instancetype)makeWithMin:(double)min max:(double)max { ++ (instancetype)makeWithMin:(nullable NSNumber *)min max:(nullable NSNumber *)max { FGMPlatformZoomRange *pigeonResult = [[FGMPlatformZoomRange alloc] init]; pigeonResult.min = min; pigeonResult.max = max; @@ -540,8 +741,8 @@ + (instancetype)makeWithMin:(double)min max:(double)max { } + (FGMPlatformZoomRange *)fromList:(NSArray *)list { FGMPlatformZoomRange *pigeonResult = [[FGMPlatformZoomRange alloc] init]; - pigeonResult.min = [GetNullableObjectAtIndex(list, 0) doubleValue]; - pigeonResult.max = [GetNullableObjectAtIndex(list, 1) doubleValue]; + pigeonResult.min = GetNullableObjectAtIndex(list, 0); + pigeonResult.max = GetNullableObjectAtIndex(list, 1); return pigeonResult; } + (nullable FGMPlatformZoomRange *)nullableFromList:(NSArray *)list { @@ -549,8 +750,8 @@ + (nullable FGMPlatformZoomRange *)nullableFromList:(NSArray *)list { } - (NSArray *)toList { return @[ - @(self.min), - @(self.max), + self.min ?: [NSNull null], + self.max ?: [NSNull null], ]; } @end @@ -569,31 +770,43 @@ - (nullable id)readValueOfType:(UInt8)type { case 132: return [FGMPlatformHeatmap fromList:[self readValue]]; case 133: - return [FGMPlatformClusterManager fromList:[self readValue]]; + return [FGMPlatformCluster fromList:[self readValue]]; case 134: - return [FGMPlatformMarker fromList:[self readValue]]; + return [FGMPlatformClusterManager fromList:[self readValue]]; case 135: - return [FGMPlatformPolygon fromList:[self readValue]]; + return [FGMPlatformMarker fromList:[self readValue]]; case 136: - return [FGMPlatformPolyline fromList:[self readValue]]; + return [FGMPlatformPolygon fromList:[self readValue]]; case 137: - return [FGMPlatformTile fromList:[self readValue]]; + return [FGMPlatformPolyline fromList:[self readValue]]; case 138: - return [FGMPlatformTileOverlay fromList:[self readValue]]; + return [FGMPlatformTile fromList:[self readValue]]; case 139: - return [FGMPlatformLatLng fromList:[self readValue]]; + return [FGMPlatformTileOverlay fromList:[self readValue]]; case 140: - return [FGMPlatformLatLngBounds fromList:[self readValue]]; + return [FGMPlatformEdgeInsets fromList:[self readValue]]; case 141: - return [FGMPlatformCluster fromList:[self readValue]]; + return [FGMPlatformLatLng fromList:[self readValue]]; case 142: - return [FGMPlatformMapConfiguration fromList:[self readValue]]; + return [FGMPlatformLatLngBounds fromList:[self readValue]]; case 143: - return [FGMPlatformPoint fromList:[self readValue]]; + return [FGMPlatformCameraTargetBounds fromList:[self readValue]]; case 144: - return [FGMPlatformTileLayer fromList:[self readValue]]; + return [FGMPlatformMapViewCreationParams fromList:[self readValue]]; case 145: + return [FGMPlatformMapConfiguration fromList:[self readValue]]; + case 146: + return [FGMPlatformPoint fromList:[self readValue]]; + case 147: + return [FGMPlatformTileLayer fromList:[self readValue]]; + case 148: return [FGMPlatformZoomRange fromList:[self readValue]]; + case 149: { + NSNumber *enumAsNumber = [self readValue]; + return enumAsNumber == nil + ? nil + : [[FGMPlatformMapTypeBox alloc] initWithValue:[enumAsNumber integerValue]]; + } default: return [super readValueOfType:type]; } @@ -616,45 +829,58 @@ - (void)writeValue:(id)value { } else if ([value isKindOfClass:[FGMPlatformHeatmap class]]) { [self writeByte:132]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FGMPlatformClusterManager class]]) { + } else if ([value isKindOfClass:[FGMPlatformCluster class]]) { [self writeByte:133]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FGMPlatformMarker class]]) { + } else if ([value isKindOfClass:[FGMPlatformClusterManager class]]) { [self writeByte:134]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FGMPlatformPolygon class]]) { + } else if ([value isKindOfClass:[FGMPlatformMarker class]]) { [self writeByte:135]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FGMPlatformPolyline class]]) { + } else if ([value isKindOfClass:[FGMPlatformPolygon class]]) { [self writeByte:136]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FGMPlatformTile class]]) { + } else if ([value isKindOfClass:[FGMPlatformPolyline class]]) { [self writeByte:137]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FGMPlatformTileOverlay class]]) { + } else if ([value isKindOfClass:[FGMPlatformTile class]]) { [self writeByte:138]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FGMPlatformLatLng class]]) { + } else if ([value isKindOfClass:[FGMPlatformTileOverlay class]]) { [self writeByte:139]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FGMPlatformLatLngBounds class]]) { + } else if ([value isKindOfClass:[FGMPlatformEdgeInsets class]]) { [self writeByte:140]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FGMPlatformCluster class]]) { + } else if ([value isKindOfClass:[FGMPlatformLatLng class]]) { [self writeByte:141]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FGMPlatformMapConfiguration class]]) { + } else if ([value isKindOfClass:[FGMPlatformLatLngBounds class]]) { [self writeByte:142]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FGMPlatformPoint class]]) { + } else if ([value isKindOfClass:[FGMPlatformCameraTargetBounds class]]) { [self writeByte:143]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FGMPlatformTileLayer class]]) { + } else if ([value isKindOfClass:[FGMPlatformMapViewCreationParams class]]) { [self writeByte:144]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FGMPlatformZoomRange class]]) { + } else if ([value isKindOfClass:[FGMPlatformMapConfiguration class]]) { [self writeByte:145]; [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformPoint class]]) { + [self writeByte:146]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformTileLayer class]]) { + [self writeByte:147]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformZoomRange class]]) { + [self writeByte:148]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformMapTypeBox class]]) { + FGMPlatformMapTypeBox *box = (FGMPlatformMapTypeBox *)value; + [self writeByte:149]; + [self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])]; } else { [super writeValue:value]; } @@ -1681,6 +1907,42 @@ - (void)tileWithOverlayIdentifier:(NSString *)arg_tileOverlayId } @end +void SetUpFGMMapsPlatformViewApi(id binaryMessenger, + NSObject *api) { + SetUpFGMMapsPlatformViewApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFGMMapsPlatformViewApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsPlatformViewApi.createView", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert( + [api respondsToSelector:@selector(createViewType:error:)], + @"FGMMapsPlatformViewApi api (%@) doesn't respond to @selector(createViewType:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FGMPlatformMapViewCreationParams *arg_type = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + [api createViewType:arg_type error:&error]; + callback(wrapResult(nil, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } +} void SetUpFGMMapsInspectorApi(id binaryMessenger, NSObject *api) { SetUpFGMMapsInspectorApiWithSuffix(binaryMessenger, api, @""); diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_maps_flutter_ios.dart b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_maps_flutter_ios.dart index 937e34d72d2..9af2e061bde 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_maps_flutter_ios.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_maps_flutter_ios.dart @@ -14,7 +14,6 @@ import 'package:stream_transform/stream_transform.dart'; import 'google_map_inspector_ios.dart'; import 'messages.g.dart'; import 'serialization.dart'; -import 'utils/cluster_manager.dart'; // TODO(stuartmorgan): Remove the dependency on platform interface toJson // methods. Channel serialization details should all be package-internal. @@ -211,8 +210,8 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { MapConfiguration configuration, { required int mapId, }) { - return updateMapOptions(_jsonForMapConfiguration(configuration), - mapId: mapId); + return _hostApi(mapId).updateMapConfiguration( + _platformMapConfigurationFromMapConfiguration(configuration)); } @override @@ -220,8 +219,8 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { Map optionsUpdate, { required int mapId, }) { - return _hostApi(mapId) - .updateMapConfiguration(PlatformMapConfiguration(json: optionsUpdate)); + return _hostApi(mapId).updateMapConfiguration( + _platformMapConfigurationFromOptionsJson(optionsUpdate)); } @override @@ -445,30 +444,39 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { Widget _buildView( int creationId, PlatformViewCreatedCallback onPlatformViewCreated, { + required PlatformMapConfiguration mapConfiguration, required MapWidgetConfiguration widgetConfiguration, MapObjects mapObjects = const MapObjects(), - Map mapOptions = const {}, }) { - final Map creationParams = { - 'initialCameraPosition': - widgetConfiguration.initialCameraPosition.toMap(), - 'options': mapOptions, - 'markersToAdd': serializeMarkerSet(mapObjects.markers), - 'polygonsToAdd': serializePolygonSet(mapObjects.polygons), - 'polylinesToAdd': serializePolylineSet(mapObjects.polylines), - 'circlesToAdd': serializeCircleSet(mapObjects.circles), - 'heatmapsToAdd': mapObjects.heatmaps.map(serializeHeatmap).toList(), - 'tileOverlaysToAdd': serializeTileOverlaySet(mapObjects.tileOverlays), - 'clusterManagersToAdd': - serializeClusterManagerSet(mapObjects.clusterManagers), - }; + final PlatformMapViewCreationParams creationParams = + PlatformMapViewCreationParams( + initialCameraPosition: _platformCameraPositionFromCameraPosition( + widgetConfiguration.initialCameraPosition), + mapConfiguration: mapConfiguration, + initialMarkers: + mapObjects.markers.map(_platformMarkerFromMarker).toList(), + initialPolygons: + mapObjects.polygons.map(_platformPolygonFromPolygon).toList(), + initialPolylines: + mapObjects.polylines.map(_platformPolylineFromPolyline).toList(), + initialCircles: + mapObjects.circles.map(_platformCircleFromCircle).toList(), + initialHeatmaps: + mapObjects.heatmaps.map(_platformHeatmapFromHeatmap).toList(), + initialTileOverlays: mapObjects.tileOverlays + .map(_platformTileOverlayFromTileOverlay) + .toList(), + initialClusterManagers: mapObjects.clusterManagers + .map(_platformClusterManagerFromClusterManager) + .toList(), + ); return UiKitView( viewType: 'plugins.flutter.dev/google_maps_ios', onPlatformViewCreated: onPlatformViewCreated, gestureRecognizers: widgetConfiguration.gestureRecognizers, creationParams: creationParams, - creationParamsCodec: const StandardMessageCodec(), + creationParamsCodec: MapsApi.pigeonChannelCodec, ); } @@ -485,7 +493,8 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { onPlatformViewCreated, widgetConfiguration: widgetConfiguration, mapObjects: mapObjects, - mapOptions: _jsonForMapConfiguration(mapConfiguration), + mapConfiguration: + _platformMapConfigurationFromMapConfiguration(mapConfiguration), ); } @@ -515,7 +524,7 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { polylines: polylines, circles: circles, tileOverlays: tileOverlays), - mapOptions: mapOptions, + mapConfiguration: _platformMapConfigurationFromOptionsJson(mapOptions), ); } @@ -566,11 +575,6 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { bounds: _latLngBoundsFromPlatformLatLngBounds(cluster.bounds)); } - static PlatformLatLng _platformLatLngFromLatLng(LatLng latLng) { - return PlatformLatLng( - latitude: latLng.latitude, longitude: latLng.longitude); - } - static ScreenCoordinate _screenCoordinateFromPlatformPoint( PlatformPoint point) { return ScreenCoordinate(x: point.x.round(), y: point.y.round()); @@ -587,7 +591,7 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { } static PlatformHeatmap _platformHeatmapFromHeatmap(Heatmap heatmap) { - return PlatformHeatmap(json: heatmap.toJson()); + return PlatformHeatmap(json: serializeHeatmap(heatmap)); } static PlatformMarker _platformMarkerFromMarker(Marker marker) { @@ -756,56 +760,198 @@ LatLngBounds _latLngBoundsFromPlatformLatLngBounds( northeast: _latLngFromPlatformLatLng(bounds.northeast)); } +PlatformLatLng _platformLatLngFromLatLng(LatLng latLng) { + return PlatformLatLng(latitude: latLng.latitude, longitude: latLng.longitude); +} + +PlatformLatLngBounds? _platformLatLngBoundsFromLatLngBounds( + LatLngBounds? bounds) { + if (bounds == null) { + return null; + } + return PlatformLatLngBounds( + northeast: _platformLatLngFromLatLng(bounds.northeast), + southwest: _platformLatLngFromLatLng(bounds.southwest)); +} + +PlatformCameraTargetBounds? _platformCameraTargetBoundsFromCameraTargetBounds( + CameraTargetBounds? bounds) { + return bounds == null + ? null + : PlatformCameraTargetBounds( + bounds: _platformLatLngBoundsFromLatLngBounds(bounds.bounds)); +} + PlatformTile _platformTileFromTile(Tile tile) { return PlatformTile(width: tile.width, height: tile.height, data: tile.data); } -Map _jsonForMapConfiguration(MapConfiguration config) { - final EdgeInsets? padding = config.padding; - return { - if (config.compassEnabled != null) 'compassEnabled': config.compassEnabled!, - if (config.mapToolbarEnabled != null) - 'mapToolbarEnabled': config.mapToolbarEnabled!, - if (config.cameraTargetBounds != null) - 'cameraTargetBounds': config.cameraTargetBounds!.toJson(), - if (config.mapType != null) 'mapType': config.mapType!.index, - if (config.minMaxZoomPreference != null) - 'minMaxZoomPreference': config.minMaxZoomPreference!.toJson(), - if (config.rotateGesturesEnabled != null) - 'rotateGesturesEnabled': config.rotateGesturesEnabled!, - if (config.scrollGesturesEnabled != null) - 'scrollGesturesEnabled': config.scrollGesturesEnabled!, - if (config.tiltGesturesEnabled != null) - 'tiltGesturesEnabled': config.tiltGesturesEnabled!, - if (config.zoomControlsEnabled != null) - 'zoomControlsEnabled': config.zoomControlsEnabled!, - if (config.zoomGesturesEnabled != null) - 'zoomGesturesEnabled': config.zoomGesturesEnabled!, - if (config.liteModeEnabled != null) - 'liteModeEnabled': config.liteModeEnabled!, - if (config.trackCameraPosition != null) - 'trackCameraPosition': config.trackCameraPosition!, - if (config.myLocationEnabled != null) - 'myLocationEnabled': config.myLocationEnabled!, - if (config.myLocationButtonEnabled != null) - 'myLocationButtonEnabled': config.myLocationButtonEnabled!, - if (padding != null) - 'padding': [ - padding.top, - padding.left, - padding.bottom, - padding.right, - ], - if (config.indoorViewEnabled != null) - 'indoorEnabled': config.indoorViewEnabled!, - if (config.trafficEnabled != null) 'trafficEnabled': config.trafficEnabled!, - if (config.buildingsEnabled != null) - 'buildingsEnabled': config.buildingsEnabled!, - if (config.cloudMapId != null) 'cloudMapId': config.cloudMapId!, - if (config.style != null) 'style': config.style!, +PlatformMapType? _platformMapTypeFromMapType(MapType? type) { + switch (type) { + case null: + return null; + case MapType.none: + return PlatformMapType.none; + case MapType.normal: + return PlatformMapType.normal; + case MapType.satellite: + return PlatformMapType.satellite; + case MapType.terrain: + return PlatformMapType.terrain; + case MapType.hybrid: + return PlatformMapType.hybrid; + } + // The enum comes from a different package, which could get a new value at + // any time, so provide a fallback that ensures this won't break when used + // with a version that contains new values. This is deliberately outside + // the switch rather than a `default` so that the linter will flag the + // switch as needing an update. + // ignore: dead_code + return PlatformMapType.normal; +} + +PlatformZoomRange? _platformZoomRangeFromMinMaxZoomPreference( + MinMaxZoomPreference? zoomPref) { + return zoomPref == null + ? null + : PlatformZoomRange(min: zoomPref.minZoom, max: zoomPref.maxZoom); +} + +PlatformEdgeInsets? _platformEdgeInsetsFromEdgeInsets(EdgeInsets? insets) { + return insets == null + ? null + : PlatformEdgeInsets( + top: insets.top, + bottom: insets.bottom, + left: insets.left, + right: insets.right); +} + +PlatformMapConfiguration _platformMapConfigurationFromMapConfiguration( + MapConfiguration config) { + return PlatformMapConfiguration( + compassEnabled: config.compassEnabled, + cameraTargetBounds: _platformCameraTargetBoundsFromCameraTargetBounds( + config.cameraTargetBounds), + mapType: _platformMapTypeFromMapType(config.mapType), + minMaxZoomPreference: + _platformZoomRangeFromMinMaxZoomPreference(config.minMaxZoomPreference), + rotateGesturesEnabled: config.rotateGesturesEnabled, + scrollGesturesEnabled: config.scrollGesturesEnabled, + tiltGesturesEnabled: config.tiltGesturesEnabled, + trackCameraPosition: config.trackCameraPosition, + zoomGesturesEnabled: config.zoomGesturesEnabled, + myLocationEnabled: config.myLocationEnabled, + myLocationButtonEnabled: config.myLocationButtonEnabled, + padding: _platformEdgeInsetsFromEdgeInsets(config.padding), + indoorViewEnabled: config.indoorViewEnabled, + trafficEnabled: config.trafficEnabled, + buildingsEnabled: config.buildingsEnabled, + cloudMapId: config.cloudMapId, + style: config.style, + ); +} + +// For supporting the deprecated updateMapOptions API. +PlatformMapConfiguration _platformMapConfigurationFromOptionsJson( + Map options) { + // All of these hard-coded values and structures come from + // google_maps_flutter_platform_interface/lib/src/types/utils/map_configuration_serialization.dart + // to support this legacy API that relied on cross-package magic strings. + final List? padding = + (options['padding'] as List?)?.cast(); + final int? mapType = options['mapType'] as int?; + return PlatformMapConfiguration( + compassEnabled: options['compassEnabled'] as bool?, + cameraTargetBounds: _platformCameraTargetBoundsFromCameraTargetBoundsJson( + options['cameraTargetBounds']), + mapType: mapType == null ? null : _platformMapTypeFromMapTypeIndex(mapType), + minMaxZoomPreference: _platformZoomRangeFromMinMaxZoomPreferenceJson( + options['minMaxZoomPreference']), + rotateGesturesEnabled: options['rotateGesturesEnabled'] as bool?, + scrollGesturesEnabled: options['scrollGesturesEnabled'] as bool?, + tiltGesturesEnabled: options['tiltGesturesEnabled'] as bool?, + trackCameraPosition: options['trackCameraPosition'] as bool?, + zoomGesturesEnabled: options['zoomGesturesEnabled'] as bool?, + myLocationEnabled: options['myLocationEnabled'] as bool?, + myLocationButtonEnabled: options['myLocationButtonEnabled'] as bool?, + padding: padding == null + ? null + : PlatformEdgeInsets( + top: padding[0], + left: padding[1], + bottom: padding[2], + right: padding[3]), + indoorViewEnabled: options['indoorEnabled'] as bool?, + trafficEnabled: options['trafficEnabled'] as bool?, + buildingsEnabled: options['buildingsEnabled'] as bool?, + cloudMapId: options['cloudMapId'] as String?, + style: options['style'] as String?, + ); +} + +PlatformCameraPosition _platformCameraPositionFromCameraPosition( + CameraPosition position) { + return PlatformCameraPosition( + bearing: position.bearing, + target: _platformLatLngFromLatLng(position.target), + tilt: position.tilt, + zoom: position.zoom); +} + +PlatformMapType _platformMapTypeFromMapTypeIndex(int index) { + // This is inherently fragile, but see comment in updateMapOptions. + return switch (index) { + 0 => PlatformMapType.none, + 1 => PlatformMapType.normal, + 2 => PlatformMapType.satellite, + 3 => PlatformMapType.terrain, + 4 => PlatformMapType.hybrid, + // For a new, unsupported type, just use normal. + _ => PlatformMapType.normal, }; } +PlatformLatLng _platformLatLngFromLatLngJson(Object latLngJson) { + // See `LatLng.toJson`. + final List list = (latLngJson as List).cast(); + return PlatformLatLng(latitude: list[0], longitude: list[1]); +} + +PlatformLatLngBounds? _platformLatLngBoundsFromLatLngBoundsJson( + Object? boundsJson) { + if (boundsJson == null) { + return null; + } + // See `LatLngBounds.toJson`. + final List boundsList = (boundsJson as List).cast(); + return PlatformLatLngBounds( + southwest: _platformLatLngFromLatLngJson(boundsList[0]), + northeast: _platformLatLngFromLatLngJson(boundsList[1])); +} + +PlatformCameraTargetBounds? + _platformCameraTargetBoundsFromCameraTargetBoundsJson(Object? targetJson) { + if (targetJson == null) { + return null; + } + // See `CameraTargetBounds.toJson`. + return PlatformCameraTargetBounds( + bounds: _platformLatLngBoundsFromLatLngBoundsJson( + (targetJson as List)[0])); +} + +PlatformZoomRange? _platformZoomRangeFromMinMaxZoomPreferenceJson( + Object? zoomPrefsJson) { + if (zoomPrefsJson == null) { + return null; + } + // See `MinMaxZoomPreference.toJson`. + final List minMaxZoom = + (zoomPrefsJson as List).cast(); + return PlatformZoomRange(min: minMaxZoom[0], max: minMaxZoom[1]); +} + /// Update specification for a set of [TileOverlay]s. // TODO(stuartmorgan): Fix the missing export of this class in the platform // interface, and remove this copy. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/messages.g.dart b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/messages.g.dart index 3e164bf2d88..8daae542a7d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/messages.g.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/messages.g.dart @@ -29,6 +29,15 @@ List wrapResponse( return [error.code, error.message, error.details]; } +/// Pigeon equivalent of MapType +enum PlatformMapType { + none, + normal, + satellite, + terrain, + hybrid, +} + /// Pigeon representatation of a CameraPosition. class PlatformCameraPosition { PlatformCameraPosition({ @@ -141,6 +150,43 @@ class PlatformHeatmap { } } +/// Pigeon equivalent of Cluster. +class PlatformCluster { + PlatformCluster({ + required this.clusterManagerId, + required this.position, + required this.bounds, + required this.markerIds, + }); + + String clusterManagerId; + + PlatformLatLng position; + + PlatformLatLngBounds bounds; + + List markerIds; + + Object encode() { + return [ + clusterManagerId, + position, + bounds, + markerIds, + ]; + } + + static PlatformCluster decode(Object result) { + result as List; + return PlatformCluster( + clusterManagerId: result[0]! as String, + position: result[1]! as PlatformLatLng, + bounds: result[2]! as PlatformLatLngBounds, + markerIds: (result[3] as List?)!.cast(), + ); + } +} + /// Pigeon equivalent of the ClusterManager class. class PlatformClusterManager { PlatformClusterManager({ @@ -295,6 +341,43 @@ class PlatformTileOverlay { } } +/// Pigeon equivalent of Flutter's EdgeInsets. +class PlatformEdgeInsets { + PlatformEdgeInsets({ + required this.top, + required this.bottom, + required this.left, + required this.right, + }); + + double top; + + double bottom; + + double left; + + double right; + + Object encode() { + return [ + top, + bottom, + left, + right, + ]; + } + + static PlatformEdgeInsets decode(Object result) { + result as List; + return PlatformEdgeInsets( + top: result[0]! as double, + bottom: result[1]! as double, + left: result[2]! as double, + right: result[3]! as double, + ); + } +} + /// Pigeon equivalent of LatLng. class PlatformLatLng { PlatformLatLng({ @@ -349,39 +432,92 @@ class PlatformLatLngBounds { } } -/// Pigeon equivalent of Cluster. -class PlatformCluster { - PlatformCluster({ - required this.clusterManagerId, - required this.position, - required this.bounds, - required this.markerIds, +/// Pigeon equivalent of CameraTargetBounds. +/// +/// As with the Dart version, it exists to distinguish between not setting a +/// a target, and having an explicitly unbounded target (null [bounds]). +class PlatformCameraTargetBounds { + PlatformCameraTargetBounds({ + this.bounds, }); - String clusterManagerId; + PlatformLatLngBounds? bounds; - PlatformLatLng position; + Object encode() { + return [ + bounds, + ]; + } - PlatformLatLngBounds bounds; + static PlatformCameraTargetBounds decode(Object result) { + result as List; + return PlatformCameraTargetBounds( + bounds: result[0] as PlatformLatLngBounds?, + ); + } +} - List markerIds; +/// Information passed to the platform view creation. +class PlatformMapViewCreationParams { + PlatformMapViewCreationParams({ + required this.initialCameraPosition, + required this.mapConfiguration, + required this.initialCircles, + required this.initialMarkers, + required this.initialPolygons, + required this.initialPolylines, + required this.initialHeatmaps, + required this.initialTileOverlays, + required this.initialClusterManagers, + }); + + PlatformCameraPosition initialCameraPosition; + + PlatformMapConfiguration mapConfiguration; + + List initialCircles; + + List initialMarkers; + + List initialPolygons; + + List initialPolylines; + + List initialHeatmaps; + + List initialTileOverlays; + + List initialClusterManagers; Object encode() { return [ - clusterManagerId, - position, - bounds, - markerIds, + initialCameraPosition, + mapConfiguration, + initialCircles, + initialMarkers, + initialPolygons, + initialPolylines, + initialHeatmaps, + initialTileOverlays, + initialClusterManagers, ]; } - static PlatformCluster decode(Object result) { + static PlatformMapViewCreationParams decode(Object result) { result as List; - return PlatformCluster( - clusterManagerId: result[0]! as String, - position: result[1]! as PlatformLatLng, - bounds: result[2]! as PlatformLatLngBounds, - markerIds: (result[3] as List?)!.cast(), + return PlatformMapViewCreationParams( + initialCameraPosition: result[0]! as PlatformCameraPosition, + mapConfiguration: result[1]! as PlatformMapConfiguration, + initialCircles: (result[2] as List?)!.cast(), + initialMarkers: (result[3] as List?)!.cast(), + initialPolygons: (result[4] as List?)!.cast(), + initialPolylines: + (result[5] as List?)!.cast(), + initialHeatmaps: (result[6] as List?)!.cast(), + initialTileOverlays: + (result[7] as List?)!.cast(), + initialClusterManagers: + (result[8] as List?)!.cast(), ); } } @@ -389,24 +525,101 @@ class PlatformCluster { /// Pigeon equivalent of MapConfiguration. class PlatformMapConfiguration { PlatformMapConfiguration({ - required this.json, + this.compassEnabled, + this.cameraTargetBounds, + this.mapType, + this.minMaxZoomPreference, + this.rotateGesturesEnabled, + this.scrollGesturesEnabled, + this.tiltGesturesEnabled, + this.trackCameraPosition, + this.zoomGesturesEnabled, + this.myLocationEnabled, + this.myLocationButtonEnabled, + this.padding, + this.indoorViewEnabled, + this.trafficEnabled, + this.buildingsEnabled, + this.cloudMapId, + this.style, }); - /// The configuration options, as JSON. This should only be set from - /// _jsonForMapConfiguration, and the native code must interpret it according - /// to the internal implementation details of that method. - Object json; + bool? compassEnabled; + + PlatformCameraTargetBounds? cameraTargetBounds; + + PlatformMapType? mapType; + + PlatformZoomRange? minMaxZoomPreference; + + bool? rotateGesturesEnabled; + + bool? scrollGesturesEnabled; + + bool? tiltGesturesEnabled; + + bool? trackCameraPosition; + + bool? zoomGesturesEnabled; + + bool? myLocationEnabled; + + bool? myLocationButtonEnabled; + + PlatformEdgeInsets? padding; + + bool? indoorViewEnabled; + + bool? trafficEnabled; + + bool? buildingsEnabled; + + String? cloudMapId; + + String? style; Object encode() { return [ - json, + compassEnabled, + cameraTargetBounds, + mapType, + minMaxZoomPreference, + rotateGesturesEnabled, + scrollGesturesEnabled, + tiltGesturesEnabled, + trackCameraPosition, + zoomGesturesEnabled, + myLocationEnabled, + myLocationButtonEnabled, + padding, + indoorViewEnabled, + trafficEnabled, + buildingsEnabled, + cloudMapId, + style, ]; } static PlatformMapConfiguration decode(Object result) { result as List; return PlatformMapConfiguration( - json: result[0]!, + compassEnabled: result[0] as bool?, + cameraTargetBounds: result[1] as PlatformCameraTargetBounds?, + mapType: result[2] as PlatformMapType?, + minMaxZoomPreference: result[3] as PlatformZoomRange?, + rotateGesturesEnabled: result[4] as bool?, + scrollGesturesEnabled: result[5] as bool?, + tiltGesturesEnabled: result[6] as bool?, + trackCameraPosition: result[7] as bool?, + zoomGesturesEnabled: result[8] as bool?, + myLocationEnabled: result[9] as bool?, + myLocationButtonEnabled: result[10] as bool?, + padding: result[11] as PlatformEdgeInsets?, + indoorViewEnabled: result[12] as bool?, + trafficEnabled: result[13] as bool?, + buildingsEnabled: result[14] as bool?, + cloudMapId: result[15] as String?, + style: result[16] as String?, ); } } @@ -478,13 +691,13 @@ class PlatformTileLayer { /// Pigeon equivalent of MinMaxZoomPreference. class PlatformZoomRange { PlatformZoomRange({ - required this.min, - required this.max, + this.min, + this.max, }); - double min; + double? min; - double max; + double? max; Object encode() { return [ @@ -496,8 +709,8 @@ class PlatformZoomRange { static PlatformZoomRange decode(Object result) { result as List; return PlatformZoomRange( - min: result[0]! as double, - max: result[1]! as double, + min: result[0] as double?, + max: result[1] as double?, ); } } @@ -518,45 +731,57 @@ class _PigeonCodec extends StandardMessageCodec { } else if (value is PlatformHeatmap) { buffer.putUint8(132); writeValue(buffer, value.encode()); - } else if (value is PlatformClusterManager) { + } else if (value is PlatformCluster) { buffer.putUint8(133); writeValue(buffer, value.encode()); - } else if (value is PlatformMarker) { + } else if (value is PlatformClusterManager) { buffer.putUint8(134); writeValue(buffer, value.encode()); - } else if (value is PlatformPolygon) { + } else if (value is PlatformMarker) { buffer.putUint8(135); writeValue(buffer, value.encode()); - } else if (value is PlatformPolyline) { + } else if (value is PlatformPolygon) { buffer.putUint8(136); writeValue(buffer, value.encode()); - } else if (value is PlatformTile) { + } else if (value is PlatformPolyline) { buffer.putUint8(137); writeValue(buffer, value.encode()); - } else if (value is PlatformTileOverlay) { + } else if (value is PlatformTile) { buffer.putUint8(138); writeValue(buffer, value.encode()); - } else if (value is PlatformLatLng) { + } else if (value is PlatformTileOverlay) { buffer.putUint8(139); writeValue(buffer, value.encode()); - } else if (value is PlatformLatLngBounds) { + } else if (value is PlatformEdgeInsets) { buffer.putUint8(140); writeValue(buffer, value.encode()); - } else if (value is PlatformCluster) { + } else if (value is PlatformLatLng) { buffer.putUint8(141); writeValue(buffer, value.encode()); - } else if (value is PlatformMapConfiguration) { + } else if (value is PlatformLatLngBounds) { buffer.putUint8(142); writeValue(buffer, value.encode()); - } else if (value is PlatformPoint) { + } else if (value is PlatformCameraTargetBounds) { buffer.putUint8(143); writeValue(buffer, value.encode()); - } else if (value is PlatformTileLayer) { + } else if (value is PlatformMapViewCreationParams) { buffer.putUint8(144); writeValue(buffer, value.encode()); - } else if (value is PlatformZoomRange) { + } else if (value is PlatformMapConfiguration) { buffer.putUint8(145); writeValue(buffer, value.encode()); + } else if (value is PlatformPoint) { + buffer.putUint8(146); + writeValue(buffer, value.encode()); + } else if (value is PlatformTileLayer) { + buffer.putUint8(147); + writeValue(buffer, value.encode()); + } else if (value is PlatformZoomRange) { + buffer.putUint8(148); + writeValue(buffer, value.encode()); + } else if (value is PlatformMapType) { + buffer.putUint8(149); + writeValue(buffer, value.index); } else { super.writeValue(buffer, value); } @@ -574,31 +799,40 @@ class _PigeonCodec extends StandardMessageCodec { case 132: return PlatformHeatmap.decode(readValue(buffer)!); case 133: - return PlatformClusterManager.decode(readValue(buffer)!); + return PlatformCluster.decode(readValue(buffer)!); case 134: - return PlatformMarker.decode(readValue(buffer)!); + return PlatformClusterManager.decode(readValue(buffer)!); case 135: - return PlatformPolygon.decode(readValue(buffer)!); + return PlatformMarker.decode(readValue(buffer)!); case 136: - return PlatformPolyline.decode(readValue(buffer)!); + return PlatformPolygon.decode(readValue(buffer)!); case 137: - return PlatformTile.decode(readValue(buffer)!); + return PlatformPolyline.decode(readValue(buffer)!); case 138: - return PlatformTileOverlay.decode(readValue(buffer)!); + return PlatformTile.decode(readValue(buffer)!); case 139: - return PlatformLatLng.decode(readValue(buffer)!); + return PlatformTileOverlay.decode(readValue(buffer)!); case 140: - return PlatformLatLngBounds.decode(readValue(buffer)!); + return PlatformEdgeInsets.decode(readValue(buffer)!); case 141: - return PlatformCluster.decode(readValue(buffer)!); + return PlatformLatLng.decode(readValue(buffer)!); case 142: - return PlatformMapConfiguration.decode(readValue(buffer)!); + return PlatformLatLngBounds.decode(readValue(buffer)!); case 143: - return PlatformPoint.decode(readValue(buffer)!); + return PlatformCameraTargetBounds.decode(readValue(buffer)!); case 144: - return PlatformTileLayer.decode(readValue(buffer)!); + return PlatformMapViewCreationParams.decode(readValue(buffer)!); case 145: + return PlatformMapConfiguration.decode(readValue(buffer)!); + case 146: + return PlatformPoint.decode(readValue(buffer)!); + case 147: + return PlatformTileLayer.decode(readValue(buffer)!); + case 148: return PlatformZoomRange.decode(readValue(buffer)!); + case 149: + final int? value = readValue(buffer) as int?; + return value == null ? null : PlatformMapType.values[value]; default: return super.readValueOfType(type, buffer); } @@ -1704,6 +1938,49 @@ abstract class MapsCallbackApi { } } +/// Dummy interface to force generation of the platform view creation params, +/// which are not used in any Pigeon calls, only the platform view creation +/// call made internally by Flutter. +class MapsPlatformViewApi { + /// Constructor for [MapsPlatformViewApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + MapsPlatformViewApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String __pigeon_messageChannelSuffix; + + Future createView(PlatformMapViewCreationParams? type) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsPlatformViewApi.createView$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([type]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } +} + /// Inspector API only intended for use in integration tests. class MapsInspectorApi { /// Constructor for [MapsInspectorApi]. The [binaryMessenger] named argument is diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/utils/cluster_manager.dart b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/utils/cluster_manager.dart deleted file mode 100644 index d644bfd8c0e..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/utils/cluster_manager.dart +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; - -/// Converts a Set of Cluster Managers into object serializable in JSON. -Object serializeClusterManagerSet(Set clusterManagers) { - return clusterManagers - .map((ClusterManager cm) => serializeClusterManager(cm)) - .toList(); -} - -/// Converts a Cluster Manager into object serializable in JSON. -Object serializeClusterManager(ClusterManager clusterManager) { - final Map json = {}; - json['clusterManagerId'] = clusterManager.clusterManagerId.value; - return json; -} diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/pigeons/messages.dart b/packages/google_maps_flutter/google_maps_flutter_ios/pigeons/messages.dart index e5c11bed645..d2b2a6c8223 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/pigeons/messages.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/pigeons/messages.dart @@ -12,6 +12,15 @@ import 'package:pigeon/pigeon.dart'; copyrightHeader: 'pigeons/copyright.txt', )) +/// Pigeon equivalent of MapType +enum PlatformMapType { + none, + normal, + satellite, + terrain, + hybrid, +} + /// Pigeon representatation of a CameraPosition. class PlatformCameraPosition { PlatformCameraPosition({ @@ -66,6 +75,24 @@ class PlatformHeatmap { final Object json; } +/// Pigeon equivalent of Cluster. +class PlatformCluster { + PlatformCluster({ + required this.clusterManagerId, + required this.position, + required this.bounds, + required this.markerIds, + }); + + final String clusterManagerId; + final PlatformLatLng position; + final PlatformLatLngBounds bounds; + // TODO(stuartmorgan): Make the generic type non-nullable once supported. + // https://github.com/flutter/flutter/issues/97848 + // The consuming code treats the entries as non-nullable. + final List markerIds; +} + /// Pigeon equivalent of the ClusterManager class. class PlatformClusterManager { PlatformClusterManager({required this.identifier}); @@ -130,6 +157,21 @@ class PlatformTileOverlay { final Object json; } +/// Pigeon equivalent of Flutter's EdgeInsets. +class PlatformEdgeInsets { + PlatformEdgeInsets({ + required this.top, + required this.bottom, + required this.left, + required this.right, + }); + + final double top; + final double bottom; + final double left; + final double right; +} + /// Pigeon equivalent of LatLng. class PlatformLatLng { PlatformLatLng({required this.latitude, required this.longitude}); @@ -146,34 +188,83 @@ class PlatformLatLngBounds { final PlatformLatLng southwest; } -/// Pigeon equivalent of Cluster. -class PlatformCluster { - PlatformCluster({ - required this.clusterManagerId, - required this.position, - required this.bounds, - required this.markerIds, +/// Pigeon equivalent of CameraTargetBounds. +/// +/// As with the Dart version, it exists to distinguish between not setting a +/// a target, and having an explicitly unbounded target (null [bounds]). +class PlatformCameraTargetBounds { + PlatformCameraTargetBounds({required this.bounds}); + + final PlatformLatLngBounds? bounds; +} + +/// Information passed to the platform view creation. +class PlatformMapViewCreationParams { + PlatformMapViewCreationParams({ + required this.initialCameraPosition, + required this.mapConfiguration, + required this.initialCircles, + required this.initialMarkers, + required this.initialPolygons, + required this.initialPolylines, + required this.initialHeatmaps, + required this.initialTileOverlays, + required this.initialClusterManagers, }); - final String clusterManagerId; - final PlatformLatLng position; - final PlatformLatLngBounds bounds; - // TODO(stuartmorgan): Make the generic type non-nullable once supported. + final PlatformCameraPosition initialCameraPosition; + final PlatformMapConfiguration mapConfiguration; + // TODO(stuartmorgan): Make the generic types non-nullable once supported. // https://github.com/flutter/flutter/issues/97848 // The consuming code treats the entries as non-nullable. - final List markerIds; + final List initialCircles; + final List initialMarkers; + final List initialPolygons; + final List initialPolylines; + final List initialHeatmaps; + final List initialTileOverlays; + final List initialClusterManagers; } /// Pigeon equivalent of MapConfiguration. class PlatformMapConfiguration { - PlatformMapConfiguration({required this.json}); + PlatformMapConfiguration({ + required this.compassEnabled, + required this.cameraTargetBounds, + required this.mapType, + required this.minMaxZoomPreference, + required this.rotateGesturesEnabled, + required this.scrollGesturesEnabled, + required this.tiltGesturesEnabled, + required this.trackCameraPosition, + required this.zoomGesturesEnabled, + required this.myLocationEnabled, + required this.myLocationButtonEnabled, + required this.padding, + required this.indoorViewEnabled, + required this.trafficEnabled, + required this.buildingsEnabled, + required this.cloudMapId, + required this.style, + }); - /// The configuration options, as JSON. This should only be set from - /// _jsonForMapConfiguration, and the native code must interpret it according - /// to the internal implementation details of that method. - // TODO(stuartmorgan): Replace this with structured data. This exists only to - // allow incremental migration to Pigeon. - final Object json; + final bool? compassEnabled; + final PlatformCameraTargetBounds? cameraTargetBounds; + final PlatformMapType? mapType; + final PlatformZoomRange? minMaxZoomPreference; + final bool? rotateGesturesEnabled; + final bool? scrollGesturesEnabled; + final bool? tiltGesturesEnabled; + final bool? trackCameraPosition; + final bool? zoomGesturesEnabled; + final bool? myLocationEnabled; + final bool? myLocationButtonEnabled; + final PlatformEdgeInsets? padding; + final bool? indoorViewEnabled; + final bool? trafficEnabled; + final bool? buildingsEnabled; + final String? cloudMapId; + final String? style; } /// Pigeon representation of an x,y coordinate. @@ -203,8 +294,8 @@ class PlatformTileLayer { class PlatformZoomRange { PlatformZoomRange({required this.min, required this.max}); - final double min; - final double max; + final double? min; + final double? max; } /// Interface for non-test interactions with the native SDK. @@ -406,6 +497,15 @@ abstract class MapsCallbackApi { String tileOverlayId, PlatformPoint location, int zoom); } +/// Dummy interface to force generation of the platform view creation params, +/// which are not used in any Pigeon calls, only the platform view creation +/// call made internally by Flutter. +@HostApi() +abstract class MapsPlatformViewApi { + // This is never actually called. + void createView(PlatformMapViewCreationParams? type); +} + /// Inspector API only intended for use in integration tests. @HostApi() abstract class MapsInspectorApi { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml index c9c90250fea..6014b6eb6ac 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml @@ -2,7 +2,7 @@ name: google_maps_flutter_ios description: iOS implementation of the google_maps_flutter plugin. repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter_ios issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 2.12.0 +version: 2.13.0 environment: sdk: ^3.3.0 diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/test/cluster_manager_utils_test.dart b/packages/google_maps_flutter/google_maps_flutter_ios/test/cluster_manager_utils_test.dart deleted file mode 100644 index d7ea7c0379f..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios/test/cluster_manager_utils_test.dart +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter_test/flutter_test.dart'; -import 'package:google_maps_flutter_ios/src/utils/cluster_manager.dart'; -import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; - -void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - - test('serializeClusterManager', () async { - const ClusterManager manager = - ClusterManager(clusterManagerId: ClusterManagerId('1234')); - final Object json = serializeClusterManager(manager); - - expect(json, { - 'clusterManagerId': '1234', - }); - }); - - test('serializeClusterManagerSet', () async { - const ClusterManager manager = - ClusterManager(clusterManagerId: ClusterManagerId('1234')); - const ClusterManager manager2 = - ClusterManager(clusterManagerId: ClusterManagerId('5678')); - const ClusterManager manager3 = - ClusterManager(clusterManagerId: ClusterManagerId('9012')); - final Object json = serializeClusterManagerSet( - {manager, manager2, manager3}); - - expect(json, [ - { - 'clusterManagerId': '1234', - }, - { - 'clusterManagerId': '5678', - }, - { - 'clusterManagerId': '9012', - } - ]); - }); -} diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/test/google_maps_flutter_ios_test.dart b/packages/google_maps_flutter/google_maps_flutter_ios/test/google_maps_flutter_ios_test.dart index a033db4f509..7a2f26809dd 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/test/google_maps_flutter_ios_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/test/google_maps_flutter_ios_test.dart @@ -209,10 +209,12 @@ void main() { setUpMockMap(mapId: mapId); // Set some arbitrary options. - const MapConfiguration config = MapConfiguration( + final CameraTargetBounds cameraBounds = CameraTargetBounds(LatLngBounds( + southwest: const LatLng(10, 20), northeast: const LatLng(30, 40))); + final MapConfiguration config = MapConfiguration( compassEnabled: true, - liteModeEnabled: false, mapType: MapType.terrain, + cameraTargetBounds: cameraBounds, ); await maps.updateMapConfiguration(config, mapId: mapId); @@ -220,16 +222,21 @@ void main() { verify(api.updateMapConfiguration(captureAny)); final PlatformMapConfiguration passedConfig = verification.captured[0] as PlatformMapConfiguration; - final Map passedConfigJson = - passedConfig.json as Map; // Each set option should be present. - expect(passedConfigJson['compassEnabled'], true); - expect(passedConfigJson['liteModeEnabled'], false); - expect(passedConfigJson['mapType'], MapType.terrain.index); + expect(passedConfig.compassEnabled, true); + expect(passedConfig.mapType, PlatformMapType.terrain); + expect(passedConfig.cameraTargetBounds?.bounds?.northeast.latitude, + cameraBounds.bounds?.northeast.latitude); + expect(passedConfig.cameraTargetBounds?.bounds?.northeast.longitude, + cameraBounds.bounds?.northeast.longitude); + expect(passedConfig.cameraTargetBounds?.bounds?.southwest.latitude, + cameraBounds.bounds?.southwest.latitude); + expect(passedConfig.cameraTargetBounds?.bounds?.southwest.longitude, + cameraBounds.bounds?.southwest.longitude); // Spot-check that unset options are not be present. - expect(passedConfigJson['myLocationEnabled'], isNull); - expect(passedConfigJson['cameraTargetBounds'], isNull); - expect(passedConfigJson['padding'], isNull); + expect(passedConfig.myLocationEnabled, isNull); + expect(passedConfig.minMaxZoomPreference, isNull); + expect(passedConfig.padding, isNull); }); test('updateMapOptions passes expected arguments', () async { @@ -238,10 +245,12 @@ void main() { setUpMockMap(mapId: mapId); // Set some arbitrary options. + final CameraTargetBounds cameraBounds = CameraTargetBounds(LatLngBounds( + southwest: const LatLng(10, 20), northeast: const LatLng(30, 40))); final Map config = { 'compassEnabled': true, - 'liteModeEnabled': false, 'mapType': MapType.terrain.index, + 'cameraTargetBounds': cameraBounds.toJson(), }; await maps.updateMapOptions(config, mapId: mapId); @@ -249,16 +258,21 @@ void main() { verify(api.updateMapConfiguration(captureAny)); final PlatformMapConfiguration passedConfig = verification.captured[0] as PlatformMapConfiguration; - final Map passedConfigJson = - passedConfig.json as Map; // Each set option should be present. - expect(passedConfigJson['compassEnabled'], true); - expect(passedConfigJson['liteModeEnabled'], false); - expect(passedConfigJson['mapType'], MapType.terrain.index); + expect(passedConfig.compassEnabled, true); + expect(passedConfig.mapType, PlatformMapType.terrain); + expect(passedConfig.cameraTargetBounds?.bounds?.northeast.latitude, + cameraBounds.bounds?.northeast.latitude); + expect(passedConfig.cameraTargetBounds?.bounds?.northeast.longitude, + cameraBounds.bounds?.northeast.longitude); + expect(passedConfig.cameraTargetBounds?.bounds?.southwest.latitude, + cameraBounds.bounds?.southwest.latitude); + expect(passedConfig.cameraTargetBounds?.bounds?.southwest.longitude, + cameraBounds.bounds?.southwest.longitude); // Spot-check that unset options are not be present. - expect(passedConfigJson['myLocationEnabled'], isNull); - expect(passedConfigJson['cameraTargetBounds'], isNull); - expect(passedConfigJson['padding'], isNull); + expect(passedConfig.myLocationEnabled, isNull); + expect(passedConfig.minMaxZoomPreference, isNull); + expect(passedConfig.padding, isNull); }); test('updateCircles passes expected arguments', () async { @@ -536,17 +550,15 @@ void main() { methodCall.arguments as Map); if (args.containsKey('params')) { final Uint8List paramsUint8List = args['params'] as Uint8List; - const StandardMessageCodec codec = StandardMessageCodec(); final ByteData byteData = ByteData.sublistView(paramsUint8List); - final Map creationParams = - Map.from( - codec.decodeMessage(byteData) as Map); - if (creationParams.containsKey('options')) { - final Map options = Map.from( - creationParams['options'] as Map); - if (options.containsKey('cloudMapId')) { - passedCloudMapIdCompleter - .complete(options['cloudMapId'] as String); + final PlatformMapViewCreationParams? creationParams = + MapsApi.pigeonChannelCodec.decodeMessage(byteData) + as PlatformMapViewCreationParams?; + if (creationParams != null) { + final String? passedMapId = + creationParams.mapConfiguration.cloudMapId; + if (passedMapId != null) { + passedCloudMapIdCompleter.complete(passedMapId); } } }