From 47b36758e3679e86c93dc84b1ac9672710db96cb Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Thu, 30 Jul 2026 12:53:03 -0400 Subject: [PATCH 01/17] Initial Gemini conversion (heatmap) --- .../HeatmapController.swift | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift new file mode 100644 index 00000000000..e1164be51a4 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift @@ -0,0 +1,115 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import GoogleMaps +import google_maps_flutter_ios_sdk9_objc + +/// Controller of a single Heatmap on the map. +class HeatmapController: NSObject { + let heatmapTileLayer: GMUHeatmapTileLayer + private weak var mapView: GMSMapView? + + init(heatmap: FGMPlatformHeatmap, tileLayer: GMUHeatmapTileLayer, mapView: GMSMapView) { + self.heatmapTileLayer = tileLayer + self.mapView = mapView + super.init() + HeatmapController.update(tileLayer, from: heatmap, mapView: mapView) + } + + func removeHeatmap() { + heatmapTileLayer.map = nil + } + + func clearTileCache() { + heatmapTileLayer.clearTileCache() + } + + func update(from platformHeatmap: FGMPlatformHeatmap) { + if let mapView = mapView { + HeatmapController.update(heatmapTileLayer, from: platformHeatmap, mapView: mapView) + } + } + + /// Updates the underlying GMUHeatmapTileLayer with the properties from the given platform heatmap. + /// + /// Setting the heatmap to visible will set its map to the given mapView. + static func update( + _ heatmapTileLayer: GMUHeatmapTileLayer, + from platformHeatmap: FGMPlatformHeatmap, + mapView: GMSMapView + ) { + heatmapTileLayer.weightedData = FGMGetWeightedDataForPigeonWeightedData(platformHeatmap.data) + if let gradient = platformHeatmap.gradient { + heatmapTileLayer.gradient = FGMGetGradientForPigeonHeatmapGradient(gradient) + } + heatmapTileLayer.opacity = Float(platformHeatmap.opacity) + heatmapTileLayer.radius = UInt(platformHeatmap.radius) + heatmapTileLayer.minimumZoomIntensity = Float(platformHeatmap.minimumZoomIntensity) + heatmapTileLayer.maximumZoomIntensity = Float(platformHeatmap.maximumZoomIntensity) + + // The map must be set each time for options to update. + // This must be done last, to avoid visual flickers of default property values. + heatmapTileLayer.map = mapView + } +} + +/// Controller of multiple Heatmaps on the map. +class HeatmapsController: NSObject { + private var heatmapIdToController: [String: HeatmapController] = [:] + private weak var mapView: GMSMapView? + + init(mapView: GMSMapView) { + self.mapView = mapView + super.init() + } + + func add(_ heatmapsToAdd: [FGMPlatformHeatmap]) { + guard let mapView = mapView else { return } + for heatmap in heatmapsToAdd { + let heatmapTileLayer = GMUHeatmapTileLayer() + let controller = HeatmapController( + heatmap: heatmap, + tileLayer: heatmapTileLayer, + mapView: mapView + ) + heatmapIdToController[heatmap.heatmapId] = controller + } + } + + func change(_ heatmapsToChange: [FGMPlatformHeatmap]) { + for heatmap in heatmapsToChange { + if let controller = heatmapIdToController[heatmap.heatmapId] { + controller.update(from: heatmap) + controller.clearTileCache() + } + } + } + + func removeHeatmaps(withIdentifiers identifiers: [String]) { + for heatmapId in identifiers { + if let controller = heatmapIdToController[heatmapId] { + controller.removeHeatmap() + heatmapIdToController.removeValue(forKey: heatmapId) + } + } + } + + func hasHeatmap(withIdentifier identifier: String) -> Bool { + return heatmapIdToController[identifier] != nil + } + + func heatmap(withIdentifier identifier: String) -> FGMPlatformHeatmap? { + guard let controller = heatmapIdToController[identifier] else { return nil } + let heatmap = controller.heatmapTileLayer + return FGMPlatformHeatmap.make( + withHeatmapId: identifier, + data: FGMGetPigeonWeightedDataForWeightedData(heatmap.weightedData), + gradient: FGMGetPigeonHeatmapGradientForGradient(heatmap.gradient), + opacity: Double(heatmap.opacity), + radius: Int(heatmap.radius), + minimumZoomIntensity: Double(heatmap.minimumZoomIntensity), + maximumZoomIntensity: Double(heatmap.maximumZoomIntensity) + ) + } +} From 2dec4a6050ddbc702e17b709ba9bd549085b5198 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Thu, 30 Jul 2026 15:35:34 -0400 Subject: [PATCH 02/17] Manual fixes (heatmap) --- .../ios/Runner.xcodeproj/project.pbxproj | 56 ++++--- .../RunnerTests/CircleControllerTests.swift | 1 + .../ClusterManagersControllerTests.swift | 1 + .../RunnerTests/ConversionsUtilsTests.swift | 1 + .../ExtractIconFromDataTests.swift | 1 + .../ios/RunnerTests/GoogleMapsTests.swift | 1 + .../GroundOverlayControllerTests.swift | 1 + .../RunnerTests/HeatmapControllerTests.swift | 5 +- .../RunnerTests/MarkerControllerTests.swift | 1 + .../RunnerTests/PolygonControllerTests.swift | 1 + .../RunnerTests/PolylineControllerTests.swift | 1 + .../TestUtils/TestAssetProvider.swift | 1 + .../TestUtils/TestMapEventHandler.swift | 1 + .../TileOverlayControllerTests.swift | 1 + .../TileProviderControllerTests.swift | 1 + .../GoogleMapController.swift | 4 +- .../HeatmapController.swift | 8 +- .../FGMHeatmapController.m | 140 ------------------ .../FGMHeatmapController.h | 58 -------- .../FGMHeatmapController_Test.h | 17 --- 20 files changed, 48 insertions(+), 253 deletions(-) delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/FGMHeatmapController.m delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/include/google_maps_flutter_ios_sdk9_objc/FGMHeatmapController.h delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/include/google_maps_flutter_ios_sdk9_objc/FGMHeatmapController_Test.h diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/Runner.xcodeproj/project.pbxproj b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/Runner.xcodeproj/project.pbxproj index 8a78da2b15e..4977a41df81 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/Runner.xcodeproj/project.pbxproj @@ -3,32 +3,32 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 60; objects = { /* Begin PBXBuildFile section */ - A73F1ED02A874D8596718BE8 /* CircleControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E0364A58CE4D1F8AA3D564 /* CircleControllerTests.swift */; }; - E680DCBC3E7E41089DF60756 /* ClusterManagersControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB05BECEF774386944B77D3 /* ClusterManagersControllerTests.swift */; }; - 24A50C44E228413BABF647EF /* ConversionsUtilsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3331542510941C3930DDCB6 /* ConversionsUtilsTests.swift */; }; - 4518AF21C4DF4AA58D1BB89A /* ExtractIconFromDataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD78CCDD89347059EA71321 /* ExtractIconFromDataTests.swift */; }; - 67E9ECF639A945B9AB14A2EE /* GoogleMapsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5F71F034C24D0AA977F27E /* GoogleMapsTests.swift */; }; - B6EBFD5819964A73A1B0AE2A /* GroundOverlayControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2A4D627F452421DBDA834D2 /* GroundOverlayControllerTests.swift */; }; - 84CBDF074688494FA4924CA0 /* HeatmapControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64D0CE44D4164F2784CA4CD7 /* HeatmapControllerTests.swift */; }; - B2982FE0843F4FCB8D07D1D3 /* MarkerControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A396257FAF0545FC87D21257 /* MarkerControllerTests.swift */; }; - A37563E79BA24E4C98D77DD0 /* PolygonControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F220BC4477BC42E8870F2D4E /* PolygonControllerTests.swift */; }; - 6F94C58F3ECF465092D78750 /* PolylineControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 350A657853294B478D70CD62 /* PolylineControllerTests.swift */; }; 02F1F6249887487CBC3019FC /* TileOverlayControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F65543ABD25496A92F8F91F /* TileOverlayControllerTests.swift */; }; - 71C9A982E01441D0A61ABCC7 /* TileProviderControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CD823EECFC4BDD8755DD92 /* TileProviderControllerTests.swift */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 24A50C44E228413BABF647EF /* ConversionsUtilsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3331542510941C3930DDCB6 /* ConversionsUtilsTests.swift */; }; 3390B45E2F33AFA60094DEB9 /* PartiallyMockedMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3390B4582F33AFA60094DEB9 /* PartiallyMockedMapView.swift */; }; 3390B45F2F33AFA60094DEB9 /* TestAssetProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3390B45A2F33AFA60094DEB9 /* TestAssetProvider.swift */; }; 3390B4602F33AFA60094DEB9 /* TestMapEventHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3390B45C2F33AFA60094DEB9 /* TestMapEventHandler.swift */; }; 339DF1F02F1FE49800748863 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 339DF1EF2F1FE49300748863 /* AppDelegate.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 4518AF21C4DF4AA58D1BB89A /* ExtractIconFromDataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD78CCDD89347059EA71321 /* ExtractIconFromDataTests.swift */; }; + 67E9ECF639A945B9AB14A2EE /* GoogleMapsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5F71F034C24D0AA977F27E /* GoogleMapsTests.swift */; }; + 6F94C58F3ECF465092D78750 /* PolylineControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 350A657853294B478D70CD62 /* PolylineControllerTests.swift */; }; + 71C9A982E01441D0A61ABCC7 /* TileProviderControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CD823EECFC4BDD8755DD92 /* TileProviderControllerTests.swift */; }; 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; }; + 84CBDF074688494FA4924CA0 /* HeatmapControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64D0CE44D4164F2784CA4CD7 /* HeatmapControllerTests.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + A37563E79BA24E4C98D77DD0 /* PolygonControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F220BC4477BC42E8870F2D4E /* PolygonControllerTests.swift */; }; + A73F1ED02A874D8596718BE8 /* CircleControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E0364A58CE4D1F8AA3D564 /* CircleControllerTests.swift */; }; + B2982FE0843F4FCB8D07D1D3 /* MarkerControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A396257FAF0545FC87D21257 /* MarkerControllerTests.swift */; }; + B6EBFD5819964A73A1B0AE2A /* GroundOverlayControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2A4D627F452421DBDA834D2 /* GroundOverlayControllerTests.swift */; }; + E680DCBC3E7E41089DF60756 /* ClusterManagersControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB05BECEF774386944B77D3 /* ClusterManagersControllerTests.swift */; }; F269303B2BB389BF00BF17C4 /* assets in Resources */ = {isa = PBXBuildFile; fileRef = F269303A2BB389BF00BF17C4 /* assets */; }; F7151F21265D7EE50028CB91 /* GoogleMapsUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3351C2253008164500700458 /* GoogleMapsUITests.swift */; }; /* End PBXBuildFile section */ @@ -64,20 +64,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; - F8E0364A58CE4D1F8AA3D564 /* CircleControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleControllerTests.swift; sourceTree = ""; }; - 9FB05BECEF774386944B77D3 /* ClusterManagersControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClusterManagersControllerTests.swift; sourceTree = ""; }; - D3331542510941C3930DDCB6 /* ConversionsUtilsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversionsUtilsTests.swift; sourceTree = ""; }; - 5BD78CCDD89347059EA71321 /* ExtractIconFromDataTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtractIconFromDataTests.swift; sourceTree = ""; }; - CD5F71F034C24D0AA977F27E /* GoogleMapsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoogleMapsTests.swift; sourceTree = ""; }; - C2A4D627F452421DBDA834D2 /* GroundOverlayControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroundOverlayControllerTests.swift; sourceTree = ""; }; - 64D0CE44D4164F2784CA4CD7 /* HeatmapControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeatmapControllerTests.swift; sourceTree = ""; }; - A396257FAF0545FC87D21257 /* MarkerControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkerControllerTests.swift; sourceTree = ""; }; - F220BC4477BC42E8870F2D4E /* PolygonControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolygonControllerTests.swift; sourceTree = ""; }; - 350A657853294B478D70CD62 /* PolylineControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolylineControllerTests.swift; sourceTree = ""; }; 0F65543ABD25496A92F8F91F /* TileOverlayControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileOverlayControllerTests.swift; sourceTree = ""; }; - 54CD823EECFC4BDD8755DD92 /* TileProviderControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileProviderControllerTests.swift; sourceTree = ""; }; - 65E43D60708A4C5DA931E12E /* RunnerTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RunnerTests-Bridging-Header.h; sourceTree = ""; }; + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 3351C2253008164500700458 /* GoogleMapsUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoogleMapsUITests.swift; sourceTree = ""; }; 3390B4582F33AFA60094DEB9 /* PartiallyMockedMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartiallyMockedMapView.swift; sourceTree = ""; }; @@ -85,7 +73,11 @@ 3390B45C2F33AFA60094DEB9 /* TestMapEventHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestMapEventHandler.swift; sourceTree = ""; }; 339DF1EF2F1FE49300748863 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 339DF1F12F1FE4AD00748863 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 350A657853294B478D70CD62 /* PolylineControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolylineControllerTests.swift; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 54CD823EECFC4BDD8755DD92 /* TileProviderControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileProviderControllerTests.swift; sourceTree = ""; }; + 5BD78CCDD89347059EA71321 /* ExtractIconFromDataTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtractIconFromDataTests.swift; sourceTree = ""; }; + 64D0CE44D4164F2784CA4CD7 /* HeatmapControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeatmapControllerTests.swift; sourceTree = ""; }; 784666492D4C4C64000A1A5F /* FlutterFramework */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterFramework; path = Flutter/ephemeral/Packages/.packages/FlutterFramework; sourceTree = ""; }; 78DABEA22ED26510000E7860 /* google_maps_flutter_ios_sdk9 */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = google_maps_flutter_ios_sdk9; path = ../../ios/google_maps_flutter_ios_sdk9; sourceTree = ""; }; 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = ""; }; @@ -97,11 +89,18 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9FB05BECEF774386944B77D3 /* ClusterManagersControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClusterManagersControllerTests.swift; sourceTree = ""; }; + A396257FAF0545FC87D21257 /* MarkerControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkerControllerTests.swift; sourceTree = ""; }; + C2A4D627F452421DBDA834D2 /* GroundOverlayControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroundOverlayControllerTests.swift; sourceTree = ""; }; + CD5F71F034C24D0AA977F27E /* GoogleMapsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoogleMapsTests.swift; sourceTree = ""; }; + D3331542510941C3930DDCB6 /* ConversionsUtilsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversionsUtilsTests.swift; sourceTree = ""; }; + F220BC4477BC42E8870F2D4E /* PolygonControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolygonControllerTests.swift; sourceTree = ""; }; F269303A2BB389BF00BF17C4 /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = assets; sourceTree = ""; }; F7151F10265D7ED70028CB91 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; F7151F14265D7ED70028CB91 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; F7151F1E265D7EE50028CB91 /* RunnerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; F7151F22265D7EE50028CB91 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F8E0364A58CE4D1F8AA3D564 /* CircleControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleControllerTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -208,7 +207,6 @@ 350A657853294B478D70CD62 /* PolylineControllerTests.swift */, 0F65543ABD25496A92F8F91F /* TileOverlayControllerTests.swift */, 54CD823EECFC4BDD8755DD92 /* TileProviderControllerTests.swift */, - 65E43D60708A4C5DA931E12E /* RunnerTests-Bridging-Header.h */, ); path = RunnerTests; sourceTree = ""; @@ -648,9 +646,8 @@ MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/Runner"; - SWIFT_OBJC_BRIDGING_HEADER = "RunnerTests/RunnerTests-Bridging-Header.h"; SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/Runner"; }; name = Debug; }; @@ -669,9 +666,8 @@ MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/Runner"; - SWIFT_OBJC_BRIDGING_HEADER = "RunnerTests/RunnerTests-Bridging-Header.h"; SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/Runner"; }; name = Release; }; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/CircleControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/CircleControllerTests.swift index 3bc49073a67..bc43878be6b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/CircleControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/CircleControllerTests.swift @@ -6,6 +6,7 @@ import GoogleMaps import Testing @testable import google_maps_flutter_ios_sdk9 +import google_maps_flutter_ios_sdk9_objc @MainActor struct CircleControllerTests { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ClusterManagersControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ClusterManagersControllerTests.swift index 888bdb1d4f4..47730e82fa7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ClusterManagersControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ClusterManagersControllerTests.swift @@ -7,6 +7,7 @@ import GoogleMaps import Testing @testable import google_maps_flutter_ios_sdk9 +import google_maps_flutter_ios_sdk9_objc @MainActor struct ClusterManagersControllerTests { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ConversionsUtilsTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ConversionsUtilsTests.swift index 585f4e128b9..e9ac2a815fa 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ConversionsUtilsTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ConversionsUtilsTests.swift @@ -6,6 +6,7 @@ import GoogleMaps import Testing @testable import google_maps_flutter_ios_sdk9 +import google_maps_flutter_ios_sdk9_objc @MainActor struct ConversionUtilsTests { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ExtractIconFromDataTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ExtractIconFromDataTests.swift index 3eec318cb86..86e8559687e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ExtractIconFromDataTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ExtractIconFromDataTests.swift @@ -6,6 +6,7 @@ import Flutter import Testing @testable import google_maps_flutter_ios_sdk9 +import google_maps_flutter_ios_sdk9_objc @MainActor struct ExtractIconFromDataTests { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GoogleMapsTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GoogleMapsTests.swift index b3ceda9c58b..0de0c8f3aa4 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GoogleMapsTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GoogleMapsTests.swift @@ -7,6 +7,7 @@ import GoogleMaps import Testing @testable import google_maps_flutter_ios_sdk9 +import google_maps_flutter_ios_sdk9_objc class MockCATransaction: NSObject, FGMCATransactionProtocol { var beginCalled = false diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GroundOverlayControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GroundOverlayControllerTests.swift index a2970173246..3802f288d68 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GroundOverlayControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GroundOverlayControllerTests.swift @@ -6,6 +6,7 @@ import GoogleMaps import Testing @testable import google_maps_flutter_ios_sdk9 +import google_maps_flutter_ios_sdk9_objc @MainActor struct GroundOverlayControllerTests { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/HeatmapControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/HeatmapControllerTests.swift index 06064985556..6aefad63ac1 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/HeatmapControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/HeatmapControllerTests.swift @@ -7,6 +7,7 @@ import GoogleMapsUtils import Testing @testable import google_maps_flutter_ios_sdk9 +import google_maps_flutter_ios_sdk9_objc @MainActor struct HeatmapControllerTests { @@ -20,7 +21,7 @@ import Testing startPoints: [0 as NSNumber, 1 as NSNumber], colorMapSize: 256 ) - FGMHeatmapController.updateHeatmap( + HeatmapController.update( heatmap, from: FGMPlatformHeatmap.make( withHeatmapId: "heatmap", @@ -40,7 +41,7 @@ import Testing minimumZoomIntensity: 1, maximumZoomIntensity: 2 ), - with: HeatmapControllerTests.mapView() + mapView: HeatmapControllerTests.mapView() ) #expect(heatmap.hasSetMap) } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/MarkerControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/MarkerControllerTests.swift index 8957f6fa89f..ff590c5ef5d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/MarkerControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/MarkerControllerTests.swift @@ -6,6 +6,7 @@ import GoogleMaps import Testing @testable import google_maps_flutter_ios_sdk9 +import google_maps_flutter_ios_sdk9_objc @MainActor struct MarkerControllerTests { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/PolygonControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/PolygonControllerTests.swift index bddd33f0757..6fa25a9ff40 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/PolygonControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/PolygonControllerTests.swift @@ -6,6 +6,7 @@ import GoogleMaps import Testing @testable import google_maps_flutter_ios_sdk9 +import google_maps_flutter_ios_sdk9_objc @MainActor struct PolygonControllerTests { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/PolylineControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/PolylineControllerTests.swift index 3ad393d3710..7803521c4a7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/PolylineControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/PolylineControllerTests.swift @@ -6,6 +6,7 @@ import GoogleMaps import Testing @testable import google_maps_flutter_ios_sdk9 +import google_maps_flutter_ios_sdk9_objc @MainActor struct PolylineControllerTests { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TestUtils/TestAssetProvider.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TestUtils/TestAssetProvider.swift index 79986f95794..97720ed2b33 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TestUtils/TestAssetProvider.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TestUtils/TestAssetProvider.swift @@ -4,6 +4,7 @@ import UIKit import google_maps_flutter_ios_sdk9 +import google_maps_flutter_ios_sdk9_objc /// Fake implementation of FGMAssetProvider for unit tests. class TestAssetProvider: NSObject, FGMAssetProvider { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TestUtils/TestMapEventHandler.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TestUtils/TestMapEventHandler.swift index 2c8fa8248be..5dec204caf4 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TestUtils/TestMapEventHandler.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TestUtils/TestMapEventHandler.swift @@ -4,6 +4,7 @@ import Foundation import google_maps_flutter_ios_sdk9 +import google_maps_flutter_ios_sdk9_objc /// Fake implementation of FGMMapEventDelegate for unit tests. class TestMapEventHandler: NSObject, FGMMapEventDelegate { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TileOverlayControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TileOverlayControllerTests.swift index 889371b8df3..9dc2bdc1af1 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TileOverlayControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TileOverlayControllerTests.swift @@ -6,6 +6,7 @@ import GoogleMaps import Testing @testable import google_maps_flutter_ios_sdk9 +import google_maps_flutter_ios_sdk9_objc @MainActor struct TileOverlayControllerTests { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TileProviderControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TileProviderControllerTests.swift index bc2a6d1885b..fba68a5ce81 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TileProviderControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TileProviderControllerTests.swift @@ -7,6 +7,7 @@ import GoogleMaps import Testing @testable import google_maps_flutter_ios_sdk9 +import google_maps_flutter_ios_sdk9_objc class StubTileReceiver: NSObject, GMSTileReceiver { func receiveTileWith(x: UInt, y: UInt, zoom: UInt, image: UIImage?) { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift index 68c16f7dbf9..13a40918740 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift @@ -127,7 +127,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV let polygonsController: PolygonsController let polylinesController: PolylinesController let circlesController: CirclesController - let heatmapsController: FGMHeatmapsController + let heatmapsController: HeatmapsController let tileOverlaysController: TileOverlaysController let groundOverlaysController: GroundOverlaysController @@ -221,7 +221,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV mapView: mapView, eventDelegate: mapEventHandler ) - heatmapsController = FGMHeatmapsController(mapView: mapView) + heatmapsController = HeatmapsController(mapView: mapView) tileProvider = ConcreteTileProvider(dartCallbackHandler: dartCallbackHandler) tileOverlaysController = TileOverlaysController( mapView: mapView, diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift index e1164be51a4..819ff537d89 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift @@ -45,8 +45,8 @@ class HeatmapController: NSObject { } heatmapTileLayer.opacity = Float(platformHeatmap.opacity) heatmapTileLayer.radius = UInt(platformHeatmap.radius) - heatmapTileLayer.minimumZoomIntensity = Float(platformHeatmap.minimumZoomIntensity) - heatmapTileLayer.maximumZoomIntensity = Float(platformHeatmap.maximumZoomIntensity) + heatmapTileLayer.minimumZoomIntensity = UInt(platformHeatmap.minimumZoomIntensity) + heatmapTileLayer.maximumZoomIntensity = UInt(platformHeatmap.maximumZoomIntensity) // The map must be set each time for options to update. // This must be done last, to avoid visual flickers of default property values. @@ -108,8 +108,8 @@ class HeatmapsController: NSObject { gradient: FGMGetPigeonHeatmapGradientForGradient(heatmap.gradient), opacity: Double(heatmap.opacity), radius: Int(heatmap.radius), - minimumZoomIntensity: Double(heatmap.minimumZoomIntensity), - maximumZoomIntensity: Double(heatmap.maximumZoomIntensity) + minimumZoomIntensity: Int(heatmap.minimumZoomIntensity), + maximumZoomIntensity: Int(heatmap.maximumZoomIntensity) ) } } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/FGMHeatmapController.m b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/FGMHeatmapController.m deleted file mode 100644 index 49ec16dff82..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/FGMHeatmapController.m +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "FGMHeatmapController.h" -#import "FGMHeatmapController_Test.h" - -@import GoogleMapsUtils; - -#import "FGMConversionUtils.h" - -@interface FGMHeatmapController () - -/// The heatmap tile layer this controller handles. -@property(nonatomic, strong) GMUHeatmapTileLayer *heatmapTileLayer; - -/// The GMSMapView to which the heatmaps are added. -@property(nonatomic, weak) GMSMapView *mapView; - -@end - -@implementation FGMHeatmapController -- (instancetype)initWithHeatmap:(FGMPlatformHeatmap *)heatmap - tileLayer:(GMUHeatmapTileLayer *)heatmapTileLayer - mapView:(GMSMapView *)mapView { - self = [super init]; - if (self) { - _heatmapTileLayer = heatmapTileLayer; - _mapView = mapView; - - [FGMHeatmapController updateHeatmap:_heatmapTileLayer - fromPlatformHeatmap:heatmap - withMapView:_mapView]; - } - return self; -} - -- (void)removeHeatmap { - _heatmapTileLayer.map = nil; -} - -- (void)clearTileCache { - [_heatmapTileLayer clearTileCache]; -} - -- (void)updateFromPlatformHeatmap:(FGMPlatformHeatmap *)platformHeatmap { - [FGMHeatmapController updateHeatmap:_heatmapTileLayer - fromPlatformHeatmap:platformHeatmap - withMapView:_mapView]; -} - -+ (void)updateHeatmap:(GMUHeatmapTileLayer *)heatmapTileLayer - fromPlatformHeatmap:(FGMPlatformHeatmap *)platformHeatmap - withMapView:(GMSMapView *)mapView { - heatmapTileLayer.weightedData = FGMGetWeightedDataForPigeonWeightedData(platformHeatmap.data); - if (platformHeatmap.gradient) { - heatmapTileLayer.gradient = FGMGetGradientForPigeonHeatmapGradient(platformHeatmap.gradient); - } - heatmapTileLayer.opacity = platformHeatmap.opacity; - heatmapTileLayer.radius = platformHeatmap.radius; - heatmapTileLayer.minimumZoomIntensity = platformHeatmap.minimumZoomIntensity; - heatmapTileLayer.maximumZoomIntensity = platformHeatmap.maximumZoomIntensity; - - // The map must be set each time for options to update. - // This must be done last, to avoid visual flickers of default property values. - heatmapTileLayer.map = mapView; -} -@end - -@interface FGMHeatmapsController () - -/// A map from heatmapId to the controller that manages it. -@property(nonatomic, strong) - NSMutableDictionary *heatmapIdToController; - -/// The map view owned by GoogmeMapController. -@property(nonatomic, weak) GMSMapView *mapView; - -@end - -@implementation FGMHeatmapsController -- (instancetype)initWithMapView:(GMSMapView *)mapView { - self = [super init]; - if (self) { - _mapView = mapView; - _heatmapIdToController = [NSMutableDictionary dictionary]; - } - return self; -} - -- (void)addHeatmaps:(NSArray *)heatmapsToAdd { - for (FGMPlatformHeatmap *heatmap in heatmapsToAdd) { - GMUHeatmapTileLayer *heatmapTileLayer = [[GMUHeatmapTileLayer alloc] init]; - FGMHeatmapController *controller = - [[FGMHeatmapController alloc] initWithHeatmap:heatmap - tileLayer:heatmapTileLayer - mapView:_mapView]; - _heatmapIdToController[heatmap.heatmapId] = controller; - } -} - -- (void)changeHeatmaps:(NSArray *)heatmapsToChange { - for (FGMPlatformHeatmap *heatmap in heatmapsToChange) { - FGMHeatmapController *controller = _heatmapIdToController[heatmap.heatmapId]; - - [controller updateFromPlatformHeatmap:heatmap]; - [controller clearTileCache]; - } -} - -- (void)removeHeatmapsWithIdentifiers:(NSArray *)identifiers { - for (NSString *heatmapId in identifiers) { - FGMHeatmapController *controller = _heatmapIdToController[heatmapId]; - if (!controller) { - continue; - } - [controller removeHeatmap]; - [_heatmapIdToController removeObjectForKey:heatmapId]; - } -} - -- (BOOL)hasHeatmapWithIdentifier:(NSString *)identifier { - return _heatmapIdToController[identifier] != nil; -} - -- (FGMPlatformHeatmap *)heatmapWithIdentifier:(NSString *)identifier { - GMUHeatmapTileLayer *heatmap = self.heatmapIdToController[identifier].heatmapTileLayer; - if (!heatmap) { - return nil; - } - return [FGMPlatformHeatmap - makeWithHeatmapId:identifier - data:FGMGetPigeonWeightedDataForWeightedData(heatmap.weightedData) - gradient:FGMGetPigeonHeatmapGradientForGradient(heatmap.gradient) - opacity:heatmap.opacity - radius:heatmap.radius - minimumZoomIntensity:heatmap.minimumZoomIntensity - maximumZoomIntensity:heatmap.maximumZoomIntensity]; -} -@end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/include/google_maps_flutter_ios_sdk9_objc/FGMHeatmapController.h b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/include/google_maps_flutter_ios_sdk9_objc/FGMHeatmapController.h deleted file mode 100644 index c8fce13543c..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/include/google_maps_flutter_ios_sdk9_objc/FGMHeatmapController.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -@import GoogleMaps; - -#import "GoogleMapsUtilsTrampoline.h" -#import "google_maps_flutter_pigeon_messages.g.h" - -NS_ASSUME_NONNULL_BEGIN - -/// Controller of a single Heatmap on the map. -@interface FGMHeatmapController : NSObject - -/// Initializes an instance of this class with a heatmap tile layer, a map view, and additional -/// configuration options. -/// -/// @param heatmap The heatmap data to display. -/// @param heatmapTileLayer The heatmap tile layer that will be used to display heatmap data on the -/// map. -/// @param mapView The map view where the heatmap layer will be overlaid. -/// -/// @return An initialized instance of this class, configured with the specified heatmap tile layer, -/// map view, and additional options. -- (instancetype)initWithHeatmap:(FGMPlatformHeatmap *)heatmap - tileLayer:(GMUHeatmapTileLayer *)heatmapTileLayer - mapView:(GMSMapView *)mapView; - -/// Removes this heatmap from the map. -- (void)removeHeatmap; - -/// Clears the tile cache in order to visually udpate this heatmap. -- (void)clearTileCache; -@end - -/// Controller of multiple Heatmaps on the map. -@interface FGMHeatmapsController : NSObject - -/// Initializes the controller with a GMSMapView. -- (instancetype)initWithMapView:(GMSMapView *)mapView; - -/// Adds heatmaps to the map. -- (void)addHeatmaps:(NSArray *)heatmapsToAdd; - -/// Updates heatmaps on the map. -- (void)changeHeatmaps:(NSArray *)heatmapsToChange; - -/// Removes heatmaps from the map. -- (void)removeHeatmapsWithIdentifiers:(NSArray *)identifiers; - -/// Returns true if a heatmap with the given identifier exists on the map. -- (BOOL)hasHeatmapWithIdentifier:(NSString *)identifier; - -/// Returns the heatmap with the given identifier. -- (nullable FGMPlatformHeatmap *)heatmapWithIdentifier:(NSString *)identifier; -@end - -NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/include/google_maps_flutter_ios_sdk9_objc/FGMHeatmapController_Test.h b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/include/google_maps_flutter_ios_sdk9_objc/FGMHeatmapController_Test.h deleted file mode 100644 index 797c309dbb2..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/include/google_maps_flutter_ios_sdk9_objc/FGMHeatmapController_Test.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "FGMHeatmapController.h" - -/// Internal APIs exposed for unit testing -@interface FGMHeatmapController (Test) - -/// Updates the underlying GMUHeatmapTileLayer with the properties from the given platform heatmap. -/// -/// Setting the heatmap to visible will set its map to the given mapView. -+ (void)updateHeatmap:(GMUHeatmapTileLayer *)heatmapTileLayer - fromPlatformHeatmap:(FGMPlatformHeatmap *)platformHeatmap - withMapView:(GMSMapView *)mapView; - -@end From ebdf0094c14c87d04ed0812cd5266d9ab7a5f672 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Thu, 30 Jul 2026 15:57:44 -0400 Subject: [PATCH 03/17] Initial conversion (conversion utils) --- .../CircleController.swift | 6 +- .../ConversionUtils.swift | 273 +++++++++++++++++- .../GoogleMapController.swift | 29 +- .../GroundOverlayController.swift | 10 +- .../HeatmapController.swift | 10 +- .../MarkerController.swift | 19 +- .../PolygonController.swift | 10 +- .../PolylineController.swift | 12 +- 8 files changed, 317 insertions(+), 52 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/CircleController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/CircleController.swift index 362372a3f32..9ae3d34e36f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/CircleController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/CircleController.swift @@ -42,11 +42,11 @@ class CircleController: NSObject { ) { circle.isTappable = platformCircle.consumeTapEvents circle.zIndex = Int32(platformCircle.zIndex) - circle.position = FGMGetCoordinateForPigeonLatLng(platformCircle.center) + circle.position = coordinate(from: platformCircle.center) circle.radius = platformCircle.radius - circle.strokeColor = FGMGetColorForPigeonColor(platformCircle.strokeColor) + circle.strokeColor = color(from: platformCircle.strokeColor) circle.strokeWidth = CGFloat(platformCircle.strokeWidth) - circle.fillColor = FGMGetColorForPigeonColor(platformCircle.fillColor) + circle.fillColor = color(from: platformCircle.fillColor) // This must be done last, to avoid visual flickers of default property values. circle.map = platformCircle.visible ? mapView : nil diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift index 1c0f6dbbaf5..dd893632dec 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift @@ -2,10 +2,279 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import Flutter +import GoogleMaps +import GoogleMapsUtils + #if canImport(google_maps_flutter_ios_sdk9_objc) import google_maps_flutter_ios_sdk9_objc #endif +/// Converts a CGPoint from its Pigeon equivalent. +func point(from point: FGMPlatformPoint) -> CGPoint { + return CGPoint(x: point.x, y: point.y) +} + +/// Converts a CGPoint to its Pigeon equivalent. +func pigeonPoint(from point: CGPoint) -> FGMPlatformPoint { + return FGMPlatformPoint.makeWith(x: point.x, y: point.y) +} + +/// Creates a CLLocationCoordinate2D from its Pigeon representation. +func coordinate(from latLng: FGMPlatformLatLng) -> CLLocationCoordinate2D { + return CLLocationCoordinate2D(latitude: latLng.latitude, longitude: latLng.longitude) +} + +/// Converts a CLLocationCoordinate2D to its Pigeon representation. +func pigeonLatLng(from coordinate: CLLocationCoordinate2D) -> FGMPlatformLatLng { + return FGMPlatformLatLng.make(withLatitude: coordinate.latitude, longitude: coordinate.longitude) +} + +/// Creates a GMSCoordinateBounds from its Pigeon representation. +func coordinateBounds(from bounds: FGMPlatformLatLngBounds) -> GMSCoordinateBounds { + return GMSCoordinateBounds( + coordinate: coordinate(from: bounds.northeast), + coordinate: coordinate(from: bounds.southwest) + ) +} + +/// Converts a GMSCoordinateBounds to its Pigeon representation. +func pigeonLatLngBounds(from bounds: GMSCoordinateBounds) -> FGMPlatformLatLngBounds { + return FGMPlatformLatLngBounds.make( + withNortheast: pigeonLatLng(from: bounds.northEast), + southwest: pigeonLatLng(from: bounds.southWest) + ) +} + +/// Converts a GMSCameraPosition to its Pigeon representation. +func pigeonCameraPosition(from position: GMSCameraPosition) -> FGMPlatformCameraPosition { + return FGMPlatformCameraPosition.make( + withBearing: position.bearing, + target: pigeonLatLng(from: position.target), + tilt: position.viewingAngle, + zoom: position.zoom + ) +} + +/// Creates a GMSCameraPosition from its Pigeon representation. +func cameraPosition(from position: FGMPlatformCameraPosition) -> GMSCameraPosition { + return GMSCameraPosition( + target: coordinate(from: position.target), + zoom: position.zoom, + bearing: position.bearing, + viewingAngle: position.tilt + ) +} + +/// Creates a CLLocation array from its Pigeon equivalent. +func points(from pigeonPoints: [FGMPlatformLatLng]) -> [CLLocation] { + return pigeonPoints.map { CLLocation(latitude: $0.latitude, longitude: $0.longitude) } +} + +/// Creates a CLLocation array array, representing a set of holes, from its Pigeon equivalent. +func holes(from pigeonHolePoints: [[FGMPlatformLatLng]]) -> [[CLLocation]] { + return pigeonHolePoints.map { points(from: $0) } +} + +/// Creates a GMSMutablePath from points. +func path(from points: [CLLocation]) -> GMSMutablePath { + let path = GMSMutablePath() + for location in points { + path.add(location.coordinate) + } + return path +} + +/// Creates a GMSMapViewType from its Pigeon representation. +func mapViewType(from type: FGMPlatformMapType) -> GMSMapViewType { + switch type { + case .none: + return .none + case .normal: + return .normal + case .satellite: + return .satellite + case .terrain: + return .terrain + case .hybrid: + return .hybrid + @unknown default: + return .normal + } +} + +/// Creates a GMSCollisionBehavior from its Pigeon representation. +func collisionBehavior(from collisionBehavior: FGMPlatformMarkerCollisionBehavior) -> GMSCollisionBehavior { + switch collisionBehavior { + case .requiredDisplay: + return .required + case .optionalAndHidesLowerPriority: + return .optionalAndHidesLowerPriority + case .requiredAndHidesOptional: + return .requiredAndHidesOptional + @unknown default: + return .required + } +} + +/// Converts a GMSGroundOverlay to its Pigeon representation. +func pigeonGroundOverlay( + from groundOverlay: GMSGroundOverlay, + overlayId: String, + isCreatedWithBounds: Bool, + zoomLevel: NSNumber? +) -> FGMPlatformGroundOverlay { + let placeholderImage = FGMPlatformBitmap.make( + withBitmap: FGMPlatformBitmapDefaultMarker.make(withHue: 0)) + if isCreatedWithBounds { + return FGMPlatformGroundOverlay.make( + withGroundOverlayId: overlayId, + image: placeholderImage, + position: nil, + bounds: FGMPlatformLatLngBounds.make( + withNortheast: FGMPlatformLatLng.make( + withLatitude: groundOverlay.bounds.northEast.latitude, + longitude: groundOverlay.bounds.northEast.longitude + ), + southwest: FGMPlatformLatLng.make( + withLatitude: groundOverlay.bounds.southWest.latitude, + longitude: groundOverlay.bounds.southWest.longitude + ) + ), + anchor: FGMPlatformPoint.makeWith(x: groundOverlay.anchor.x, y: groundOverlay.anchor.y), + transparency: 1.0 - Double(groundOverlay.opacity), + bearing: groundOverlay.bearing, + zIndex: Double(groundOverlay.zIndex), + visible: groundOverlay.map != nil, + clickable: groundOverlay.isTappable, + zoomLevel: zoomLevel + ) + } else { + return FGMPlatformGroundOverlay.make( + withGroundOverlayId: overlayId, + image: placeholderImage, + position: FGMPlatformLatLng.make( + withLatitude: groundOverlay.position.latitude, + longitude: groundOverlay.position.longitude + ), + bounds: nil, + anchor: FGMPlatformPoint.makeWith(x: groundOverlay.anchor.x, y: groundOverlay.anchor.y), + transparency: 1.0 - Double(groundOverlay.opacity), + bearing: groundOverlay.bearing, + zIndex: Double(groundOverlay.zIndex), + visible: groundOverlay.map != nil, + clickable: groundOverlay.isTappable, + zoomLevel: zoomLevel + ) + } +} + +/// Creates a GMUGradient from its Pigeon representation. +func gradient(from heatmapGradient: FGMPlatformHeatmapGradient) -> GMUGradient { + let colors = heatmapGradient.colors.map { color(from: $0) } + return GMUGradient( + colors: colors, + startPoints: heatmapGradient.startPoints, + colorMapSize: heatmapGradient.colorMapSize + ) +} + +/// Converts a GMUGradient to its Pigeon representation. +func pigeonHeatmapGradient(from gradient: GMUGradient) -> FGMPlatformHeatmapGradient { + let colors = gradient.colors.map { pigeonColor(from: $0) } + return FGMPlatformHeatmapGradient.make( + withColors: colors, + startPoints: gradient.startPoints, + colorMapSize: gradient.mapSize + ) +} + +/// Creates a GMUWeightedLatLng array from its Pigeon equivalent. +func weightedData(from weightedLatLngs: [FGMPlatformWeightedLatLng]) -> [GMUWeightedLatLng] { + return weightedLatLngs.map { + GMUWeightedLatLng( + coordinate: coordinate(from: $0.point), + intensity: Float($0.weight) + ) + } +} + +/// Converts a GMUWeightedLatLng array to its Pigeon equivalent. +func pigeonWeightedData(from weightedLatLngs: [GMUWeightedLatLng]) -> [FGMPlatformWeightedLatLng] { + return weightedLatLngs.map { + let point = GMSMapPoint(x: $0.point.x, y: $0.point.y) + return FGMPlatformWeightedLatLng.make( + withPoint: pigeonLatLng(from: GMSUnproject(point)), + weight: Double($0.intensity) + ) + } +} + +/// Creates a GMSCameraUpdate from its Pigeon equivalent. +func cameraUpdate(from cameraUpdate: FGMPlatformCameraUpdate) -> GMSCameraUpdate? { + // See note in messages.dart for why this is so loosely typed. + let update = cameraUpdate.cameraUpdate + if let newCameraPosition = update as? FGMPlatformCameraUpdateNewCameraPosition { + return GMSCameraUpdate.setCamera(cameraPosition(from: newCameraPosition.cameraPosition)) + } else if let newLatLng = update as? FGMPlatformCameraUpdateNewLatLng { + return GMSCameraUpdate.setTarget(coordinate(from: newLatLng.latLng)) + } else if let newLatLngBounds = update as? FGMPlatformCameraUpdateNewLatLngBounds { + return GMSCameraUpdate.fit( + coordinateBounds(from: newLatLngBounds.bounds), + withPadding: CGFloat(newLatLngBounds.padding) + ) + } else if let newLatLngZoom = update as? FGMPlatformCameraUpdateNewLatLngZoom { + return GMSCameraUpdate.setTarget( + coordinate(from: newLatLngZoom.latLng), + zoom: Float(newLatLngZoom.zoom) + ) + } else if let scrollBy = update as? FGMPlatformCameraUpdateScrollBy { + return GMSCameraUpdate.scrollBy(x: scrollBy.dx, y: scrollBy.dy) + } else if let zoomBy = update as? FGMPlatformCameraUpdateZoomBy { + if let focus = zoomBy.focus { + return GMSCameraUpdate.zoom(by: Float(zoomBy.amount), at: point(from: focus)) + } else { + return GMSCameraUpdate.zoom(by: Float(zoomBy.amount)) + } + } else if let zoom = update as? FGMPlatformCameraUpdateZoom { + return zoom.out ? GMSCameraUpdate.zoomOut() : GMSCameraUpdate.zoomIn() + } else if let zoomTo = update as? FGMPlatformCameraUpdateZoomTo { + return GMSCameraUpdate.zoom(to: Float(zoomTo.zoom)) + } + return nil +} + +/// Creates a UIColor from its Pigeon representation. +func color(from color: FGMPlatformColor) -> UIColor { + return UIColor(red: color.red, green: color.green, blue: color.blue, alpha: color.alpha) +} + +/// Converts a UIColor to its Pigeon representation. +func pigeonColor(from color: UIColor) -> FGMPlatformColor { + var red: CGFloat = 0 + var green: CGFloat = 0 + var blue: CGFloat = 0 + var alpha: CGFloat = 0 + color.getRed(&red, green: &green, blue: &blue, alpha: &alpha) + return FGMPlatformColor.make( + withRed: Double(red), green: Double(green), blue: Double(blue), alpha: Double(alpha)) +} + +/// Creates an array of GMSStrokeStyles using the given patterns and stroke color. +func strokeStyles( + from patterns: [FGMPlatformPatternItem], strokeColor: UIColor +) -> [GMSStrokeStyle] { + return patterns.map { pattern in + let color = pattern.type == .gap ? UIColor.clear : strokeColor + return GMSStrokeStyle.solidColor(color) + } +} + +/// Creates an array of span lengths using the given patterns. +func spanLengths(from patterns: [FGMPlatformPatternItem]) -> [NSNumber] { + return patterns.map { $0.length ?? 0 } +} + /// Converts a GMUCluster to its Pigeon representation. func pigeonCluster( for cluster: GMUCluster, @@ -22,8 +291,8 @@ func pigeonCluster( return FGMPlatformCluster.make( withClusterManagerId: clusterManagerIdentifier, - position: FGMGetPigeonLatLngForCoordinate(cluster.position), - bounds: FGMGetPigeonLatLngBoundsForCoordinateBounds(bounds), + position: pigeonLatLng(from: cluster.position), + bounds: pigeonLatLngBounds(from: bounds), markerIds: markerIds ) } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift index 13a40918740..b86ccecde6c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift @@ -146,8 +146,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV creationParameters: FGMPlatformMapViewCreationParams, registrar: FlutterPluginRegistrar ) { - let camera = FGMGetCameraPositionForPigeonCameraPosition( - creationParameters.initialCameraPosition) + let camera = cameraPosition(from: creationParameters.initialCameraPosition) let options = GMSMapViewOptions() options.frame = frame @@ -361,7 +360,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV public func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) { if trackCameraPosition { - mapEventHandler.didMoveCamera(to: FGMGetPigeonCameraPositionForPosition(position)) + mapEventHandler.didMoveCamera(to: pigeonCameraPosition(from: position)) } } @@ -422,11 +421,11 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV } public func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) { - mapEventHandler.didTap(atPosition: FGMGetPigeonLatLngForCoordinate(coordinate)) + mapEventHandler.didTap(atPosition: pigeonLatLng(from: coordinate)) } public func mapView(_ mapView: GMSMapView, didLongPressAt coordinate: CLLocationCoordinate2D) { - mapEventHandler.didLongPress(atPosition: FGMGetPigeonLatLngForCoordinate(coordinate)) + mapEventHandler.didLongPress(atPosition: pigeonLatLng(from: coordinate)) } func interpretMapConfiguration(_ config: FGMPlatformMapConfiguration) { @@ -452,7 +451,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV ) -> (Bool, String?) { if let cameraTargetBounds = config.cameraTargetBounds { if let bounds = cameraTargetBounds.bounds { - mapView.cameraTargetBounds = FGMGetCoordinateBoundsForPigeonLatLngBounds(bounds) + mapView.cameraTargetBounds = coordinateBounds(from: bounds) } else { mapView.cameraTargetBounds = nil } @@ -470,7 +469,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV mapView.isBuildingsEnabled = buildingsEnabled.boolValue } if let mapType = config.mapType { - mapView.mapType = FGMGetMapViewTypeForPigeonMapType(mapType.value) + mapView.mapType = mapViewType(from: mapType.value) } if let zoomData = config.minMaxZoomPreference { let minZoom = zoomData.min?.floatValue ?? kGMSMinZoomLevel @@ -651,9 +650,9 @@ class MapCallHandler: NSObject, FGMMapsApi { ) return nil } - let point = FGMGetCGPointForPigeonPoint(screenCoordinate) + let point = point(from: screenCoordinate) let latlng = mapView.projection.coordinate(for: point) - return FGMGetPigeonLatLngForCoordinate(latlng) + return pigeonLatLng(from: latlng) } func screenCoordinates( @@ -667,9 +666,9 @@ class MapCallHandler: NSObject, FGMMapsApi { ) return nil } - let location = FGMGetCoordinateForPigeonLatLng(latLng) + let location = coordinate(from: latLng) let point = mapView.projection.point(for: location) - return FGMGetPigeonPointForCGPoint(point) + return pigeonPoint(from: point) } func visibleMapRegion(_ error: AutoreleasingUnsafeMutablePointer) @@ -685,14 +684,14 @@ class MapCallHandler: NSObject, FGMMapsApi { } let visibleRegion = mapView.projection.visibleRegion() let bounds = GMSCoordinateBounds(region: visibleRegion) - return FGMGetPigeonLatLngBoundsForCoordinateBounds(bounds) + return pigeonLatLngBounds(from: bounds) } func moveCamera( with cameraUpdate: FGMPlatformCameraUpdate, error: AutoreleasingUnsafeMutablePointer ) { - guard let update = FGMGetCameraUpdateForPigeonCameraUpdate(cameraUpdate) else { + guard let update = cameraUpdate(from: cameraUpdate) else { error.pointee = FlutterError( code: "Invalid update", message: "Unrecognized camera update", @@ -707,7 +706,7 @@ class MapCallHandler: NSObject, FGMMapsApi { with cameraUpdate: FGMPlatformCameraUpdate, duration durationMilliseconds: NSNumber?, error: AutoreleasingUnsafeMutablePointer ) { - guard let update = FGMGetCameraUpdateForPigeonCameraUpdate(cameraUpdate) else { + guard let update = cameraUpdate(from: cameraUpdate) else { error.pointee = FlutterError( code: "Invalid update", message: "Unrecognized camera update", @@ -935,6 +934,6 @@ class MapInspector: NSObject, FGMMapsInspectorApi { guard let mapView = controller?.mapView else { return nil } - return FGMGetPigeonCameraPositionForPosition(mapView.camera) + return pigeonCameraPosition(from: mapView.camera) } } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GroundOverlayController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GroundOverlayController.swift index 6b6d66bddf6..f5511ff7556 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GroundOverlayController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GroundOverlayController.swift @@ -220,11 +220,11 @@ class GroundOverlaysController: NSObject { guard let controller = groundOverlayControllerByIdentifier[identifier] else { return nil } - return FGMGetPigeonGroundOverlay( - controller.groundOverlay, - identifier, - controller.createdWithBounds, - controller.zoomLevel + return pigeonGroundOverlay( + from: controller.groundOverlay, + overlayId: identifier, + isCreatedWithBounds: controller.createdWithBounds, + zoomLevel: controller.zoomLevel ) } } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift index 819ff537d89..1f5deebdbc7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift @@ -39,9 +39,9 @@ class HeatmapController: NSObject { from platformHeatmap: FGMPlatformHeatmap, mapView: GMSMapView ) { - heatmapTileLayer.weightedData = FGMGetWeightedDataForPigeonWeightedData(platformHeatmap.data) - if let gradient = platformHeatmap.gradient { - heatmapTileLayer.gradient = FGMGetGradientForPigeonHeatmapGradient(gradient) + heatmapTileLayer.weightedData = weightedData(from: platformHeatmap.data) + if let gradientValue = platformHeatmap.gradient { + heatmapTileLayer.gradient = gradient(from: gradientValue) } heatmapTileLayer.opacity = Float(platformHeatmap.opacity) heatmapTileLayer.radius = UInt(platformHeatmap.radius) @@ -104,8 +104,8 @@ class HeatmapsController: NSObject { let heatmap = controller.heatmapTileLayer return FGMPlatformHeatmap.make( withHeatmapId: identifier, - data: FGMGetPigeonWeightedDataForWeightedData(heatmap.weightedData), - gradient: FGMGetPigeonHeatmapGradientForGradient(heatmap.gradient), + data: pigeonWeightedData(from: heatmap.weightedData), + gradient: pigeonHeatmapGradient(from: heatmap.gradient), opacity: Double(heatmap.opacity), radius: Int(heatmap.radius), minimumZoomIntensity: Int(heatmap.minimumZoomIntensity), diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/MarkerController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/MarkerController.swift index 417023190c3..1fb7c4b586e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/MarkerController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/MarkerController.swift @@ -82,25 +82,24 @@ class MarkerController: NSObject { screenScale: CGFloat, usingOpacityForVisibility useOpacityForVisibility: Bool ) { - marker.groundAnchor = FGMGetCGPointForPigeonPoint(platformMarker.anchor) + marker.groundAnchor = point(from: platformMarker.anchor ?? FGMPlatformPoint.makeWith(x: 0, y: 0)) marker.isDraggable = platformMarker.draggable marker.icon = FGMIconFromBitmap(platformMarker.icon, assetProvider, screenScale) marker.isFlat = platformMarker.flat - marker.position = FGMGetCoordinateForPigeonLatLng(platformMarker.position) + marker.position = coordinate(from: platformMarker.position) marker.rotation = platformMarker.rotation marker.zIndex = Int32(platformMarker.zIndex) let infoWindow = platformMarker.infoWindow - marker.infoWindowAnchor = FGMGetCGPointForPigeonPoint(infoWindow.anchor) + marker.infoWindowAnchor = point(from: infoWindow.anchor ?? FGMPlatformPoint.makeWith(x: 0, y: 0)) if let title = infoWindow.title { marker.title = title marker.snippet = infoWindow.snippet } if let advancedMarker = marker as? GMSAdvancedMarker, - let collisionBehavior = platformMarker.collisionBehavior + let collisionBehaviorValue = platformMarker.collisionBehavior { - advancedMarker.collisionBehavior = FGMGetCollisionBehaviorForPigeonCollisionBehavior( - collisionBehavior.value) + advancedMarker.collisionBehavior = collisionBehavior(from: collisionBehaviorValue.value) } // This must be done last, to avoid visual flickers of default property values. @@ -145,7 +144,7 @@ class MarkersController: NSObject { private func addMarker(_ markerToAdd: FGMPlatformMarker) { guard let mapView = mapView else { return } - let position = FGMGetCoordinateForPigeonLatLng(markerToAdd.position) + let position = coordinate(from: markerToAdd.position) let markerIdentifier = markerToAdd.markerId let clusterManagerIdentifier = markerToAdd.clusterManagerId @@ -229,7 +228,7 @@ class MarkersController: NSObject { guard markerIdentifierToController[identifier] != nil else { return } eventDelegate?.didStartDragForMarker( withIdentifier: identifier, - atPosition: FGMGetPigeonLatLngForCoordinate(location) + atPosition: pigeonLatLng(from: location) ) } @@ -237,7 +236,7 @@ class MarkersController: NSObject { guard markerIdentifierToController[identifier] != nil else { return } eventDelegate?.didDragMarker( withIdentifier: identifier, - atPosition: FGMGetPigeonLatLngForCoordinate(location) + atPosition: pigeonLatLng(from: location) ) } @@ -245,7 +244,7 @@ class MarkersController: NSObject { guard markerIdentifierToController[identifier] != nil else { return } eventDelegate?.didEndDragForMarker( withIdentifier: identifier, - atPosition: FGMGetPigeonLatLngForCoordinate(location) + atPosition: pigeonLatLng(from: location) ) } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolygonController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolygonController.swift index 36ba6c91091..501044bb6b1 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolygonController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolygonController.swift @@ -41,12 +41,10 @@ class PolygonController: NSObject { ) { polygon.isTappable = platformPolygon.consumesTapEvents polygon.zIndex = Int32(platformPolygon.zIndex) - polygon.path = FGMGetPathFromPoints(FGMGetPointsForPigeonLatLngs(platformPolygon.points)) - polygon.holes = FGMGetHolesForPigeonLatLngArrays(platformPolygon.holes).map { - FGMGetPathFromPoints($0) - } - polygon.fillColor = FGMGetColorForPigeonColor(platformPolygon.fillColor) - polygon.strokeColor = FGMGetColorForPigeonColor(platformPolygon.strokeColor) + polygon.path = path(from: points(from: platformPolygon.points)) + polygon.holes = holes(from: platformPolygon.holes).map { path(from: $0) } + polygon.fillColor = color(from: platformPolygon.fillColor) + polygon.strokeColor = color(from: platformPolygon.strokeColor) polygon.strokeWidth = CGFloat(platformPolygon.strokeWidth) // This must be done last, to avoid visual flickers of default property values. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolylineController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolylineController.swift index dda82e6c703..132203f6773 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolylineController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolylineController.swift @@ -41,16 +41,16 @@ class PolylineController: NSObject { ) { polyline.isTappable = platformPolyline.consumesTapEvents polyline.zIndex = Int32(platformPolyline.zIndex) - let path = FGMGetPathFromPoints(FGMGetPointsForPigeonLatLngs(platformPolyline.points)) - polyline.path = path - let strokeColor = FGMGetColorForPigeonColor(platformPolyline.color) + let gmsPath = path(from: points(from: platformPolyline.points)) + polyline.path = gmsPath + let strokeColor = color(from: platformPolyline.color) polyline.strokeColor = strokeColor polyline.strokeWidth = CGFloat(platformPolyline.width) polyline.geodesic = platformPolyline.geodesic polyline.spans = GMSStyleSpans( - path, - FGMGetStrokeStylesFromPatterns(platformPolyline.patterns, strokeColor), - FGMGetSpanLengthsFromPatterns(platformPolyline.patterns), + gmsPath, + strokeStyles(from: platformPolyline.patterns ?? [], strokeColor: strokeColor), + spanLengths(from: platformPolyline.patterns ?? []), .rhumb ) From 35ad51ab56a28f83df31b608920951e7610c22c7 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Thu, 30 Jul 2026 16:10:52 -0400 Subject: [PATCH 04/17] Manual cleanup (conversion utils) --- .../ConversionUtils.swift | 32 +- .../GoogleMapController.swift | 6 +- .../FGMConversionUtils.m | 275 ------------------ .../FGMConversionUtils.h | 93 ------ 4 files changed, 19 insertions(+), 387 deletions(-) delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/FGMConversionUtils.m delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/include/google_maps_flutter_ios_sdk9_objc/FGMConversionUtils.h diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift index dd893632dec..25e0a91f291 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift @@ -52,15 +52,15 @@ func pigeonCameraPosition(from position: GMSCameraPosition) -> FGMPlatformCamera withBearing: position.bearing, target: pigeonLatLng(from: position.target), tilt: position.viewingAngle, - zoom: position.zoom + zoom: Double(position.zoom) ) } /// Creates a GMSCameraPosition from its Pigeon representation. -func cameraPosition(from position: FGMPlatformCameraPosition) -> GMSCameraPosition { +func gmsCameraPosition(from position: FGMPlatformCameraPosition) -> GMSCameraPosition { return GMSCameraPosition( target: coordinate(from: position.target), - zoom: position.zoom, + zoom: Float(position.zoom), bearing: position.bearing, viewingAngle: position.tilt ) @@ -126,25 +126,25 @@ func pigeonGroundOverlay( ) -> FGMPlatformGroundOverlay { let placeholderImage = FGMPlatformBitmap.make( withBitmap: FGMPlatformBitmapDefaultMarker.make(withHue: 0)) - if isCreatedWithBounds { + if isCreatedWithBounds, let bounds = groundOverlay.bounds { return FGMPlatformGroundOverlay.make( withGroundOverlayId: overlayId, image: placeholderImage, position: nil, bounds: FGMPlatformLatLngBounds.make( withNortheast: FGMPlatformLatLng.make( - withLatitude: groundOverlay.bounds.northEast.latitude, - longitude: groundOverlay.bounds.northEast.longitude + withLatitude: bounds.northEast.latitude, + longitude: bounds.northEast.longitude ), southwest: FGMPlatformLatLng.make( - withLatitude: groundOverlay.bounds.southWest.latitude, - longitude: groundOverlay.bounds.southWest.longitude + withLatitude: bounds.southWest.latitude, + longitude: bounds.southWest.longitude ) ), anchor: FGMPlatformPoint.makeWith(x: groundOverlay.anchor.x, y: groundOverlay.anchor.y), transparency: 1.0 - Double(groundOverlay.opacity), bearing: groundOverlay.bearing, - zIndex: Double(groundOverlay.zIndex), + zIndex: Int(groundOverlay.zIndex), visible: groundOverlay.map != nil, clickable: groundOverlay.isTappable, zoomLevel: zoomLevel @@ -161,7 +161,7 @@ func pigeonGroundOverlay( anchor: FGMPlatformPoint.makeWith(x: groundOverlay.anchor.x, y: groundOverlay.anchor.y), transparency: 1.0 - Double(groundOverlay.opacity), bearing: groundOverlay.bearing, - zIndex: Double(groundOverlay.zIndex), + zIndex: Int(groundOverlay.zIndex), visible: groundOverlay.map != nil, clickable: groundOverlay.isTappable, zoomLevel: zoomLevel @@ -175,7 +175,7 @@ func gradient(from heatmapGradient: FGMPlatformHeatmapGradient) -> GMUGradient { return GMUGradient( colors: colors, startPoints: heatmapGradient.startPoints, - colorMapSize: heatmapGradient.colorMapSize + colorMapSize: UInt(heatmapGradient.colorMapSize) ) } @@ -183,9 +183,9 @@ func gradient(from heatmapGradient: FGMPlatformHeatmapGradient) -> GMUGradient { func pigeonHeatmapGradient(from gradient: GMUGradient) -> FGMPlatformHeatmapGradient { let colors = gradient.colors.map { pigeonColor(from: $0) } return FGMPlatformHeatmapGradient.make( - withColors: colors, + with: colors, startPoints: gradient.startPoints, - colorMapSize: gradient.mapSize + colorMapSize: Int(gradient.mapSize) ) } @@ -202,7 +202,7 @@ func weightedData(from weightedLatLngs: [FGMPlatformWeightedLatLng]) -> [GMUWeig /// Converts a GMUWeightedLatLng array to its Pigeon equivalent. func pigeonWeightedData(from weightedLatLngs: [GMUWeightedLatLng]) -> [FGMPlatformWeightedLatLng] { return weightedLatLngs.map { - let point = GMSMapPoint(x: $0.point.x, y: $0.point.y) + let point = GMSMapPoint(x: $0.point().x, y: $0.point().y) return FGMPlatformWeightedLatLng.make( withPoint: pigeonLatLng(from: GMSUnproject(point)), weight: Double($0.intensity) @@ -211,11 +211,11 @@ func pigeonWeightedData(from weightedLatLngs: [GMUWeightedLatLng]) -> [FGMPlatfo } /// Creates a GMSCameraUpdate from its Pigeon equivalent. -func cameraUpdate(from cameraUpdate: FGMPlatformCameraUpdate) -> GMSCameraUpdate? { +func gmsCameraUpdate(from cameraUpdate: FGMPlatformCameraUpdate) -> GMSCameraUpdate? { // See note in messages.dart for why this is so loosely typed. let update = cameraUpdate.cameraUpdate if let newCameraPosition = update as? FGMPlatformCameraUpdateNewCameraPosition { - return GMSCameraUpdate.setCamera(cameraPosition(from: newCameraPosition.cameraPosition)) + return GMSCameraUpdate.setCamera(gmsCameraPosition(from: newCameraPosition.cameraPosition)) } else if let newLatLng = update as? FGMPlatformCameraUpdateNewLatLng { return GMSCameraUpdate.setTarget(coordinate(from: newLatLng.latLng)) } else if let newLatLngBounds = update as? FGMPlatformCameraUpdateNewLatLngBounds { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift index b86ccecde6c..d239ceb8fcc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift @@ -146,7 +146,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV creationParameters: FGMPlatformMapViewCreationParams, registrar: FlutterPluginRegistrar ) { - let camera = cameraPosition(from: creationParameters.initialCameraPosition) + let camera = gmsCameraPosition(from: creationParameters.initialCameraPosition) let options = GMSMapViewOptions() options.frame = frame @@ -691,7 +691,7 @@ class MapCallHandler: NSObject, FGMMapsApi { with cameraUpdate: FGMPlatformCameraUpdate, error: AutoreleasingUnsafeMutablePointer ) { - guard let update = cameraUpdate(from: cameraUpdate) else { + guard let update = gmsCameraUpdate(from: cameraUpdate) else { error.pointee = FlutterError( code: "Invalid update", message: "Unrecognized camera update", @@ -706,7 +706,7 @@ class MapCallHandler: NSObject, FGMMapsApi { with cameraUpdate: FGMPlatformCameraUpdate, duration durationMilliseconds: NSNumber?, error: AutoreleasingUnsafeMutablePointer ) { - guard let update = cameraUpdate(from: cameraUpdate) else { + guard let update = gmsCameraUpdate(from: cameraUpdate) else { error.pointee = FlutterError( code: "Invalid update", message: "Unrecognized camera update", diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/FGMConversionUtils.m b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/FGMConversionUtils.m deleted file mode 100644 index 219d8df44a1..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/FGMConversionUtils.m +++ /dev/null @@ -1,275 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "FGMConversionUtils.h" - -CGPoint FGMGetCGPointForPigeonPoint(FGMPlatformPoint *point) { - return CGPointMake(point.x, point.y); -} - -FGMPlatformPoint *FGMGetPigeonPointForCGPoint(CGPoint point) { - return [FGMPlatformPoint makeWithX:point.x y:point.y]; -} - -CLLocationCoordinate2D FGMGetCoordinateForPigeonLatLng(FGMPlatformLatLng *latLng) { - return CLLocationCoordinate2DMake(latLng.latitude, latLng.longitude); -} - -FGMPlatformLatLng *FGMGetPigeonLatLngForCoordinate(CLLocationCoordinate2D coord) { - 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) - southwest:FGMGetPigeonLatLngForCoordinate(bounds.southWest)]; -} - -FGMPlatformCameraPosition *FGMGetPigeonCameraPositionForPosition(GMSCameraPosition *position) { - return [FGMPlatformCameraPosition makeWithBearing:position.bearing - target:FGMGetPigeonLatLngForCoordinate(position.target) - tilt:position.viewingAngle - zoom:position.zoom]; -} - -GMSCameraPosition *FGMGetCameraPositionForPigeonCameraPosition( - FGMPlatformCameraPosition *position) { - return [GMSCameraPosition cameraWithTarget:FGMGetCoordinateForPigeonLatLng(position.target) - zoom:position.zoom - bearing:position.bearing - viewingAngle:position.tilt]; -} - -NSArray *FGMGetPointsForPigeonLatLngs(NSArray *pigeonPoints) { - NSMutableArray *points = [[NSMutableArray alloc] initWithCapacity:pigeonPoints.count]; - for (FGMPlatformLatLng *point in pigeonPoints) { - [points addObject:[[CLLocation alloc] initWithLatitude:point.latitude - longitude:point.longitude]]; - } - return points; -} - -NSArray *> *FGMGetHolesForPigeonLatLngArrays( - NSArray *> *pigeonHolePoints) { - NSMutableArray *> *holes = - [[NSMutableArray alloc] initWithCapacity:pigeonHolePoints.count]; - for (NSArray *holePoints in pigeonHolePoints) { - [holes addObject:FGMGetPointsForPigeonLatLngs(holePoints)]; - } - return holes; -} - -GMSMutablePath *FGMGetPathFromPoints(NSArray *points) { - GMSMutablePath *path = [GMSMutablePath path]; - for (CLLocation *location in points) { - [path addCoordinate:location.coordinate]; - } - return path; -} - -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; - } -} - -GMSCollisionBehavior FGMGetCollisionBehaviorForPigeonCollisionBehavior( - FGMPlatformMarkerCollisionBehavior collisionBehavior) { - switch (collisionBehavior) { - case FGMPlatformMarkerCollisionBehaviorRequiredDisplay: - return GMSCollisionBehaviorRequired; - case FGMPlatformMarkerCollisionBehaviorOptionalAndHidesLowerPriority: - return GMSCollisionBehaviorOptionalAndHidesLowerPriority; - case FGMPlatformMarkerCollisionBehaviorRequiredAndHidesOptional: - return GMSCollisionBehaviorRequiredAndHidesOptional; - } -} - -FGMPlatformGroundOverlay *FGMGetPigeonGroundOverlay(GMSGroundOverlay *groundOverlay, - NSString *overlayId, BOOL isCreatedWithBounds, - NSNumber *zoomLevel) { - // Image is mandatory field on FGMPlatformGroundOverlay (and it should be kept - // non-nullable), therefore image must be set for the object. The image is - // description either contains set of bytes, or path to asset. This info is - // converted to format google maps uses (BitmapDescription), and the original - // data is not stored on native code. Therefore placeholder image is used for - // the image field. - FGMPlatformBitmap *placeholderImage = - [FGMPlatformBitmap makeWithBitmap:[FGMPlatformBitmapDefaultMarker makeWithHue:0]]; - if (isCreatedWithBounds) { - return [FGMPlatformGroundOverlay - makeWithGroundOverlayId:overlayId - image:placeholderImage - position:nil - bounds:[FGMPlatformLatLngBounds - makeWithNortheast:[FGMPlatformLatLng - makeWithLatitude:groundOverlay.bounds - .northEast.latitude - longitude:groundOverlay.bounds - .northEast.longitude] - southwest:[FGMPlatformLatLng - makeWithLatitude:groundOverlay.bounds - .southWest.latitude - longitude:groundOverlay.bounds - .southWest - .longitude]] - anchor:[FGMPlatformPoint makeWithX:groundOverlay.anchor.x - y:groundOverlay.anchor.y] - transparency:1.0f - groundOverlay.opacity - bearing:groundOverlay.bearing - zIndex:groundOverlay.zIndex - visible:groundOverlay.map != nil - clickable:groundOverlay.isTappable - zoomLevel:zoomLevel]; - } else { - return [FGMPlatformGroundOverlay - makeWithGroundOverlayId:overlayId - image:placeholderImage - position:[FGMPlatformLatLng - makeWithLatitude:groundOverlay.position.latitude - longitude:groundOverlay.position.longitude] - bounds:nil - anchor:[FGMPlatformPoint makeWithX:groundOverlay.anchor.x - y:groundOverlay.anchor.y] - transparency:1.0f - groundOverlay.opacity - bearing:groundOverlay.bearing - zIndex:groundOverlay.zIndex - visible:groundOverlay.map != nil - clickable:groundOverlay.isTappable - zoomLevel:zoomLevel]; - } -} - -GMUGradient *FGMGetGradientForPigeonHeatmapGradient(FGMPlatformHeatmapGradient *gradient) { - NSMutableArray *colors = [[NSMutableArray alloc] initWithCapacity:gradient.colors.count]; - for (FGMPlatformColor *color in gradient.colors) { - [colors addObject:FGMGetColorForPigeonColor(color)]; - } - return [[GMUGradient alloc] initWithColors:colors - startPoints:gradient.startPoints - colorMapSize:gradient.colorMapSize]; -} - -FGMPlatformHeatmapGradient *FGMGetPigeonHeatmapGradientForGradient(GMUGradient *gradient) { - NSMutableArray *colors = [[NSMutableArray alloc] initWithCapacity:gradient.colors.count]; - for (UIColor *color in gradient.colors) { - [colors addObject:FGMGetPigeonColorForColor(color)]; - } - return [FGMPlatformHeatmapGradient makeWithColors:colors - startPoints:gradient.startPoints - colorMapSize:gradient.mapSize]; -} - -NSArray *FGMGetWeightedDataForPigeonWeightedData( - NSArray *weightedLatLngs) { - NSMutableArray *weightedData = [[NSMutableArray alloc] initWithCapacity:weightedLatLngs.count]; - for (FGMPlatformWeightedLatLng *weightedLatLng in weightedLatLngs) { - [weightedData - addObject:[[GMUWeightedLatLng alloc] - initWithCoordinate:FGMGetCoordinateForPigeonLatLng(weightedLatLng.point) - intensity:weightedLatLng.weight]]; - } - return weightedData; -} - -NSArray *FGMGetPigeonWeightedDataForWeightedData( - NSArray *weightedLatLngs) { - NSMutableArray *weightedData = [[NSMutableArray alloc] initWithCapacity:weightedLatLngs.count]; - for (GMUWeightedLatLng *weightedLatLng in weightedLatLngs) { - GMSMapPoint point = {weightedLatLng.point.x, weightedLatLng.point.y}; - [weightedData addObject:[FGMPlatformWeightedLatLng - makeWithPoint:FGMGetPigeonLatLngForCoordinate(GMSUnproject(point)) - weight:weightedLatLng.intensity]]; - } - return weightedData; -} - -GMSCameraUpdate *FGMGetCameraUpdateForPigeonCameraUpdate(FGMPlatformCameraUpdate *cameraUpdate) { - // See note in messages.dart for why this is so loosely typed. - id update = cameraUpdate.cameraUpdate; - if ([update isKindOfClass:[FGMPlatformCameraUpdateNewCameraPosition class]]) { - return [GMSCameraUpdate - setCamera:FGMGetCameraPositionForPigeonCameraPosition( - ((FGMPlatformCameraUpdateNewCameraPosition *)update).cameraPosition)]; - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateNewLatLng class]]) { - return [GMSCameraUpdate setTarget:FGMGetCoordinateForPigeonLatLng( - ((FGMPlatformCameraUpdateNewLatLng *)update).latLng)]; - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateNewLatLngBounds class]]) { - FGMPlatformCameraUpdateNewLatLngBounds *typedUpdate = - (FGMPlatformCameraUpdateNewLatLngBounds *)update; - return - [GMSCameraUpdate fitBounds:FGMGetCoordinateBoundsForPigeonLatLngBounds(typedUpdate.bounds) - withPadding:typedUpdate.padding]; - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateNewLatLngZoom class]]) { - FGMPlatformCameraUpdateNewLatLngZoom *typedUpdate = - (FGMPlatformCameraUpdateNewLatLngZoom *)update; - return [GMSCameraUpdate setTarget:FGMGetCoordinateForPigeonLatLng(typedUpdate.latLng) - zoom:typedUpdate.zoom]; - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateScrollBy class]]) { - FGMPlatformCameraUpdateScrollBy *typedUpdate = (FGMPlatformCameraUpdateScrollBy *)update; - return [GMSCameraUpdate scrollByX:typedUpdate.dx Y:typedUpdate.dy]; - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateZoomBy class]]) { - FGMPlatformCameraUpdateZoomBy *typedUpdate = (FGMPlatformCameraUpdateZoomBy *)update; - if (typedUpdate.focus) { - return [GMSCameraUpdate zoomBy:typedUpdate.amount - atPoint:FGMGetCGPointForPigeonPoint(typedUpdate.focus)]; - } else { - return [GMSCameraUpdate zoomBy:typedUpdate.amount]; - } - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateZoom class]]) { - if (((FGMPlatformCameraUpdateZoom *)update).out) { - return [GMSCameraUpdate zoomOut]; - } else { - return [GMSCameraUpdate zoomIn]; - } - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateZoomTo class]]) { - return [GMSCameraUpdate zoomTo:((FGMPlatformCameraUpdateZoomTo *)update).zoom]; - } - return nil; -} - -UIColor *FGMGetColorForPigeonColor(FGMPlatformColor *color) { - return [UIColor colorWithRed:color.red green:color.green blue:color.blue alpha:color.alpha]; -} - -FGMPlatformColor *FGMGetPigeonColorForColor(UIColor *color) { - double red, green, blue, alpha; - [color getRed:&red green:&green blue:&blue alpha:&alpha]; - return [FGMPlatformColor makeWithRed:red green:green blue:blue alpha:alpha]; -} - -NSArray *FGMGetStrokeStylesFromPatterns( - NSArray *patterns, UIColor *strokeColor) { - NSMutableArray *strokeStyles = [[NSMutableArray alloc] initWithCapacity:[patterns count]]; - for (FGMPlatformPatternItem *pattern in patterns) { - UIColor *color = - pattern.type == FGMPlatformPatternItemTypeGap ? UIColor.clearColor : strokeColor; - [strokeStyles addObject:[GMSStrokeStyle solidColor:color]]; - } - return strokeStyles; -} - -NSArray *FGMGetSpanLengthsFromPatterns(NSArray *patterns) { - NSMutableArray *lengths = [[NSMutableArray alloc] initWithCapacity:[patterns count]]; - for (FGMPlatformPatternItem *pattern in patterns) { - NSNumber *length = pattern.length ?: @0; - [lengths addObject:length]; - } - return lengths; -} diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/include/google_maps_flutter_ios_sdk9_objc/FGMConversionUtils.h b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/include/google_maps_flutter_ios_sdk9_objc/FGMConversionUtils.h deleted file mode 100644 index b7344e6b492..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/include/google_maps_flutter_ios_sdk9_objc/FGMConversionUtils.h +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -@import Foundation; -@import GoogleMaps; - -#import "GoogleMapsUtilsTrampoline.h" -#import "google_maps_flutter_pigeon_messages.g.h" - -NS_ASSUME_NONNULL_BEGIN - -/// Creates a CGPoint from its Pigeon equivalent. -extern CGPoint FGMGetCGPointForPigeonPoint(FGMPlatformPoint *point); - -/// Converts a CGPoint to its Pigeon equivalent. -extern FGMPlatformPoint *FGMGetPigeonPointForCGPoint(CGPoint point); - -/// Creates a CLLocationCoordinate2D from its Pigeon representation. -extern CLLocationCoordinate2D FGMGetCoordinateForPigeonLatLng(FGMPlatformLatLng *latLng); - -/// 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); - -/// Converts a GMSCameraPosition to its Pigeon representation. -extern FGMPlatformCameraPosition *FGMGetPigeonCameraPositionForPosition( - GMSCameraPosition *position); - -/// Creates a GMSCameraPosition from its Pigeon representation. -extern GMSCameraPosition *FGMGetCameraPositionForPigeonCameraPosition( - FGMPlatformCameraPosition *position); - -/// Creates a CLLocation array from its Pigeon equivalent. -extern NSArray *FGMGetPointsForPigeonLatLngs(NSArray *points); - -/// Creates a CLLocation arary array, representing a set of holes, from its Pigeon equivalent. -extern NSArray *> *FGMGetHolesForPigeonLatLngArrays( - NSArray *> *points); - -extern GMSMutablePath *FGMGetPathFromPoints(NSArray *points); - -/// Creates a GMSMapViewType from its Pigeon representation. -extern GMSMapViewType FGMGetMapViewTypeForPigeonMapType(FGMPlatformMapType type); - -/// Creates a GMSCollisionBehavior from its Pigeon representation. -extern GMSCollisionBehavior FGMGetCollisionBehaviorForPigeonCollisionBehavior( - FGMPlatformMarkerCollisionBehavior collisionBehavior); - -/// Converts a GMSGroundOverlay to its Pigeon representation. -extern FGMPlatformGroundOverlay *FGMGetPigeonGroundOverlay(GMSGroundOverlay *groundOverlay, - NSString *overlayId, - BOOL isCreatedWithBounds, - NSNumber *_Nullable zoomLevel); - -extern GMUGradient *FGMGetGradientForPigeonHeatmapGradient(FGMPlatformHeatmapGradient *gradient); - -extern FGMPlatformHeatmapGradient *FGMGetPigeonHeatmapGradientForGradient(GMUGradient *gradient); - -/// Creates a GMUWeightedLatLng array from its Pigeon equivalent. -extern NSArray *FGMGetWeightedDataForPigeonWeightedData( - NSArray *weightedLatLngs); - -/// Converts a GMUWeightedLatLng array to its Pigeon equivalent. -extern NSArray *FGMGetPigeonWeightedDataForWeightedData( - NSArray *weightedLatLngs); - -/// Creates a GMSCameraUpdate from its Pigeon equivalent. -extern GMSCameraUpdate *_Nullable FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate *update); - -/// Creates a UIColor from its Pigeon representation. -extern UIColor *FGMGetColorForPigeonColor(FGMPlatformColor *color); - -/// Converts a UIColor to its Pigeon representation. -extern FGMPlatformColor *FGMGetPigeonColorForColor(UIColor *color); - -/// Creates an array of GMSStrokeStyles using the given patterns and stroke color. -extern NSArray *FGMGetStrokeStylesFromPatterns( - NSArray *patterns, UIColor *strokeColor); - -/// Creates an array of span lengths using the given patterns. -extern NSArray *FGMGetSpanLengthsFromPatterns( - NSArray *patterns); - -NS_ASSUME_NONNULL_END From 3559feeecfdd011c2e7fc0ceb9b6dbd553501270 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Thu, 30 Jul 2026 16:17:17 -0400 Subject: [PATCH 05/17] Initial conversion (image utils) --- .../GroundOverlayController.swift | 2 +- .../ImageUtils.swift | 222 ++++++++++++++++++ .../MarkerController.swift | 2 +- 3 files changed, 224 insertions(+), 2 deletions(-) create mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GroundOverlayController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GroundOverlayController.swift index f5511ff7556..f2384d70715 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GroundOverlayController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GroundOverlayController.swift @@ -66,7 +66,7 @@ class GroundOverlayController: NSObject { if let anchor = platformGroundOverlay.anchor { groundOverlay.anchor = CGPoint(x: anchor.x, y: anchor.y) } - groundOverlay.icon = FGMIconFromBitmap(platformGroundOverlay.image, assetProvider, screenScale) + groundOverlay.icon = icon(from: platformGroundOverlay.image, assetProvider: assetProvider, screenScale: screenScale) groundOverlay.bearing = platformGroundOverlay.bearing groundOverlay.opacity = Float(1.0 - platformGroundOverlay.transparency) if useBounds { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift new file mode 100644 index 00000000000..e51d8fc2627 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift @@ -0,0 +1,222 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import Flutter +import GoogleMaps +import UIKit + +#if canImport(google_maps_flutter_ios_sdk9_objc) + import google_maps_flutter_ios_sdk9_objc +#endif + +/// Creates a UIImage from a Pigeon bitmap representation. +func makeIcon( + from platformBitmap: FGMPlatformBitmap?, + assetProvider: FGMAssetProvider, + screenScale: CGFloat +) -> UIImage? { + assert(screenScale > 0, "Screen scale must be greater than 0") + + guard let platformBitmap = platformBitmap else { + return nil + } + + let bitmap = platformBitmap.bitmap + var image: UIImage? + + if let bitmapDefaultMarker = bitmap as? FGMPlatformBitmapDefaultMarker { + let hue = bitmapDefaultMarker.hue.doubleValue + image = GMSMarker.markerImage(with: UIColor(hue: CGFloat(hue) / 360.0, + saturation: 1.0, + brightness: 0.7, + alpha: 1.0)) + } else if let bitmapAsset = bitmap as? FGMPlatformBitmapAsset { + // Deprecated: This message handling for 'fromAsset' has been replaced by 'asset'. + // Refer to the flutter google_maps_flutter_platform_interface package for details. + if let pkg = bitmapAsset.pkg { + if let key = assetProvider.lookupKey(forAsset: bitmapAsset.name, fromPackage: pkg) { + image = assetProvider.image(named: key) + } + } else { + if let key = assetProvider.lookupKey(forAsset: bitmapAsset.name) { + image = assetProvider.image(named: key) + } + } + } else if let bitmapAssetImage = bitmap as? FGMPlatformBitmapAssetImage { + // Deprecated: This message handling for 'fromAssetImage' has been replaced by 'asset'. + // Refer to the flutter google_maps_flutter_platform_interface package for details. + if let key = assetProvider.lookupKey(forAsset: bitmapAssetImage.name) { + if let assetImage = assetProvider.image(named: key) { + image = scaledImage(assetImage, scale: bitmapAssetImage.scale.doubleValue) + } + } + } else if let bitmapBytes = bitmap as? FGMPlatformBitmapBytes { + // Deprecated: This message handling for 'fromBytes' has been replaced by 'bytes'. + // Refer to the flutter google_maps_flutter_platform_interface package for details. + image = UIImage(data: bitmapBytes.byteData.data, scale: screenScale) + } else if let bitmapAssetMap = bitmap as? FGMPlatformBitmapAssetMap { + if let key = assetProvider.lookupKey(forAsset: bitmapAssetMap.assetName) { + image = assetProvider.image(named: key) + } + if let currentImage = image, bitmapAssetMap.bitmapScaling == .auto { + let width = bitmapAssetMap.width + let height = bitmapAssetMap.height + if width != nil || height != nil { + let tempImage = scaledImage(currentImage, scale: screenScale) + image = scaledImage(tempImage, width: width, height: height, screenScale: screenScale) + } else { + image = scaledImage(currentImage, scale: CGFloat(bitmapAssetMap.imagePixelRatio.doubleValue)) + } + } + } else if let bitmapBytesMap = bitmap as? FGMPlatformBitmapBytesMap { + let bytes = bitmapBytesMap.byteData + image = UIImage(data: bytes.data, scale: screenScale) + if let currentImage = image { + if bitmapBytesMap.bitmapScaling == .auto { + let width = bitmapBytesMap.width + let height = bitmapBytesMap.height + if width != nil || height != nil { + let tempImage = scaledImage(currentImage, scale: screenScale) + image = scaledImage(tempImage, width: width, height: height, screenScale: screenScale) + } else { + image = scaledImage(currentImage, scale: CGFloat(bitmapBytesMap.imagePixelRatio.doubleValue)) + } + } + } + } else if let pinConfig = bitmap as? FGMPlatformBitmapPinConfig { + let options = GMSPinImageOptions() + if let backgroundColor = pinConfig.backgroundColor { + options.backgroundColor = color(from: backgroundColor) + } + if let borderColor = pinConfig.borderColor { + options.borderColor = color(from: borderColor) + } + + var glyph: GMSPinImageGlyph? + if let glyphText = pinConfig.glyphText { + let glyphTextColor: UIColor + if let textColor = pinConfig.glyphTextColor { + glyphTextColor = color(from: textColor) + } else { + glyphTextColor = .black + } + glyph = GMSPinImageGlyph(text: glyphText, textColor: glyphTextColor) + } else if let glyphColorValue = pinConfig.glyphColor { + glyph = GMSPinImageGlyph(glyphColor: color(from: glyphColorValue)) + } else if let glyphBitmap = pinConfig.glyphBitmap { + if let glyphImage = icon(from: glyphBitmap, assetProvider: assetProvider, screenScale: screenScale) { + glyph = GMSPinImageGlyph(image: glyphImage) + } + } + options.glyph = glyph + image = GMSPinImage.pinImage(with: options) + } + + return image +} + +/// Creates a scaled version of the provided UIImage based on a specified scale factor. +/// +/// This method is deprecated within the context of `BitmapDescriptor.fromBytes` handling in the +/// flutter google_maps_flutter_platform_interface package which has been replaced by 'bytes' +/// message handling. +private func scaledImage(_ image: UIImage, scale: Double) -> UIImage { + if abs(scale - 1.0) > 1e-3 { + if let cgImage = image.cgImage { + return UIImage( + cgImage: cgImage, + scale: image.scale * CGFloat(scale), + orientation: image.imageOrientation + ) + } + } + return image +} + +private func scaledImage(_ image: UIImage, scale: CGFloat) -> UIImage { + if abs(scale - image.scale) > .ulpOfOne { + if let cgImage = image.cgImage { + return UIImage( + cgImage: cgImage, + scale: scale, + orientation: image.imageOrientation + ) + } + } + return image +} + +private func scaledImage(_ image: UIImage, size: CGSize) -> UIImage { + let originalPixelWidth = image.size.width * image.scale + let originalPixelHeight = image.size.height * image.scale + + if originalPixelWidth <= 0 || originalPixelHeight <= 0 || size.width <= 0 || size.height <= 0 { + return image + } + + if abs(originalPixelWidth - size.width) <= .ulpOfOne && + abs(originalPixelHeight - size.height) <= .ulpOfOne { + return image + } + + let originalPixelSize = CGSize(width: originalPixelWidth, height: originalPixelHeight) + if isScalableWithScaleFactor(from: originalPixelSize, targetSize: size) { + let factor = originalPixelWidth / size.width + return scaledImage(image, scale: image.scale * factor) + } else { + let format = UIGraphicsImageRendererFormat.default() + format.scale = 1.0 + format.opaque = false + let renderer = UIGraphicsImageRenderer(size: size, format: format) + let newImage = renderer.image { _ in + image.draw(in: CGRect(origin: .zero, size: size)) + } + return scaledImage(newImage, scale: image.scale) + } +} + +private func scaledImage( + _ image: UIImage, + width: NSNumber?, + height: NSNumber?, + screenScale: CGFloat +) -> UIImage { + if width == nil && height == nil { + return image + } + + let targetWidth = width == nil ? image.size.width : CGFloat(width!.doubleValue) + let targetHeight = height == nil ? image.size.height : CGFloat(height!.doubleValue) + + var calculatedWidth = targetWidth + var calculatedHeight = targetHeight + + if width != nil && height == nil { + let aspectRatio = image.size.height / image.size.width + calculatedHeight = (targetWidth * aspectRatio).rounded() + } else if width == nil && height != nil { + let aspectRatio = image.size.width / image.size.height + calculatedWidth = (targetHeight * aspectRatio).rounded() + } + + let targetSize = CGSize( + width: (calculatedWidth * screenScale).rounded(), + height: (calculatedHeight * screenScale).rounded() + ) + return scaledImage(image, size: targetSize) +} + +func isScalableWithScaleFactor(from originalSize: CGSize, targetSize: CGSize) -> Bool { + let scaleFactor = (originalSize.width > originalSize.height) + ? (targetSize.width / originalSize.width) + : (targetSize.height / originalSize.height) + + let scaledWidth = originalSize.width * scaleFactor + let scaledHeight = originalSize.height * scaleFactor + + let widthWithinThreshold = abs(scaledWidth - targetSize.width) <= 1.0 + let heightWithinThreshold = abs(scaledHeight - targetSize.height) <= 1.0 + + return widthWithinThreshold && heightWithinThreshold +} diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/MarkerController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/MarkerController.swift index 1fb7c4b586e..39456e6c0dd 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/MarkerController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/MarkerController.swift @@ -84,7 +84,7 @@ class MarkerController: NSObject { ) { marker.groundAnchor = point(from: platformMarker.anchor ?? FGMPlatformPoint.makeWith(x: 0, y: 0)) marker.isDraggable = platformMarker.draggable - marker.icon = FGMIconFromBitmap(platformMarker.icon, assetProvider, screenScale) + marker.icon = icon(from: platformMarker.icon, assetProvider: assetProvider, screenScale: screenScale) marker.isFlat = platformMarker.flat marker.position = coordinate(from: platformMarker.position) marker.rotation = platformMarker.rotation From b7e430bdb5ddaaca7df32104948a0c10f556090b Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Mon, 3 Aug 2026 11:41:02 -0400 Subject: [PATCH 06/17] Manual fixes and adjustments, including moving conversion utils to extensions --- .../RunnerTests/CircleControllerTests.swift | 2 +- .../ClusterManagersControllerTests.swift | 2 +- .../RunnerTests/ConversionsUtilsTests.swift | 2 +- .../ExtractIconFromDataTests.swift | 2 +- .../ios/RunnerTests/GoogleMapsTests.swift | 2 +- .../GroundOverlayControllerTests.swift | 2 +- .../RunnerTests/HeatmapControllerTests.swift | 2 +- .../RunnerTests/MarkerControllerTests.swift | 2 +- .../RunnerTests/PolygonControllerTests.swift | 2 +- .../RunnerTests/PolylineControllerTests.swift | 2 +- .../TileOverlayControllerTests.swift | 2 +- .../TileProviderControllerTests.swift | 2 +- .../CircleController.swift | 6 +- .../ConversionUtils.swift | 385 ++++++++++-------- .../GoogleMapController.swift | 26 +- .../GroundOverlayController.swift | 3 +- .../ImageUtils.swift | 88 ++-- .../MarkerController.swift | 17 +- .../FGMImageUtils.m | 271 ------------ .../FGMImageUtils.h | 21 - 20 files changed, 306 insertions(+), 535 deletions(-) delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/FGMImageUtils.m delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/include/google_maps_flutter_ios_sdk9_objc/FGMImageUtils.h diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/CircleControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/CircleControllerTests.swift index bc43878be6b..b65e95836cf 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/CircleControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/CircleControllerTests.swift @@ -4,9 +4,9 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 -import google_maps_flutter_ios_sdk9_objc @MainActor struct CircleControllerTests { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ClusterManagersControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ClusterManagersControllerTests.swift index 47730e82fa7..c28a6f1f74c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ClusterManagersControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ClusterManagersControllerTests.swift @@ -5,9 +5,9 @@ import Flutter import GoogleMaps import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 -import google_maps_flutter_ios_sdk9_objc @MainActor struct ClusterManagersControllerTests { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ConversionsUtilsTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ConversionsUtilsTests.swift index e9ac2a815fa..cbc1361717c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ConversionsUtilsTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ConversionsUtilsTests.swift @@ -4,9 +4,9 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 -import google_maps_flutter_ios_sdk9_objc @MainActor struct ConversionUtilsTests { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ExtractIconFromDataTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ExtractIconFromDataTests.swift index 86e8559687e..1179c69744f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ExtractIconFromDataTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ExtractIconFromDataTests.swift @@ -4,9 +4,9 @@ import Flutter import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 -import google_maps_flutter_ios_sdk9_objc @MainActor struct ExtractIconFromDataTests { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GoogleMapsTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GoogleMapsTests.swift index 0de0c8f3aa4..5268b227e74 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GoogleMapsTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GoogleMapsTests.swift @@ -5,9 +5,9 @@ import Flutter import GoogleMaps import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 -import google_maps_flutter_ios_sdk9_objc class MockCATransaction: NSObject, FGMCATransactionProtocol { var beginCalled = false diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GroundOverlayControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GroundOverlayControllerTests.swift index 3802f288d68..0d2e80b00c5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GroundOverlayControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GroundOverlayControllerTests.swift @@ -4,9 +4,9 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 -import google_maps_flutter_ios_sdk9_objc @MainActor struct GroundOverlayControllerTests { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/HeatmapControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/HeatmapControllerTests.swift index 6aefad63ac1..bbfe98e7857 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/HeatmapControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/HeatmapControllerTests.swift @@ -5,9 +5,9 @@ import GoogleMaps import GoogleMapsUtils import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 -import google_maps_flutter_ios_sdk9_objc @MainActor struct HeatmapControllerTests { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/MarkerControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/MarkerControllerTests.swift index ff590c5ef5d..6cff56be74e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/MarkerControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/MarkerControllerTests.swift @@ -4,9 +4,9 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 -import google_maps_flutter_ios_sdk9_objc @MainActor struct MarkerControllerTests { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/PolygonControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/PolygonControllerTests.swift index 6fa25a9ff40..4ce8f46fe6e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/PolygonControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/PolygonControllerTests.swift @@ -4,9 +4,9 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 -import google_maps_flutter_ios_sdk9_objc @MainActor struct PolygonControllerTests { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/PolylineControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/PolylineControllerTests.swift index 7803521c4a7..6012e3d9d6e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/PolylineControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/PolylineControllerTests.swift @@ -4,9 +4,9 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 -import google_maps_flutter_ios_sdk9_objc @MainActor struct PolylineControllerTests { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TileOverlayControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TileOverlayControllerTests.swift index 9dc2bdc1af1..2f44cbfb166 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TileOverlayControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TileOverlayControllerTests.swift @@ -4,9 +4,9 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 -import google_maps_flutter_ios_sdk9_objc @MainActor struct TileOverlayControllerTests { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TileProviderControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TileProviderControllerTests.swift index fba68a5ce81..d17866f837a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TileProviderControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/TileProviderControllerTests.swift @@ -5,9 +5,9 @@ import Flutter import GoogleMaps import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 -import google_maps_flutter_ios_sdk9_objc class StubTileReceiver: NSObject, GMSTileReceiver { func receiveTileWith(x: UInt, y: UInt, zoom: UInt, image: UIImage?) { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/CircleController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/CircleController.swift index 9ae3d34e36f..67dd76b8016 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/CircleController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/CircleController.swift @@ -42,11 +42,11 @@ class CircleController: NSObject { ) { circle.isTappable = platformCircle.consumeTapEvents circle.zIndex = Int32(platformCircle.zIndex) - circle.position = coordinate(from: platformCircle.center) + circle.position = platformCircle.center.toCLCoordinate() circle.radius = platformCircle.radius - circle.strokeColor = color(from: platformCircle.strokeColor) + circle.strokeColor = platformCircle.strokeColor.toUIColor() circle.strokeWidth = CGFloat(platformCircle.strokeWidth) - circle.fillColor = color(from: platformCircle.fillColor) + circle.fillColor = platformCircle.fillColor.toUIColor() // This must be done last, to avoid visual flickers of default property values. circle.map = platformCircle.visible ? mapView : nil diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift index 25e0a91f291..6140a3385fb 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift @@ -10,74 +10,83 @@ import GoogleMapsUtils import google_maps_flutter_ios_sdk9_objc #endif -/// Converts a CGPoint from its Pigeon equivalent. -func point(from point: FGMPlatformPoint) -> CGPoint { - return CGPoint(x: point.x, y: point.y) -} +extension FGMPlatformPoint { + /// Converts a CGPoint to its Pigeon equivalent. + static func make(from point: CGPoint) -> FGMPlatformPoint { + return FGMPlatformPoint.makeWith(x: point.x, y: point.y) + } -/// Converts a CGPoint to its Pigeon equivalent. -func pigeonPoint(from point: CGPoint) -> FGMPlatformPoint { - return FGMPlatformPoint.makeWith(x: point.x, y: point.y) + /// Converts a CGPoint from its Pigeon equivalent. + func toCGPoint() -> CGPoint { + return CGPoint(x: x, y: y) + } } -/// Creates a CLLocationCoordinate2D from its Pigeon representation. -func coordinate(from latLng: FGMPlatformLatLng) -> CLLocationCoordinate2D { - return CLLocationCoordinate2D(latitude: latLng.latitude, longitude: latLng.longitude) -} +extension FGMPlatformLatLng { + /// Converts a CLLocationCoordinate2D to its Pigeon representation. + static func make(from coordinate: CLLocationCoordinate2D) -> FGMPlatformLatLng { + return FGMPlatformLatLng.make( + withLatitude: coordinate.latitude, longitude: coordinate.longitude) + } -/// Converts a CLLocationCoordinate2D to its Pigeon representation. -func pigeonLatLng(from coordinate: CLLocationCoordinate2D) -> FGMPlatformLatLng { - return FGMPlatformLatLng.make(withLatitude: coordinate.latitude, longitude: coordinate.longitude) + /// Creates a CLLocationCoordinate2D from its Pigeon representation. + func toCLCoordinate() -> CLLocationCoordinate2D { + return CLLocationCoordinate2D(latitude: latitude, longitude: longitude) + } } -/// Creates a GMSCoordinateBounds from its Pigeon representation. -func coordinateBounds(from bounds: FGMPlatformLatLngBounds) -> GMSCoordinateBounds { - return GMSCoordinateBounds( - coordinate: coordinate(from: bounds.northeast), - coordinate: coordinate(from: bounds.southwest) - ) -} +extension FGMPlatformLatLngBounds { + /// Converts a GMSCoordinateBounds to its Pigeon representation. + static func make(from bounds: GMSCoordinateBounds) -> FGMPlatformLatLngBounds { + return FGMPlatformLatLngBounds.make( + withNortheast: FGMPlatformLatLng.make(from: bounds.northEast), + southwest: FGMPlatformLatLng.make(from: bounds.southWest) + ) + } -/// Converts a GMSCoordinateBounds to its Pigeon representation. -func pigeonLatLngBounds(from bounds: GMSCoordinateBounds) -> FGMPlatformLatLngBounds { - return FGMPlatformLatLngBounds.make( - withNortheast: pigeonLatLng(from: bounds.northEast), - southwest: pigeonLatLng(from: bounds.southWest) - ) + /// Creates a GMSCoordinateBounds from its Pigeon representation. + func toGMSBounds() -> GMSCoordinateBounds { + return GMSCoordinateBounds( + coordinate: northeast.toCLCoordinate(), + coordinate: southwest.toCLCoordinate() + ) + } } -/// Converts a GMSCameraPosition to its Pigeon representation. -func pigeonCameraPosition(from position: GMSCameraPosition) -> FGMPlatformCameraPosition { - return FGMPlatformCameraPosition.make( - withBearing: position.bearing, - target: pigeonLatLng(from: position.target), - tilt: position.viewingAngle, - zoom: Double(position.zoom) - ) -} +extension FGMPlatformCameraPosition { + /// Converts a GMSCameraPosition to its Pigeon representation. + static func make(from position: GMSCameraPosition) -> FGMPlatformCameraPosition { + return FGMPlatformCameraPosition.make( + withBearing: position.bearing, + target: FGMPlatformLatLng.make(from: position.target), + tilt: position.viewingAngle, + zoom: Double(position.zoom) + ) + } -/// Creates a GMSCameraPosition from its Pigeon representation. -func gmsCameraPosition(from position: FGMPlatformCameraPosition) -> GMSCameraPosition { - return GMSCameraPosition( - target: coordinate(from: position.target), - zoom: Float(position.zoom), - bearing: position.bearing, - viewingAngle: position.tilt - ) + /// Creates a GMSCameraPosition from its Pigeon representation. + func toGMSCameraPosition() -> GMSCameraPosition { + return GMSCameraPosition( + target: target.toCLCoordinate(), + zoom: Float(zoom), + bearing: bearing, + viewingAngle: tilt + ) + } } /// Creates a CLLocation array from its Pigeon equivalent. -func points(from pigeonPoints: [FGMPlatformLatLng]) -> [CLLocation] { +func makePoints(from pigeonPoints: [FGMPlatformLatLng]) -> [CLLocation] { return pigeonPoints.map { CLLocation(latitude: $0.latitude, longitude: $0.longitude) } } /// Creates a CLLocation array array, representing a set of holes, from its Pigeon equivalent. -func holes(from pigeonHolePoints: [[FGMPlatformLatLng]]) -> [[CLLocation]] { - return pigeonHolePoints.map { points(from: $0) } +func makeHoles(from pigeonHolePoints: [[FGMPlatformLatLng]]) -> [[CLLocation]] { + return pigeonHolePoints.map { makePoints(from: $0) } } /// Creates a GMSMutablePath from points. -func path(from points: [CLLocation]) -> GMSMutablePath { +func makePath(from points: [CLLocation]) -> GMSMutablePath { let path = GMSMutablePath() for location in points { path.add(location.coordinate) @@ -104,7 +113,9 @@ func mapViewType(from type: FGMPlatformMapType) -> GMSMapViewType { } /// Creates a GMSCollisionBehavior from its Pigeon representation. -func collisionBehavior(from collisionBehavior: FGMPlatformMarkerCollisionBehavior) -> GMSCollisionBehavior { +func collisionBehavior(from collisionBehavior: FGMPlatformMarkerCollisionBehavior) + -> GMSCollisionBehavior +{ switch collisionBehavior { case .requiredDisplay: return .required @@ -117,151 +128,161 @@ func collisionBehavior(from collisionBehavior: FGMPlatformMarkerCollisionBehavio } } -/// Converts a GMSGroundOverlay to its Pigeon representation. -func pigeonGroundOverlay( - from groundOverlay: GMSGroundOverlay, - overlayId: String, - isCreatedWithBounds: Bool, - zoomLevel: NSNumber? -) -> FGMPlatformGroundOverlay { - let placeholderImage = FGMPlatformBitmap.make( - withBitmap: FGMPlatformBitmapDefaultMarker.make(withHue: 0)) - if isCreatedWithBounds, let bounds = groundOverlay.bounds { - return FGMPlatformGroundOverlay.make( - withGroundOverlayId: overlayId, - image: placeholderImage, - position: nil, - bounds: FGMPlatformLatLngBounds.make( - withNortheast: FGMPlatformLatLng.make( - withLatitude: bounds.northEast.latitude, - longitude: bounds.northEast.longitude +extension FGMPlatformGroundOverlay { + /// Converts a GMSGroundOverlay to its Pigeon representation. + static func make( + from groundOverlay: GMSGroundOverlay, + overlayId: String, + isCreatedWithBounds: Bool, + zoomLevel: NSNumber? + ) -> FGMPlatformGroundOverlay { + let placeholderImage = FGMPlatformBitmap.make( + withBitmap: FGMPlatformBitmapDefaultMarker.make(withHue: 0)) + if isCreatedWithBounds, let bounds = groundOverlay.bounds { + return FGMPlatformGroundOverlay.make( + withGroundOverlayId: overlayId, + image: placeholderImage, + position: nil, + bounds: FGMPlatformLatLngBounds.make( + withNortheast: FGMPlatformLatLng.make( + withLatitude: bounds.northEast.latitude, + longitude: bounds.northEast.longitude + ), + southwest: FGMPlatformLatLng.make( + withLatitude: bounds.southWest.latitude, + longitude: bounds.southWest.longitude + ) ), - southwest: FGMPlatformLatLng.make( - withLatitude: bounds.southWest.latitude, - longitude: bounds.southWest.longitude - ) - ), - anchor: FGMPlatformPoint.makeWith(x: groundOverlay.anchor.x, y: groundOverlay.anchor.y), - transparency: 1.0 - Double(groundOverlay.opacity), - bearing: groundOverlay.bearing, - zIndex: Int(groundOverlay.zIndex), - visible: groundOverlay.map != nil, - clickable: groundOverlay.isTappable, - zoomLevel: zoomLevel - ) - } else { - return FGMPlatformGroundOverlay.make( - withGroundOverlayId: overlayId, - image: placeholderImage, - position: FGMPlatformLatLng.make( - withLatitude: groundOverlay.position.latitude, - longitude: groundOverlay.position.longitude - ), - bounds: nil, - anchor: FGMPlatformPoint.makeWith(x: groundOverlay.anchor.x, y: groundOverlay.anchor.y), - transparency: 1.0 - Double(groundOverlay.opacity), - bearing: groundOverlay.bearing, - zIndex: Int(groundOverlay.zIndex), - visible: groundOverlay.map != nil, - clickable: groundOverlay.isTappable, - zoomLevel: zoomLevel - ) + anchor: FGMPlatformPoint.makeWith(x: groundOverlay.anchor.x, y: groundOverlay.anchor.y), + transparency: 1.0 - Double(groundOverlay.opacity), + bearing: groundOverlay.bearing, + zIndex: Int(groundOverlay.zIndex), + visible: groundOverlay.map != nil, + clickable: groundOverlay.isTappable, + zoomLevel: zoomLevel + ) + } else { + return FGMPlatformGroundOverlay.make( + withGroundOverlayId: overlayId, + image: placeholderImage, + position: FGMPlatformLatLng.make( + withLatitude: groundOverlay.position.latitude, + longitude: groundOverlay.position.longitude + ), + bounds: nil, + anchor: FGMPlatformPoint.makeWith(x: groundOverlay.anchor.x, y: groundOverlay.anchor.y), + transparency: 1.0 - Double(groundOverlay.opacity), + bearing: groundOverlay.bearing, + zIndex: Int(groundOverlay.zIndex), + visible: groundOverlay.map != nil, + clickable: groundOverlay.isTappable, + zoomLevel: zoomLevel + ) + } } } -/// Creates a GMUGradient from its Pigeon representation. -func gradient(from heatmapGradient: FGMPlatformHeatmapGradient) -> GMUGradient { - let colors = heatmapGradient.colors.map { color(from: $0) } - return GMUGradient( - colors: colors, - startPoints: heatmapGradient.startPoints, - colorMapSize: UInt(heatmapGradient.colorMapSize) - ) -} +extension FGMPlatformHeatmapGradient { + /// Converts a GMUGradient to its Pigeon representation. + static func make(from gradient: GMUGradient) -> FGMPlatformHeatmapGradient { + let colors = gradient.colors.map { FGMPlatformColor.make(from: $0) } + return FGMPlatformHeatmapGradient.make( + with: colors, + startPoints: gradient.startPoints, + colorMapSize: Int(gradient.mapSize) + ) + } -/// Converts a GMUGradient to its Pigeon representation. -func pigeonHeatmapGradient(from gradient: GMUGradient) -> FGMPlatformHeatmapGradient { - let colors = gradient.colors.map { pigeonColor(from: $0) } - return FGMPlatformHeatmapGradient.make( - with: colors, - startPoints: gradient.startPoints, - colorMapSize: Int(gradient.mapSize) - ) + /// Creates a GMUGradient from its Pigeon representation. + func toGMUGradient() -> GMUGradient { + let colors = colors.map { $0.toUIColor() } + return GMUGradient( + colors: colors, + startPoints: startPoints, + colorMapSize: UInt(colorMapSize) + ) + } } /// Creates a GMUWeightedLatLng array from its Pigeon equivalent. -func weightedData(from weightedLatLngs: [FGMPlatformWeightedLatLng]) -> [GMUWeightedLatLng] { +func makeWeightedData(from weightedLatLngs: [FGMPlatformWeightedLatLng]) -> [GMUWeightedLatLng] { return weightedLatLngs.map { GMUWeightedLatLng( - coordinate: coordinate(from: $0.point), + coordinate: $0.point.toCLCoordinate(), intensity: Float($0.weight) ) } } /// Converts a GMUWeightedLatLng array to its Pigeon equivalent. -func pigeonWeightedData(from weightedLatLngs: [GMUWeightedLatLng]) -> [FGMPlatformWeightedLatLng] { +func makePigeonWeightedData(from weightedLatLngs: [GMUWeightedLatLng]) + -> [FGMPlatformWeightedLatLng] +{ return weightedLatLngs.map { let point = GMSMapPoint(x: $0.point().x, y: $0.point().y) return FGMPlatformWeightedLatLng.make( - withPoint: pigeonLatLng(from: GMSUnproject(point)), + withPoint: FGMPlatformLatLng.make(from: GMSUnproject(point)), weight: Double($0.intensity) ) } } -/// Creates a GMSCameraUpdate from its Pigeon equivalent. -func gmsCameraUpdate(from cameraUpdate: FGMPlatformCameraUpdate) -> GMSCameraUpdate? { - // See note in messages.dart for why this is so loosely typed. - let update = cameraUpdate.cameraUpdate - if let newCameraPosition = update as? FGMPlatformCameraUpdateNewCameraPosition { - return GMSCameraUpdate.setCamera(gmsCameraPosition(from: newCameraPosition.cameraPosition)) - } else if let newLatLng = update as? FGMPlatformCameraUpdateNewLatLng { - return GMSCameraUpdate.setTarget(coordinate(from: newLatLng.latLng)) - } else if let newLatLngBounds = update as? FGMPlatformCameraUpdateNewLatLngBounds { - return GMSCameraUpdate.fit( - coordinateBounds(from: newLatLngBounds.bounds), - withPadding: CGFloat(newLatLngBounds.padding) - ) - } else if let newLatLngZoom = update as? FGMPlatformCameraUpdateNewLatLngZoom { - return GMSCameraUpdate.setTarget( - coordinate(from: newLatLngZoom.latLng), - zoom: Float(newLatLngZoom.zoom) - ) - } else if let scrollBy = update as? FGMPlatformCameraUpdateScrollBy { - return GMSCameraUpdate.scrollBy(x: scrollBy.dx, y: scrollBy.dy) - } else if let zoomBy = update as? FGMPlatformCameraUpdateZoomBy { - if let focus = zoomBy.focus { - return GMSCameraUpdate.zoom(by: Float(zoomBy.amount), at: point(from: focus)) - } else { - return GMSCameraUpdate.zoom(by: Float(zoomBy.amount)) +extension FGMPlatformCameraUpdate { + /// Creates a GMSCameraUpdate from its Pigeon equivalent. + static func make(from cameraUpdate: FGMPlatformCameraUpdate) -> GMSCameraUpdate? { + // See note in messages.dart for why this is so loosely typed. + let update = cameraUpdate.cameraUpdate + if let newCameraPosition = update as? FGMPlatformCameraUpdateNewCameraPosition { + return GMSCameraUpdate.setCamera(newCameraPosition.cameraPosition.toGMSCameraPosition()) + } else if let newLatLng = update as? FGMPlatformCameraUpdateNewLatLng { + return GMSCameraUpdate.setTarget(newLatLng.latLng.toCLCoordinate()) + } else if let newLatLngBounds = update as? FGMPlatformCameraUpdateNewLatLngBounds { + return GMSCameraUpdate.fit( + newLatLngBounds.bounds.toGMSBounds(), + withPadding: CGFloat(newLatLngBounds.padding) + ) + } else if let newLatLngZoom = update as? FGMPlatformCameraUpdateNewLatLngZoom { + return GMSCameraUpdate.setTarget( + newLatLngZoom.latLng.toCLCoordinate(), + zoom: Float(newLatLngZoom.zoom) + ) + } else if let scrollBy = update as? FGMPlatformCameraUpdateScrollBy { + return GMSCameraUpdate.scrollBy(x: scrollBy.dx, y: scrollBy.dy) + } else if let zoomBy = update as? FGMPlatformCameraUpdateZoomBy { + if let focus = zoomBy.focus { + return GMSCameraUpdate.zoom(by: Float(zoomBy.amount), at: focus.toCGPoint()) + } else { + return GMSCameraUpdate.zoom(by: Float(zoomBy.amount)) + } + } else if let zoom = update as? FGMPlatformCameraUpdateZoom { + return zoom.out ? GMSCameraUpdate.zoomOut() : GMSCameraUpdate.zoomIn() + } else if let zoomTo = update as? FGMPlatformCameraUpdateZoomTo { + return GMSCameraUpdate.zoom(to: Float(zoomTo.zoom)) } - } else if let zoom = update as? FGMPlatformCameraUpdateZoom { - return zoom.out ? GMSCameraUpdate.zoomOut() : GMSCameraUpdate.zoomIn() - } else if let zoomTo = update as? FGMPlatformCameraUpdateZoomTo { - return GMSCameraUpdate.zoom(to: Float(zoomTo.zoom)) + return nil } - return nil } -/// Creates a UIColor from its Pigeon representation. -func color(from color: FGMPlatformColor) -> UIColor { - return UIColor(red: color.red, green: color.green, blue: color.blue, alpha: color.alpha) -} +extension FGMPlatformColor { + /// Creates a UIColor from its Pigeon representation. + func toUIColor() -> UIColor { + return UIColor(red: red, green: green, blue: blue, alpha: alpha) + } -/// Converts a UIColor to its Pigeon representation. -func pigeonColor(from color: UIColor) -> FGMPlatformColor { - var red: CGFloat = 0 - var green: CGFloat = 0 - var blue: CGFloat = 0 - var alpha: CGFloat = 0 - color.getRed(&red, green: &green, blue: &blue, alpha: &alpha) - return FGMPlatformColor.make( - withRed: Double(red), green: Double(green), blue: Double(blue), alpha: Double(alpha)) + /// Converts a UIColor to its Pigeon representation. + static func make(from color: UIColor) -> FGMPlatformColor { + var red: CGFloat = 0 + var green: CGFloat = 0 + var blue: CGFloat = 0 + var alpha: CGFloat = 0 + color.getRed(&red, green: &green, blue: &blue, alpha: &alpha) + return FGMPlatformColor.make( + withRed: Double(red), green: Double(green), blue: Double(blue), alpha: Double(alpha)) + } } /// Creates an array of GMSStrokeStyles using the given patterns and stroke color. -func strokeStyles( +func makeStrokeStyles( from patterns: [FGMPlatformPatternItem], strokeColor: UIColor ) -> [GMSStrokeStyle] { return patterns.map { pattern in @@ -271,28 +292,30 @@ func strokeStyles( } /// Creates an array of span lengths using the given patterns. -func spanLengths(from patterns: [FGMPlatformPatternItem]) -> [NSNumber] { +func makeSpanLengths(from patterns: [FGMPlatformPatternItem]) -> [NSNumber] { return patterns.map { $0.length ?? 0 } } -/// Converts a GMUCluster to its Pigeon representation. -func pigeonCluster( - for cluster: GMUCluster, - clusterManagerIdentifier: String -) -> FGMPlatformCluster { - var bounds = GMSCoordinateBounds() - for item in cluster.items { - bounds = bounds.includingCoordinate(item.position) - } +extension FGMPlatformCluster { + /// Converts a GMUCluster to its Pigeon representation. + static func make( + from cluster: GMUCluster, + clusterManagerIdentifier: String + ) -> FGMPlatformCluster { + var bounds = GMSCoordinateBounds() + for item in cluster.items { + bounds = bounds.includingCoordinate(item.position) + } - let markerIds = cluster.items.filter { $0 is GMSMarker }.compactMap { - markerIdentifierFromMarker($0 as! GMSMarker) - } + let markerIds = cluster.items.filter { $0 is GMSMarker }.compactMap { + markerIdentifierFromMarker($0 as! GMSMarker) + } - return FGMPlatformCluster.make( - withClusterManagerId: clusterManagerIdentifier, - position: pigeonLatLng(from: cluster.position), - bounds: pigeonLatLngBounds(from: bounds), - markerIds: markerIds - ) + return FGMPlatformCluster.make( + withClusterManagerId: clusterManagerIdentifier, + position: FGMPlatformLatLng.make(from: cluster.position), + bounds: FGMPlatformLatLngBounds.make(from: bounds), + markerIds: markerIds + ) + } } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift index d239ceb8fcc..08090a0674a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift @@ -146,7 +146,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV creationParameters: FGMPlatformMapViewCreationParams, registrar: FlutterPluginRegistrar ) { - let camera = gmsCameraPosition(from: creationParameters.initialCameraPosition) + let camera = creationParameters.initialCameraPosition.toGMSCameraPosition() let options = GMSMapViewOptions() options.frame = frame @@ -360,7 +360,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV public func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) { if trackCameraPosition { - mapEventHandler.didMoveCamera(to: pigeonCameraPosition(from: position)) + mapEventHandler.didMoveCamera(to: FGMPlatformCameraPosition.make(from: position)) } } @@ -421,11 +421,11 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV } public func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) { - mapEventHandler.didTap(atPosition: pigeonLatLng(from: coordinate)) + mapEventHandler.didTap(atPosition: FGMPlatformLatLng.make(from: coordinate)) } public func mapView(_ mapView: GMSMapView, didLongPressAt coordinate: CLLocationCoordinate2D) { - mapEventHandler.didLongPress(atPosition: pigeonLatLng(from: coordinate)) + mapEventHandler.didLongPress(atPosition: FGMPlatformLatLng.make(from: coordinate)) } func interpretMapConfiguration(_ config: FGMPlatformMapConfiguration) { @@ -451,7 +451,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV ) -> (Bool, String?) { if let cameraTargetBounds = config.cameraTargetBounds { if let bounds = cameraTargetBounds.bounds { - mapView.cameraTargetBounds = coordinateBounds(from: bounds) + mapView.cameraTargetBounds = bounds.toGMSBounds() } else { mapView.cameraTargetBounds = nil } @@ -650,9 +650,9 @@ class MapCallHandler: NSObject, FGMMapsApi { ) return nil } - let point = point(from: screenCoordinate) + let point = screenCoordinate.toCGPoint() let latlng = mapView.projection.coordinate(for: point) - return pigeonLatLng(from: latlng) + return FGMPlatformLatLng.make(from: latlng) } func screenCoordinates( @@ -666,9 +666,9 @@ class MapCallHandler: NSObject, FGMMapsApi { ) return nil } - let location = coordinate(from: latLng) + let location = latLng.toCLCoordinate() let point = mapView.projection.point(for: location) - return pigeonPoint(from: point) + return FGMPlatformPoint.make(from: point) } func visibleMapRegion(_ error: AutoreleasingUnsafeMutablePointer) @@ -684,14 +684,14 @@ class MapCallHandler: NSObject, FGMMapsApi { } let visibleRegion = mapView.projection.visibleRegion() let bounds = GMSCoordinateBounds(region: visibleRegion) - return pigeonLatLngBounds(from: bounds) + return FGMPlatformLatLngBounds.make(from: bounds) } func moveCamera( with cameraUpdate: FGMPlatformCameraUpdate, error: AutoreleasingUnsafeMutablePointer ) { - guard let update = gmsCameraUpdate(from: cameraUpdate) else { + guard let update = FGMPlatformCameraUpdate.make(from: cameraUpdate) else { error.pointee = FlutterError( code: "Invalid update", message: "Unrecognized camera update", @@ -706,7 +706,7 @@ class MapCallHandler: NSObject, FGMMapsApi { with cameraUpdate: FGMPlatformCameraUpdate, duration durationMilliseconds: NSNumber?, error: AutoreleasingUnsafeMutablePointer ) { - guard let update = gmsCameraUpdate(from: cameraUpdate) else { + guard let update = FGMPlatformCameraUpdate.make(from: cameraUpdate) else { error.pointee = FlutterError( code: "Invalid update", message: "Unrecognized camera update", @@ -934,6 +934,6 @@ class MapInspector: NSObject, FGMMapsInspectorApi { guard let mapView = controller?.mapView else { return nil } - return pigeonCameraPosition(from: mapView.camera) + return FGMPlatformCameraPosition.make(from: mapView.camera) } } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GroundOverlayController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GroundOverlayController.swift index f2384d70715..fa8e119be97 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GroundOverlayController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GroundOverlayController.swift @@ -66,7 +66,8 @@ class GroundOverlayController: NSObject { if let anchor = platformGroundOverlay.anchor { groundOverlay.anchor = CGPoint(x: anchor.x, y: anchor.y) } - groundOverlay.icon = icon(from: platformGroundOverlay.image, assetProvider: assetProvider, screenScale: screenScale) + groundOverlay.icon = makeIcon( + from: platformGroundOverlay.image, assetProvider: assetProvider, screenScale: screenScale) groundOverlay.bearing = platformGroundOverlay.bearing groundOverlay.opacity = Float(1.0 - platformGroundOverlay.transparency) if useBounds { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift index e51d8fc2627..572cbb6e681 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift @@ -26,29 +26,31 @@ func makeIcon( var image: UIImage? if let bitmapDefaultMarker = bitmap as? FGMPlatformBitmapDefaultMarker { - let hue = bitmapDefaultMarker.hue.doubleValue - image = GMSMarker.markerImage(with: UIColor(hue: CGFloat(hue) / 360.0, - saturation: 1.0, - brightness: 0.7, - alpha: 1.0)) + let hue = bitmapDefaultMarker.hue?.doubleValue ?? 0 + image = GMSMarker.markerImage( + with: UIColor( + hue: CGFloat(hue) / 360.0, + saturation: 1.0, + brightness: 0.7, + alpha: 1.0)) } else if let bitmapAsset = bitmap as? FGMPlatformBitmapAsset { // Deprecated: This message handling for 'fromAsset' has been replaced by 'asset'. // Refer to the flutter google_maps_flutter_platform_interface package for details. if let pkg = bitmapAsset.pkg { if let key = assetProvider.lookupKey(forAsset: bitmapAsset.name, fromPackage: pkg) { - image = assetProvider.image(named: key) + image = assetProvider.imageNamed(key) } } else { if let key = assetProvider.lookupKey(forAsset: bitmapAsset.name) { - image = assetProvider.image(named: key) + image = assetProvider.imageNamed(key) } } } else if let bitmapAssetImage = bitmap as? FGMPlatformBitmapAssetImage { // Deprecated: This message handling for 'fromAssetImage' has been replaced by 'asset'. // Refer to the flutter google_maps_flutter_platform_interface package for details. if let key = assetProvider.lookupKey(forAsset: bitmapAssetImage.name) { - if let assetImage = assetProvider.image(named: key) { - image = scaledImage(assetImage, scale: bitmapAssetImage.scale.doubleValue) + if let assetImage = assetProvider.imageNamed(key) { + image = scaledImage(assetImage, scale: bitmapAssetImage.scale) } } } else if let bitmapBytes = bitmap as? FGMPlatformBitmapBytes { @@ -57,7 +59,7 @@ func makeIcon( image = UIImage(data: bitmapBytes.byteData.data, scale: screenScale) } else if let bitmapAssetMap = bitmap as? FGMPlatformBitmapAssetMap { if let key = assetProvider.lookupKey(forAsset: bitmapAssetMap.assetName) { - image = assetProvider.image(named: key) + image = assetProvider.imageNamed(key) } if let currentImage = image, bitmapAssetMap.bitmapScaling == .auto { let width = bitmapAssetMap.width @@ -66,7 +68,7 @@ func makeIcon( let tempImage = scaledImage(currentImage, scale: screenScale) image = scaledImage(tempImage, width: width, height: height, screenScale: screenScale) } else { - image = scaledImage(currentImage, scale: CGFloat(bitmapAssetMap.imagePixelRatio.doubleValue)) + image = scaledImage(currentImage, scale: CGFloat(bitmapAssetMap.imagePixelRatio)) } } } else if let bitmapBytesMap = bitmap as? FGMPlatformBitmapBytesMap { @@ -77,40 +79,46 @@ func makeIcon( let width = bitmapBytesMap.width let height = bitmapBytesMap.height if width != nil || height != nil { + // Before scaling the image, image must be in screenScale. let tempImage = scaledImage(currentImage, scale: screenScale) image = scaledImage(tempImage, width: width, height: height, screenScale: screenScale) } else { - image = scaledImage(currentImage, scale: CGFloat(bitmapBytesMap.imagePixelRatio.doubleValue)) + image = scaledImage(currentImage, scale: CGFloat(bitmapBytesMap.imagePixelRatio)) } + } else { + // No scaling, load image from bytes without scale parameter. + image = UIImage(data: bytes.data) } } } else if let pinConfig = bitmap as? FGMPlatformBitmapPinConfig { let options = GMSPinImageOptions() if let backgroundColor = pinConfig.backgroundColor { - options.backgroundColor = color(from: backgroundColor) + options.backgroundColor = backgroundColor.toUIColor() } if let borderColor = pinConfig.borderColor { - options.borderColor = color(from: borderColor) + options.borderColor = borderColor.toUIColor() } var glyph: GMSPinImageGlyph? if let glyphText = pinConfig.glyphText { let glyphTextColor: UIColor if let textColor = pinConfig.glyphTextColor { - glyphTextColor = color(from: textColor) + glyphTextColor = textColor.toUIColor() } else { glyphTextColor = .black } glyph = GMSPinImageGlyph(text: glyphText, textColor: glyphTextColor) } else if let glyphColorValue = pinConfig.glyphColor { - glyph = GMSPinImageGlyph(glyphColor: color(from: glyphColorValue)) + glyph = GMSPinImageGlyph(glyphColor: glyphColorValue.toUIColor()) } else if let glyphBitmap = pinConfig.glyphBitmap { - if let glyphImage = icon(from: glyphBitmap, assetProvider: assetProvider, screenScale: screenScale) { + if let glyphImage = makeIcon( + from: glyphBitmap, assetProvider: assetProvider, screenScale: screenScale) + { glyph = GMSPinImageGlyph(image: glyphImage) } } options.glyph = glyph - image = GMSPinImage.pinImage(with: options) + image = GMSPinImage(options: options) } return image @@ -134,6 +142,11 @@ private func scaledImage(_ image: UIImage, scale: Double) -> UIImage { return image } +/// Creates a scaled version of the provided UIImage based on a specified scale factor. +/// +/// If the scale factor differs from the image's current scale by more than a small epsilon-delta +/// (to account for minor floating-point inaccuracies), a new UIImage object is created with the +/// specified scale. Otherwise, the original image is returned. private func scaledImage(_ image: UIImage, scale: CGFloat) -> UIImage { if abs(scale - image.scale) > .ulpOfOne { if let cgImage = image.cgImage { @@ -147,24 +160,38 @@ private func scaledImage(_ image: UIImage, scale: CGFloat) -> UIImage { return image } -private func scaledImage(_ image: UIImage, size: CGSize) -> UIImage { +/// Scales an input UIImage to a specified size. +/// +/// If the aspect ratio of the input image closely matches the target size, indicated by a +/// small epsilon-delta, the image's scale property is updated instead of resizing the image. If +/// the aspect ratios differ beyond this threshold, the method redraws the image at the target +/// size. +private func scaledImage(_ image: UIImage, to size: CGSize) -> UIImage { let originalPixelWidth = image.size.width * image.scale let originalPixelHeight = image.size.height * image.scale + // Return original image if either original image size or target size is so small that + // image cannot be resized or displayed. if originalPixelWidth <= 0 || originalPixelHeight <= 0 || size.width <= 0 || size.height <= 0 { return image } - if abs(originalPixelWidth - size.width) <= .ulpOfOne && - abs(originalPixelHeight - size.height) <= .ulpOfOne { + // Check if the image's size, accounting for scale, matches the target size. + if abs(originalPixelWidth - size.width) <= .ulpOfOne + && abs(originalPixelHeight - size.height) <= .ulpOfOne + { return image } + // Check if the aspect ratios are approximately equal. let originalPixelSize = CGSize(width: originalPixelWidth, height: originalPixelHeight) - if isScalableWithScaleFactor(from: originalPixelSize, targetSize: size) { + if isScalableWithScaleFactor(from: originalPixelSize, to: size) { + // Scaled image has close to same aspect ratio, + // updating image scale instead of resizing image. let factor = originalPixelWidth / size.width return scaledImage(image, scale: image.scale * factor) } else { + // Aspect ratios differ significantly, resize the image. let format = UIGraphicsImageRendererFormat.default() format.scale = 1.0 format.opaque = false @@ -176,6 +203,8 @@ private func scaledImage(_ image: UIImage, size: CGSize) -> UIImage { } } +/// Scales an input UIImage to a specified width and height, preserving aspect ratio if both +/// widht and height are not given. private func scaledImage( _ image: UIImage, width: NSNumber?, @@ -193,9 +222,11 @@ private func scaledImage( var calculatedHeight = targetHeight if width != nil && height == nil { + // Calculate height based on aspect ratio if only width is provided. let aspectRatio = image.size.height / image.size.width calculatedHeight = (targetWidth * aspectRatio).rounded() } else if width == nil && height != nil { + // Calculate width based on aspect ratio if only height is provided. let aspectRatio = image.size.width / image.size.height calculatedWidth = (targetHeight * aspectRatio).rounded() } @@ -204,19 +235,26 @@ private func scaledImage( width: (calculatedWidth * screenScale).rounded(), height: (calculatedHeight * screenScale).rounded() ) - return scaledImage(image, size: targetSize) + return scaledImage(image, to: targetSize) } -func isScalableWithScaleFactor(from originalSize: CGSize, targetSize: CGSize) -> Bool { - let scaleFactor = (originalSize.width > originalSize.height) +func isScalableWithScaleFactor(from originalSize: CGSize, to targetSize: CGSize) -> Bool { + // Select the scaling factor based on the longer side to have good precision. + let scaleFactor = + (originalSize.width > originalSize.height) ? (targetSize.width / originalSize.width) : (targetSize.height / originalSize.height) + // Calculate the scaled dimensions. let scaledWidth = originalSize.width * scaleFactor let scaledHeight = originalSize.height * scaleFactor + // Check if the scaled dimensions are within a one-pixel + // threshold of the target dimensions. let widthWithinThreshold = abs(scaledWidth - targetSize.width) <= 1.0 let heightWithinThreshold = abs(scaledHeight - targetSize.height) <= 1.0 + // The image is considered scalable with scale factor + // if both dimensions are within the threshold. return widthWithinThreshold && heightWithinThreshold } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/MarkerController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/MarkerController.swift index 39456e6c0dd..9887a4f58df 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/MarkerController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/MarkerController.swift @@ -82,15 +82,16 @@ class MarkerController: NSObject { screenScale: CGFloat, usingOpacityForVisibility useOpacityForVisibility: Bool ) { - marker.groundAnchor = point(from: platformMarker.anchor ?? FGMPlatformPoint.makeWith(x: 0, y: 0)) + marker.groundAnchor = platformMarker.anchor.toCGPoint() marker.isDraggable = platformMarker.draggable - marker.icon = icon(from: platformMarker.icon, assetProvider: assetProvider, screenScale: screenScale) + marker.icon = makeIcon( + from: platformMarker.icon, assetProvider: assetProvider, screenScale: screenScale) marker.isFlat = platformMarker.flat - marker.position = coordinate(from: platformMarker.position) + marker.position = platformMarker.position.toCLCoordinate() marker.rotation = platformMarker.rotation marker.zIndex = Int32(platformMarker.zIndex) let infoWindow = platformMarker.infoWindow - marker.infoWindowAnchor = point(from: infoWindow.anchor ?? FGMPlatformPoint.makeWith(x: 0, y: 0)) + marker.infoWindowAnchor = infoWindow.anchor.toCGPoint() if let title = infoWindow.title { marker.title = title marker.snippet = infoWindow.snippet @@ -144,7 +145,7 @@ class MarkersController: NSObject { private func addMarker(_ markerToAdd: FGMPlatformMarker) { guard let mapView = mapView else { return } - let position = coordinate(from: markerToAdd.position) + let position = markerToAdd.position.toCLCoordinate() let markerIdentifier = markerToAdd.markerId let clusterManagerIdentifier = markerToAdd.clusterManagerId @@ -228,7 +229,7 @@ class MarkersController: NSObject { guard markerIdentifierToController[identifier] != nil else { return } eventDelegate?.didStartDragForMarker( withIdentifier: identifier, - atPosition: pigeonLatLng(from: location) + atPosition: FGMPlatformLatLng.make(from: location) ) } @@ -236,7 +237,7 @@ class MarkersController: NSObject { guard markerIdentifierToController[identifier] != nil else { return } eventDelegate?.didDragMarker( withIdentifier: identifier, - atPosition: pigeonLatLng(from: location) + atPosition: FGMPlatformLatLng.make(from: location) ) } @@ -244,7 +245,7 @@ class MarkersController: NSObject { guard markerIdentifierToController[identifier] != nil else { return } eventDelegate?.didEndDragForMarker( withIdentifier: identifier, - atPosition: pigeonLatLng(from: location) + atPosition: FGMPlatformLatLng.make(from: location) ) } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/FGMImageUtils.m b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/FGMImageUtils.m deleted file mode 100644 index 03eb36eeb40..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/FGMImageUtils.m +++ /dev/null @@ -1,271 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -@import Flutter; - -#import "FGMImageUtils.h" -#import "FGMConversionUtils.h" - -@import Foundation; - -/// This method is deprecated within the context of `BitmapDescriptor.fromBytes` handling in the -/// flutter google_maps_flutter_platform_interface package which has been replaced by 'bytes' -/// message handling. It will be removed when the deprecated image bitmap description type -/// 'fromBytes' is removed from the platform interface. -static UIImage *scaledImage(UIImage *image, double scale); - -/// Creates a scaled version of the provided UIImage based on a specified scale factor. If the -/// scale factor differs from the image's current scale by more than a small epsilon-delta (to -/// account for minor floating-point inaccuracies), a new UIImage object is created with the -/// specified scale. Otherwise, the original image is returned. -/// -/// @param image The UIImage to scale. -/// @param scale The factor by which to scale the image. -/// @return UIImage Returns the scaled UIImage. -static UIImage *scaledImageWithScale(UIImage *image, CGFloat scale); - -/// Scales an input UIImage to a specified size. If the aspect ratio of the input image -/// closely matches the target size, indicated by a small epsilon-delta, the image's scale -/// property is updated instead of resizing the image. If the aspect ratios differ beyond this -/// threshold, the method redraws the image at the target size. -/// -/// @param image The UIImage to scale. -/// @param size The target CGSize to scale the image to. -/// @return UIImage Returns the scaled UIImage. -static UIImage *scaledImageWithSize(UIImage *image, CGSize size); - -/// Scales an input UIImage to a specified width and height preserving aspect ratio if both -/// widht and height are not given.. -/// -/// @param image The UIImage to scale. -/// @param width The target width to scale the image to. -/// @param height The target height to scale the image to. -/// @param screenScale The current screen scale. -/// @return UIImage Returns the scaled UIImage. -static UIImage *scaledImageWithWidthHeight(UIImage *image, NSNumber *width, NSNumber *height, - CGFloat screenScale); - -UIImage *FGMIconFromBitmap(FGMPlatformBitmap *platformBitmap, - NSObject *assetProvider, CGFloat screenScale) { - assert(screenScale > 0 && "Screen scale must be greater than 0"); - // See comment in messages.dart for why this is so loosely typed. See also - // https://github.com/flutter/flutter/issues/117819. - id bitmap = platformBitmap.bitmap; - UIImage *image; - if ([bitmap isKindOfClass:[FGMPlatformBitmapDefaultMarker class]]) { - FGMPlatformBitmapDefaultMarker *bitmapDefaultMarker = bitmap; - CGFloat hue = bitmapDefaultMarker.hue.doubleValue; - image = [GMSMarker markerImageWithColor:[UIColor colorWithHue:hue / 360.0 - saturation:1.0 - brightness:0.7 - alpha:1.0]]; - } else if ([bitmap isKindOfClass:[FGMPlatformBitmapAsset class]]) { - // Deprecated: This message handling for 'fromAsset' has been replaced by 'asset'. - // Refer to the flutter google_maps_flutter_platform_interface package for details. - FGMPlatformBitmapAsset *bitmapAsset = bitmap; - if (bitmapAsset.pkg) { - image = [assetProvider imageNamed:[assetProvider lookupKeyForAsset:bitmapAsset.name - fromPackage:bitmapAsset.pkg]]; - } else { - image = [assetProvider imageNamed:[assetProvider lookupKeyForAsset:bitmapAsset.name]]; - } - } else if ([bitmap isKindOfClass:[FGMPlatformBitmapAssetImage class]]) { - // Deprecated: This message handling for 'fromAssetImage' has been replaced by 'asset'. - // Refer to the flutter google_maps_flutter_platform_interface package for details. - FGMPlatformBitmapAssetImage *bitmapAssetImage = bitmap; - image = [assetProvider imageNamed:[assetProvider lookupKeyForAsset:bitmapAssetImage.name]]; - image = scaledImage(image, bitmapAssetImage.scale); - } else if ([bitmap isKindOfClass:[FGMPlatformBitmapBytes class]]) { - // Deprecated: This message handling for 'fromBytes' has been replaced by 'bytes'. - // Refer to the flutter google_maps_flutter_platform_interface package for details. - FGMPlatformBitmapBytes *bitmapBytes = bitmap; - @try { - image = [UIImage imageWithData:bitmapBytes.byteData.data scale:screenScale]; - } @catch (NSException *exception) { - @throw [NSException exceptionWithName:@"InvalidByteDescriptor" - reason:@"Unable to interpret bytes as a valid image." - userInfo:nil]; - } - } else if ([bitmap isKindOfClass:[FGMPlatformBitmapAssetMap class]]) { - FGMPlatformBitmapAssetMap *bitmapAssetMap = bitmap; - - image = [assetProvider imageNamed:[assetProvider lookupKeyForAsset:bitmapAssetMap.assetName]]; - - if (bitmapAssetMap.bitmapScaling == FGMPlatformMapBitmapScalingAuto) { - NSNumber *width = bitmapAssetMap.width; - NSNumber *height = bitmapAssetMap.height; - if (width || height) { - image = scaledImageWithScale(image, screenScale); - image = scaledImageWithWidthHeight(image, width, height, screenScale); - } else { - image = scaledImageWithScale(image, bitmapAssetMap.imagePixelRatio); - } - } - } else if ([bitmap isKindOfClass:[FGMPlatformBitmapBytesMap class]]) { - FGMPlatformBitmapBytesMap *bitmapBytesMap = bitmap; - FlutterStandardTypedData *bytes = bitmapBytesMap.byteData; - - @try { - image = [UIImage imageWithData:bytes.data scale:screenScale]; - if (bitmapBytesMap.bitmapScaling == FGMPlatformMapBitmapScalingAuto) { - NSNumber *width = bitmapBytesMap.width; - NSNumber *height = bitmapBytesMap.height; - - if (width || height) { - // Before scaling the image, image must be in screenScale. - image = scaledImageWithScale(image, screenScale); - image = scaledImageWithWidthHeight(image, width, height, screenScale); - } else { - image = scaledImageWithScale(image, bitmapBytesMap.imagePixelRatio); - } - } else { - // No scaling, load image from bytes without scale parameter. - image = [UIImage imageWithData:bytes.data]; - } - } @catch (NSException *exception) { - @throw [NSException exceptionWithName:@"InvalidByteDescriptor" - reason:@"Unable to interpret bytes as a valid image." - userInfo:nil]; - } - } else if ([bitmap isKindOfClass:[FGMPlatformBitmapPinConfig class]]) { - FGMPlatformBitmapPinConfig *pinConfig = bitmap; - - GMSPinImageOptions *options = [[GMSPinImageOptions alloc] init]; - FGMPlatformColor *backgroundColor = pinConfig.backgroundColor; - if (backgroundColor) { - options.backgroundColor = FGMGetColorForPigeonColor(backgroundColor); - } - - FGMPlatformColor *borderColor = pinConfig.borderColor; - if (borderColor) { - options.borderColor = FGMGetColorForPigeonColor(borderColor); - } - - GMSPinImageGlyph *glyph; - NSString *glyphText = pinConfig.glyphText; - FGMPlatformColor *glyphColor = pinConfig.glyphColor; - FGMPlatformBitmap *glyphBitmap = pinConfig.glyphBitmap; - if (glyphText) { - FGMPlatformColor *glyphTextColorValue = pinConfig.glyphTextColor; - UIColor *glyphTextColor = glyphTextColorValue ? FGMGetColorForPigeonColor(glyphTextColorValue) - : [UIColor blackColor]; - glyph = [[GMSPinImageGlyph alloc] initWithText:glyphText textColor:glyphTextColor]; - } else if (glyphColor) { - UIColor *color = FGMGetColorForPigeonColor(glyphColor); - glyph = [[GMSPinImageGlyph alloc] initWithGlyphColor:color]; - } else if (glyphBitmap) { - UIImage *glyphImage = FGMIconFromBitmap(glyphBitmap, assetProvider, screenScale); - glyph = [[GMSPinImageGlyph alloc] initWithImage:glyphImage]; - } - - options.glyph = glyph; - - image = [GMSPinImage pinImageWithOptions:options]; - } - - return image; -} - -UIImage *scaledImage(UIImage *image, double scale) { - if (fabs(scale - 1) > 1e-3) { - return [UIImage imageWithCGImage:[image CGImage] - scale:(image.scale * scale) - orientation:(image.imageOrientation)]; - } - return image; -} - -UIImage *scaledImageWithScale(UIImage *image, CGFloat scale) { - if (fabs(scale - image.scale) > DBL_EPSILON) { - return [UIImage imageWithCGImage:[image CGImage] - scale:scale - orientation:(image.imageOrientation)]; - } - return image; -} - -UIImage *scaledImageWithSize(UIImage *image, CGSize size) { - CGFloat originalPixelWidth = image.size.width * image.scale; - CGFloat originalPixelHeight = image.size.height * image.scale; - - // Return original image if either original image size or target size is so small that - // image cannot be resized or displayed. - if (originalPixelWidth <= 0 || originalPixelHeight <= 0 || size.width <= 0 || size.height <= 0) { - return image; - } - - // Check if the image's size, accounting for scale, matches the target size. - if (fabs(originalPixelWidth - size.width) <= DBL_EPSILON && - fabs(originalPixelHeight - size.height) <= DBL_EPSILON) { - // No need for resizing, return the original image - return image; - } - - // Check if the aspect ratios are approximately equal. - CGSize originalPixelSize = CGSizeMake(originalPixelWidth, originalPixelHeight); - if (FGMIsScalableWithScaleFactorFromSize(originalPixelSize, size)) { - // Scaled image has close to same aspect ratio, - // updating image scale instead of resizing image. - CGFloat factor = originalPixelWidth / size.width; - return scaledImageWithScale(image, image.scale * factor); - } else { - // Aspect ratios differ significantly, resize the image. - UIGraphicsImageRendererFormat *format = [UIGraphicsImageRendererFormat defaultFormat]; - format.scale = 1.0; - format.opaque = NO; - UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:size - format:format]; - UIImage *newImage = - [renderer imageWithActions:^(UIGraphicsImageRendererContext *_Nonnull context) { - [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; - }]; - - // Return image with proper scaling. - return scaledImageWithScale(newImage, image.scale); - } -} - -UIImage *scaledImageWithWidthHeight(UIImage *image, NSNumber *width, NSNumber *height, - CGFloat screenScale) { - if ((width == nil) && (height == nil)) { - return image; - } - - CGFloat targetWidth = width == nil ? image.size.width : width.doubleValue; - CGFloat targetHeight = height == nil ? image.size.height : height.doubleValue; - - if ((width != nil) && (height == nil)) { - // Calculate height based on aspect ratio if only width is provided. - double aspectRatio = image.size.height / image.size.width; - targetHeight = round(targetWidth * aspectRatio); - } else if ((width == nil) && (height != nil)) { - // Calculate width based on aspect ratio if only height is provided. - double aspectRatio = image.size.width / image.size.height; - targetWidth = round(targetHeight * aspectRatio); - } - - CGSize targetSize = - CGSizeMake(round(targetWidth * screenScale), round(targetHeight * screenScale)); - return scaledImageWithSize(image, targetSize); -} - -BOOL FGMIsScalableWithScaleFactorFromSize(CGSize originalSize, CGSize targetSize) { - // Select the scaling factor based on the longer side to have good precision. - CGFloat scaleFactor = (originalSize.width > originalSize.height) - ? (targetSize.width / originalSize.width) - : (targetSize.height / originalSize.height); - - // Calculate the scaled dimensions. - CGFloat scaledWidth = originalSize.width * scaleFactor; - CGFloat scaledHeight = originalSize.height * scaleFactor; - - // Check if the scaled dimensions are within a one-pixel - // threshold of the target dimensions. - BOOL widthWithinThreshold = fabs(scaledWidth - targetSize.width) <= 1.0; - BOOL heightWithinThreshold = fabs(scaledHeight - targetSize.height) <= 1.0; - - // The image is considered scalable with scale factor - // if both dimensions are within the threshold. - return widthWithinThreshold && heightWithinThreshold; -} diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/include/google_maps_flutter_ios_sdk9_objc/FGMImageUtils.h b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/include/google_maps_flutter_ios_sdk9_objc/FGMImageUtils.h deleted file mode 100644 index a8fd0c82c68..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9_objc/include/google_maps_flutter_ios_sdk9_objc/FGMImageUtils.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -@import GoogleMaps; -@import UIKit; - -#import "FGMAssetProvider.h" -#import "google_maps_flutter_pigeon_messages.g.h" - -NS_ASSUME_NONNULL_BEGIN - -/// Creates a UIImage from Pigeon bitmap. -UIImage *_Nullable FGMIconFromBitmap(FGMPlatformBitmap *platformBitmap, - NSObject *assetProvider, - CGFloat screenScale); -/// Returns a BOOL indicating whether image is considered scalable with the given scale factor from -/// size. -BOOL FGMIsScalableWithScaleFactorFromSize(CGSize originalSize, CGSize targetSize); - -NS_ASSUME_NONNULL_END From 8d5b11be744c70a5a690e6b24b81e970d0316136 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Mon, 17 Aug 2026 10:34:48 -0400 Subject: [PATCH 07/17] Update names and callsites --- .../RunnerTests/ConversionsUtilsTests.swift | 94 ++++++-------- .../ExtractIconFromDataTests.swift | 120 +++++++++--------- .../GroundOverlayControllerTests.swift | 20 +-- .../ClusterManagersController.swift | 5 +- .../ConversionUtils.swift | 23 ++-- .../GoogleMapController.swift | 4 +- .../GroundOverlayController.swift | 2 +- .../HeatmapController.swift | 10 +- .../PolygonController.swift | 8 +- .../PolylineController.swift | 8 +- 10 files changed, 137 insertions(+), 157 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ConversionsUtilsTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ConversionsUtilsTests.swift index cbc1361717c..588c2506d61 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ConversionsUtilsTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ConversionsUtilsTests.swift @@ -15,14 +15,12 @@ import google_maps_flutter_ios_sdk9_objc let platformGreen: CGFloat = 2 / 255.0 let platformBlue: CGFloat = 3 / 255.0 let platformAlpha: CGFloat = 4 / 255.0 - let color = FGMGetColorForPigeonColor( - FGMPlatformColor.make( - withRed: platformRed, - green: platformGreen, - blue: platformBlue, - alpha: platformAlpha - ) - ) + let color = FGMPlatformColor.make( + withRed: platformRed, + green: platformGreen, + blue: platformBlue, + alpha: platformAlpha + ).toUIColor() var red: CGFloat = 0 var green: CGFloat = 0 var blue: CGFloat = 0 @@ -41,7 +39,7 @@ import google_maps_flutter_ios_sdk9_objc let blue: CGFloat = 3 / 255.0 let alpha: CGFloat = 4 / 255.0 let color = UIColor(red: red, green: green, blue: blue, alpha: alpha) - let platformColor = FGMGetPigeonColorForColor(color) + let platformColor = FGMPlatformColor.make(from: color) #expect(abs(red - platformColor.red) <= CGFloat.ulpOfOne) #expect(abs(green - platformColor.green) <= CGFloat.ulpOfOne) #expect(abs(blue - platformColor.blue) <= CGFloat.ulpOfOne) @@ -53,7 +51,7 @@ import google_maps_flutter_ios_sdk9_objc FGMPlatformLatLng.make(withLatitude: 1, longitude: 2), FGMPlatformLatLng.make(withLatitude: 3, longitude: 4), ] - let locations = FGMGetPointsForPigeonLatLngs(latlongs) + let locations = makePoints(from: latlongs) #expect(locations.count == 2) #expect(locations[0].coordinate.latitude == 1) #expect(locations[0].coordinate.longitude == 2) @@ -72,7 +70,7 @@ import google_maps_flutter_ios_sdk9_objc FGMPlatformLatLng.make(withLatitude: 7, longitude: 8), ], ] - let holes = FGMGetHolesForPigeonLatLngArrays(pointsArray) + let holes = makeHoles(from: pointsArray) #expect(holes.count == 2) #expect(holes[0][0].coordinate.latitude == 1) #expect(holes[0][0].coordinate.longitude == 2) @@ -91,7 +89,7 @@ import google_maps_flutter_ios_sdk9_objc bearing: 3.0, viewingAngle: 75.0 ) - let pigeonPosition = FGMGetPigeonCameraPositionForPosition(position) + let pigeonPosition = FGMPlatformCameraPosition.make(from: position) #expect(abs(pigeonPosition.target.latitude - position.target.latitude) <= Double.ulpOfOne) #expect(abs(pigeonPosition.target.longitude - position.target.longitude) <= Double.ulpOfOne) #expect(abs(Float(pigeonPosition.zoom) - position.zoom) <= Float.ulpOfOne) @@ -101,7 +99,7 @@ import google_maps_flutter_ios_sdk9_objc @Test func pigeonPointForGCPoint() { let point = CGPoint(x: 10, y: 20) - let pigeonPoint = FGMGetPigeonPointForCGPoint(point) + let pigeonPoint = FGMPlatformPoint.make(from: point) #expect(abs(pigeonPoint.x - Double(point.x)) <= Double.ulpOfOne) #expect(abs(pigeonPoint.y - Double(point.y)) <= Double.ulpOfOne) } @@ -111,7 +109,7 @@ import google_maps_flutter_ios_sdk9_objc coordinate: CLLocationCoordinate2D(latitude: 10, longitude: 20), coordinate: CLLocationCoordinate2D(latitude: 30, longitude: 40) ) - let pigeonBounds = FGMGetPigeonLatLngBoundsForCoordinateBounds(bounds) + let pigeonBounds = FGMPlatformLatLngBounds.make(from: bounds) #expect(abs(pigeonBounds.southwest.latitude - bounds.southWest.latitude) <= Double.ulpOfOne) #expect(abs(pigeonBounds.southwest.longitude - bounds.southWest.longitude) <= Double.ulpOfOne) #expect(abs(pigeonBounds.northeast.latitude - bounds.northEast.latitude) <= Double.ulpOfOne) @@ -126,7 +124,7 @@ import google_maps_flutter_ios_sdk9_objc zoom: 5.0 ) - let cameraPosition = FGMGetCameraPositionForPigeonCameraPosition(pigeonCameraPosition) + let cameraPosition = pigeonCameraPosition.toGMSCameraPosition() #expect( abs(cameraPosition.target.latitude - pigeonCameraPosition.target.latitude) <= Double.ulpOfOne) @@ -141,7 +139,7 @@ import google_maps_flutter_ios_sdk9_objc @Test func cgPointForPigeonPoint() { let pigeonPoint = FGMPlatformPoint.makeWith(x: 1.0, y: 2.0) - let point = FGMGetCGPointForPigeonPoint(pigeonPoint) + let point = pigeonPoint.toCGPoint() #expect(abs(pigeonPoint.x - Double(point.x)) <= Double.ulpOfOne) #expect(abs(pigeonPoint.y - Double(point.y)) <= Double.ulpOfOne) @@ -153,7 +151,7 @@ import google_maps_flutter_ios_sdk9_objc southwest: FGMPlatformLatLng.make(withLatitude: 1, longitude: 2) ) - let bounds = FGMGetCoordinateBoundsForPigeonLatLngBounds(pigeonBounds) + let bounds = pigeonBounds.toGMSBounds() let accuracy: Double = 0.001 #expect(abs(bounds.southWest.latitude - 1) <= accuracy) @@ -163,11 +161,11 @@ import google_maps_flutter_ios_sdk9_objc } @Test func mapViewTypeFromPigeonType() { - #expect(GMSMapViewType.normal == FGMGetMapViewTypeForPigeonMapType(.normal)) - #expect(GMSMapViewType.satellite == FGMGetMapViewTypeForPigeonMapType(.satellite)) - #expect(GMSMapViewType.terrain == FGMGetMapViewTypeForPigeonMapType(.terrain)) - #expect(GMSMapViewType.hybrid == FGMGetMapViewTypeForPigeonMapType(.hybrid)) - #expect(GMSMapViewType.none == FGMGetMapViewTypeForPigeonMapType(.none)) + #expect(GMSMapViewType.normal == mapViewType(from: .normal)) + #expect(GMSMapViewType.satellite == mapViewType(from: .satellite)) + #expect(GMSMapViewType.terrain == mapViewType(from: .terrain)) + #expect(GMSMapViewType.hybrid == mapViewType(from: .hybrid)) + #expect(GMSMapViewType.none == mapViewType(from: .none)) } @Test func cameraUpdateFromNewCameraPosition() { @@ -179,9 +177,7 @@ import google_maps_flutter_ios_sdk9_objc zoom: 3 ) ) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: newPositionUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: newPositionUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -195,9 +191,7 @@ import google_maps_flutter_ios_sdk9_objc with: FGMPlatformLatLng.make(withLatitude: lat, longitude: lng) ) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -209,16 +203,14 @@ import google_maps_flutter_ios_sdk9_objc withNortheast: FGMPlatformLatLng.make(withLatitude: 1, longitude: 2), southwest: FGMPlatformLatLng.make(withLatitude: 3, longitude: 4) ) - let bounds = FGMGetCoordinateBoundsForPigeonLatLngBounds(pigeonBounds) + let bounds = pigeonBounds.toGMSBounds() let padding: Double = 20 let platformUpdate = FGMPlatformCameraUpdateNewLatLngBounds.make( - with: FGMGetPigeonLatLngBoundsForCoordinateBounds(bounds), + with: FGMPlatformLatLngBounds.make(from: bounds), padding: padding ) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -234,9 +226,7 @@ import google_maps_flutter_ios_sdk9_objc zoom: zoom ) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -248,9 +238,7 @@ import google_maps_flutter_ios_sdk9_objc let y: Double = 2 let platformUpdate = FGMPlatformCameraUpdateScrollBy.make(withDx: x, dy: y) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -261,9 +249,7 @@ import google_maps_flutter_ios_sdk9_objc let zoom: Double = 1 let platformUpdateNoPoint = FGMPlatformCameraUpdateZoomBy.make(withAmount: zoom, focus: nil) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdateNoPoint) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdateNoPoint).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -279,9 +265,7 @@ import google_maps_flutter_ios_sdk9_objc focus: FGMPlatformPoint.makeWith(x: x, y: y) ) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -291,9 +275,7 @@ import google_maps_flutter_ios_sdk9_objc @Test func cameraUpdateFromZoomIn() { let platformUpdate = FGMPlatformCameraUpdateZoom.make(withOut: false) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -303,9 +285,7 @@ import google_maps_flutter_ios_sdk9_objc @Test func cameraUpdateFromZoomOut() { let platformUpdate = FGMPlatformCameraUpdateZoom.make(withOut: true) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -316,9 +296,7 @@ import google_maps_flutter_ios_sdk9_objc let zoom: Double = 1 let platformUpdate = FGMPlatformCameraUpdateZoomTo.make(withZoom: zoom) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -332,7 +310,7 @@ import google_maps_flutter_ios_sdk9_objc ] let strokeColor = UIColor.red - let patternStrokeStyle = FGMGetStrokeStylesFromPatterns(patterns, strokeColor) + let patternStrokeStyle = makeStrokeStyles(from: patterns, strokeColor: strokeColor) #expect(patternStrokeStyle.count == 2) // None of the parameters of `patternStrokeStyle` is observable, so we limit to testing @@ -347,7 +325,7 @@ import google_maps_flutter_ios_sdk9_objc FGMPlatformPatternItem.make(with: .dash, length: dashLength as NSNumber), ] - let spanLengths = FGMGetSpanLengthsFromPatterns(patterns) + let spanLengths = makeSpanLengths(from: patterns) #expect(spanLengths.count == 2) @@ -372,7 +350,7 @@ import google_maps_flutter_ios_sdk9_objc ), ] - let weightedData = FGMGetWeightedDataForPigeonWeightedData(data) + let weightedData = makeWeightedData(from: data) #expect(Double(weightedData[0].intensity) == intensity1) #expect(Double(weightedData[1].intensity) == intensity2) } @@ -397,7 +375,7 @@ import google_maps_flutter_ios_sdk9_objc colorMapSize: colorMapSize ) - let gradient = FGMGetGradientForPigeonHeatmapGradient(platformGradient) + let gradient = platformGradient.toGMUGradient() var red: CGFloat = 0 var green: CGFloat = 0 var blue: CGFloat = 0 diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ExtractIconFromDataTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ExtractIconFromDataTests.swift index 1179c69744f..2e50149f2c5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ExtractIconFromDataTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ExtractIconFromDataTests.swift @@ -25,10 +25,10 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) @@ -53,10 +53,10 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) @@ -83,10 +83,10 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) #expect(testImage.scale == 1.0) @@ -118,10 +118,10 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == screenScale) @@ -145,10 +145,10 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) @@ -172,10 +172,10 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) @@ -199,10 +199,10 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == 10) @@ -227,10 +227,10 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) @@ -262,10 +262,10 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == screenScale) @@ -288,10 +288,10 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == 1.0) @@ -300,7 +300,7 @@ import google_maps_flutter_ios_sdk9_objc } /// Tests for PinConfig (GMSPinImageOptions) - requires iOS 16.0+ and Google Maps SDK 9.0+. - /// On earlier versions, FGMIconFromBitmap returns nil for PinConfig, which is expected behavior. + /// On earlier versions, makeIcon returns nil for PinConfig, which is expected behavior. @Test func extractIconFromPinConfigWithGlyphColor() { let assetProvider = TestAssetProvider() @@ -319,10 +319,10 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: pinConfig), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: pinConfig), + assetProvider: assetProvider, + screenScale: screenScale ) // PinConfig may return nil on old Google Maps SDK versions (<=8.4.0). @@ -348,10 +348,10 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: pinConfig), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: pinConfig), + assetProvider: assetProvider, + screenScale: screenScale ) // PinConfig returns nil on iOS versions without GMSPinImageOptions support (< iOS 16.0). @@ -390,10 +390,10 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: pinConfig), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: pinConfig), + assetProvider: assetProvider, + screenScale: screenScale ) // PinConfig returns nil on iOS versions without GMSPinImageOptions support (< iOS 16.0). @@ -407,43 +407,43 @@ import google_maps_flutter_ios_sdk9_objc @Test func isScalableWithScaleFactorFromSize100x100to10x100() { let originalSize = CGSize(width: 100.0, height: 100.0) let targetSize = CGSize(width: 10.0, height: 100.0) - #expect(!FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(!isScalableWithScaleFactor(from: originalSize, to: targetSize)) } @Test func isScalableWithScaleFactorFromSize100x100to10x10() { let originalSize = CGSize(width: 100.0, height: 100.0) let targetSize = CGSize(width: 10.0, height: 10.0) - #expect(FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(isScalableWithScaleFactor(from: originalSize, to: targetSize)) } @Test func isScalableWithScaleFactorFromSize233x200to23x20() { let originalSize = CGSize(width: 233.0, height: 200.0) let targetSize = CGSize(width: 23.0, height: 20.0) - #expect(FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(isScalableWithScaleFactor(from: originalSize, to: targetSize)) } @Test func isScalableWithScaleFactorFromSize233x200to22x20() { let originalSize = CGSize(width: 233.0, height: 200.0) let targetSize = CGSize(width: 22.0, height: 20.0) - #expect(!FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(!isScalableWithScaleFactor(from: originalSize, to: targetSize)) } @Test func isScalableWithScaleFactorFromSize200x233to20x23() { let originalSize = CGSize(width: 200.0, height: 233.0) let targetSize = CGSize(width: 20.0, height: 23.0) - #expect(FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(isScalableWithScaleFactor(from: originalSize, to: targetSize)) } @Test func isScalableWithScaleFactorFromSize200x233to20x22() { let originalSize = CGSize(width: 200.0, height: 233.0) let targetSize = CGSize(width: 20.0, height: 22.0) - #expect(!FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(!isScalableWithScaleFactor(from: originalSize, to: targetSize)) } @Test func isScalableWithScaleFactorFromSize1024x768to500x250() { let originalSize = CGSize(width: 1024.0, height: 768.0) let targetSize = CGSize(width: 500.0, height: 250.0) - #expect(!FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(!isScalableWithScaleFactor(from: originalSize, to: targetSize)) } private func createOnePixelImage() -> UIImage { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GroundOverlayControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GroundOverlayControllerTests.swift index 0d2e80b00c5..8223f32486b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GroundOverlayControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GroundOverlayControllerTests.swift @@ -116,11 +116,11 @@ import google_maps_flutter_ios_sdk9_objc #expect(abs(groundOverlayController.groundOverlay.anchor.y - 0.5) <= Double.ulpOfOne) #expect(groundOverlayController.groundOverlay.zIndex == Int32(platformGroundOverlay.zIndex)) - let convertedPlatformGroundOverlay = FGMGetPigeonGroundOverlay( - groundOverlayController.groundOverlay, - "id_1", - false, - 14.0 + let convertedPlatformGroundOverlay = FGMPlatformGroundOverlay.make( + from: groundOverlayController.groundOverlay, + overlayId: "id_1", + isCreatedWithBounds: false, + zoomLevel: 14.0 ) #expect(convertedPlatformGroundOverlay.groundOverlayId == "id_1") #expect( @@ -183,11 +183,11 @@ import google_maps_flutter_ios_sdk9_objc #expect(abs(groundOverlayController.groundOverlay.anchor.y - 0.5) <= Double.ulpOfOne) #expect(groundOverlayController.groundOverlay.zIndex == Int32(platformGroundOverlay.zIndex)) - let convertedPlatformGroundOverlay = FGMGetPigeonGroundOverlay( - groundOverlayController.groundOverlay, - "id_1", - true, - nil + let convertedPlatformGroundOverlay = FGMPlatformGroundOverlay.make( + from: groundOverlayController.groundOverlay, + overlayId: "id_1", + isCreatedWithBounds: true, + zoomLevel: nil ) #expect(convertedPlatformGroundOverlay.groundOverlayId == "id_1") #expect( diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ClusterManagersController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ClusterManagersController.swift index 62340b9db55..5c6fea53c63 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ClusterManagersController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ClusterManagersController.swift @@ -74,12 +74,13 @@ class ClusterManagersController: NSObject { // https://github.com/googlemaps/google-maps-ios-utils/blob/0e7ed81f1bbd9d29e4529c40ae39b0791b0a0eb8/src/Clustering/GMUClusterManager.m#L94. let integralZoom = floorf(Float(mapView.camera.zoom) + 0.5) let clusters = clusterManager.algorithm.clusters(atZoom: integralZoom) - return clusters.map { pigeonCluster(for: $0, clusterManagerIdentifier: identifier) } + return clusters.map { FGMPlatformCluster.make(from: $0, clusterManagerIdentifier: identifier) } } func didTap(_ cluster: GMUStaticCluster) { guard let clusterManagerId = clusterManagerIdentifier(for: cluster) else { return } - let platformCluster = pigeonCluster(for: cluster, clusterManagerIdentifier: clusterManagerId) + let platformCluster = FGMPlatformCluster.make( + from: cluster, clusterManagerIdentifier: clusterManagerId) eventDelegate?.didTap(platformCluster) } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift index 6140a3385fb..bdd59270e8c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift @@ -229,37 +229,38 @@ func makePigeonWeightedData(from weightedLatLngs: [GMUWeightedLatLng]) extension FGMPlatformCameraUpdate { /// Creates a GMSCameraUpdate from its Pigeon equivalent. - static func make(from cameraUpdate: FGMPlatformCameraUpdate) -> GMSCameraUpdate? { + func toGMSCameraUpdate() -> GMSCameraUpdate? { // See note in messages.dart for why this is so loosely typed. - let update = cameraUpdate.cameraUpdate - if let newCameraPosition = update as? FGMPlatformCameraUpdateNewCameraPosition { + switch cameraUpdate { + case let newCameraPosition as FGMPlatformCameraUpdateNewCameraPosition: return GMSCameraUpdate.setCamera(newCameraPosition.cameraPosition.toGMSCameraPosition()) - } else if let newLatLng = update as? FGMPlatformCameraUpdateNewLatLng { + case let newLatLng as FGMPlatformCameraUpdateNewLatLng: return GMSCameraUpdate.setTarget(newLatLng.latLng.toCLCoordinate()) - } else if let newLatLngBounds = update as? FGMPlatformCameraUpdateNewLatLngBounds { + case let newLatLngBounds as FGMPlatformCameraUpdateNewLatLngBounds: return GMSCameraUpdate.fit( newLatLngBounds.bounds.toGMSBounds(), withPadding: CGFloat(newLatLngBounds.padding) ) - } else if let newLatLngZoom = update as? FGMPlatformCameraUpdateNewLatLngZoom { + case let newLatLngZoom as FGMPlatformCameraUpdateNewLatLngZoom: return GMSCameraUpdate.setTarget( newLatLngZoom.latLng.toCLCoordinate(), zoom: Float(newLatLngZoom.zoom) ) - } else if let scrollBy = update as? FGMPlatformCameraUpdateScrollBy { + case let scrollBy as FGMPlatformCameraUpdateScrollBy: return GMSCameraUpdate.scrollBy(x: scrollBy.dx, y: scrollBy.dy) - } else if let zoomBy = update as? FGMPlatformCameraUpdateZoomBy { + case let zoomBy as FGMPlatformCameraUpdateZoomBy: if let focus = zoomBy.focus { return GMSCameraUpdate.zoom(by: Float(zoomBy.amount), at: focus.toCGPoint()) } else { return GMSCameraUpdate.zoom(by: Float(zoomBy.amount)) } - } else if let zoom = update as? FGMPlatformCameraUpdateZoom { + case let zoom as FGMPlatformCameraUpdateZoom: return zoom.out ? GMSCameraUpdate.zoomOut() : GMSCameraUpdate.zoomIn() - } else if let zoomTo = update as? FGMPlatformCameraUpdateZoomTo { + case let zoomTo as FGMPlatformCameraUpdateZoomTo: return GMSCameraUpdate.zoom(to: Float(zoomTo.zoom)) + default: + return nil } - return nil } } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift index 08090a0674a..d0208298d7f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift @@ -691,7 +691,7 @@ class MapCallHandler: NSObject, FGMMapsApi { with cameraUpdate: FGMPlatformCameraUpdate, error: AutoreleasingUnsafeMutablePointer ) { - guard let update = FGMPlatformCameraUpdate.make(from: cameraUpdate) else { + guard let update = cameraUpdate.toGMSCameraUpdate() else { error.pointee = FlutterError( code: "Invalid update", message: "Unrecognized camera update", @@ -706,7 +706,7 @@ class MapCallHandler: NSObject, FGMMapsApi { with cameraUpdate: FGMPlatformCameraUpdate, duration durationMilliseconds: NSNumber?, error: AutoreleasingUnsafeMutablePointer ) { - guard let update = FGMPlatformCameraUpdate.make(from: cameraUpdate) else { + guard let update = cameraUpdate.toGMSCameraUpdate() else { error.pointee = FlutterError( code: "Invalid update", message: "Unrecognized camera update", diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GroundOverlayController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GroundOverlayController.swift index fa8e119be97..616824fe4a1 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GroundOverlayController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GroundOverlayController.swift @@ -221,7 +221,7 @@ class GroundOverlaysController: NSObject { guard let controller = groundOverlayControllerByIdentifier[identifier] else { return nil } - return pigeonGroundOverlay( + return FGMPlatformGroundOverlay.make( from: controller.groundOverlay, overlayId: identifier, isCreatedWithBounds: controller.createdWithBounds, diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift index 1f5deebdbc7..e8e4bdda61d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift @@ -39,9 +39,9 @@ class HeatmapController: NSObject { from platformHeatmap: FGMPlatformHeatmap, mapView: GMSMapView ) { - heatmapTileLayer.weightedData = weightedData(from: platformHeatmap.data) - if let gradientValue = platformHeatmap.gradient { - heatmapTileLayer.gradient = gradient(from: gradientValue) + heatmapTileLayer.weightedData = makeWeightedData(from: platformHeatmap.data) + if let gradient = platformHeatmap.gradient { + heatmapTileLayer.gradient = gradient.toGMUGradient() } heatmapTileLayer.opacity = Float(platformHeatmap.opacity) heatmapTileLayer.radius = UInt(platformHeatmap.radius) @@ -104,8 +104,8 @@ class HeatmapsController: NSObject { let heatmap = controller.heatmapTileLayer return FGMPlatformHeatmap.make( withHeatmapId: identifier, - data: pigeonWeightedData(from: heatmap.weightedData), - gradient: pigeonHeatmapGradient(from: heatmap.gradient), + data: makePigeonWeightedData(from: heatmap.weightedData), + gradient: FGMPlatformHeatmapGradient.make(from: heatmap.gradient), opacity: Double(heatmap.opacity), radius: Int(heatmap.radius), minimumZoomIntensity: Int(heatmap.minimumZoomIntensity), diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolygonController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolygonController.swift index 501044bb6b1..17ef749ffa3 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolygonController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolygonController.swift @@ -41,10 +41,10 @@ class PolygonController: NSObject { ) { polygon.isTappable = platformPolygon.consumesTapEvents polygon.zIndex = Int32(platformPolygon.zIndex) - polygon.path = path(from: points(from: platformPolygon.points)) - polygon.holes = holes(from: platformPolygon.holes).map { path(from: $0) } - polygon.fillColor = color(from: platformPolygon.fillColor) - polygon.strokeColor = color(from: platformPolygon.strokeColor) + polygon.path = makePath(from: makePoints(from: platformPolygon.points)) + polygon.holes = makeHoles(from: platformPolygon.holes).map { makePath(from: $0) } + polygon.fillColor = platformPolygon.fillColor.toUIColor() + polygon.strokeColor = platformPolygon.strokeColor.toUIColor() polygon.strokeWidth = CGFloat(platformPolygon.strokeWidth) // This must be done last, to avoid visual flickers of default property values. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolylineController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolylineController.swift index 132203f6773..f84a0e3cbe8 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolylineController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolylineController.swift @@ -41,16 +41,16 @@ class PolylineController: NSObject { ) { polyline.isTappable = platformPolyline.consumesTapEvents polyline.zIndex = Int32(platformPolyline.zIndex) - let gmsPath = path(from: points(from: platformPolyline.points)) + let gmsPath = makePath(from: makePoints(from: platformPolyline.points)) polyline.path = gmsPath - let strokeColor = color(from: platformPolyline.color) + let strokeColor = platformPolyline.color.toUIColor() polyline.strokeColor = strokeColor polyline.strokeWidth = CGFloat(platformPolyline.width) polyline.geodesic = platformPolyline.geodesic polyline.spans = GMSStyleSpans( gmsPath, - strokeStyles(from: platformPolyline.patterns ?? [], strokeColor: strokeColor), - spanLengths(from: platformPolyline.patterns ?? []), + makeStrokeStyles(from: platformPolyline.patterns, strokeColor: strokeColor), + makeSpanLengths(from: platformPolyline.patterns), .rhumb ) From 2f38ed8ea7d4d55782be69b9572923e047a17e25 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Mon, 31 Aug 2026 14:22:03 -0400 Subject: [PATCH 08/17] Remove unused file --- .../example/ios/RunnerTests/RunnerTests-Bridging-Header.h | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/RunnerTests-Bridging-Header.h diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/RunnerTests-Bridging-Header.h b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/RunnerTests-Bridging-Header.h deleted file mode 100644 index dbf1fceec6c..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/RunnerTests-Bridging-Header.h +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Import private _Test.h headers from the plugin framework -#import From 71c226d608e40b7d666b2b5cffb11fbafcd2d620 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Mon, 31 Aug 2026 14:23:46 -0400 Subject: [PATCH 09/17] Simplify project changes manually --- .../ios/Runner.xcodeproj/project.pbxproj | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/Runner.xcodeproj/project.pbxproj b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/Runner.xcodeproj/project.pbxproj index 4977a41df81..df7519a7282 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/Runner.xcodeproj/project.pbxproj @@ -3,32 +3,32 @@ archiveVersion = 1; classes = { }; - objectVersion = 60; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ + A73F1ED02A874D8596718BE8 /* CircleControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E0364A58CE4D1F8AA3D564 /* CircleControllerTests.swift */; }; + E680DCBC3E7E41089DF60756 /* ClusterManagersControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB05BECEF774386944B77D3 /* ClusterManagersControllerTests.swift */; }; + 24A50C44E228413BABF647EF /* ConversionsUtilsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3331542510941C3930DDCB6 /* ConversionsUtilsTests.swift */; }; + 4518AF21C4DF4AA58D1BB89A /* ExtractIconFromDataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD78CCDD89347059EA71321 /* ExtractIconFromDataTests.swift */; }; + 67E9ECF639A945B9AB14A2EE /* GoogleMapsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5F71F034C24D0AA977F27E /* GoogleMapsTests.swift */; }; + B6EBFD5819964A73A1B0AE2A /* GroundOverlayControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2A4D627F452421DBDA834D2 /* GroundOverlayControllerTests.swift */; }; + 84CBDF074688494FA4924CA0 /* HeatmapControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64D0CE44D4164F2784CA4CD7 /* HeatmapControllerTests.swift */; }; + B2982FE0843F4FCB8D07D1D3 /* MarkerControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A396257FAF0545FC87D21257 /* MarkerControllerTests.swift */; }; + A37563E79BA24E4C98D77DD0 /* PolygonControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F220BC4477BC42E8870F2D4E /* PolygonControllerTests.swift */; }; + 6F94C58F3ECF465092D78750 /* PolylineControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 350A657853294B478D70CD62 /* PolylineControllerTests.swift */; }; 02F1F6249887487CBC3019FC /* TileOverlayControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F65543ABD25496A92F8F91F /* TileOverlayControllerTests.swift */; }; + 71C9A982E01441D0A61ABCC7 /* TileProviderControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CD823EECFC4BDD8755DD92 /* TileProviderControllerTests.swift */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 24A50C44E228413BABF647EF /* ConversionsUtilsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3331542510941C3930DDCB6 /* ConversionsUtilsTests.swift */; }; 3390B45E2F33AFA60094DEB9 /* PartiallyMockedMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3390B4582F33AFA60094DEB9 /* PartiallyMockedMapView.swift */; }; 3390B45F2F33AFA60094DEB9 /* TestAssetProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3390B45A2F33AFA60094DEB9 /* TestAssetProvider.swift */; }; 3390B4602F33AFA60094DEB9 /* TestMapEventHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3390B45C2F33AFA60094DEB9 /* TestMapEventHandler.swift */; }; 339DF1F02F1FE49800748863 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 339DF1EF2F1FE49300748863 /* AppDelegate.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 4518AF21C4DF4AA58D1BB89A /* ExtractIconFromDataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD78CCDD89347059EA71321 /* ExtractIconFromDataTests.swift */; }; - 67E9ECF639A945B9AB14A2EE /* GoogleMapsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5F71F034C24D0AA977F27E /* GoogleMapsTests.swift */; }; - 6F94C58F3ECF465092D78750 /* PolylineControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 350A657853294B478D70CD62 /* PolylineControllerTests.swift */; }; - 71C9A982E01441D0A61ABCC7 /* TileProviderControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CD823EECFC4BDD8755DD92 /* TileProviderControllerTests.swift */; }; 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; }; - 84CBDF074688494FA4924CA0 /* HeatmapControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64D0CE44D4164F2784CA4CD7 /* HeatmapControllerTests.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - A37563E79BA24E4C98D77DD0 /* PolygonControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F220BC4477BC42E8870F2D4E /* PolygonControllerTests.swift */; }; - A73F1ED02A874D8596718BE8 /* CircleControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E0364A58CE4D1F8AA3D564 /* CircleControllerTests.swift */; }; - B2982FE0843F4FCB8D07D1D3 /* MarkerControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A396257FAF0545FC87D21257 /* MarkerControllerTests.swift */; }; - B6EBFD5819964A73A1B0AE2A /* GroundOverlayControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2A4D627F452421DBDA834D2 /* GroundOverlayControllerTests.swift */; }; - E680DCBC3E7E41089DF60756 /* ClusterManagersControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB05BECEF774386944B77D3 /* ClusterManagersControllerTests.swift */; }; F269303B2BB389BF00BF17C4 /* assets in Resources */ = {isa = PBXBuildFile; fileRef = F269303A2BB389BF00BF17C4 /* assets */; }; F7151F21265D7EE50028CB91 /* GoogleMapsUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3351C2253008164500700458 /* GoogleMapsUITests.swift */; }; /* End PBXBuildFile section */ @@ -64,8 +64,19 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 0F65543ABD25496A92F8F91F /* TileOverlayControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileOverlayControllerTests.swift; sourceTree = ""; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + F8E0364A58CE4D1F8AA3D564 /* CircleControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleControllerTests.swift; sourceTree = ""; }; + 9FB05BECEF774386944B77D3 /* ClusterManagersControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClusterManagersControllerTests.swift; sourceTree = ""; }; + D3331542510941C3930DDCB6 /* ConversionsUtilsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversionsUtilsTests.swift; sourceTree = ""; }; + 5BD78CCDD89347059EA71321 /* ExtractIconFromDataTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtractIconFromDataTests.swift; sourceTree = ""; }; + CD5F71F034C24D0AA977F27E /* GoogleMapsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoogleMapsTests.swift; sourceTree = ""; }; + C2A4D627F452421DBDA834D2 /* GroundOverlayControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroundOverlayControllerTests.swift; sourceTree = ""; }; + 64D0CE44D4164F2784CA4CD7 /* HeatmapControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeatmapControllerTests.swift; sourceTree = ""; }; + A396257FAF0545FC87D21257 /* MarkerControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkerControllerTests.swift; sourceTree = ""; }; + F220BC4477BC42E8870F2D4E /* PolygonControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolygonControllerTests.swift; sourceTree = ""; }; + 350A657853294B478D70CD62 /* PolylineControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolylineControllerTests.swift; sourceTree = ""; }; + 0F65543ABD25496A92F8F91F /* TileOverlayControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileOverlayControllerTests.swift; sourceTree = ""; }; + 54CD823EECFC4BDD8755DD92 /* TileProviderControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileProviderControllerTests.swift; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 3351C2253008164500700458 /* GoogleMapsUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoogleMapsUITests.swift; sourceTree = ""; }; 3390B4582F33AFA60094DEB9 /* PartiallyMockedMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartiallyMockedMapView.swift; sourceTree = ""; }; @@ -73,11 +84,7 @@ 3390B45C2F33AFA60094DEB9 /* TestMapEventHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestMapEventHandler.swift; sourceTree = ""; }; 339DF1EF2F1FE49300748863 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 339DF1F12F1FE4AD00748863 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; - 350A657853294B478D70CD62 /* PolylineControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolylineControllerTests.swift; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 54CD823EECFC4BDD8755DD92 /* TileProviderControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileProviderControllerTests.swift; sourceTree = ""; }; - 5BD78CCDD89347059EA71321 /* ExtractIconFromDataTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtractIconFromDataTests.swift; sourceTree = ""; }; - 64D0CE44D4164F2784CA4CD7 /* HeatmapControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeatmapControllerTests.swift; sourceTree = ""; }; 784666492D4C4C64000A1A5F /* FlutterFramework */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterFramework; path = Flutter/ephemeral/Packages/.packages/FlutterFramework; sourceTree = ""; }; 78DABEA22ED26510000E7860 /* google_maps_flutter_ios_sdk9 */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = google_maps_flutter_ios_sdk9; path = ../../ios/google_maps_flutter_ios_sdk9; sourceTree = ""; }; 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = ""; }; @@ -89,18 +96,11 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 9FB05BECEF774386944B77D3 /* ClusterManagersControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClusterManagersControllerTests.swift; sourceTree = ""; }; - A396257FAF0545FC87D21257 /* MarkerControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkerControllerTests.swift; sourceTree = ""; }; - C2A4D627F452421DBDA834D2 /* GroundOverlayControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroundOverlayControllerTests.swift; sourceTree = ""; }; - CD5F71F034C24D0AA977F27E /* GoogleMapsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoogleMapsTests.swift; sourceTree = ""; }; - D3331542510941C3930DDCB6 /* ConversionsUtilsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversionsUtilsTests.swift; sourceTree = ""; }; - F220BC4477BC42E8870F2D4E /* PolygonControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolygonControllerTests.swift; sourceTree = ""; }; F269303A2BB389BF00BF17C4 /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = assets; sourceTree = ""; }; F7151F10265D7ED70028CB91 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; F7151F14265D7ED70028CB91 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; F7151F1E265D7EE50028CB91 /* RunnerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; F7151F22265D7EE50028CB91 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - F8E0364A58CE4D1F8AA3D564 /* CircleControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleControllerTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -646,8 +646,8 @@ MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/Runner"; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -666,8 +666,8 @@ MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/Runner"; + SWIFT_VERSION = 5.0; }; name = Release; }; From 67ef495bf11ce9a8de0108e6bdc68f0d12c881fa Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Tue, 1 Sep 2026 11:16:52 -0400 Subject: [PATCH 10/17] More extensions, local Gemini review --- .../RunnerTests/ConversionsUtilsTests.swift | 118 ++++-------- .../CircleController.swift | 2 +- .../ConversionUtils.swift | 172 ++++++++---------- .../GoogleMapController.swift | 6 +- .../HeatmapController.swift | 4 +- .../ImageUtils.swift | 63 ++++--- .../MarkerController.swift | 6 +- .../PolygonController.swift | 4 +- .../PolylineController.swift | 6 +- 9 files changed, 155 insertions(+), 226 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ConversionsUtilsTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ConversionsUtilsTests.swift index 588c2506d61..c73da79c62b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ConversionsUtilsTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ConversionsUtilsTests.swift @@ -46,40 +46,11 @@ import google_maps_flutter_ios_sdk9_objc #expect(abs(alpha - platformColor.alpha) <= CGFloat.ulpOfOne) } - @Test func pointsFromLatLongs() { - let latlongs = [ - FGMPlatformLatLng.make(withLatitude: 1, longitude: 2), - FGMPlatformLatLng.make(withLatitude: 3, longitude: 4), - ] - let locations = makePoints(from: latlongs) - #expect(locations.count == 2) - #expect(locations[0].coordinate.latitude == 1) - #expect(locations[0].coordinate.longitude == 2) - #expect(locations[1].coordinate.latitude == 3) - #expect(locations[1].coordinate.longitude == 4) - } - - @Test func holesFromPointsArray() { - let pointsArray = [ - [ - FGMPlatformLatLng.make(withLatitude: 1, longitude: 2), - FGMPlatformLatLng.make(withLatitude: 3, longitude: 4), - ], - [ - FGMPlatformLatLng.make(withLatitude: 5, longitude: 6), - FGMPlatformLatLng.make(withLatitude: 7, longitude: 8), - ], - ] - let holes = makeHoles(from: pointsArray) - #expect(holes.count == 2) - #expect(holes[0][0].coordinate.latitude == 1) - #expect(holes[0][0].coordinate.longitude == 2) - #expect(holes[0][1].coordinate.latitude == 3) - #expect(holes[0][1].coordinate.longitude == 4) - #expect(holes[1][0].coordinate.latitude == 5) - #expect(holes[1][0].coordinate.longitude == 6) - #expect(holes[1][1].coordinate.latitude == 7) - #expect(holes[1][1].coordinate.longitude == 8) + @Test func pointFromLatLong() { + let latlong = FGMPlatformLatLng.make(withLatitude: 1, longitude: 2) + let location = latlong.toCLLocation() + #expect(location.coordinate.latitude == 1) + #expect(location.coordinate.longitude == 2) } @Test func getPigeonCameraPositionForPosition() { @@ -151,7 +122,7 @@ import google_maps_flutter_ios_sdk9_objc southwest: FGMPlatformLatLng.make(withLatitude: 1, longitude: 2) ) - let bounds = pigeonBounds.toGMSBounds() + let bounds = pigeonBounds.toGMSCoordinateBounds() let accuracy: Double = 0.001 #expect(abs(bounds.southWest.latitude - 1) <= accuracy) @@ -161,11 +132,11 @@ import google_maps_flutter_ios_sdk9_objc } @Test func mapViewTypeFromPigeonType() { - #expect(GMSMapViewType.normal == mapViewType(from: .normal)) - #expect(GMSMapViewType.satellite == mapViewType(from: .satellite)) - #expect(GMSMapViewType.terrain == mapViewType(from: .terrain)) - #expect(GMSMapViewType.hybrid == mapViewType(from: .hybrid)) - #expect(GMSMapViewType.none == mapViewType(from: .none)) + #expect(GMSMapViewType.normal == FGMPlatformMapType.normal.gmsMapViewType) + #expect(GMSMapViewType.satellite == FGMPlatformMapType.satellite.gmsMapViewType) + #expect(GMSMapViewType.terrain == FGMPlatformMapType.terrain.gmsMapViewType) + #expect(GMSMapViewType.hybrid == FGMPlatformMapType.hybrid.gmsMapViewType) + #expect(GMSMapViewType.none == FGMPlatformMapType.none.gmsMapViewType) } @Test func cameraUpdateFromNewCameraPosition() { @@ -203,7 +174,7 @@ import google_maps_flutter_ios_sdk9_objc withNortheast: FGMPlatformLatLng.make(withLatitude: 1, longitude: 2), southwest: FGMPlatformLatLng.make(withLatitude: 3, longitude: 4) ) - let bounds = pigeonBounds.toGMSBounds() + let bounds = pigeonBounds.toGMSCoordinateBounds() let padding: Double = 20 let platformUpdate = FGMPlatformCameraUpdateNewLatLngBounds.make( @@ -303,56 +274,41 @@ import google_maps_flutter_ios_sdk9_objc // implementation would be about as complex as the conversion function itself. } - @Test func strokeStylesFromPatterns() { - let patterns = [ - FGMPlatformPatternItem.make(with: .gap, length: 1), - FGMPlatformPatternItem.make(with: .dash, length: 1), - ] + @Test func strokeStyleFromPattern() { + let pattern = FGMPlatformPatternItem.make(with: .dash, length: 1) let strokeColor = UIColor.red - let patternStrokeStyle = makeStrokeStyles(from: patterns, strokeColor: strokeColor) - - #expect(patternStrokeStyle.count == 2) - // None of the parameters of `patternStrokeStyle` is observable, so we limit to testing - // the length of this output array. + _ = pattern.gmsStrokeStyle(strokeColor: strokeColor) + // GMSStrokeStyle is not inspectable, so this test just ensures that the codepath + // doesn't throw. } - @Test func lengthsFromPatterns() { - let gapLength: Double = 10 - let dashLength: Double = 6.4 - let patterns = [ - FGMPlatformPatternItem.make(with: .gap, length: gapLength as NSNumber), - FGMPlatformPatternItem.make(with: .dash, length: dashLength as NSNumber), - ] + @Test func nonNullLengthFromPatternItem() { + let length: Double = 6.4 + let pattern = FGMPlatformPatternItem.make(with: .gap, length: length as NSNumber) - let spanLengths = makeSpanLengths(from: patterns) + let spanLength = pattern.gmsStyleSpanLength() - #expect(spanLengths.count == 2) + #expect(spanLength.doubleValue == length) + } + + @Test func nullLengthFromPatternItem() { + let pattern = FGMPlatformPatternItem.make(with: .dot, length: nil) - let firstSpanLength = spanLengths[0] - let secondSpanLength = spanLengths[1] + let spanLength = pattern.gmsStyleSpanLength() - #expect(firstSpanLength.doubleValue == gapLength) - #expect(secondSpanLength.doubleValue == dashLength) + #expect(spanLength.doubleValue == 0) } - @Test func weightedDataFromPlatformWeightedData() { - let intensity1: Double = 3.0 - let intensity2: Double = 6.0 - let data = [ - FGMPlatformWeightedLatLng.make( - withPoint: FGMPlatformLatLng.make(withLatitude: 10, longitude: 20), - weight: intensity1 - ), - FGMPlatformWeightedLatLng.make( - withPoint: FGMPlatformLatLng.make(withLatitude: 30, longitude: 40), - weight: intensity2 - ), - ] - - let weightedData = makeWeightedData(from: data) - #expect(Double(weightedData[0].intensity) == intensity1) - #expect(Double(weightedData[1].intensity) == intensity2) + @Test func weightedLatLngFromPlatformWeightedLatLng() { + let intensity: Double = 3.0 + let data = FGMPlatformWeightedLatLng.make( + withPoint: FGMPlatformLatLng.make(withLatitude: 10, longitude: 20), + weight: intensity + ) + + let weightedData = data.toGMUWeightedLatLng() + #expect(Double(weightedData.intensity) == intensity) } @Test func gradientFromPlatformGradient() { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/CircleController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/CircleController.swift index 67dd76b8016..cec0abb3cbb 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/CircleController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/CircleController.swift @@ -42,7 +42,7 @@ class CircleController: NSObject { ) { circle.isTappable = platformCircle.consumeTapEvents circle.zIndex = Int32(platformCircle.zIndex) - circle.position = platformCircle.center.toCLCoordinate() + circle.position = platformCircle.center.toCLLocationCoordinate2D() circle.radius = platformCircle.radius circle.strokeColor = platformCircle.strokeColor.toUIColor() circle.strokeWidth = CGFloat(platformCircle.strokeWidth) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift index bdd59270e8c..6b770e82e08 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift @@ -16,7 +16,7 @@ extension FGMPlatformPoint { return FGMPlatformPoint.makeWith(x: point.x, y: point.y) } - /// Converts a CGPoint from its Pigeon equivalent. + /// Returns the equivalent CGPoint. func toCGPoint() -> CGPoint { return CGPoint(x: x, y: y) } @@ -29,10 +29,15 @@ extension FGMPlatformLatLng { withLatitude: coordinate.latitude, longitude: coordinate.longitude) } - /// Creates a CLLocationCoordinate2D from its Pigeon representation. - func toCLCoordinate() -> CLLocationCoordinate2D { + /// Returns the equivalent CLLocationCoordinate2D. + func toCLLocationCoordinate2D() -> CLLocationCoordinate2D { return CLLocationCoordinate2D(latitude: latitude, longitude: longitude) } + + /// Returns the equivalent CLLocation. + func toCLLocation() -> CLLocation { + return CLLocation(latitude: latitude, longitude: longitude) + } } extension FGMPlatformLatLngBounds { @@ -44,11 +49,11 @@ extension FGMPlatformLatLngBounds { ) } - /// Creates a GMSCoordinateBounds from its Pigeon representation. - func toGMSBounds() -> GMSCoordinateBounds { + /// Returns the equivalent GMSCoordinateBounds. + func toGMSCoordinateBounds() -> GMSCoordinateBounds { return GMSCoordinateBounds( - coordinate: northeast.toCLCoordinate(), - coordinate: southwest.toCLCoordinate() + coordinate: northeast.toCLLocationCoordinate2D(), + coordinate: southwest.toCLLocationCoordinate2D() ) } } @@ -64,10 +69,10 @@ extension FGMPlatformCameraPosition { ) } - /// Creates a GMSCameraPosition from its Pigeon representation. + /// Returns the equivalent GMSCameraPosition. func toGMSCameraPosition() -> GMSCameraPosition { return GMSCameraPosition( - target: target.toCLCoordinate(), + target: target.toCLLocationCoordinate2D(), zoom: Float(zoom), bearing: bearing, viewingAngle: tilt @@ -75,16 +80,6 @@ extension FGMPlatformCameraPosition { } } -/// Creates a CLLocation array from its Pigeon equivalent. -func makePoints(from pigeonPoints: [FGMPlatformLatLng]) -> [CLLocation] { - return pigeonPoints.map { CLLocation(latitude: $0.latitude, longitude: $0.longitude) } -} - -/// Creates a CLLocation array array, representing a set of holes, from its Pigeon equivalent. -func makeHoles(from pigeonHolePoints: [[FGMPlatformLatLng]]) -> [[CLLocation]] { - return pigeonHolePoints.map { makePoints(from: $0) } -} - /// Creates a GMSMutablePath from points. func makePath(from points: [CLLocation]) -> GMSMutablePath { let path = GMSMutablePath() @@ -94,37 +89,33 @@ func makePath(from points: [CLLocation]) -> GMSMutablePath { return path } -/// Creates a GMSMapViewType from its Pigeon representation. -func mapViewType(from type: FGMPlatformMapType) -> GMSMapViewType { - switch type { - case .none: - return .none - case .normal: - return .normal - case .satellite: - return .satellite - case .terrain: - return .terrain - case .hybrid: - return .hybrid - @unknown default: - return .normal +extension FGMPlatformMapType { + /// The corresponding GMSMapViewType. + var gmsMapViewType: GMSMapViewType { + switch self { + case .none: return .none + case .normal: return .normal + case .satellite: return .satellite + case .terrain: return .terrain + case .hybrid: return .hybrid + @unknown default: return .normal + } } } -/// Creates a GMSCollisionBehavior from its Pigeon representation. -func collisionBehavior(from collisionBehavior: FGMPlatformMarkerCollisionBehavior) - -> GMSCollisionBehavior -{ - switch collisionBehavior { - case .requiredDisplay: - return .required - case .optionalAndHidesLowerPriority: - return .optionalAndHidesLowerPriority - case .requiredAndHidesOptional: - return .requiredAndHidesOptional - @unknown default: - return .required +extension FGMPlatformMarkerCollisionBehavior { + /// The corresponding GMSCollisionBehavior. + var gmsCollisionBehavior: GMSCollisionBehavior { + switch self { + case .requiredDisplay: + return .required + case .optionalAndHidesLowerPriority: + return .optionalAndHidesLowerPriority + case .requiredAndHidesOptional: + return .requiredAndHidesOptional + @unknown default: + return .required + } } } @@ -143,17 +134,8 @@ extension FGMPlatformGroundOverlay { withGroundOverlayId: overlayId, image: placeholderImage, position: nil, - bounds: FGMPlatformLatLngBounds.make( - withNortheast: FGMPlatformLatLng.make( - withLatitude: bounds.northEast.latitude, - longitude: bounds.northEast.longitude - ), - southwest: FGMPlatformLatLng.make( - withLatitude: bounds.southWest.latitude, - longitude: bounds.southWest.longitude - ) - ), - anchor: FGMPlatformPoint.makeWith(x: groundOverlay.anchor.x, y: groundOverlay.anchor.y), + bounds: FGMPlatformLatLngBounds.make(from: bounds), + anchor: FGMPlatformPoint.make(from: groundOverlay.anchor), transparency: 1.0 - Double(groundOverlay.opacity), bearing: groundOverlay.bearing, zIndex: Int(groundOverlay.zIndex), @@ -165,12 +147,9 @@ extension FGMPlatformGroundOverlay { return FGMPlatformGroundOverlay.make( withGroundOverlayId: overlayId, image: placeholderImage, - position: FGMPlatformLatLng.make( - withLatitude: groundOverlay.position.latitude, - longitude: groundOverlay.position.longitude - ), + position: FGMPlatformLatLng.make(from: groundOverlay.position), bounds: nil, - anchor: FGMPlatformPoint.makeWith(x: groundOverlay.anchor.x, y: groundOverlay.anchor.y), + anchor: FGMPlatformPoint.make(from: groundOverlay.anchor), transparency: 1.0 - Double(groundOverlay.opacity), bearing: groundOverlay.bearing, zIndex: Int(groundOverlay.zIndex), @@ -193,7 +172,7 @@ extension FGMPlatformHeatmapGradient { ) } - /// Creates a GMUGradient from its Pigeon representation. + /// Returns the equivalent GMUGradient. func toGMUGradient() -> GMUGradient { let colors = colors.map { $0.toUIColor() } return GMUGradient( @@ -204,27 +183,20 @@ extension FGMPlatformHeatmapGradient { } } -/// Creates a GMUWeightedLatLng array from its Pigeon equivalent. -func makeWeightedData(from weightedLatLngs: [FGMPlatformWeightedLatLng]) -> [GMUWeightedLatLng] { - return weightedLatLngs.map { - GMUWeightedLatLng( - coordinate: $0.point.toCLCoordinate(), - intensity: Float($0.weight) - ) - } -} - -/// Converts a GMUWeightedLatLng array to its Pigeon equivalent. -func makePigeonWeightedData(from weightedLatLngs: [GMUWeightedLatLng]) - -> [FGMPlatformWeightedLatLng] -{ - return weightedLatLngs.map { - let point = GMSMapPoint(x: $0.point().x, y: $0.point().y) +extension FGMPlatformWeightedLatLng { + /// Converts a GMUWeightedLatLng to its Pigeon representation. + static func make(from weightedLatLng: GMUWeightedLatLng) -> FGMPlatformWeightedLatLng { + let point = GMSMapPoint(x: weightedLatLng.point().x, y: weightedLatLng.point().y) return FGMPlatformWeightedLatLng.make( withPoint: FGMPlatformLatLng.make(from: GMSUnproject(point)), - weight: Double($0.intensity) + weight: Double(weightedLatLng.intensity) ) } + + /// Returns the equivalent GMUWeightedLatLng. + func toGMUWeightedLatLng() -> GMUWeightedLatLng { + return GMUWeightedLatLng(coordinate: point.toCLLocationCoordinate2D(), intensity: Float(weight)) + } } extension FGMPlatformCameraUpdate { @@ -235,15 +207,15 @@ extension FGMPlatformCameraUpdate { case let newCameraPosition as FGMPlatformCameraUpdateNewCameraPosition: return GMSCameraUpdate.setCamera(newCameraPosition.cameraPosition.toGMSCameraPosition()) case let newLatLng as FGMPlatformCameraUpdateNewLatLng: - return GMSCameraUpdate.setTarget(newLatLng.latLng.toCLCoordinate()) + return GMSCameraUpdate.setTarget(newLatLng.latLng.toCLLocationCoordinate2D()) case let newLatLngBounds as FGMPlatformCameraUpdateNewLatLngBounds: return GMSCameraUpdate.fit( - newLatLngBounds.bounds.toGMSBounds(), + newLatLngBounds.bounds.toGMSCoordinateBounds(), withPadding: CGFloat(newLatLngBounds.padding) ) case let newLatLngZoom as FGMPlatformCameraUpdateNewLatLngZoom: return GMSCameraUpdate.setTarget( - newLatLngZoom.latLng.toCLCoordinate(), + newLatLngZoom.latLng.toCLLocationCoordinate2D(), zoom: Float(newLatLngZoom.zoom) ) case let scrollBy as FGMPlatformCameraUpdateScrollBy: @@ -265,11 +237,6 @@ extension FGMPlatformCameraUpdate { } extension FGMPlatformColor { - /// Creates a UIColor from its Pigeon representation. - func toUIColor() -> UIColor { - return UIColor(red: red, green: green, blue: blue, alpha: alpha) - } - /// Converts a UIColor to its Pigeon representation. static func make(from color: UIColor) -> FGMPlatformColor { var red: CGFloat = 0 @@ -280,21 +247,24 @@ extension FGMPlatformColor { return FGMPlatformColor.make( withRed: Double(red), green: Double(green), blue: Double(blue), alpha: Double(alpha)) } + + /// Returns the equivalent UIColor. + func toUIColor() -> UIColor { + return UIColor(red: red, green: green, blue: blue, alpha: alpha) + } } -/// Creates an array of GMSStrokeStyles using the given patterns and stroke color. -func makeStrokeStyles( - from patterns: [FGMPlatformPatternItem], strokeColor: UIColor -) -> [GMSStrokeStyle] { - return patterns.map { pattern in - let color = pattern.type == .gap ? UIColor.clear : strokeColor +extension FGMPlatformPatternItem { + /// The GMSStrokeStyle expression of this pattern, using the given stroke color. + func gmsStrokeStyle(strokeColor: UIColor) -> GMSStrokeStyle { + let color = type == .gap ? UIColor.clear : strokeColor return GMSStrokeStyle.solidColor(color) } -} -/// Creates an array of span lengths using the given patterns. -func makeSpanLengths(from patterns: [FGMPlatformPatternItem]) -> [NSNumber] { - return patterns.map { $0.length ?? 0 } + /// The span length for this pattern, in the form expected by GMSStyleSpans. + func gmsStyleSpanLength() -> NSNumber { + return length ?? 0 + } } extension FGMPlatformCluster { @@ -308,8 +278,8 @@ extension FGMPlatformCluster { bounds = bounds.includingCoordinate(item.position) } - let markerIds = cluster.items.filter { $0 is GMSMarker }.compactMap { - markerIdentifierFromMarker($0 as! GMSMarker) + let markerIds = cluster.items.compactMap { $0 as? GMSMarker }.compactMap { + markerIdentifierFromMarker($0) } return FGMPlatformCluster.make( diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift index d0208298d7f..06949262ec8 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GoogleMapController.swift @@ -451,7 +451,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV ) -> (Bool, String?) { if let cameraTargetBounds = config.cameraTargetBounds { if let bounds = cameraTargetBounds.bounds { - mapView.cameraTargetBounds = bounds.toGMSBounds() + mapView.cameraTargetBounds = bounds.toGMSCoordinateBounds() } else { mapView.cameraTargetBounds = nil } @@ -469,7 +469,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV mapView.isBuildingsEnabled = buildingsEnabled.boolValue } if let mapType = config.mapType { - mapView.mapType = mapViewType(from: mapType.value) + mapView.mapType = mapType.value.gmsMapViewType } if let zoomData = config.minMaxZoomPreference { let minZoom = zoomData.min?.floatValue ?? kGMSMinZoomLevel @@ -666,7 +666,7 @@ class MapCallHandler: NSObject, FGMMapsApi { ) return nil } - let location = latLng.toCLCoordinate() + let location = latLng.toCLLocationCoordinate2D() let point = mapView.projection.point(for: location) return FGMPlatformPoint.make(from: point) } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift index e8e4bdda61d..257c78512d5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift @@ -39,7 +39,7 @@ class HeatmapController: NSObject { from platformHeatmap: FGMPlatformHeatmap, mapView: GMSMapView ) { - heatmapTileLayer.weightedData = makeWeightedData(from: platformHeatmap.data) + heatmapTileLayer.weightedData = platformHeatmap.data.map({ $0.toGMUWeightedLatLng() }) if let gradient = platformHeatmap.gradient { heatmapTileLayer.gradient = gradient.toGMUGradient() } @@ -104,7 +104,7 @@ class HeatmapsController: NSObject { let heatmap = controller.heatmapTileLayer return FGMPlatformHeatmap.make( withHeatmapId: identifier, - data: makePigeonWeightedData(from: heatmap.weightedData), + data: heatmap.weightedData.map { FGMPlatformWeightedLatLng.make(from: $0) }, gradient: FGMPlatformHeatmapGradient.make(from: heatmap.gradient), opacity: Double(heatmap.opacity), radius: Int(heatmap.radius), diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift index 572cbb6e681..b2c577c149c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift @@ -25,92 +25,93 @@ func makeIcon( let bitmap = platformBitmap.bitmap var image: UIImage? - if let bitmapDefaultMarker = bitmap as? FGMPlatformBitmapDefaultMarker { - let hue = bitmapDefaultMarker.hue?.doubleValue ?? 0 + switch bitmap { + case let bitmap as FGMPlatformBitmapDefaultMarker: + let hue = bitmap.hue?.doubleValue ?? 0 image = GMSMarker.markerImage( with: UIColor( hue: CGFloat(hue) / 360.0, saturation: 1.0, brightness: 0.7, alpha: 1.0)) - } else if let bitmapAsset = bitmap as? FGMPlatformBitmapAsset { + case let bitmap as FGMPlatformBitmapAsset: // Deprecated: This message handling for 'fromAsset' has been replaced by 'asset'. // Refer to the flutter google_maps_flutter_platform_interface package for details. - if let pkg = bitmapAsset.pkg { - if let key = assetProvider.lookupKey(forAsset: bitmapAsset.name, fromPackage: pkg) { + if let pkg = bitmap.pkg { + if let key = assetProvider.lookupKey(forAsset: bitmap.name, fromPackage: pkg) { image = assetProvider.imageNamed(key) } } else { - if let key = assetProvider.lookupKey(forAsset: bitmapAsset.name) { + if let key = assetProvider.lookupKey(forAsset: bitmap.name) { image = assetProvider.imageNamed(key) } } - } else if let bitmapAssetImage = bitmap as? FGMPlatformBitmapAssetImage { + case let bitmap as FGMPlatformBitmapAssetImage: // Deprecated: This message handling for 'fromAssetImage' has been replaced by 'asset'. // Refer to the flutter google_maps_flutter_platform_interface package for details. - if let key = assetProvider.lookupKey(forAsset: bitmapAssetImage.name) { + if let key = assetProvider.lookupKey(forAsset: bitmap.name) { if let assetImage = assetProvider.imageNamed(key) { - image = scaledImage(assetImage, scale: bitmapAssetImage.scale) + image = scaledImage(assetImage, scale: bitmap.scale) } } - } else if let bitmapBytes = bitmap as? FGMPlatformBitmapBytes { + case let bitmap as FGMPlatformBitmapBytes: // Deprecated: This message handling for 'fromBytes' has been replaced by 'bytes'. // Refer to the flutter google_maps_flutter_platform_interface package for details. - image = UIImage(data: bitmapBytes.byteData.data, scale: screenScale) - } else if let bitmapAssetMap = bitmap as? FGMPlatformBitmapAssetMap { - if let key = assetProvider.lookupKey(forAsset: bitmapAssetMap.assetName) { + image = UIImage(data: bitmap.byteData.data, scale: screenScale) + case let bitmap as FGMPlatformBitmapAssetMap: + if let key = assetProvider.lookupKey(forAsset: bitmap.assetName) { image = assetProvider.imageNamed(key) } - if let currentImage = image, bitmapAssetMap.bitmapScaling == .auto { - let width = bitmapAssetMap.width - let height = bitmapAssetMap.height + if let currentImage = image, bitmap.bitmapScaling == .auto { + let width = bitmap.width + let height = bitmap.height if width != nil || height != nil { let tempImage = scaledImage(currentImage, scale: screenScale) image = scaledImage(tempImage, width: width, height: height, screenScale: screenScale) } else { - image = scaledImage(currentImage, scale: CGFloat(bitmapAssetMap.imagePixelRatio)) + image = scaledImage(currentImage, scale: CGFloat(bitmap.imagePixelRatio)) } } - } else if let bitmapBytesMap = bitmap as? FGMPlatformBitmapBytesMap { - let bytes = bitmapBytesMap.byteData + case let bitmap as FGMPlatformBitmapBytesMap: + let bytes = bitmap.byteData image = UIImage(data: bytes.data, scale: screenScale) if let currentImage = image { - if bitmapBytesMap.bitmapScaling == .auto { - let width = bitmapBytesMap.width - let height = bitmapBytesMap.height + if bitmap.bitmapScaling == .auto { + let width = bitmap.width + let height = bitmap.height if width != nil || height != nil { // Before scaling the image, image must be in screenScale. let tempImage = scaledImage(currentImage, scale: screenScale) image = scaledImage(tempImage, width: width, height: height, screenScale: screenScale) } else { - image = scaledImage(currentImage, scale: CGFloat(bitmapBytesMap.imagePixelRatio)) + image = scaledImage(currentImage, scale: CGFloat(bitmap.imagePixelRatio)) } } else { // No scaling, load image from bytes without scale parameter. image = UIImage(data: bytes.data) } } - } else if let pinConfig = bitmap as? FGMPlatformBitmapPinConfig { + case let bitmap as FGMPlatformBitmapPinConfig: let options = GMSPinImageOptions() - if let backgroundColor = pinConfig.backgroundColor { + if let backgroundColor = bitmap.backgroundColor { options.backgroundColor = backgroundColor.toUIColor() } - if let borderColor = pinConfig.borderColor { + if let borderColor = bitmap.borderColor { options.borderColor = borderColor.toUIColor() } var glyph: GMSPinImageGlyph? - if let glyphText = pinConfig.glyphText { + if let glyphText = bitmap.glyphText { let glyphTextColor: UIColor - if let textColor = pinConfig.glyphTextColor { + if let textColor = bitmap.glyphTextColor { glyphTextColor = textColor.toUIColor() } else { glyphTextColor = .black } glyph = GMSPinImageGlyph(text: glyphText, textColor: glyphTextColor) - } else if let glyphColorValue = pinConfig.glyphColor { + } else if let glyphColorValue = bitmap.glyphColor { glyph = GMSPinImageGlyph(glyphColor: glyphColorValue.toUIColor()) - } else if let glyphBitmap = pinConfig.glyphBitmap { + } else if let glyphBitmap = bitmap.glyphBitmap { if let glyphImage = makeIcon( from: glyphBitmap, assetProvider: assetProvider, screenScale: screenScale) { @@ -119,6 +120,8 @@ func makeIcon( } options.glyph = glyph image = GMSPinImage(options: options) + default: + break } return image diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/MarkerController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/MarkerController.swift index 9887a4f58df..8e38cd8f4b5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/MarkerController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/MarkerController.swift @@ -87,7 +87,7 @@ class MarkerController: NSObject { marker.icon = makeIcon( from: platformMarker.icon, assetProvider: assetProvider, screenScale: screenScale) marker.isFlat = platformMarker.flat - marker.position = platformMarker.position.toCLCoordinate() + marker.position = platformMarker.position.toCLLocationCoordinate2D() marker.rotation = platformMarker.rotation marker.zIndex = Int32(platformMarker.zIndex) let infoWindow = platformMarker.infoWindow @@ -100,7 +100,7 @@ class MarkerController: NSObject { if let advancedMarker = marker as? GMSAdvancedMarker, let collisionBehaviorValue = platformMarker.collisionBehavior { - advancedMarker.collisionBehavior = collisionBehavior(from: collisionBehaviorValue.value) + advancedMarker.collisionBehavior = collisionBehaviorValue.value.gmsCollisionBehavior } // This must be done last, to avoid visual flickers of default property values. @@ -145,7 +145,7 @@ class MarkersController: NSObject { private func addMarker(_ markerToAdd: FGMPlatformMarker) { guard let mapView = mapView else { return } - let position = markerToAdd.position.toCLCoordinate() + let position = markerToAdd.position.toCLLocationCoordinate2D() let markerIdentifier = markerToAdd.markerId let clusterManagerIdentifier = markerToAdd.clusterManagerId diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolygonController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolygonController.swift index 17ef749ffa3..dd758e57544 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolygonController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolygonController.swift @@ -41,8 +41,8 @@ class PolygonController: NSObject { ) { polygon.isTappable = platformPolygon.consumesTapEvents polygon.zIndex = Int32(platformPolygon.zIndex) - polygon.path = makePath(from: makePoints(from: platformPolygon.points)) - polygon.holes = makeHoles(from: platformPolygon.holes).map { makePath(from: $0) } + polygon.path = makePath(from: platformPolygon.points.map({ $0.toCLLocation() })) + polygon.holes = platformPolygon.holes.map { makePath(from: $0.map({ $0.toCLLocation() })) } polygon.fillColor = platformPolygon.fillColor.toUIColor() polygon.strokeColor = platformPolygon.strokeColor.toUIColor() polygon.strokeWidth = CGFloat(platformPolygon.strokeWidth) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolylineController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolylineController.swift index f84a0e3cbe8..caef84694a0 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolylineController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolylineController.swift @@ -41,7 +41,7 @@ class PolylineController: NSObject { ) { polyline.isTappable = platformPolyline.consumesTapEvents polyline.zIndex = Int32(platformPolyline.zIndex) - let gmsPath = makePath(from: makePoints(from: platformPolyline.points)) + let gmsPath = makePath(from: platformPolyline.points.map({ $0.toCLLocation() })) polyline.path = gmsPath let strokeColor = platformPolyline.color.toUIColor() polyline.strokeColor = strokeColor @@ -49,8 +49,8 @@ class PolylineController: NSObject { polyline.geodesic = platformPolyline.geodesic polyline.spans = GMSStyleSpans( gmsPath, - makeStrokeStyles(from: platformPolyline.patterns, strokeColor: strokeColor), - makeSpanLengths(from: platformPolyline.patterns), + platformPolyline.patterns.map { $0.gmsStrokeStyle(strokeColor: strokeColor) }, + platformPolyline.patterns.map { $0.gmsStyleSpanLength() }, .rhumb ) From b0be92315e920f9c8e593c8f699b9bfe8907c2cd Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Tue, 1 Sep 2026 12:41:16 -0400 Subject: [PATCH 11/17] Sync changes --- .../ios/Runner.xcodeproj/project.pbxproj | 4 - .../RunnerTests/CircleControllerTests.swift | 1 + .../ClusterManagersControllerTests.swift | 1 + .../RunnerTests/ConversionsUtilsTests.swift | 189 ++++------- .../ExtractIconFromDataTests.swift | 121 +++---- .../ios/RunnerTests/GoogleMapsTests.swift | 1 + .../GroundOverlayControllerTests.swift | 21 +- .../RunnerTests/HeatmapControllerTests.swift | 5 +- .../RunnerTests/MarkerControllerTests.swift | 1 + .../RunnerTests/PolygonControllerTests.swift | 1 + .../RunnerTests/PolylineControllerTests.swift | 1 + .../RunnerTests/RunnerTests-Bridging-Header.h | 6 - .../TestUtils/TestAssetProvider.swift | 1 + .../TestUtils/TestMapEventHandler.swift | 1 + .../TileOverlayControllerTests.swift | 1 + .../TileProviderControllerTests.swift | 1 + .../CircleController.swift | 6 +- .../ClusterManagersController.swift | 5 +- .../ConversionUtils.swift | 295 +++++++++++++++++- .../GoogleMapController.swift | 33 +- .../GroundOverlayController.swift | 13 +- .../MarkerController.swift | 22 +- .../PolygonController.swift | 10 +- .../PolylineController.swift | 12 +- .../FGMConversionUtils.m | 275 ---------------- .../FGMHeatmapController.m | 140 --------- .../FGMImageUtils.m | 271 ---------------- .../FGMConversionUtils.h | 93 ------ .../FGMHeatmapController.h | 58 ---- .../FGMHeatmapController_Test.h | 17 - .../FGMImageUtils.h | 21 -- .../RunnerTests/CircleControllerTests.swift | 1 + .../ClusterManagersControllerTests.swift | 1 + .../RunnerTests/ConversionsUtilsTests.swift | 189 ++++------- .../ExtractIconFromDataTests.swift | 121 +++---- .../ios/RunnerTests/GoogleMapsTests.swift | 1 + .../GroundOverlayControllerTests.swift | 21 +- .../RunnerTests/HeatmapControllerTests.swift | 5 +- .../RunnerTests/MarkerControllerTests.swift | 1 + .../RunnerTests/PolygonControllerTests.swift | 1 + .../RunnerTests/PolylineControllerTests.swift | 1 + .../RunnerTests/RunnerTests-Bridging-Header.h | 6 - .../TestUtils/TestAssetProvider.swift | 1 + .../TestUtils/TestMapEventHandler.swift | 1 + .../TileOverlayControllerTests.swift | 1 + .../TileProviderControllerTests.swift | 1 + .../CircleController.swift | 6 +- .../ClusterManagersController.swift | 5 +- .../ConversionUtils.swift | 295 +++++++++++++++++- .../GoogleMapController.swift | 33 +- .../GroundOverlayController.swift | 13 +- .../MarkerController.swift | 22 +- .../PolygonController.swift | 10 +- .../PolylineController.swift | 12 +- .../FGMConversionUtils.m | 275 ---------------- .../FGMHeatmapController.m | 140 --------- .../FGMImageUtils.m | 271 ---------------- .../FGMConversionUtils.h | 93 ------ .../FGMHeatmapController.h | 58 ---- .../FGMHeatmapController_Test.h | 17 - .../FGMImageUtils.h | 21 -- 61 files changed, 952 insertions(+), 2298 deletions(-) delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/RunnerTests-Bridging-Header.h delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/FGMConversionUtils.m delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/FGMHeatmapController.m delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/FGMImageUtils.m delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/include/google_maps_flutter_ios_sdk10_objc/FGMConversionUtils.h delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/include/google_maps_flutter_ios_sdk10_objc/FGMHeatmapController.h delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/include/google_maps_flutter_ios_sdk10_objc/FGMHeatmapController_Test.h delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/include/google_maps_flutter_ios_sdk10_objc/FGMImageUtils.h delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/RunnerTests-Bridging-Header.h delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/FGMConversionUtils.m delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/FGMHeatmapController.m delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/FGMImageUtils.m delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/include/google_maps_flutter_ios_objc/FGMConversionUtils.h delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/include/google_maps_flutter_ios_objc/FGMHeatmapController.h delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/include/google_maps_flutter_ios_objc/FGMHeatmapController_Test.h delete mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/include/google_maps_flutter_ios_objc/FGMImageUtils.h diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/Runner.xcodeproj/project.pbxproj b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/Runner.xcodeproj/project.pbxproj index 2d79e5c1f3a..f0b1d078a8d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/Runner.xcodeproj/project.pbxproj @@ -77,7 +77,6 @@ 350A657853294B478D70CD62 /* PolylineControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolylineControllerTests.swift; sourceTree = ""; }; 0F65543ABD25496A92F8F91F /* TileOverlayControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileOverlayControllerTests.swift; sourceTree = ""; }; 54CD823EECFC4BDD8755DD92 /* TileProviderControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileProviderControllerTests.swift; sourceTree = ""; }; - 65E43D60708A4C5DA931E12E /* RunnerTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RunnerTests-Bridging-Header.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 3351C2253008164500700458 /* GoogleMapsUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoogleMapsUITests.swift; sourceTree = ""; }; 3390B4582F33AFA60094DEB9 /* PartiallyMockedMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartiallyMockedMapView.swift; sourceTree = ""; }; @@ -208,7 +207,6 @@ 350A657853294B478D70CD62 /* PolylineControllerTests.swift */, 0F65543ABD25496A92F8F91F /* TileOverlayControllerTests.swift */, 54CD823EECFC4BDD8755DD92 /* TileProviderControllerTests.swift */, - 65E43D60708A4C5DA931E12E /* RunnerTests-Bridging-Header.h */, ); path = RunnerTests; sourceTree = ""; @@ -649,7 +647,6 @@ PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/Runner"; - SWIFT_OBJC_BRIDGING_HEADER = "RunnerTests/RunnerTests-Bridging-Header.h"; SWIFT_VERSION = 5.0; }; name = Debug; @@ -670,7 +667,6 @@ PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/Runner"; - SWIFT_OBJC_BRIDGING_HEADER = "RunnerTests/RunnerTests-Bridging-Header.h"; SWIFT_VERSION = 5.0; }; name = Release; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/CircleControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/CircleControllerTests.swift index d8cfa6ead24..8276502818c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/CircleControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/CircleControllerTests.swift @@ -4,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk10_objc @testable import google_maps_flutter_ios_sdk10 diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ClusterManagersControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ClusterManagersControllerTests.swift index cf68af2150a..797e78859ec 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ClusterManagersControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ClusterManagersControllerTests.swift @@ -5,6 +5,7 @@ import Flutter import GoogleMaps import Testing +import google_maps_flutter_ios_sdk10_objc @testable import google_maps_flutter_ios_sdk10 diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ConversionsUtilsTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ConversionsUtilsTests.swift index 8bcb2f5a5da..73276e09cce 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ConversionsUtilsTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ConversionsUtilsTests.swift @@ -4,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk10_objc @testable import google_maps_flutter_ios_sdk10 @@ -14,14 +15,12 @@ import Testing let platformGreen: CGFloat = 2 / 255.0 let platformBlue: CGFloat = 3 / 255.0 let platformAlpha: CGFloat = 4 / 255.0 - let color = FGMGetColorForPigeonColor( - FGMPlatformColor.make( - withRed: platformRed, - green: platformGreen, - blue: platformBlue, - alpha: platformAlpha - ) - ) + let color = FGMPlatformColor.make( + withRed: platformRed, + green: platformGreen, + blue: platformBlue, + alpha: platformAlpha + ).toUIColor() var red: CGFloat = 0 var green: CGFloat = 0 var blue: CGFloat = 0 @@ -40,47 +39,18 @@ import Testing let blue: CGFloat = 3 / 255.0 let alpha: CGFloat = 4 / 255.0 let color = UIColor(red: red, green: green, blue: blue, alpha: alpha) - let platformColor = FGMGetPigeonColorForColor(color) + let platformColor = FGMPlatformColor.make(from: color) #expect(abs(red - platformColor.red) <= CGFloat.ulpOfOne) #expect(abs(green - platformColor.green) <= CGFloat.ulpOfOne) #expect(abs(blue - platformColor.blue) <= CGFloat.ulpOfOne) #expect(abs(alpha - platformColor.alpha) <= CGFloat.ulpOfOne) } - @Test func pointsFromLatLongs() { - let latlongs = [ - FGMPlatformLatLng.make(withLatitude: 1, longitude: 2), - FGMPlatformLatLng.make(withLatitude: 3, longitude: 4), - ] - let locations = FGMGetPointsForPigeonLatLngs(latlongs) - #expect(locations.count == 2) - #expect(locations[0].coordinate.latitude == 1) - #expect(locations[0].coordinate.longitude == 2) - #expect(locations[1].coordinate.latitude == 3) - #expect(locations[1].coordinate.longitude == 4) - } - - @Test func holesFromPointsArray() { - let pointsArray = [ - [ - FGMPlatformLatLng.make(withLatitude: 1, longitude: 2), - FGMPlatformLatLng.make(withLatitude: 3, longitude: 4), - ], - [ - FGMPlatformLatLng.make(withLatitude: 5, longitude: 6), - FGMPlatformLatLng.make(withLatitude: 7, longitude: 8), - ], - ] - let holes = FGMGetHolesForPigeonLatLngArrays(pointsArray) - #expect(holes.count == 2) - #expect(holes[0][0].coordinate.latitude == 1) - #expect(holes[0][0].coordinate.longitude == 2) - #expect(holes[0][1].coordinate.latitude == 3) - #expect(holes[0][1].coordinate.longitude == 4) - #expect(holes[1][0].coordinate.latitude == 5) - #expect(holes[1][0].coordinate.longitude == 6) - #expect(holes[1][1].coordinate.latitude == 7) - #expect(holes[1][1].coordinate.longitude == 8) + @Test func pointFromLatLong() { + let latlong = FGMPlatformLatLng.make(withLatitude: 1, longitude: 2) + let location = latlong.toCLLocation() + #expect(location.coordinate.latitude == 1) + #expect(location.coordinate.longitude == 2) } @Test func getPigeonCameraPositionForPosition() { @@ -90,7 +60,7 @@ import Testing bearing: 3.0, viewingAngle: 75.0 ) - let pigeonPosition = FGMGetPigeonCameraPositionForPosition(position) + let pigeonPosition = FGMPlatformCameraPosition.make(from: position) #expect(abs(pigeonPosition.target.latitude - position.target.latitude) <= Double.ulpOfOne) #expect(abs(pigeonPosition.target.longitude - position.target.longitude) <= Double.ulpOfOne) #expect(abs(Float(pigeonPosition.zoom) - position.zoom) <= Float.ulpOfOne) @@ -100,7 +70,7 @@ import Testing @Test func pigeonPointForGCPoint() { let point = CGPoint(x: 10, y: 20) - let pigeonPoint = FGMGetPigeonPointForCGPoint(point) + let pigeonPoint = FGMPlatformPoint.make(from: point) #expect(abs(pigeonPoint.x - Double(point.x)) <= Double.ulpOfOne) #expect(abs(pigeonPoint.y - Double(point.y)) <= Double.ulpOfOne) } @@ -110,7 +80,7 @@ import Testing coordinate: CLLocationCoordinate2D(latitude: 10, longitude: 20), coordinate: CLLocationCoordinate2D(latitude: 30, longitude: 40) ) - let pigeonBounds = FGMGetPigeonLatLngBoundsForCoordinateBounds(bounds) + let pigeonBounds = FGMPlatformLatLngBounds.make(from: bounds) #expect(abs(pigeonBounds.southwest.latitude - bounds.southWest.latitude) <= Double.ulpOfOne) #expect(abs(pigeonBounds.southwest.longitude - bounds.southWest.longitude) <= Double.ulpOfOne) #expect(abs(pigeonBounds.northeast.latitude - bounds.northEast.latitude) <= Double.ulpOfOne) @@ -125,7 +95,7 @@ import Testing zoom: 5.0 ) - let cameraPosition = FGMGetCameraPositionForPigeonCameraPosition(pigeonCameraPosition) + let cameraPosition = pigeonCameraPosition.toGMSCameraPosition() #expect( abs(cameraPosition.target.latitude - pigeonCameraPosition.target.latitude) <= Double.ulpOfOne) @@ -140,7 +110,7 @@ import Testing @Test func cgPointForPigeonPoint() { let pigeonPoint = FGMPlatformPoint.makeWith(x: 1.0, y: 2.0) - let point = FGMGetCGPointForPigeonPoint(pigeonPoint) + let point = pigeonPoint.toCGPoint() #expect(abs(pigeonPoint.x - Double(point.x)) <= Double.ulpOfOne) #expect(abs(pigeonPoint.y - Double(point.y)) <= Double.ulpOfOne) @@ -152,7 +122,7 @@ import Testing southwest: FGMPlatformLatLng.make(withLatitude: 1, longitude: 2) ) - let bounds = FGMGetCoordinateBoundsForPigeonLatLngBounds(pigeonBounds) + let bounds = pigeonBounds.toGMSCoordinateBounds() let accuracy: Double = 0.001 #expect(abs(bounds.southWest.latitude - 1) <= accuracy) @@ -162,11 +132,11 @@ import Testing } @Test func mapViewTypeFromPigeonType() { - #expect(GMSMapViewType.normal == FGMGetMapViewTypeForPigeonMapType(.normal)) - #expect(GMSMapViewType.satellite == FGMGetMapViewTypeForPigeonMapType(.satellite)) - #expect(GMSMapViewType.terrain == FGMGetMapViewTypeForPigeonMapType(.terrain)) - #expect(GMSMapViewType.hybrid == FGMGetMapViewTypeForPigeonMapType(.hybrid)) - #expect(GMSMapViewType.none == FGMGetMapViewTypeForPigeonMapType(.none)) + #expect(GMSMapViewType.normal == FGMPlatformMapType.normal.gmsMapViewType) + #expect(GMSMapViewType.satellite == FGMPlatformMapType.satellite.gmsMapViewType) + #expect(GMSMapViewType.terrain == FGMPlatformMapType.terrain.gmsMapViewType) + #expect(GMSMapViewType.hybrid == FGMPlatformMapType.hybrid.gmsMapViewType) + #expect(GMSMapViewType.none == FGMPlatformMapType.none.gmsMapViewType) } @Test func cameraUpdateFromNewCameraPosition() { @@ -178,9 +148,7 @@ import Testing zoom: 3 ) ) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: newPositionUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: newPositionUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -194,9 +162,7 @@ import Testing with: FGMPlatformLatLng.make(withLatitude: lat, longitude: lng) ) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -208,16 +174,14 @@ import Testing withNortheast: FGMPlatformLatLng.make(withLatitude: 1, longitude: 2), southwest: FGMPlatformLatLng.make(withLatitude: 3, longitude: 4) ) - let bounds = FGMGetCoordinateBoundsForPigeonLatLngBounds(pigeonBounds) + let bounds = pigeonBounds.toGMSCoordinateBounds() let padding: Double = 20 let platformUpdate = FGMPlatformCameraUpdateNewLatLngBounds.make( - with: FGMGetPigeonLatLngBoundsForCoordinateBounds(bounds), + with: FGMPlatformLatLngBounds.make(from: bounds), padding: padding ) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -233,9 +197,7 @@ import Testing zoom: zoom ) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -247,9 +209,7 @@ import Testing let y: Double = 2 let platformUpdate = FGMPlatformCameraUpdateScrollBy.make(withDx: x, dy: y) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -260,9 +220,7 @@ import Testing let zoom: Double = 1 let platformUpdateNoPoint = FGMPlatformCameraUpdateZoomBy.make(withAmount: zoom, focus: nil) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdateNoPoint) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdateNoPoint).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -278,9 +236,7 @@ import Testing focus: FGMPlatformPoint.makeWith(x: x, y: y) ) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -290,9 +246,7 @@ import Testing @Test func cameraUpdateFromZoomIn() { let platformUpdate = FGMPlatformCameraUpdateZoom.make(withOut: false) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -302,9 +256,7 @@ import Testing @Test func cameraUpdateFromZoomOut() { let platformUpdate = FGMPlatformCameraUpdateZoom.make(withOut: true) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -315,65 +267,48 @@ import Testing let zoom: Double = 1 let platformUpdate = FGMPlatformCameraUpdateZoomTo.make(withZoom: zoom) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test // implementation would be about as complex as the conversion function itself. } - @Test func strokeStylesFromPatterns() { - let patterns = [ - FGMPlatformPatternItem.make(with: .gap, length: 1), - FGMPlatformPatternItem.make(with: .dash, length: 1), - ] + @Test func strokeStyleFromPattern() { + let pattern = FGMPlatformPatternItem.make(with: .dash, length: 1) let strokeColor = UIColor.red - let patternStrokeStyle = FGMGetStrokeStylesFromPatterns(patterns, strokeColor) - - #expect(patternStrokeStyle.count == 2) - // None of the parameters of `patternStrokeStyle` is observable, so we limit to testing - // the length of this output array. + _ = pattern.gmsStrokeStyle(strokeColor: strokeColor) + // GMSStrokeStyle is not inspectable, so this test just ensures that the codepath + // doesn't throw. } - @Test func lengthsFromPatterns() { - let gapLength: Double = 10 - let dashLength: Double = 6.4 - let patterns = [ - FGMPlatformPatternItem.make(with: .gap, length: gapLength as NSNumber), - FGMPlatformPatternItem.make(with: .dash, length: dashLength as NSNumber), - ] + @Test func nonNullLengthFromPatternItem() { + let length: Double = 6.4 + let pattern = FGMPlatformPatternItem.make(with: .gap, length: length as NSNumber) + + let spanLength = pattern.gmsStyleSpanLength() - let spanLengths = FGMGetSpanLengthsFromPatterns(patterns) + #expect(spanLength.doubleValue == length) + } - #expect(spanLengths.count == 2) + @Test func nullLengthFromPatternItem() { + let pattern = FGMPlatformPatternItem.make(with: .dot, length: nil) - let firstSpanLength = spanLengths[0] - let secondSpanLength = spanLengths[1] + let spanLength = pattern.gmsStyleSpanLength() - #expect(firstSpanLength.doubleValue == gapLength) - #expect(secondSpanLength.doubleValue == dashLength) + #expect(spanLength.doubleValue == 0) } - @Test func weightedDataFromPlatformWeightedData() { - let intensity1: Double = 3.0 - let intensity2: Double = 6.0 - let data = [ - FGMPlatformWeightedLatLng.make( - withPoint: FGMPlatformLatLng.make(withLatitude: 10, longitude: 20), - weight: intensity1 - ), - FGMPlatformWeightedLatLng.make( - withPoint: FGMPlatformLatLng.make(withLatitude: 30, longitude: 40), - weight: intensity2 - ), - ] - - let weightedData = FGMGetWeightedDataForPigeonWeightedData(data) - #expect(Double(weightedData[0].intensity) == intensity1) - #expect(Double(weightedData[1].intensity) == intensity2) + @Test func weightedLatLngFromPlatformWeightedLatLng() { + let intensity: Double = 3.0 + let data = FGMPlatformWeightedLatLng.make( + withPoint: FGMPlatformLatLng.make(withLatitude: 10, longitude: 20), + weight: intensity + ) + + let weightedData = data.toGMUWeightedLatLng() + #expect(Double(weightedData.intensity) == intensity) } @Test func gradientFromPlatformGradient() { @@ -396,7 +331,7 @@ import Testing colorMapSize: colorMapSize ) - let gradient = FGMGetGradientForPigeonHeatmapGradient(platformGradient) + let gradient = platformGradient.toGMUGradient() var red: CGFloat = 0 var green: CGFloat = 0 var blue: CGFloat = 0 diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ExtractIconFromDataTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ExtractIconFromDataTests.swift index 5d8a3bd2d74..d0533616e2b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ExtractIconFromDataTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ExtractIconFromDataTests.swift @@ -4,6 +4,7 @@ import Flutter import Testing +import google_maps_flutter_ios_sdk10_objc @testable import google_maps_flutter_ios_sdk10 @@ -24,10 +25,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) @@ -52,10 +53,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) @@ -82,10 +83,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) #expect(testImage.scale == 1.0) @@ -117,10 +118,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == screenScale) @@ -144,10 +145,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) @@ -171,10 +172,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) @@ -198,10 +199,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == 10) @@ -226,10 +227,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) @@ -261,10 +262,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == screenScale) @@ -287,10 +288,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == 1.0) @@ -299,7 +300,7 @@ import Testing } /// Tests for PinConfig (GMSPinImageOptions) - requires iOS 16.0+ and Google Maps SDK 9.0+. - /// On earlier versions, FGMIconFromBitmap returns nil for PinConfig, which is expected behavior. + /// On earlier versions, makeIcon returns nil for PinConfig, which is expected behavior. @Test func extractIconFromPinConfigWithGlyphColor() { let assetProvider = TestAssetProvider() @@ -318,10 +319,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: pinConfig), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: pinConfig), + assetProvider: assetProvider, + screenScale: screenScale ) // PinConfig may return nil on old Google Maps SDK versions (<=8.4.0). @@ -347,10 +348,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: pinConfig), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: pinConfig), + assetProvider: assetProvider, + screenScale: screenScale ) // PinConfig returns nil on iOS versions without GMSPinImageOptions support (< iOS 16.0). @@ -389,10 +390,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: pinConfig), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: pinConfig), + assetProvider: assetProvider, + screenScale: screenScale ) // PinConfig returns nil on iOS versions without GMSPinImageOptions support (< iOS 16.0). @@ -406,43 +407,43 @@ import Testing @Test func isScalableWithScaleFactorFromSize100x100to10x100() { let originalSize = CGSize(width: 100.0, height: 100.0) let targetSize = CGSize(width: 10.0, height: 100.0) - #expect(!FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(!isScalableWithScaleFactor(from: originalSize, to: targetSize)) } @Test func isScalableWithScaleFactorFromSize100x100to10x10() { let originalSize = CGSize(width: 100.0, height: 100.0) let targetSize = CGSize(width: 10.0, height: 10.0) - #expect(FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(isScalableWithScaleFactor(from: originalSize, to: targetSize)) } @Test func isScalableWithScaleFactorFromSize233x200to23x20() { let originalSize = CGSize(width: 233.0, height: 200.0) let targetSize = CGSize(width: 23.0, height: 20.0) - #expect(FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(isScalableWithScaleFactor(from: originalSize, to: targetSize)) } @Test func isScalableWithScaleFactorFromSize233x200to22x20() { let originalSize = CGSize(width: 233.0, height: 200.0) let targetSize = CGSize(width: 22.0, height: 20.0) - #expect(!FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(!isScalableWithScaleFactor(from: originalSize, to: targetSize)) } @Test func isScalableWithScaleFactorFromSize200x233to20x23() { let originalSize = CGSize(width: 200.0, height: 233.0) let targetSize = CGSize(width: 20.0, height: 23.0) - #expect(FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(isScalableWithScaleFactor(from: originalSize, to: targetSize)) } @Test func isScalableWithScaleFactorFromSize200x233to20x22() { let originalSize = CGSize(width: 200.0, height: 233.0) let targetSize = CGSize(width: 20.0, height: 22.0) - #expect(!FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(!isScalableWithScaleFactor(from: originalSize, to: targetSize)) } @Test func isScalableWithScaleFactorFromSize1024x768to500x250() { let originalSize = CGSize(width: 1024.0, height: 768.0) let targetSize = CGSize(width: 500.0, height: 250.0) - #expect(!FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(!isScalableWithScaleFactor(from: originalSize, to: targetSize)) } private func createOnePixelImage() -> UIImage { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/GoogleMapsTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/GoogleMapsTests.swift index e763082ad1b..c0d68c649ff 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/GoogleMapsTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/GoogleMapsTests.swift @@ -5,6 +5,7 @@ import Flutter import GoogleMaps import Testing +import google_maps_flutter_ios_sdk10_objc @testable import google_maps_flutter_ios_sdk10 diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/GroundOverlayControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/GroundOverlayControllerTests.swift index ce80ddfe68f..22180d01807 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/GroundOverlayControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/GroundOverlayControllerTests.swift @@ -4,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk10_objc @testable import google_maps_flutter_ios_sdk10 @@ -115,11 +116,11 @@ import Testing #expect(abs(groundOverlayController.groundOverlay.anchor.y - 0.5) <= Double.ulpOfOne) #expect(groundOverlayController.groundOverlay.zIndex == Int32(platformGroundOverlay.zIndex)) - let convertedPlatformGroundOverlay = FGMGetPigeonGroundOverlay( - groundOverlayController.groundOverlay, - "id_1", - false, - 14.0 + let convertedPlatformGroundOverlay = FGMPlatformGroundOverlay.make( + from: groundOverlayController.groundOverlay, + overlayId: "id_1", + isCreatedWithBounds: false, + zoomLevel: 14.0 ) #expect(convertedPlatformGroundOverlay.groundOverlayId == "id_1") #expect( @@ -182,11 +183,11 @@ import Testing #expect(abs(groundOverlayController.groundOverlay.anchor.y - 0.5) <= Double.ulpOfOne) #expect(groundOverlayController.groundOverlay.zIndex == Int32(platformGroundOverlay.zIndex)) - let convertedPlatformGroundOverlay = FGMGetPigeonGroundOverlay( - groundOverlayController.groundOverlay, - "id_1", - true, - nil + let convertedPlatformGroundOverlay = FGMPlatformGroundOverlay.make( + from: groundOverlayController.groundOverlay, + overlayId: "id_1", + isCreatedWithBounds: true, + zoomLevel: nil ) #expect(convertedPlatformGroundOverlay.groundOverlayId == "id_1") #expect( diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/HeatmapControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/HeatmapControllerTests.swift index 1af11a144c2..cd37fc83c7e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/HeatmapControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/HeatmapControllerTests.swift @@ -5,6 +5,7 @@ import GoogleMaps import GoogleMapsUtils import Testing +import google_maps_flutter_ios_sdk10_objc @testable import google_maps_flutter_ios_sdk10 @@ -20,7 +21,7 @@ import Testing startPoints: [0 as NSNumber, 1 as NSNumber], colorMapSize: 256 ) - FGMHeatmapController.updateHeatmap( + HeatmapController.update( heatmap, from: FGMPlatformHeatmap.make( withHeatmapId: "heatmap", @@ -40,7 +41,7 @@ import Testing minimumZoomIntensity: 1, maximumZoomIntensity: 2 ), - with: HeatmapControllerTests.mapView() + mapView: HeatmapControllerTests.mapView() ) #expect(heatmap.hasSetMap) } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/MarkerControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/MarkerControllerTests.swift index c052a5ee586..5cc8c4fa6ae 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/MarkerControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/MarkerControllerTests.swift @@ -4,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk10_objc @testable import google_maps_flutter_ios_sdk10 diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/PolygonControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/PolygonControllerTests.swift index 7125108589f..0eef55ee3f0 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/PolygonControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/PolygonControllerTests.swift @@ -4,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk10_objc @testable import google_maps_flutter_ios_sdk10 diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/PolylineControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/PolylineControllerTests.swift index 702d5171599..c346ca4c1ad 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/PolylineControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/PolylineControllerTests.swift @@ -4,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk10_objc @testable import google_maps_flutter_ios_sdk10 diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/RunnerTests-Bridging-Header.h b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/RunnerTests-Bridging-Header.h deleted file mode 100644 index 050c9ce00b2..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/RunnerTests-Bridging-Header.h +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Import private _Test.h headers from the plugin framework -#import diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/TestUtils/TestAssetProvider.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/TestUtils/TestAssetProvider.swift index 2db2bdc1d74..745075545d8 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/TestUtils/TestAssetProvider.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/TestUtils/TestAssetProvider.swift @@ -4,6 +4,7 @@ import UIKit import google_maps_flutter_ios_sdk10 +import google_maps_flutter_ios_sdk10_objc /// Fake implementation of FGMAssetProvider for unit tests. class TestAssetProvider: NSObject, FGMAssetProvider { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/TestUtils/TestMapEventHandler.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/TestUtils/TestMapEventHandler.swift index 86b567e6adc..f1ea77a9ecc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/TestUtils/TestMapEventHandler.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/TestUtils/TestMapEventHandler.swift @@ -4,6 +4,7 @@ import Foundation import google_maps_flutter_ios_sdk10 +import google_maps_flutter_ios_sdk10_objc /// Fake implementation of FGMMapEventDelegate for unit tests. class TestMapEventHandler: NSObject, FGMMapEventDelegate { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/TileOverlayControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/TileOverlayControllerTests.swift index 99a5cca7802..065ef5ace5d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/TileOverlayControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/TileOverlayControllerTests.swift @@ -4,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk10_objc @testable import google_maps_flutter_ios_sdk10 diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/TileProviderControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/TileProviderControllerTests.swift index 90da6a4ef35..95d93c98ae1 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/TileProviderControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/TileProviderControllerTests.swift @@ -5,6 +5,7 @@ import Flutter import GoogleMaps import Testing +import google_maps_flutter_ios_sdk10_objc @testable import google_maps_flutter_ios_sdk10 diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/CircleController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/CircleController.swift index 23aaefeacf0..12685084077 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/CircleController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/CircleController.swift @@ -42,11 +42,11 @@ class CircleController: NSObject { ) { circle.isTappable = platformCircle.consumeTapEvents circle.zIndex = Int32(platformCircle.zIndex) - circle.position = FGMGetCoordinateForPigeonLatLng(platformCircle.center) + circle.position = platformCircle.center.toCLLocationCoordinate2D() circle.radius = platformCircle.radius - circle.strokeColor = FGMGetColorForPigeonColor(platformCircle.strokeColor) + circle.strokeColor = platformCircle.strokeColor.toUIColor() circle.strokeWidth = CGFloat(platformCircle.strokeWidth) - circle.fillColor = FGMGetColorForPigeonColor(platformCircle.fillColor) + circle.fillColor = platformCircle.fillColor.toUIColor() // This must be done last, to avoid visual flickers of default property values. circle.map = platformCircle.visible ? mapView : nil diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/ClusterManagersController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/ClusterManagersController.swift index 59177bcd5b3..c1ed35fffa6 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/ClusterManagersController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/ClusterManagersController.swift @@ -74,12 +74,13 @@ class ClusterManagersController: NSObject { // https://github.com/googlemaps/google-maps-ios-utils/blob/0e7ed81f1bbd9d29e4529c40ae39b0791b0a0eb8/src/Clustering/GMUClusterManager.m#L94. let integralZoom = floorf(Float(mapView.camera.zoom) + 0.5) let clusters = clusterManager.algorithm.clusters(atZoom: integralZoom) - return clusters.map { pigeonCluster(for: $0, clusterManagerIdentifier: identifier) } + return clusters.map { FGMPlatformCluster.make(from: $0, clusterManagerIdentifier: identifier) } } func didTap(_ cluster: GMUStaticCluster) { guard let clusterManagerId = clusterManagerIdentifier(for: cluster) else { return } - let platformCluster = pigeonCluster(for: cluster, clusterManagerIdentifier: clusterManagerId) + let platformCluster = FGMPlatformCluster.make( + from: cluster, clusterManagerIdentifier: clusterManagerId) eventDelegate?.didTap(platformCluster) } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/ConversionUtils.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/ConversionUtils.swift index 430d2237d1b..a1f26b733f8 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/ConversionUtils.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/ConversionUtils.swift @@ -2,28 +2,291 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import Flutter +import GoogleMaps +import GoogleMapsUtils + #if canImport(google_maps_flutter_ios_sdk10_objc) import google_maps_flutter_ios_sdk10_objc #endif -/// Converts a GMUCluster to its Pigeon representation. -func pigeonCluster( - for cluster: GMUCluster, - clusterManagerIdentifier: String -) -> FGMPlatformCluster { - var bounds = GMSCoordinateBounds() - for item in cluster.items { - bounds = bounds.includingCoordinate(item.position) +extension FGMPlatformPoint { + /// Converts a CGPoint to its Pigeon equivalent. + static func make(from point: CGPoint) -> FGMPlatformPoint { + return FGMPlatformPoint.makeWith(x: point.x, y: point.y) + } + + /// Returns the equivalent CGPoint. + func toCGPoint() -> CGPoint { + return CGPoint(x: x, y: y) + } +} + +extension FGMPlatformLatLng { + /// Converts a CLLocationCoordinate2D to its Pigeon representation. + static func make(from coordinate: CLLocationCoordinate2D) -> FGMPlatformLatLng { + return FGMPlatformLatLng.make( + withLatitude: coordinate.latitude, longitude: coordinate.longitude) } - let markerIds = cluster.items.filter { $0 is GMSMarker }.compactMap { - markerIdentifierFromMarker($0 as! GMSMarker) + /// Returns the equivalent CLLocationCoordinate2D. + func toCLLocationCoordinate2D() -> CLLocationCoordinate2D { + return CLLocationCoordinate2D(latitude: latitude, longitude: longitude) } - return FGMPlatformCluster.make( - withClusterManagerId: clusterManagerIdentifier, - position: FGMGetPigeonLatLngForCoordinate(cluster.position), - bounds: FGMGetPigeonLatLngBoundsForCoordinateBounds(bounds), - markerIds: markerIds - ) + /// Returns the equivalent CLLocation. + func toCLLocation() -> CLLocation { + return CLLocation(latitude: latitude, longitude: longitude) + } +} + +extension FGMPlatformLatLngBounds { + /// Converts a GMSCoordinateBounds to its Pigeon representation. + static func make(from bounds: GMSCoordinateBounds) -> FGMPlatformLatLngBounds { + return FGMPlatformLatLngBounds.make( + withNortheast: FGMPlatformLatLng.make(from: bounds.northEast), + southwest: FGMPlatformLatLng.make(from: bounds.southWest) + ) + } + + /// Returns the equivalent GMSCoordinateBounds. + func toGMSCoordinateBounds() -> GMSCoordinateBounds { + return GMSCoordinateBounds( + coordinate: northeast.toCLLocationCoordinate2D(), + coordinate: southwest.toCLLocationCoordinate2D() + ) + } +} + +extension FGMPlatformCameraPosition { + /// Converts a GMSCameraPosition to its Pigeon representation. + static func make(from position: GMSCameraPosition) -> FGMPlatformCameraPosition { + return FGMPlatformCameraPosition.make( + withBearing: position.bearing, + target: FGMPlatformLatLng.make(from: position.target), + tilt: position.viewingAngle, + zoom: Double(position.zoom) + ) + } + + /// Returns the equivalent GMSCameraPosition. + func toGMSCameraPosition() -> GMSCameraPosition { + return GMSCameraPosition( + target: target.toCLLocationCoordinate2D(), + zoom: Float(zoom), + bearing: bearing, + viewingAngle: tilt + ) + } +} + +/// Creates a GMSMutablePath from points. +func makePath(from points: [CLLocation]) -> GMSMutablePath { + let path = GMSMutablePath() + for location in points { + path.add(location.coordinate) + } + return path +} + +extension FGMPlatformMapType { + /// The corresponding GMSMapViewType. + var gmsMapViewType: GMSMapViewType { + switch self { + case .none: return .none + case .normal: return .normal + case .satellite: return .satellite + case .terrain: return .terrain + case .hybrid: return .hybrid + @unknown default: return .normal + } + } +} + +extension FGMPlatformMarkerCollisionBehavior { + /// The corresponding GMSCollisionBehavior. + var gmsCollisionBehavior: GMSCollisionBehavior { + switch self { + case .requiredDisplay: + return .required + case .optionalAndHidesLowerPriority: + return .optionalAndHidesLowerPriority + case .requiredAndHidesOptional: + return .requiredAndHidesOptional + @unknown default: + return .required + } + } +} + +extension FGMPlatformGroundOverlay { + /// Converts a GMSGroundOverlay to its Pigeon representation. + static func make( + from groundOverlay: GMSGroundOverlay, + overlayId: String, + isCreatedWithBounds: Bool, + zoomLevel: NSNumber? + ) -> FGMPlatformGroundOverlay { + let placeholderImage = FGMPlatformBitmap.make( + withBitmap: FGMPlatformBitmapDefaultMarker.make(withHue: 0)) + if isCreatedWithBounds, let bounds = groundOverlay.bounds { + return FGMPlatformGroundOverlay.make( + withGroundOverlayId: overlayId, + image: placeholderImage, + position: nil, + bounds: FGMPlatformLatLngBounds.make(from: bounds), + anchor: FGMPlatformPoint.make(from: groundOverlay.anchor), + transparency: 1.0 - Double(groundOverlay.opacity), + bearing: groundOverlay.bearing, + zIndex: Int(groundOverlay.zIndex), + visible: groundOverlay.map != nil, + clickable: groundOverlay.isTappable, + zoomLevel: zoomLevel + ) + } else { + return FGMPlatformGroundOverlay.make( + withGroundOverlayId: overlayId, + image: placeholderImage, + position: FGMPlatformLatLng.make(from: groundOverlay.position), + bounds: nil, + anchor: FGMPlatformPoint.make(from: groundOverlay.anchor), + transparency: 1.0 - Double(groundOverlay.opacity), + bearing: groundOverlay.bearing, + zIndex: Int(groundOverlay.zIndex), + visible: groundOverlay.map != nil, + clickable: groundOverlay.isTappable, + zoomLevel: zoomLevel + ) + } + } +} + +extension FGMPlatformHeatmapGradient { + /// Converts a GMUGradient to its Pigeon representation. + static func make(from gradient: GMUGradient) -> FGMPlatformHeatmapGradient { + let colors = gradient.colors.map { FGMPlatformColor.make(from: $0) } + return FGMPlatformHeatmapGradient.make( + with: colors, + startPoints: gradient.startPoints, + colorMapSize: Int(gradient.mapSize) + ) + } + + /// Returns the equivalent GMUGradient. + func toGMUGradient() -> GMUGradient { + let colors = colors.map { $0.toUIColor() } + return GMUGradient( + colors: colors, + startPoints: startPoints, + colorMapSize: UInt(colorMapSize) + ) + } +} + +extension FGMPlatformWeightedLatLng { + /// Converts a GMUWeightedLatLng to its Pigeon representation. + static func make(from weightedLatLng: GMUWeightedLatLng) -> FGMPlatformWeightedLatLng { + let point = GMSMapPoint(x: weightedLatLng.point().x, y: weightedLatLng.point().y) + return FGMPlatformWeightedLatLng.make( + withPoint: FGMPlatformLatLng.make(from: GMSUnproject(point)), + weight: Double(weightedLatLng.intensity) + ) + } + + /// Returns the equivalent GMUWeightedLatLng. + func toGMUWeightedLatLng() -> GMUWeightedLatLng { + return GMUWeightedLatLng(coordinate: point.toCLLocationCoordinate2D(), intensity: Float(weight)) + } +} + +extension FGMPlatformCameraUpdate { + /// Creates a GMSCameraUpdate from its Pigeon equivalent. + func toGMSCameraUpdate() -> GMSCameraUpdate? { + // See note in messages.dart for why this is so loosely typed. + switch cameraUpdate { + case let newCameraPosition as FGMPlatformCameraUpdateNewCameraPosition: + return GMSCameraUpdate.setCamera(newCameraPosition.cameraPosition.toGMSCameraPosition()) + case let newLatLng as FGMPlatformCameraUpdateNewLatLng: + return GMSCameraUpdate.setTarget(newLatLng.latLng.toCLLocationCoordinate2D()) + case let newLatLngBounds as FGMPlatformCameraUpdateNewLatLngBounds: + return GMSCameraUpdate.fit( + newLatLngBounds.bounds.toGMSCoordinateBounds(), + withPadding: CGFloat(newLatLngBounds.padding) + ) + case let newLatLngZoom as FGMPlatformCameraUpdateNewLatLngZoom: + return GMSCameraUpdate.setTarget( + newLatLngZoom.latLng.toCLLocationCoordinate2D(), + zoom: Float(newLatLngZoom.zoom) + ) + case let scrollBy as FGMPlatformCameraUpdateScrollBy: + return GMSCameraUpdate.scrollBy(x: scrollBy.dx, y: scrollBy.dy) + case let zoomBy as FGMPlatformCameraUpdateZoomBy: + if let focus = zoomBy.focus { + return GMSCameraUpdate.zoom(by: Float(zoomBy.amount), at: focus.toCGPoint()) + } else { + return GMSCameraUpdate.zoom(by: Float(zoomBy.amount)) + } + case let zoom as FGMPlatformCameraUpdateZoom: + return zoom.out ? GMSCameraUpdate.zoomOut() : GMSCameraUpdate.zoomIn() + case let zoomTo as FGMPlatformCameraUpdateZoomTo: + return GMSCameraUpdate.zoom(to: Float(zoomTo.zoom)) + default: + return nil + } + } +} + +extension FGMPlatformColor { + /// Converts a UIColor to its Pigeon representation. + static func make(from color: UIColor) -> FGMPlatformColor { + var red: CGFloat = 0 + var green: CGFloat = 0 + var blue: CGFloat = 0 + var alpha: CGFloat = 0 + color.getRed(&red, green: &green, blue: &blue, alpha: &alpha) + return FGMPlatformColor.make( + withRed: Double(red), green: Double(green), blue: Double(blue), alpha: Double(alpha)) + } + + /// Returns the equivalent UIColor. + func toUIColor() -> UIColor { + return UIColor(red: red, green: green, blue: blue, alpha: alpha) + } +} + +extension FGMPlatformPatternItem { + /// The GMSStrokeStyle expression of this pattern, using the given stroke color. + func gmsStrokeStyle(strokeColor: UIColor) -> GMSStrokeStyle { + let color = type == .gap ? UIColor.clear : strokeColor + return GMSStrokeStyle.solidColor(color) + } + + /// The span length for this pattern, in the form expected by GMSStyleSpans. + func gmsStyleSpanLength() -> NSNumber { + return length ?? 0 + } +} + +extension FGMPlatformCluster { + /// Converts a GMUCluster to its Pigeon representation. + static func make( + from cluster: GMUCluster, + clusterManagerIdentifier: String + ) -> FGMPlatformCluster { + var bounds = GMSCoordinateBounds() + for item in cluster.items { + bounds = bounds.includingCoordinate(item.position) + } + + let markerIds = cluster.items.compactMap { $0 as? GMSMarker }.compactMap { + markerIdentifierFromMarker($0) + } + + return FGMPlatformCluster.make( + withClusterManagerId: clusterManagerIdentifier, + position: FGMPlatformLatLng.make(from: cluster.position), + bounds: FGMPlatformLatLngBounds.make(from: bounds), + markerIds: markerIds + ) + } } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/GoogleMapController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/GoogleMapController.swift index 5a9088af435..1407ca72bab 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/GoogleMapController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/GoogleMapController.swift @@ -127,7 +127,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV let polygonsController: PolygonsController let polylinesController: PolylinesController let circlesController: CirclesController - let heatmapsController: FGMHeatmapsController + let heatmapsController: HeatmapsController let tileOverlaysController: TileOverlaysController let groundOverlaysController: GroundOverlaysController @@ -146,8 +146,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV creationParameters: FGMPlatformMapViewCreationParams, registrar: FlutterPluginRegistrar ) { - let camera = FGMGetCameraPositionForPigeonCameraPosition( - creationParameters.initialCameraPosition) + let camera = creationParameters.initialCameraPosition.toGMSCameraPosition() let options = GMSMapViewOptions() options.frame = frame @@ -221,7 +220,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV mapView: mapView, eventDelegate: mapEventHandler ) - heatmapsController = FGMHeatmapsController(mapView: mapView) + heatmapsController = HeatmapsController(mapView: mapView) tileProvider = ConcreteTileProvider(dartCallbackHandler: dartCallbackHandler) tileOverlaysController = TileOverlaysController( mapView: mapView, @@ -361,7 +360,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV public func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) { if trackCameraPosition { - mapEventHandler.didMoveCamera(to: FGMGetPigeonCameraPositionForPosition(position)) + mapEventHandler.didMoveCamera(to: FGMPlatformCameraPosition.make(from: position)) } } @@ -422,11 +421,11 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV } public func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) { - mapEventHandler.didTap(atPosition: FGMGetPigeonLatLngForCoordinate(coordinate)) + mapEventHandler.didTap(atPosition: FGMPlatformLatLng.make(from: coordinate)) } public func mapView(_ mapView: GMSMapView, didLongPressAt coordinate: CLLocationCoordinate2D) { - mapEventHandler.didLongPress(atPosition: FGMGetPigeonLatLngForCoordinate(coordinate)) + mapEventHandler.didLongPress(atPosition: FGMPlatformLatLng.make(from: coordinate)) } func interpretMapConfiguration(_ config: FGMPlatformMapConfiguration) { @@ -452,7 +451,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV ) -> (Bool, String?) { if let cameraTargetBounds = config.cameraTargetBounds { if let bounds = cameraTargetBounds.bounds { - mapView.cameraTargetBounds = FGMGetCoordinateBoundsForPigeonLatLngBounds(bounds) + mapView.cameraTargetBounds = bounds.toGMSCoordinateBounds() } else { mapView.cameraTargetBounds = nil } @@ -470,7 +469,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV mapView.isBuildingsEnabled = buildingsEnabled.boolValue } if let mapType = config.mapType { - mapView.mapType = FGMGetMapViewTypeForPigeonMapType(mapType.value) + mapView.mapType = mapType.value.gmsMapViewType } if let zoomData = config.minMaxZoomPreference { let minZoom = zoomData.min?.floatValue ?? kGMSMinZoomLevel @@ -651,9 +650,9 @@ class MapCallHandler: NSObject, FGMMapsApi { ) return nil } - let point = FGMGetCGPointForPigeonPoint(screenCoordinate) + let point = screenCoordinate.toCGPoint() let latlng = mapView.projection.coordinate(for: point) - return FGMGetPigeonLatLngForCoordinate(latlng) + return FGMPlatformLatLng.make(from: latlng) } func screenCoordinates( @@ -667,9 +666,9 @@ class MapCallHandler: NSObject, FGMMapsApi { ) return nil } - let location = FGMGetCoordinateForPigeonLatLng(latLng) + let location = latLng.toCLLocationCoordinate2D() let point = mapView.projection.point(for: location) - return FGMGetPigeonPointForCGPoint(point) + return FGMPlatformPoint.make(from: point) } func visibleMapRegion(_ error: AutoreleasingUnsafeMutablePointer) @@ -685,14 +684,14 @@ class MapCallHandler: NSObject, FGMMapsApi { } let visibleRegion = mapView.projection.visibleRegion() let bounds = GMSCoordinateBounds(region: visibleRegion) - return FGMGetPigeonLatLngBoundsForCoordinateBounds(bounds) + return FGMPlatformLatLngBounds.make(from: bounds) } func moveCamera( with cameraUpdate: FGMPlatformCameraUpdate, error: AutoreleasingUnsafeMutablePointer ) { - guard let update = FGMGetCameraUpdateForPigeonCameraUpdate(cameraUpdate) else { + guard let update = cameraUpdate.toGMSCameraUpdate() else { error.pointee = FlutterError( code: "Invalid update", message: "Unrecognized camera update", @@ -707,7 +706,7 @@ class MapCallHandler: NSObject, FGMMapsApi { with cameraUpdate: FGMPlatformCameraUpdate, duration durationMilliseconds: NSNumber?, error: AutoreleasingUnsafeMutablePointer ) { - guard let update = FGMGetCameraUpdateForPigeonCameraUpdate(cameraUpdate) else { + guard let update = cameraUpdate.toGMSCameraUpdate() else { error.pointee = FlutterError( code: "Invalid update", message: "Unrecognized camera update", @@ -935,6 +934,6 @@ class MapInspector: NSObject, FGMMapsInspectorApi { guard let mapView = controller?.mapView else { return nil } - return FGMGetPigeonCameraPositionForPosition(mapView.camera) + return FGMPlatformCameraPosition.make(from: mapView.camera) } } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/GroundOverlayController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/GroundOverlayController.swift index 450472dc638..7e52a01d0d8 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/GroundOverlayController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/GroundOverlayController.swift @@ -66,7 +66,8 @@ class GroundOverlayController: NSObject { if let anchor = platformGroundOverlay.anchor { groundOverlay.anchor = CGPoint(x: anchor.x, y: anchor.y) } - groundOverlay.icon = FGMIconFromBitmap(platformGroundOverlay.image, assetProvider, screenScale) + groundOverlay.icon = makeIcon( + from: platformGroundOverlay.image, assetProvider: assetProvider, screenScale: screenScale) groundOverlay.bearing = platformGroundOverlay.bearing groundOverlay.opacity = Float(1.0 - platformGroundOverlay.transparency) if useBounds { @@ -220,11 +221,11 @@ class GroundOverlaysController: NSObject { guard let controller = groundOverlayControllerByIdentifier[identifier] else { return nil } - return FGMGetPigeonGroundOverlay( - controller.groundOverlay, - identifier, - controller.createdWithBounds, - controller.zoomLevel + return FGMPlatformGroundOverlay.make( + from: controller.groundOverlay, + overlayId: identifier, + isCreatedWithBounds: controller.createdWithBounds, + zoomLevel: controller.zoomLevel ) } } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/MarkerController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/MarkerController.swift index ce63a5be7cf..d1c1608ffed 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/MarkerController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/MarkerController.swift @@ -82,25 +82,25 @@ class MarkerController: NSObject { screenScale: CGFloat, usingOpacityForVisibility useOpacityForVisibility: Bool ) { - marker.groundAnchor = FGMGetCGPointForPigeonPoint(platformMarker.anchor) + marker.groundAnchor = platformMarker.anchor.toCGPoint() marker.isDraggable = platformMarker.draggable - marker.icon = FGMIconFromBitmap(platformMarker.icon, assetProvider, screenScale) + marker.icon = makeIcon( + from: platformMarker.icon, assetProvider: assetProvider, screenScale: screenScale) marker.isFlat = platformMarker.flat - marker.position = FGMGetCoordinateForPigeonLatLng(platformMarker.position) + marker.position = platformMarker.position.toCLLocationCoordinate2D() marker.rotation = platformMarker.rotation marker.zIndex = Int32(platformMarker.zIndex) let infoWindow = platformMarker.infoWindow - marker.infoWindowAnchor = FGMGetCGPointForPigeonPoint(infoWindow.anchor) + marker.infoWindowAnchor = infoWindow.anchor.toCGPoint() if let title = infoWindow.title { marker.title = title marker.snippet = infoWindow.snippet } if let advancedMarker = marker as? GMSAdvancedMarker, - let collisionBehavior = platformMarker.collisionBehavior + let collisionBehaviorValue = platformMarker.collisionBehavior { - advancedMarker.collisionBehavior = FGMGetCollisionBehaviorForPigeonCollisionBehavior( - collisionBehavior.value) + advancedMarker.collisionBehavior = collisionBehaviorValue.value.gmsCollisionBehavior } // This must be done last, to avoid visual flickers of default property values. @@ -145,7 +145,7 @@ class MarkersController: NSObject { private func addMarker(_ markerToAdd: FGMPlatformMarker) { guard let mapView = mapView else { return } - let position = FGMGetCoordinateForPigeonLatLng(markerToAdd.position) + let position = markerToAdd.position.toCLLocationCoordinate2D() let markerIdentifier = markerToAdd.markerId let clusterManagerIdentifier = markerToAdd.clusterManagerId @@ -229,7 +229,7 @@ class MarkersController: NSObject { guard markerIdentifierToController[identifier] != nil else { return } eventDelegate?.didStartDragForMarker( withIdentifier: identifier, - atPosition: FGMGetPigeonLatLngForCoordinate(location) + atPosition: FGMPlatformLatLng.make(from: location) ) } @@ -237,7 +237,7 @@ class MarkersController: NSObject { guard markerIdentifierToController[identifier] != nil else { return } eventDelegate?.didDragMarker( withIdentifier: identifier, - atPosition: FGMGetPigeonLatLngForCoordinate(location) + atPosition: FGMPlatformLatLng.make(from: location) ) } @@ -245,7 +245,7 @@ class MarkersController: NSObject { guard markerIdentifierToController[identifier] != nil else { return } eventDelegate?.didEndDragForMarker( withIdentifier: identifier, - atPosition: FGMGetPigeonLatLngForCoordinate(location) + atPosition: FGMPlatformLatLng.make(from: location) ) } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/PolygonController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/PolygonController.swift index 0808d878462..06b4d722f77 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/PolygonController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/PolygonController.swift @@ -41,12 +41,10 @@ class PolygonController: NSObject { ) { polygon.isTappable = platformPolygon.consumesTapEvents polygon.zIndex = Int32(platformPolygon.zIndex) - polygon.path = FGMGetPathFromPoints(FGMGetPointsForPigeonLatLngs(platformPolygon.points)) - polygon.holes = FGMGetHolesForPigeonLatLngArrays(platformPolygon.holes).map { - FGMGetPathFromPoints($0) - } - polygon.fillColor = FGMGetColorForPigeonColor(platformPolygon.fillColor) - polygon.strokeColor = FGMGetColorForPigeonColor(platformPolygon.strokeColor) + polygon.path = makePath(from: platformPolygon.points.map({ $0.toCLLocation() })) + polygon.holes = platformPolygon.holes.map { makePath(from: $0.map({ $0.toCLLocation() })) } + polygon.fillColor = platformPolygon.fillColor.toUIColor() + polygon.strokeColor = platformPolygon.strokeColor.toUIColor() polygon.strokeWidth = CGFloat(platformPolygon.strokeWidth) // This must be done last, to avoid visual flickers of default property values. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/PolylineController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/PolylineController.swift index b6c0d57aef1..1d6efa1c4d5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/PolylineController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/PolylineController.swift @@ -41,16 +41,16 @@ class PolylineController: NSObject { ) { polyline.isTappable = platformPolyline.consumesTapEvents polyline.zIndex = Int32(platformPolyline.zIndex) - let path = FGMGetPathFromPoints(FGMGetPointsForPigeonLatLngs(platformPolyline.points)) - polyline.path = path - let strokeColor = FGMGetColorForPigeonColor(platformPolyline.color) + let gmsPath = makePath(from: platformPolyline.points.map({ $0.toCLLocation() })) + polyline.path = gmsPath + let strokeColor = platformPolyline.color.toUIColor() polyline.strokeColor = strokeColor polyline.strokeWidth = CGFloat(platformPolyline.width) polyline.geodesic = platformPolyline.geodesic polyline.spans = GMSStyleSpans( - path, - FGMGetStrokeStylesFromPatterns(platformPolyline.patterns, strokeColor), - FGMGetSpanLengthsFromPatterns(platformPolyline.patterns), + gmsPath, + platformPolyline.patterns.map { $0.gmsStrokeStyle(strokeColor: strokeColor) }, + platformPolyline.patterns.map { $0.gmsStyleSpanLength() }, .rhumb ) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/FGMConversionUtils.m b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/FGMConversionUtils.m deleted file mode 100644 index 219d8df44a1..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/FGMConversionUtils.m +++ /dev/null @@ -1,275 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "FGMConversionUtils.h" - -CGPoint FGMGetCGPointForPigeonPoint(FGMPlatformPoint *point) { - return CGPointMake(point.x, point.y); -} - -FGMPlatformPoint *FGMGetPigeonPointForCGPoint(CGPoint point) { - return [FGMPlatformPoint makeWithX:point.x y:point.y]; -} - -CLLocationCoordinate2D FGMGetCoordinateForPigeonLatLng(FGMPlatformLatLng *latLng) { - return CLLocationCoordinate2DMake(latLng.latitude, latLng.longitude); -} - -FGMPlatformLatLng *FGMGetPigeonLatLngForCoordinate(CLLocationCoordinate2D coord) { - 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) - southwest:FGMGetPigeonLatLngForCoordinate(bounds.southWest)]; -} - -FGMPlatformCameraPosition *FGMGetPigeonCameraPositionForPosition(GMSCameraPosition *position) { - return [FGMPlatformCameraPosition makeWithBearing:position.bearing - target:FGMGetPigeonLatLngForCoordinate(position.target) - tilt:position.viewingAngle - zoom:position.zoom]; -} - -GMSCameraPosition *FGMGetCameraPositionForPigeonCameraPosition( - FGMPlatformCameraPosition *position) { - return [GMSCameraPosition cameraWithTarget:FGMGetCoordinateForPigeonLatLng(position.target) - zoom:position.zoom - bearing:position.bearing - viewingAngle:position.tilt]; -} - -NSArray *FGMGetPointsForPigeonLatLngs(NSArray *pigeonPoints) { - NSMutableArray *points = [[NSMutableArray alloc] initWithCapacity:pigeonPoints.count]; - for (FGMPlatformLatLng *point in pigeonPoints) { - [points addObject:[[CLLocation alloc] initWithLatitude:point.latitude - longitude:point.longitude]]; - } - return points; -} - -NSArray *> *FGMGetHolesForPigeonLatLngArrays( - NSArray *> *pigeonHolePoints) { - NSMutableArray *> *holes = - [[NSMutableArray alloc] initWithCapacity:pigeonHolePoints.count]; - for (NSArray *holePoints in pigeonHolePoints) { - [holes addObject:FGMGetPointsForPigeonLatLngs(holePoints)]; - } - return holes; -} - -GMSMutablePath *FGMGetPathFromPoints(NSArray *points) { - GMSMutablePath *path = [GMSMutablePath path]; - for (CLLocation *location in points) { - [path addCoordinate:location.coordinate]; - } - return path; -} - -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; - } -} - -GMSCollisionBehavior FGMGetCollisionBehaviorForPigeonCollisionBehavior( - FGMPlatformMarkerCollisionBehavior collisionBehavior) { - switch (collisionBehavior) { - case FGMPlatformMarkerCollisionBehaviorRequiredDisplay: - return GMSCollisionBehaviorRequired; - case FGMPlatformMarkerCollisionBehaviorOptionalAndHidesLowerPriority: - return GMSCollisionBehaviorOptionalAndHidesLowerPriority; - case FGMPlatformMarkerCollisionBehaviorRequiredAndHidesOptional: - return GMSCollisionBehaviorRequiredAndHidesOptional; - } -} - -FGMPlatformGroundOverlay *FGMGetPigeonGroundOverlay(GMSGroundOverlay *groundOverlay, - NSString *overlayId, BOOL isCreatedWithBounds, - NSNumber *zoomLevel) { - // Image is mandatory field on FGMPlatformGroundOverlay (and it should be kept - // non-nullable), therefore image must be set for the object. The image is - // description either contains set of bytes, or path to asset. This info is - // converted to format google maps uses (BitmapDescription), and the original - // data is not stored on native code. Therefore placeholder image is used for - // the image field. - FGMPlatformBitmap *placeholderImage = - [FGMPlatformBitmap makeWithBitmap:[FGMPlatformBitmapDefaultMarker makeWithHue:0]]; - if (isCreatedWithBounds) { - return [FGMPlatformGroundOverlay - makeWithGroundOverlayId:overlayId - image:placeholderImage - position:nil - bounds:[FGMPlatformLatLngBounds - makeWithNortheast:[FGMPlatformLatLng - makeWithLatitude:groundOverlay.bounds - .northEast.latitude - longitude:groundOverlay.bounds - .northEast.longitude] - southwest:[FGMPlatformLatLng - makeWithLatitude:groundOverlay.bounds - .southWest.latitude - longitude:groundOverlay.bounds - .southWest - .longitude]] - anchor:[FGMPlatformPoint makeWithX:groundOverlay.anchor.x - y:groundOverlay.anchor.y] - transparency:1.0f - groundOverlay.opacity - bearing:groundOverlay.bearing - zIndex:groundOverlay.zIndex - visible:groundOverlay.map != nil - clickable:groundOverlay.isTappable - zoomLevel:zoomLevel]; - } else { - return [FGMPlatformGroundOverlay - makeWithGroundOverlayId:overlayId - image:placeholderImage - position:[FGMPlatformLatLng - makeWithLatitude:groundOverlay.position.latitude - longitude:groundOverlay.position.longitude] - bounds:nil - anchor:[FGMPlatformPoint makeWithX:groundOverlay.anchor.x - y:groundOverlay.anchor.y] - transparency:1.0f - groundOverlay.opacity - bearing:groundOverlay.bearing - zIndex:groundOverlay.zIndex - visible:groundOverlay.map != nil - clickable:groundOverlay.isTappable - zoomLevel:zoomLevel]; - } -} - -GMUGradient *FGMGetGradientForPigeonHeatmapGradient(FGMPlatformHeatmapGradient *gradient) { - NSMutableArray *colors = [[NSMutableArray alloc] initWithCapacity:gradient.colors.count]; - for (FGMPlatformColor *color in gradient.colors) { - [colors addObject:FGMGetColorForPigeonColor(color)]; - } - return [[GMUGradient alloc] initWithColors:colors - startPoints:gradient.startPoints - colorMapSize:gradient.colorMapSize]; -} - -FGMPlatformHeatmapGradient *FGMGetPigeonHeatmapGradientForGradient(GMUGradient *gradient) { - NSMutableArray *colors = [[NSMutableArray alloc] initWithCapacity:gradient.colors.count]; - for (UIColor *color in gradient.colors) { - [colors addObject:FGMGetPigeonColorForColor(color)]; - } - return [FGMPlatformHeatmapGradient makeWithColors:colors - startPoints:gradient.startPoints - colorMapSize:gradient.mapSize]; -} - -NSArray *FGMGetWeightedDataForPigeonWeightedData( - NSArray *weightedLatLngs) { - NSMutableArray *weightedData = [[NSMutableArray alloc] initWithCapacity:weightedLatLngs.count]; - for (FGMPlatformWeightedLatLng *weightedLatLng in weightedLatLngs) { - [weightedData - addObject:[[GMUWeightedLatLng alloc] - initWithCoordinate:FGMGetCoordinateForPigeonLatLng(weightedLatLng.point) - intensity:weightedLatLng.weight]]; - } - return weightedData; -} - -NSArray *FGMGetPigeonWeightedDataForWeightedData( - NSArray *weightedLatLngs) { - NSMutableArray *weightedData = [[NSMutableArray alloc] initWithCapacity:weightedLatLngs.count]; - for (GMUWeightedLatLng *weightedLatLng in weightedLatLngs) { - GMSMapPoint point = {weightedLatLng.point.x, weightedLatLng.point.y}; - [weightedData addObject:[FGMPlatformWeightedLatLng - makeWithPoint:FGMGetPigeonLatLngForCoordinate(GMSUnproject(point)) - weight:weightedLatLng.intensity]]; - } - return weightedData; -} - -GMSCameraUpdate *FGMGetCameraUpdateForPigeonCameraUpdate(FGMPlatformCameraUpdate *cameraUpdate) { - // See note in messages.dart for why this is so loosely typed. - id update = cameraUpdate.cameraUpdate; - if ([update isKindOfClass:[FGMPlatformCameraUpdateNewCameraPosition class]]) { - return [GMSCameraUpdate - setCamera:FGMGetCameraPositionForPigeonCameraPosition( - ((FGMPlatformCameraUpdateNewCameraPosition *)update).cameraPosition)]; - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateNewLatLng class]]) { - return [GMSCameraUpdate setTarget:FGMGetCoordinateForPigeonLatLng( - ((FGMPlatformCameraUpdateNewLatLng *)update).latLng)]; - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateNewLatLngBounds class]]) { - FGMPlatformCameraUpdateNewLatLngBounds *typedUpdate = - (FGMPlatformCameraUpdateNewLatLngBounds *)update; - return - [GMSCameraUpdate fitBounds:FGMGetCoordinateBoundsForPigeonLatLngBounds(typedUpdate.bounds) - withPadding:typedUpdate.padding]; - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateNewLatLngZoom class]]) { - FGMPlatformCameraUpdateNewLatLngZoom *typedUpdate = - (FGMPlatformCameraUpdateNewLatLngZoom *)update; - return [GMSCameraUpdate setTarget:FGMGetCoordinateForPigeonLatLng(typedUpdate.latLng) - zoom:typedUpdate.zoom]; - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateScrollBy class]]) { - FGMPlatformCameraUpdateScrollBy *typedUpdate = (FGMPlatformCameraUpdateScrollBy *)update; - return [GMSCameraUpdate scrollByX:typedUpdate.dx Y:typedUpdate.dy]; - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateZoomBy class]]) { - FGMPlatformCameraUpdateZoomBy *typedUpdate = (FGMPlatformCameraUpdateZoomBy *)update; - if (typedUpdate.focus) { - return [GMSCameraUpdate zoomBy:typedUpdate.amount - atPoint:FGMGetCGPointForPigeonPoint(typedUpdate.focus)]; - } else { - return [GMSCameraUpdate zoomBy:typedUpdate.amount]; - } - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateZoom class]]) { - if (((FGMPlatformCameraUpdateZoom *)update).out) { - return [GMSCameraUpdate zoomOut]; - } else { - return [GMSCameraUpdate zoomIn]; - } - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateZoomTo class]]) { - return [GMSCameraUpdate zoomTo:((FGMPlatformCameraUpdateZoomTo *)update).zoom]; - } - return nil; -} - -UIColor *FGMGetColorForPigeonColor(FGMPlatformColor *color) { - return [UIColor colorWithRed:color.red green:color.green blue:color.blue alpha:color.alpha]; -} - -FGMPlatformColor *FGMGetPigeonColorForColor(UIColor *color) { - double red, green, blue, alpha; - [color getRed:&red green:&green blue:&blue alpha:&alpha]; - return [FGMPlatformColor makeWithRed:red green:green blue:blue alpha:alpha]; -} - -NSArray *FGMGetStrokeStylesFromPatterns( - NSArray *patterns, UIColor *strokeColor) { - NSMutableArray *strokeStyles = [[NSMutableArray alloc] initWithCapacity:[patterns count]]; - for (FGMPlatformPatternItem *pattern in patterns) { - UIColor *color = - pattern.type == FGMPlatformPatternItemTypeGap ? UIColor.clearColor : strokeColor; - [strokeStyles addObject:[GMSStrokeStyle solidColor:color]]; - } - return strokeStyles; -} - -NSArray *FGMGetSpanLengthsFromPatterns(NSArray *patterns) { - NSMutableArray *lengths = [[NSMutableArray alloc] initWithCapacity:[patterns count]]; - for (FGMPlatformPatternItem *pattern in patterns) { - NSNumber *length = pattern.length ?: @0; - [lengths addObject:length]; - } - return lengths; -} diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/FGMHeatmapController.m b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/FGMHeatmapController.m deleted file mode 100644 index 49ec16dff82..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/FGMHeatmapController.m +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "FGMHeatmapController.h" -#import "FGMHeatmapController_Test.h" - -@import GoogleMapsUtils; - -#import "FGMConversionUtils.h" - -@interface FGMHeatmapController () - -/// The heatmap tile layer this controller handles. -@property(nonatomic, strong) GMUHeatmapTileLayer *heatmapTileLayer; - -/// The GMSMapView to which the heatmaps are added. -@property(nonatomic, weak) GMSMapView *mapView; - -@end - -@implementation FGMHeatmapController -- (instancetype)initWithHeatmap:(FGMPlatformHeatmap *)heatmap - tileLayer:(GMUHeatmapTileLayer *)heatmapTileLayer - mapView:(GMSMapView *)mapView { - self = [super init]; - if (self) { - _heatmapTileLayer = heatmapTileLayer; - _mapView = mapView; - - [FGMHeatmapController updateHeatmap:_heatmapTileLayer - fromPlatformHeatmap:heatmap - withMapView:_mapView]; - } - return self; -} - -- (void)removeHeatmap { - _heatmapTileLayer.map = nil; -} - -- (void)clearTileCache { - [_heatmapTileLayer clearTileCache]; -} - -- (void)updateFromPlatformHeatmap:(FGMPlatformHeatmap *)platformHeatmap { - [FGMHeatmapController updateHeatmap:_heatmapTileLayer - fromPlatformHeatmap:platformHeatmap - withMapView:_mapView]; -} - -+ (void)updateHeatmap:(GMUHeatmapTileLayer *)heatmapTileLayer - fromPlatformHeatmap:(FGMPlatformHeatmap *)platformHeatmap - withMapView:(GMSMapView *)mapView { - heatmapTileLayer.weightedData = FGMGetWeightedDataForPigeonWeightedData(platformHeatmap.data); - if (platformHeatmap.gradient) { - heatmapTileLayer.gradient = FGMGetGradientForPigeonHeatmapGradient(platformHeatmap.gradient); - } - heatmapTileLayer.opacity = platformHeatmap.opacity; - heatmapTileLayer.radius = platformHeatmap.radius; - heatmapTileLayer.minimumZoomIntensity = platformHeatmap.minimumZoomIntensity; - heatmapTileLayer.maximumZoomIntensity = platformHeatmap.maximumZoomIntensity; - - // The map must be set each time for options to update. - // This must be done last, to avoid visual flickers of default property values. - heatmapTileLayer.map = mapView; -} -@end - -@interface FGMHeatmapsController () - -/// A map from heatmapId to the controller that manages it. -@property(nonatomic, strong) - NSMutableDictionary *heatmapIdToController; - -/// The map view owned by GoogmeMapController. -@property(nonatomic, weak) GMSMapView *mapView; - -@end - -@implementation FGMHeatmapsController -- (instancetype)initWithMapView:(GMSMapView *)mapView { - self = [super init]; - if (self) { - _mapView = mapView; - _heatmapIdToController = [NSMutableDictionary dictionary]; - } - return self; -} - -- (void)addHeatmaps:(NSArray *)heatmapsToAdd { - for (FGMPlatformHeatmap *heatmap in heatmapsToAdd) { - GMUHeatmapTileLayer *heatmapTileLayer = [[GMUHeatmapTileLayer alloc] init]; - FGMHeatmapController *controller = - [[FGMHeatmapController alloc] initWithHeatmap:heatmap - tileLayer:heatmapTileLayer - mapView:_mapView]; - _heatmapIdToController[heatmap.heatmapId] = controller; - } -} - -- (void)changeHeatmaps:(NSArray *)heatmapsToChange { - for (FGMPlatformHeatmap *heatmap in heatmapsToChange) { - FGMHeatmapController *controller = _heatmapIdToController[heatmap.heatmapId]; - - [controller updateFromPlatformHeatmap:heatmap]; - [controller clearTileCache]; - } -} - -- (void)removeHeatmapsWithIdentifiers:(NSArray *)identifiers { - for (NSString *heatmapId in identifiers) { - FGMHeatmapController *controller = _heatmapIdToController[heatmapId]; - if (!controller) { - continue; - } - [controller removeHeatmap]; - [_heatmapIdToController removeObjectForKey:heatmapId]; - } -} - -- (BOOL)hasHeatmapWithIdentifier:(NSString *)identifier { - return _heatmapIdToController[identifier] != nil; -} - -- (FGMPlatformHeatmap *)heatmapWithIdentifier:(NSString *)identifier { - GMUHeatmapTileLayer *heatmap = self.heatmapIdToController[identifier].heatmapTileLayer; - if (!heatmap) { - return nil; - } - return [FGMPlatformHeatmap - makeWithHeatmapId:identifier - data:FGMGetPigeonWeightedDataForWeightedData(heatmap.weightedData) - gradient:FGMGetPigeonHeatmapGradientForGradient(heatmap.gradient) - opacity:heatmap.opacity - radius:heatmap.radius - minimumZoomIntensity:heatmap.minimumZoomIntensity - maximumZoomIntensity:heatmap.maximumZoomIntensity]; -} -@end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/FGMImageUtils.m b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/FGMImageUtils.m deleted file mode 100644 index 03eb36eeb40..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/FGMImageUtils.m +++ /dev/null @@ -1,271 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -@import Flutter; - -#import "FGMImageUtils.h" -#import "FGMConversionUtils.h" - -@import Foundation; - -/// This method is deprecated within the context of `BitmapDescriptor.fromBytes` handling in the -/// flutter google_maps_flutter_platform_interface package which has been replaced by 'bytes' -/// message handling. It will be removed when the deprecated image bitmap description type -/// 'fromBytes' is removed from the platform interface. -static UIImage *scaledImage(UIImage *image, double scale); - -/// Creates a scaled version of the provided UIImage based on a specified scale factor. If the -/// scale factor differs from the image's current scale by more than a small epsilon-delta (to -/// account for minor floating-point inaccuracies), a new UIImage object is created with the -/// specified scale. Otherwise, the original image is returned. -/// -/// @param image The UIImage to scale. -/// @param scale The factor by which to scale the image. -/// @return UIImage Returns the scaled UIImage. -static UIImage *scaledImageWithScale(UIImage *image, CGFloat scale); - -/// Scales an input UIImage to a specified size. If the aspect ratio of the input image -/// closely matches the target size, indicated by a small epsilon-delta, the image's scale -/// property is updated instead of resizing the image. If the aspect ratios differ beyond this -/// threshold, the method redraws the image at the target size. -/// -/// @param image The UIImage to scale. -/// @param size The target CGSize to scale the image to. -/// @return UIImage Returns the scaled UIImage. -static UIImage *scaledImageWithSize(UIImage *image, CGSize size); - -/// Scales an input UIImage to a specified width and height preserving aspect ratio if both -/// widht and height are not given.. -/// -/// @param image The UIImage to scale. -/// @param width The target width to scale the image to. -/// @param height The target height to scale the image to. -/// @param screenScale The current screen scale. -/// @return UIImage Returns the scaled UIImage. -static UIImage *scaledImageWithWidthHeight(UIImage *image, NSNumber *width, NSNumber *height, - CGFloat screenScale); - -UIImage *FGMIconFromBitmap(FGMPlatformBitmap *platformBitmap, - NSObject *assetProvider, CGFloat screenScale) { - assert(screenScale > 0 && "Screen scale must be greater than 0"); - // See comment in messages.dart for why this is so loosely typed. See also - // https://github.com/flutter/flutter/issues/117819. - id bitmap = platformBitmap.bitmap; - UIImage *image; - if ([bitmap isKindOfClass:[FGMPlatformBitmapDefaultMarker class]]) { - FGMPlatformBitmapDefaultMarker *bitmapDefaultMarker = bitmap; - CGFloat hue = bitmapDefaultMarker.hue.doubleValue; - image = [GMSMarker markerImageWithColor:[UIColor colorWithHue:hue / 360.0 - saturation:1.0 - brightness:0.7 - alpha:1.0]]; - } else if ([bitmap isKindOfClass:[FGMPlatformBitmapAsset class]]) { - // Deprecated: This message handling for 'fromAsset' has been replaced by 'asset'. - // Refer to the flutter google_maps_flutter_platform_interface package for details. - FGMPlatformBitmapAsset *bitmapAsset = bitmap; - if (bitmapAsset.pkg) { - image = [assetProvider imageNamed:[assetProvider lookupKeyForAsset:bitmapAsset.name - fromPackage:bitmapAsset.pkg]]; - } else { - image = [assetProvider imageNamed:[assetProvider lookupKeyForAsset:bitmapAsset.name]]; - } - } else if ([bitmap isKindOfClass:[FGMPlatformBitmapAssetImage class]]) { - // Deprecated: This message handling for 'fromAssetImage' has been replaced by 'asset'. - // Refer to the flutter google_maps_flutter_platform_interface package for details. - FGMPlatformBitmapAssetImage *bitmapAssetImage = bitmap; - image = [assetProvider imageNamed:[assetProvider lookupKeyForAsset:bitmapAssetImage.name]]; - image = scaledImage(image, bitmapAssetImage.scale); - } else if ([bitmap isKindOfClass:[FGMPlatformBitmapBytes class]]) { - // Deprecated: This message handling for 'fromBytes' has been replaced by 'bytes'. - // Refer to the flutter google_maps_flutter_platform_interface package for details. - FGMPlatformBitmapBytes *bitmapBytes = bitmap; - @try { - image = [UIImage imageWithData:bitmapBytes.byteData.data scale:screenScale]; - } @catch (NSException *exception) { - @throw [NSException exceptionWithName:@"InvalidByteDescriptor" - reason:@"Unable to interpret bytes as a valid image." - userInfo:nil]; - } - } else if ([bitmap isKindOfClass:[FGMPlatformBitmapAssetMap class]]) { - FGMPlatformBitmapAssetMap *bitmapAssetMap = bitmap; - - image = [assetProvider imageNamed:[assetProvider lookupKeyForAsset:bitmapAssetMap.assetName]]; - - if (bitmapAssetMap.bitmapScaling == FGMPlatformMapBitmapScalingAuto) { - NSNumber *width = bitmapAssetMap.width; - NSNumber *height = bitmapAssetMap.height; - if (width || height) { - image = scaledImageWithScale(image, screenScale); - image = scaledImageWithWidthHeight(image, width, height, screenScale); - } else { - image = scaledImageWithScale(image, bitmapAssetMap.imagePixelRatio); - } - } - } else if ([bitmap isKindOfClass:[FGMPlatformBitmapBytesMap class]]) { - FGMPlatformBitmapBytesMap *bitmapBytesMap = bitmap; - FlutterStandardTypedData *bytes = bitmapBytesMap.byteData; - - @try { - image = [UIImage imageWithData:bytes.data scale:screenScale]; - if (bitmapBytesMap.bitmapScaling == FGMPlatformMapBitmapScalingAuto) { - NSNumber *width = bitmapBytesMap.width; - NSNumber *height = bitmapBytesMap.height; - - if (width || height) { - // Before scaling the image, image must be in screenScale. - image = scaledImageWithScale(image, screenScale); - image = scaledImageWithWidthHeight(image, width, height, screenScale); - } else { - image = scaledImageWithScale(image, bitmapBytesMap.imagePixelRatio); - } - } else { - // No scaling, load image from bytes without scale parameter. - image = [UIImage imageWithData:bytes.data]; - } - } @catch (NSException *exception) { - @throw [NSException exceptionWithName:@"InvalidByteDescriptor" - reason:@"Unable to interpret bytes as a valid image." - userInfo:nil]; - } - } else if ([bitmap isKindOfClass:[FGMPlatformBitmapPinConfig class]]) { - FGMPlatformBitmapPinConfig *pinConfig = bitmap; - - GMSPinImageOptions *options = [[GMSPinImageOptions alloc] init]; - FGMPlatformColor *backgroundColor = pinConfig.backgroundColor; - if (backgroundColor) { - options.backgroundColor = FGMGetColorForPigeonColor(backgroundColor); - } - - FGMPlatformColor *borderColor = pinConfig.borderColor; - if (borderColor) { - options.borderColor = FGMGetColorForPigeonColor(borderColor); - } - - GMSPinImageGlyph *glyph; - NSString *glyphText = pinConfig.glyphText; - FGMPlatformColor *glyphColor = pinConfig.glyphColor; - FGMPlatformBitmap *glyphBitmap = pinConfig.glyphBitmap; - if (glyphText) { - FGMPlatformColor *glyphTextColorValue = pinConfig.glyphTextColor; - UIColor *glyphTextColor = glyphTextColorValue ? FGMGetColorForPigeonColor(glyphTextColorValue) - : [UIColor blackColor]; - glyph = [[GMSPinImageGlyph alloc] initWithText:glyphText textColor:glyphTextColor]; - } else if (glyphColor) { - UIColor *color = FGMGetColorForPigeonColor(glyphColor); - glyph = [[GMSPinImageGlyph alloc] initWithGlyphColor:color]; - } else if (glyphBitmap) { - UIImage *glyphImage = FGMIconFromBitmap(glyphBitmap, assetProvider, screenScale); - glyph = [[GMSPinImageGlyph alloc] initWithImage:glyphImage]; - } - - options.glyph = glyph; - - image = [GMSPinImage pinImageWithOptions:options]; - } - - return image; -} - -UIImage *scaledImage(UIImage *image, double scale) { - if (fabs(scale - 1) > 1e-3) { - return [UIImage imageWithCGImage:[image CGImage] - scale:(image.scale * scale) - orientation:(image.imageOrientation)]; - } - return image; -} - -UIImage *scaledImageWithScale(UIImage *image, CGFloat scale) { - if (fabs(scale - image.scale) > DBL_EPSILON) { - return [UIImage imageWithCGImage:[image CGImage] - scale:scale - orientation:(image.imageOrientation)]; - } - return image; -} - -UIImage *scaledImageWithSize(UIImage *image, CGSize size) { - CGFloat originalPixelWidth = image.size.width * image.scale; - CGFloat originalPixelHeight = image.size.height * image.scale; - - // Return original image if either original image size or target size is so small that - // image cannot be resized or displayed. - if (originalPixelWidth <= 0 || originalPixelHeight <= 0 || size.width <= 0 || size.height <= 0) { - return image; - } - - // Check if the image's size, accounting for scale, matches the target size. - if (fabs(originalPixelWidth - size.width) <= DBL_EPSILON && - fabs(originalPixelHeight - size.height) <= DBL_EPSILON) { - // No need for resizing, return the original image - return image; - } - - // Check if the aspect ratios are approximately equal. - CGSize originalPixelSize = CGSizeMake(originalPixelWidth, originalPixelHeight); - if (FGMIsScalableWithScaleFactorFromSize(originalPixelSize, size)) { - // Scaled image has close to same aspect ratio, - // updating image scale instead of resizing image. - CGFloat factor = originalPixelWidth / size.width; - return scaledImageWithScale(image, image.scale * factor); - } else { - // Aspect ratios differ significantly, resize the image. - UIGraphicsImageRendererFormat *format = [UIGraphicsImageRendererFormat defaultFormat]; - format.scale = 1.0; - format.opaque = NO; - UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:size - format:format]; - UIImage *newImage = - [renderer imageWithActions:^(UIGraphicsImageRendererContext *_Nonnull context) { - [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; - }]; - - // Return image with proper scaling. - return scaledImageWithScale(newImage, image.scale); - } -} - -UIImage *scaledImageWithWidthHeight(UIImage *image, NSNumber *width, NSNumber *height, - CGFloat screenScale) { - if ((width == nil) && (height == nil)) { - return image; - } - - CGFloat targetWidth = width == nil ? image.size.width : width.doubleValue; - CGFloat targetHeight = height == nil ? image.size.height : height.doubleValue; - - if ((width != nil) && (height == nil)) { - // Calculate height based on aspect ratio if only width is provided. - double aspectRatio = image.size.height / image.size.width; - targetHeight = round(targetWidth * aspectRatio); - } else if ((width == nil) && (height != nil)) { - // Calculate width based on aspect ratio if only height is provided. - double aspectRatio = image.size.width / image.size.height; - targetWidth = round(targetHeight * aspectRatio); - } - - CGSize targetSize = - CGSizeMake(round(targetWidth * screenScale), round(targetHeight * screenScale)); - return scaledImageWithSize(image, targetSize); -} - -BOOL FGMIsScalableWithScaleFactorFromSize(CGSize originalSize, CGSize targetSize) { - // Select the scaling factor based on the longer side to have good precision. - CGFloat scaleFactor = (originalSize.width > originalSize.height) - ? (targetSize.width / originalSize.width) - : (targetSize.height / originalSize.height); - - // Calculate the scaled dimensions. - CGFloat scaledWidth = originalSize.width * scaleFactor; - CGFloat scaledHeight = originalSize.height * scaleFactor; - - // Check if the scaled dimensions are within a one-pixel - // threshold of the target dimensions. - BOOL widthWithinThreshold = fabs(scaledWidth - targetSize.width) <= 1.0; - BOOL heightWithinThreshold = fabs(scaledHeight - targetSize.height) <= 1.0; - - // The image is considered scalable with scale factor - // if both dimensions are within the threshold. - return widthWithinThreshold && heightWithinThreshold; -} diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/include/google_maps_flutter_ios_sdk10_objc/FGMConversionUtils.h b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/include/google_maps_flutter_ios_sdk10_objc/FGMConversionUtils.h deleted file mode 100644 index b7344e6b492..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/include/google_maps_flutter_ios_sdk10_objc/FGMConversionUtils.h +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -@import Foundation; -@import GoogleMaps; - -#import "GoogleMapsUtilsTrampoline.h" -#import "google_maps_flutter_pigeon_messages.g.h" - -NS_ASSUME_NONNULL_BEGIN - -/// Creates a CGPoint from its Pigeon equivalent. -extern CGPoint FGMGetCGPointForPigeonPoint(FGMPlatformPoint *point); - -/// Converts a CGPoint to its Pigeon equivalent. -extern FGMPlatformPoint *FGMGetPigeonPointForCGPoint(CGPoint point); - -/// Creates a CLLocationCoordinate2D from its Pigeon representation. -extern CLLocationCoordinate2D FGMGetCoordinateForPigeonLatLng(FGMPlatformLatLng *latLng); - -/// 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); - -/// Converts a GMSCameraPosition to its Pigeon representation. -extern FGMPlatformCameraPosition *FGMGetPigeonCameraPositionForPosition( - GMSCameraPosition *position); - -/// Creates a GMSCameraPosition from its Pigeon representation. -extern GMSCameraPosition *FGMGetCameraPositionForPigeonCameraPosition( - FGMPlatformCameraPosition *position); - -/// Creates a CLLocation array from its Pigeon equivalent. -extern NSArray *FGMGetPointsForPigeonLatLngs(NSArray *points); - -/// Creates a CLLocation arary array, representing a set of holes, from its Pigeon equivalent. -extern NSArray *> *FGMGetHolesForPigeonLatLngArrays( - NSArray *> *points); - -extern GMSMutablePath *FGMGetPathFromPoints(NSArray *points); - -/// Creates a GMSMapViewType from its Pigeon representation. -extern GMSMapViewType FGMGetMapViewTypeForPigeonMapType(FGMPlatformMapType type); - -/// Creates a GMSCollisionBehavior from its Pigeon representation. -extern GMSCollisionBehavior FGMGetCollisionBehaviorForPigeonCollisionBehavior( - FGMPlatformMarkerCollisionBehavior collisionBehavior); - -/// Converts a GMSGroundOverlay to its Pigeon representation. -extern FGMPlatformGroundOverlay *FGMGetPigeonGroundOverlay(GMSGroundOverlay *groundOverlay, - NSString *overlayId, - BOOL isCreatedWithBounds, - NSNumber *_Nullable zoomLevel); - -extern GMUGradient *FGMGetGradientForPigeonHeatmapGradient(FGMPlatformHeatmapGradient *gradient); - -extern FGMPlatformHeatmapGradient *FGMGetPigeonHeatmapGradientForGradient(GMUGradient *gradient); - -/// Creates a GMUWeightedLatLng array from its Pigeon equivalent. -extern NSArray *FGMGetWeightedDataForPigeonWeightedData( - NSArray *weightedLatLngs); - -/// Converts a GMUWeightedLatLng array to its Pigeon equivalent. -extern NSArray *FGMGetPigeonWeightedDataForWeightedData( - NSArray *weightedLatLngs); - -/// Creates a GMSCameraUpdate from its Pigeon equivalent. -extern GMSCameraUpdate *_Nullable FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate *update); - -/// Creates a UIColor from its Pigeon representation. -extern UIColor *FGMGetColorForPigeonColor(FGMPlatformColor *color); - -/// Converts a UIColor to its Pigeon representation. -extern FGMPlatformColor *FGMGetPigeonColorForColor(UIColor *color); - -/// Creates an array of GMSStrokeStyles using the given patterns and stroke color. -extern NSArray *FGMGetStrokeStylesFromPatterns( - NSArray *patterns, UIColor *strokeColor); - -/// Creates an array of span lengths using the given patterns. -extern NSArray *FGMGetSpanLengthsFromPatterns( - NSArray *patterns); - -NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/include/google_maps_flutter_ios_sdk10_objc/FGMHeatmapController.h b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/include/google_maps_flutter_ios_sdk10_objc/FGMHeatmapController.h deleted file mode 100644 index c8fce13543c..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/include/google_maps_flutter_ios_sdk10_objc/FGMHeatmapController.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -@import GoogleMaps; - -#import "GoogleMapsUtilsTrampoline.h" -#import "google_maps_flutter_pigeon_messages.g.h" - -NS_ASSUME_NONNULL_BEGIN - -/// Controller of a single Heatmap on the map. -@interface FGMHeatmapController : NSObject - -/// Initializes an instance of this class with a heatmap tile layer, a map view, and additional -/// configuration options. -/// -/// @param heatmap The heatmap data to display. -/// @param heatmapTileLayer The heatmap tile layer that will be used to display heatmap data on the -/// map. -/// @param mapView The map view where the heatmap layer will be overlaid. -/// -/// @return An initialized instance of this class, configured with the specified heatmap tile layer, -/// map view, and additional options. -- (instancetype)initWithHeatmap:(FGMPlatformHeatmap *)heatmap - tileLayer:(GMUHeatmapTileLayer *)heatmapTileLayer - mapView:(GMSMapView *)mapView; - -/// Removes this heatmap from the map. -- (void)removeHeatmap; - -/// Clears the tile cache in order to visually udpate this heatmap. -- (void)clearTileCache; -@end - -/// Controller of multiple Heatmaps on the map. -@interface FGMHeatmapsController : NSObject - -/// Initializes the controller with a GMSMapView. -- (instancetype)initWithMapView:(GMSMapView *)mapView; - -/// Adds heatmaps to the map. -- (void)addHeatmaps:(NSArray *)heatmapsToAdd; - -/// Updates heatmaps on the map. -- (void)changeHeatmaps:(NSArray *)heatmapsToChange; - -/// Removes heatmaps from the map. -- (void)removeHeatmapsWithIdentifiers:(NSArray *)identifiers; - -/// Returns true if a heatmap with the given identifier exists on the map. -- (BOOL)hasHeatmapWithIdentifier:(NSString *)identifier; - -/// Returns the heatmap with the given identifier. -- (nullable FGMPlatformHeatmap *)heatmapWithIdentifier:(NSString *)identifier; -@end - -NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/include/google_maps_flutter_ios_sdk10_objc/FGMHeatmapController_Test.h b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/include/google_maps_flutter_ios_sdk10_objc/FGMHeatmapController_Test.h deleted file mode 100644 index 797c309dbb2..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/include/google_maps_flutter_ios_sdk10_objc/FGMHeatmapController_Test.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "FGMHeatmapController.h" - -/// Internal APIs exposed for unit testing -@interface FGMHeatmapController (Test) - -/// Updates the underlying GMUHeatmapTileLayer with the properties from the given platform heatmap. -/// -/// Setting the heatmap to visible will set its map to the given mapView. -+ (void)updateHeatmap:(GMUHeatmapTileLayer *)heatmapTileLayer - fromPlatformHeatmap:(FGMPlatformHeatmap *)platformHeatmap - withMapView:(GMSMapView *)mapView; - -@end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/include/google_maps_flutter_ios_sdk10_objc/FGMImageUtils.h b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/include/google_maps_flutter_ios_sdk10_objc/FGMImageUtils.h deleted file mode 100644 index a8fd0c82c68..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10_objc/include/google_maps_flutter_ios_sdk10_objc/FGMImageUtils.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -@import GoogleMaps; -@import UIKit; - -#import "FGMAssetProvider.h" -#import "google_maps_flutter_pigeon_messages.g.h" - -NS_ASSUME_NONNULL_BEGIN - -/// Creates a UIImage from Pigeon bitmap. -UIImage *_Nullable FGMIconFromBitmap(FGMPlatformBitmap *platformBitmap, - NSObject *assetProvider, - CGFloat screenScale); -/// Returns a BOOL indicating whether image is considered scalable with the given scale factor from -/// size. -BOOL FGMIsScalableWithScaleFactorFromSize(CGSize originalSize, CGSize targetSize); - -NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/CircleControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/CircleControllerTests.swift index 063e12d4c3c..5be000f1d2a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/CircleControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/CircleControllerTests.swift @@ -4,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_objc @testable import google_maps_flutter_ios diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ClusterManagersControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ClusterManagersControllerTests.swift index bf24cecb1a3..0d2cf1f8a89 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ClusterManagersControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ClusterManagersControllerTests.swift @@ -5,6 +5,7 @@ import Flutter import GoogleMaps import Testing +import google_maps_flutter_ios_objc @testable import google_maps_flutter_ios diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ConversionsUtilsTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ConversionsUtilsTests.swift index 4e72b8fbc4c..deb8571c955 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ConversionsUtilsTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ConversionsUtilsTests.swift @@ -4,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_objc @testable import google_maps_flutter_ios @@ -14,14 +15,12 @@ import Testing let platformGreen: CGFloat = 2 / 255.0 let platformBlue: CGFloat = 3 / 255.0 let platformAlpha: CGFloat = 4 / 255.0 - let color = FGMGetColorForPigeonColor( - FGMPlatformColor.make( - withRed: platformRed, - green: platformGreen, - blue: platformBlue, - alpha: platformAlpha - ) - ) + let color = FGMPlatformColor.make( + withRed: platformRed, + green: platformGreen, + blue: platformBlue, + alpha: platformAlpha + ).toUIColor() var red: CGFloat = 0 var green: CGFloat = 0 var blue: CGFloat = 0 @@ -40,47 +39,18 @@ import Testing let blue: CGFloat = 3 / 255.0 let alpha: CGFloat = 4 / 255.0 let color = UIColor(red: red, green: green, blue: blue, alpha: alpha) - let platformColor = FGMGetPigeonColorForColor(color) + let platformColor = FGMPlatformColor.make(from: color) #expect(abs(red - platformColor.red) <= CGFloat.ulpOfOne) #expect(abs(green - platformColor.green) <= CGFloat.ulpOfOne) #expect(abs(blue - platformColor.blue) <= CGFloat.ulpOfOne) #expect(abs(alpha - platformColor.alpha) <= CGFloat.ulpOfOne) } - @Test func pointsFromLatLongs() { - let latlongs = [ - FGMPlatformLatLng.make(withLatitude: 1, longitude: 2), - FGMPlatformLatLng.make(withLatitude: 3, longitude: 4), - ] - let locations = FGMGetPointsForPigeonLatLngs(latlongs) - #expect(locations.count == 2) - #expect(locations[0].coordinate.latitude == 1) - #expect(locations[0].coordinate.longitude == 2) - #expect(locations[1].coordinate.latitude == 3) - #expect(locations[1].coordinate.longitude == 4) - } - - @Test func holesFromPointsArray() { - let pointsArray = [ - [ - FGMPlatformLatLng.make(withLatitude: 1, longitude: 2), - FGMPlatformLatLng.make(withLatitude: 3, longitude: 4), - ], - [ - FGMPlatformLatLng.make(withLatitude: 5, longitude: 6), - FGMPlatformLatLng.make(withLatitude: 7, longitude: 8), - ], - ] - let holes = FGMGetHolesForPigeonLatLngArrays(pointsArray) - #expect(holes.count == 2) - #expect(holes[0][0].coordinate.latitude == 1) - #expect(holes[0][0].coordinate.longitude == 2) - #expect(holes[0][1].coordinate.latitude == 3) - #expect(holes[0][1].coordinate.longitude == 4) - #expect(holes[1][0].coordinate.latitude == 5) - #expect(holes[1][0].coordinate.longitude == 6) - #expect(holes[1][1].coordinate.latitude == 7) - #expect(holes[1][1].coordinate.longitude == 8) + @Test func pointFromLatLong() { + let latlong = FGMPlatformLatLng.make(withLatitude: 1, longitude: 2) + let location = latlong.toCLLocation() + #expect(location.coordinate.latitude == 1) + #expect(location.coordinate.longitude == 2) } @Test func getPigeonCameraPositionForPosition() { @@ -90,7 +60,7 @@ import Testing bearing: 3.0, viewingAngle: 75.0 ) - let pigeonPosition = FGMGetPigeonCameraPositionForPosition(position) + let pigeonPosition = FGMPlatformCameraPosition.make(from: position) #expect(abs(pigeonPosition.target.latitude - position.target.latitude) <= Double.ulpOfOne) #expect(abs(pigeonPosition.target.longitude - position.target.longitude) <= Double.ulpOfOne) #expect(abs(Float(pigeonPosition.zoom) - position.zoom) <= Float.ulpOfOne) @@ -100,7 +70,7 @@ import Testing @Test func pigeonPointForGCPoint() { let point = CGPoint(x: 10, y: 20) - let pigeonPoint = FGMGetPigeonPointForCGPoint(point) + let pigeonPoint = FGMPlatformPoint.make(from: point) #expect(abs(pigeonPoint.x - Double(point.x)) <= Double.ulpOfOne) #expect(abs(pigeonPoint.y - Double(point.y)) <= Double.ulpOfOne) } @@ -110,7 +80,7 @@ import Testing coordinate: CLLocationCoordinate2D(latitude: 10, longitude: 20), coordinate: CLLocationCoordinate2D(latitude: 30, longitude: 40) ) - let pigeonBounds = FGMGetPigeonLatLngBoundsForCoordinateBounds(bounds) + let pigeonBounds = FGMPlatformLatLngBounds.make(from: bounds) #expect(abs(pigeonBounds.southwest.latitude - bounds.southWest.latitude) <= Double.ulpOfOne) #expect(abs(pigeonBounds.southwest.longitude - bounds.southWest.longitude) <= Double.ulpOfOne) #expect(abs(pigeonBounds.northeast.latitude - bounds.northEast.latitude) <= Double.ulpOfOne) @@ -125,7 +95,7 @@ import Testing zoom: 5.0 ) - let cameraPosition = FGMGetCameraPositionForPigeonCameraPosition(pigeonCameraPosition) + let cameraPosition = pigeonCameraPosition.toGMSCameraPosition() #expect( abs(cameraPosition.target.latitude - pigeonCameraPosition.target.latitude) <= Double.ulpOfOne) @@ -140,7 +110,7 @@ import Testing @Test func cgPointForPigeonPoint() { let pigeonPoint = FGMPlatformPoint.makeWith(x: 1.0, y: 2.0) - let point = FGMGetCGPointForPigeonPoint(pigeonPoint) + let point = pigeonPoint.toCGPoint() #expect(abs(pigeonPoint.x - Double(point.x)) <= Double.ulpOfOne) #expect(abs(pigeonPoint.y - Double(point.y)) <= Double.ulpOfOne) @@ -152,7 +122,7 @@ import Testing southwest: FGMPlatformLatLng.make(withLatitude: 1, longitude: 2) ) - let bounds = FGMGetCoordinateBoundsForPigeonLatLngBounds(pigeonBounds) + let bounds = pigeonBounds.toGMSCoordinateBounds() let accuracy: Double = 0.001 #expect(abs(bounds.southWest.latitude - 1) <= accuracy) @@ -162,11 +132,11 @@ import Testing } @Test func mapViewTypeFromPigeonType() { - #expect(GMSMapViewType.normal == FGMGetMapViewTypeForPigeonMapType(.normal)) - #expect(GMSMapViewType.satellite == FGMGetMapViewTypeForPigeonMapType(.satellite)) - #expect(GMSMapViewType.terrain == FGMGetMapViewTypeForPigeonMapType(.terrain)) - #expect(GMSMapViewType.hybrid == FGMGetMapViewTypeForPigeonMapType(.hybrid)) - #expect(GMSMapViewType.none == FGMGetMapViewTypeForPigeonMapType(.none)) + #expect(GMSMapViewType.normal == FGMPlatformMapType.normal.gmsMapViewType) + #expect(GMSMapViewType.satellite == FGMPlatformMapType.satellite.gmsMapViewType) + #expect(GMSMapViewType.terrain == FGMPlatformMapType.terrain.gmsMapViewType) + #expect(GMSMapViewType.hybrid == FGMPlatformMapType.hybrid.gmsMapViewType) + #expect(GMSMapViewType.none == FGMPlatformMapType.none.gmsMapViewType) } @Test func cameraUpdateFromNewCameraPosition() { @@ -178,9 +148,7 @@ import Testing zoom: 3 ) ) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: newPositionUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: newPositionUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -194,9 +162,7 @@ import Testing with: FGMPlatformLatLng.make(withLatitude: lat, longitude: lng) ) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -208,16 +174,14 @@ import Testing withNortheast: FGMPlatformLatLng.make(withLatitude: 1, longitude: 2), southwest: FGMPlatformLatLng.make(withLatitude: 3, longitude: 4) ) - let bounds = FGMGetCoordinateBoundsForPigeonLatLngBounds(pigeonBounds) + let bounds = pigeonBounds.toGMSCoordinateBounds() let padding: Double = 20 let platformUpdate = FGMPlatformCameraUpdateNewLatLngBounds.make( - with: FGMGetPigeonLatLngBoundsForCoordinateBounds(bounds), + with: FGMPlatformLatLngBounds.make(from: bounds), padding: padding ) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -233,9 +197,7 @@ import Testing zoom: zoom ) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -247,9 +209,7 @@ import Testing let y: Double = 2 let platformUpdate = FGMPlatformCameraUpdateScrollBy.make(withDx: x, dy: y) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -260,9 +220,7 @@ import Testing let zoom: Double = 1 let platformUpdateNoPoint = FGMPlatformCameraUpdateZoomBy.make(withAmount: zoom, focus: nil) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdateNoPoint) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdateNoPoint).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -278,9 +236,7 @@ import Testing focus: FGMPlatformPoint.makeWith(x: x, y: y) ) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -290,9 +246,7 @@ import Testing @Test func cameraUpdateFromZoomIn() { let platformUpdate = FGMPlatformCameraUpdateZoom.make(withOut: false) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -302,9 +256,7 @@ import Testing @Test func cameraUpdateFromZoomOut() { let platformUpdate = FGMPlatformCameraUpdateZoom.make(withOut: true) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test @@ -315,65 +267,48 @@ import Testing let zoom: Double = 1 let platformUpdate = FGMPlatformCameraUpdateZoomTo.make(withZoom: zoom) - _ = FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate) - ) + _ = FGMPlatformCameraUpdate.make(withCameraUpdate: platformUpdate).toGMSCameraUpdate() // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that // injecting a wrapper would not meaningfully improve test coverage, since the non-test // implementation would be about as complex as the conversion function itself. } - @Test func strokeStylesFromPatterns() { - let patterns = [ - FGMPlatformPatternItem.make(with: .gap, length: 1), - FGMPlatformPatternItem.make(with: .dash, length: 1), - ] + @Test func strokeStyleFromPattern() { + let pattern = FGMPlatformPatternItem.make(with: .dash, length: 1) let strokeColor = UIColor.red - let patternStrokeStyle = FGMGetStrokeStylesFromPatterns(patterns, strokeColor) - - #expect(patternStrokeStyle.count == 2) - // None of the parameters of `patternStrokeStyle` is observable, so we limit to testing - // the length of this output array. + _ = pattern.gmsStrokeStyle(strokeColor: strokeColor) + // GMSStrokeStyle is not inspectable, so this test just ensures that the codepath + // doesn't throw. } - @Test func lengthsFromPatterns() { - let gapLength: Double = 10 - let dashLength: Double = 6.4 - let patterns = [ - FGMPlatformPatternItem.make(with: .gap, length: gapLength as NSNumber), - FGMPlatformPatternItem.make(with: .dash, length: dashLength as NSNumber), - ] + @Test func nonNullLengthFromPatternItem() { + let length: Double = 6.4 + let pattern = FGMPlatformPatternItem.make(with: .gap, length: length as NSNumber) + + let spanLength = pattern.gmsStyleSpanLength() - let spanLengths = FGMGetSpanLengthsFromPatterns(patterns) + #expect(spanLength.doubleValue == length) + } - #expect(spanLengths.count == 2) + @Test func nullLengthFromPatternItem() { + let pattern = FGMPlatformPatternItem.make(with: .dot, length: nil) - let firstSpanLength = spanLengths[0] - let secondSpanLength = spanLengths[1] + let spanLength = pattern.gmsStyleSpanLength() - #expect(firstSpanLength.doubleValue == gapLength) - #expect(secondSpanLength.doubleValue == dashLength) + #expect(spanLength.doubleValue == 0) } - @Test func weightedDataFromPlatformWeightedData() { - let intensity1: Double = 3.0 - let intensity2: Double = 6.0 - let data = [ - FGMPlatformWeightedLatLng.make( - withPoint: FGMPlatformLatLng.make(withLatitude: 10, longitude: 20), - weight: intensity1 - ), - FGMPlatformWeightedLatLng.make( - withPoint: FGMPlatformLatLng.make(withLatitude: 30, longitude: 40), - weight: intensity2 - ), - ] - - let weightedData = FGMGetWeightedDataForPigeonWeightedData(data) - #expect(Double(weightedData[0].intensity) == intensity1) - #expect(Double(weightedData[1].intensity) == intensity2) + @Test func weightedLatLngFromPlatformWeightedLatLng() { + let intensity: Double = 3.0 + let data = FGMPlatformWeightedLatLng.make( + withPoint: FGMPlatformLatLng.make(withLatitude: 10, longitude: 20), + weight: intensity + ) + + let weightedData = data.toGMUWeightedLatLng() + #expect(Double(weightedData.intensity) == intensity) } @Test func gradientFromPlatformGradient() { @@ -396,7 +331,7 @@ import Testing colorMapSize: colorMapSize ) - let gradient = FGMGetGradientForPigeonHeatmapGradient(platformGradient) + let gradient = platformGradient.toGMUGradient() var red: CGFloat = 0 var green: CGFloat = 0 var blue: CGFloat = 0 diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ExtractIconFromDataTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ExtractIconFromDataTests.swift index da3978359e4..57ad2ab7b1f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ExtractIconFromDataTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ExtractIconFromDataTests.swift @@ -4,6 +4,7 @@ import Flutter import Testing +import google_maps_flutter_ios_objc @testable import google_maps_flutter_ios @@ -24,10 +25,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) @@ -52,10 +53,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) @@ -82,10 +83,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) #expect(testImage.scale == 1.0) @@ -117,10 +118,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == screenScale) @@ -144,10 +145,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) @@ -171,10 +172,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) @@ -198,10 +199,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == 10) @@ -226,10 +227,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) @@ -261,10 +262,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == screenScale) @@ -287,10 +288,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: bitmap), + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == 1.0) @@ -299,7 +300,7 @@ import Testing } /// Tests for PinConfig (GMSPinImageOptions) - requires iOS 16.0+ and Google Maps SDK 9.0+. - /// On earlier versions, FGMIconFromBitmap returns nil for PinConfig, which is expected behavior. + /// On earlier versions, makeIcon returns nil for PinConfig, which is expected behavior. @Test func extractIconFromPinConfigWithGlyphColor() { let assetProvider = TestAssetProvider() @@ -318,10 +319,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: pinConfig), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: pinConfig), + assetProvider: assetProvider, + screenScale: screenScale ) // PinConfig may return nil on old Google Maps SDK versions (<=8.4.0). @@ -347,10 +348,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: pinConfig), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: pinConfig), + assetProvider: assetProvider, + screenScale: screenScale ) // PinConfig returns nil on iOS versions without GMSPinImageOptions support (< iOS 16.0). @@ -389,10 +390,10 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: pinConfig), - assetProvider, - screenScale + let resultImage = makeIcon( + from: FGMPlatformBitmap.make(withBitmap: pinConfig), + assetProvider: assetProvider, + screenScale: screenScale ) // PinConfig returns nil on iOS versions without GMSPinImageOptions support (< iOS 16.0). @@ -406,43 +407,43 @@ import Testing @Test func isScalableWithScaleFactorFromSize100x100to10x100() { let originalSize = CGSize(width: 100.0, height: 100.0) let targetSize = CGSize(width: 10.0, height: 100.0) - #expect(!FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(!isScalableWithScaleFactor(from: originalSize, to: targetSize)) } @Test func isScalableWithScaleFactorFromSize100x100to10x10() { let originalSize = CGSize(width: 100.0, height: 100.0) let targetSize = CGSize(width: 10.0, height: 10.0) - #expect(FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(isScalableWithScaleFactor(from: originalSize, to: targetSize)) } @Test func isScalableWithScaleFactorFromSize233x200to23x20() { let originalSize = CGSize(width: 233.0, height: 200.0) let targetSize = CGSize(width: 23.0, height: 20.0) - #expect(FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(isScalableWithScaleFactor(from: originalSize, to: targetSize)) } @Test func isScalableWithScaleFactorFromSize233x200to22x20() { let originalSize = CGSize(width: 233.0, height: 200.0) let targetSize = CGSize(width: 22.0, height: 20.0) - #expect(!FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(!isScalableWithScaleFactor(from: originalSize, to: targetSize)) } @Test func isScalableWithScaleFactorFromSize200x233to20x23() { let originalSize = CGSize(width: 200.0, height: 233.0) let targetSize = CGSize(width: 20.0, height: 23.0) - #expect(FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(isScalableWithScaleFactor(from: originalSize, to: targetSize)) } @Test func isScalableWithScaleFactorFromSize200x233to20x22() { let originalSize = CGSize(width: 200.0, height: 233.0) let targetSize = CGSize(width: 20.0, height: 22.0) - #expect(!FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(!isScalableWithScaleFactor(from: originalSize, to: targetSize)) } @Test func isScalableWithScaleFactorFromSize1024x768to500x250() { let originalSize = CGSize(width: 1024.0, height: 768.0) let targetSize = CGSize(width: 500.0, height: 250.0) - #expect(!FGMIsScalableWithScaleFactorFromSize(originalSize, targetSize)) + #expect(!isScalableWithScaleFactor(from: originalSize, to: targetSize)) } private func createOnePixelImage() -> UIImage { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/GoogleMapsTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/GoogleMapsTests.swift index 3d1e74a59dd..9178990a73b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/GoogleMapsTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/GoogleMapsTests.swift @@ -5,6 +5,7 @@ import Flutter import GoogleMaps import Testing +import google_maps_flutter_ios_objc @testable import google_maps_flutter_ios diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/GroundOverlayControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/GroundOverlayControllerTests.swift index 84110580525..05ebaa988ce 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/GroundOverlayControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/GroundOverlayControllerTests.swift @@ -4,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_objc @testable import google_maps_flutter_ios @@ -115,11 +116,11 @@ import Testing #expect(abs(groundOverlayController.groundOverlay.anchor.y - 0.5) <= Double.ulpOfOne) #expect(groundOverlayController.groundOverlay.zIndex == Int32(platformGroundOverlay.zIndex)) - let convertedPlatformGroundOverlay = FGMGetPigeonGroundOverlay( - groundOverlayController.groundOverlay, - "id_1", - false, - 14.0 + let convertedPlatformGroundOverlay = FGMPlatformGroundOverlay.make( + from: groundOverlayController.groundOverlay, + overlayId: "id_1", + isCreatedWithBounds: false, + zoomLevel: 14.0 ) #expect(convertedPlatformGroundOverlay.groundOverlayId == "id_1") #expect( @@ -182,11 +183,11 @@ import Testing #expect(abs(groundOverlayController.groundOverlay.anchor.y - 0.5) <= Double.ulpOfOne) #expect(groundOverlayController.groundOverlay.zIndex == Int32(platformGroundOverlay.zIndex)) - let convertedPlatformGroundOverlay = FGMGetPigeonGroundOverlay( - groundOverlayController.groundOverlay, - "id_1", - true, - nil + let convertedPlatformGroundOverlay = FGMPlatformGroundOverlay.make( + from: groundOverlayController.groundOverlay, + overlayId: "id_1", + isCreatedWithBounds: true, + zoomLevel: nil ) #expect(convertedPlatformGroundOverlay.groundOverlayId == "id_1") #expect( diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/HeatmapControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/HeatmapControllerTests.swift index 5cefabeef37..649d7311b64 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/HeatmapControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/HeatmapControllerTests.swift @@ -5,6 +5,7 @@ import GoogleMaps import GoogleMapsUtils import Testing +import google_maps_flutter_ios_objc @testable import google_maps_flutter_ios @@ -20,7 +21,7 @@ import Testing startPoints: [0 as NSNumber, 1 as NSNumber], colorMapSize: 256 ) - FGMHeatmapController.updateHeatmap( + HeatmapController.update( heatmap, from: FGMPlatformHeatmap.make( withHeatmapId: "heatmap", @@ -40,7 +41,7 @@ import Testing minimumZoomIntensity: 1, maximumZoomIntensity: 2 ), - with: HeatmapControllerTests.mapView() + mapView: HeatmapControllerTests.mapView() ) #expect(heatmap.hasSetMap) } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/MarkerControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/MarkerControllerTests.swift index 2aa8e9228e5..4c3d751062a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/MarkerControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/MarkerControllerTests.swift @@ -4,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_objc @testable import google_maps_flutter_ios diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/PolygonControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/PolygonControllerTests.swift index ad46bf96235..921f095db53 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/PolygonControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/PolygonControllerTests.swift @@ -4,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_objc @testable import google_maps_flutter_ios diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/PolylineControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/PolylineControllerTests.swift index ed693262a00..2b8d9d4f75a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/PolylineControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/PolylineControllerTests.swift @@ -4,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_objc @testable import google_maps_flutter_ios diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/RunnerTests-Bridging-Header.h b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/RunnerTests-Bridging-Header.h deleted file mode 100644 index 5a7800a1a7b..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/RunnerTests-Bridging-Header.h +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Import private _Test.h headers from the plugin framework -#import diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/TestUtils/TestAssetProvider.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/TestUtils/TestAssetProvider.swift index 9dc3fe4c1b4..e32bc617a11 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/TestUtils/TestAssetProvider.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/TestUtils/TestAssetProvider.swift @@ -4,6 +4,7 @@ import UIKit import google_maps_flutter_ios +import google_maps_flutter_ios_objc /// Fake implementation of FGMAssetProvider for unit tests. class TestAssetProvider: NSObject, FGMAssetProvider { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/TestUtils/TestMapEventHandler.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/TestUtils/TestMapEventHandler.swift index 121738f6c54..e40d4244a16 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/TestUtils/TestMapEventHandler.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/TestUtils/TestMapEventHandler.swift @@ -4,6 +4,7 @@ import Foundation import google_maps_flutter_ios +import google_maps_flutter_ios_objc /// Fake implementation of FGMMapEventDelegate for unit tests. class TestMapEventHandler: NSObject, FGMMapEventDelegate { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/TileOverlayControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/TileOverlayControllerTests.swift index 4320f3a0fbb..61c2e853bfc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/TileOverlayControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/TileOverlayControllerTests.swift @@ -4,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_objc @testable import google_maps_flutter_ios diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/TileProviderControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/TileProviderControllerTests.swift index 073d696f190..e333c633c9c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/TileProviderControllerTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/TileProviderControllerTests.swift @@ -5,6 +5,7 @@ import Flutter import GoogleMaps import Testing +import google_maps_flutter_ios_objc @testable import google_maps_flutter_ios diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/CircleController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/CircleController.swift index 809bc3a9700..4fdae6200fc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/CircleController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/CircleController.swift @@ -42,11 +42,11 @@ class CircleController: NSObject { ) { circle.isTappable = platformCircle.consumeTapEvents circle.zIndex = Int32(platformCircle.zIndex) - circle.position = FGMGetCoordinateForPigeonLatLng(platformCircle.center) + circle.position = platformCircle.center.toCLLocationCoordinate2D() circle.radius = platformCircle.radius - circle.strokeColor = FGMGetColorForPigeonColor(platformCircle.strokeColor) + circle.strokeColor = platformCircle.strokeColor.toUIColor() circle.strokeWidth = CGFloat(platformCircle.strokeWidth) - circle.fillColor = FGMGetColorForPigeonColor(platformCircle.fillColor) + circle.fillColor = platformCircle.fillColor.toUIColor() // This must be done last, to avoid visual flickers of default property values. circle.map = platformCircle.visible ? mapView : nil diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/ClusterManagersController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/ClusterManagersController.swift index 5cd22b3bd78..e4db55d05d3 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/ClusterManagersController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/ClusterManagersController.swift @@ -74,12 +74,13 @@ class ClusterManagersController: NSObject { // https://github.com/googlemaps/google-maps-ios-utils/blob/0e7ed81f1bbd9d29e4529c40ae39b0791b0a0eb8/src/Clustering/GMUClusterManager.m#L94. let integralZoom = floorf(Float(mapView.camera.zoom) + 0.5) let clusters = clusterManager.algorithm.clusters(atZoom: integralZoom) - return clusters.map { pigeonCluster(for: $0, clusterManagerIdentifier: identifier) } + return clusters.map { FGMPlatformCluster.make(from: $0, clusterManagerIdentifier: identifier) } } func didTap(_ cluster: GMUStaticCluster) { guard let clusterManagerId = clusterManagerIdentifier(for: cluster) else { return } - let platformCluster = pigeonCluster(for: cluster, clusterManagerIdentifier: clusterManagerId) + let platformCluster = FGMPlatformCluster.make( + from: cluster, clusterManagerIdentifier: clusterManagerId) eventDelegate?.didTap(platformCluster) } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/ConversionUtils.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/ConversionUtils.swift index 04950aad2e0..dcb85c57f46 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/ConversionUtils.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/ConversionUtils.swift @@ -2,28 +2,291 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import Flutter +import GoogleMaps +import GoogleMapsUtils + #if canImport(google_maps_flutter_ios_objc) import google_maps_flutter_ios_objc #endif -/// Converts a GMUCluster to its Pigeon representation. -func pigeonCluster( - for cluster: GMUCluster, - clusterManagerIdentifier: String -) -> FGMPlatformCluster { - var bounds = GMSCoordinateBounds() - for item in cluster.items { - bounds = bounds.includingCoordinate(item.position) +extension FGMPlatformPoint { + /// Converts a CGPoint to its Pigeon equivalent. + static func make(from point: CGPoint) -> FGMPlatformPoint { + return FGMPlatformPoint.makeWith(x: point.x, y: point.y) + } + + /// Returns the equivalent CGPoint. + func toCGPoint() -> CGPoint { + return CGPoint(x: x, y: y) + } +} + +extension FGMPlatformLatLng { + /// Converts a CLLocationCoordinate2D to its Pigeon representation. + static func make(from coordinate: CLLocationCoordinate2D) -> FGMPlatformLatLng { + return FGMPlatformLatLng.make( + withLatitude: coordinate.latitude, longitude: coordinate.longitude) } - let markerIds = cluster.items.filter { $0 is GMSMarker }.compactMap { - markerIdentifierFromMarker($0 as! GMSMarker) + /// Returns the equivalent CLLocationCoordinate2D. + func toCLLocationCoordinate2D() -> CLLocationCoordinate2D { + return CLLocationCoordinate2D(latitude: latitude, longitude: longitude) } - return FGMPlatformCluster.make( - withClusterManagerId: clusterManagerIdentifier, - position: FGMGetPigeonLatLngForCoordinate(cluster.position), - bounds: FGMGetPigeonLatLngBoundsForCoordinateBounds(bounds), - markerIds: markerIds - ) + /// Returns the equivalent CLLocation. + func toCLLocation() -> CLLocation { + return CLLocation(latitude: latitude, longitude: longitude) + } +} + +extension FGMPlatformLatLngBounds { + /// Converts a GMSCoordinateBounds to its Pigeon representation. + static func make(from bounds: GMSCoordinateBounds) -> FGMPlatformLatLngBounds { + return FGMPlatformLatLngBounds.make( + withNortheast: FGMPlatformLatLng.make(from: bounds.northEast), + southwest: FGMPlatformLatLng.make(from: bounds.southWest) + ) + } + + /// Returns the equivalent GMSCoordinateBounds. + func toGMSCoordinateBounds() -> GMSCoordinateBounds { + return GMSCoordinateBounds( + coordinate: northeast.toCLLocationCoordinate2D(), + coordinate: southwest.toCLLocationCoordinate2D() + ) + } +} + +extension FGMPlatformCameraPosition { + /// Converts a GMSCameraPosition to its Pigeon representation. + static func make(from position: GMSCameraPosition) -> FGMPlatformCameraPosition { + return FGMPlatformCameraPosition.make( + withBearing: position.bearing, + target: FGMPlatformLatLng.make(from: position.target), + tilt: position.viewingAngle, + zoom: Double(position.zoom) + ) + } + + /// Returns the equivalent GMSCameraPosition. + func toGMSCameraPosition() -> GMSCameraPosition { + return GMSCameraPosition( + target: target.toCLLocationCoordinate2D(), + zoom: Float(zoom), + bearing: bearing, + viewingAngle: tilt + ) + } +} + +/// Creates a GMSMutablePath from points. +func makePath(from points: [CLLocation]) -> GMSMutablePath { + let path = GMSMutablePath() + for location in points { + path.add(location.coordinate) + } + return path +} + +extension FGMPlatformMapType { + /// The corresponding GMSMapViewType. + var gmsMapViewType: GMSMapViewType { + switch self { + case .none: return .none + case .normal: return .normal + case .satellite: return .satellite + case .terrain: return .terrain + case .hybrid: return .hybrid + @unknown default: return .normal + } + } +} + +extension FGMPlatformMarkerCollisionBehavior { + /// The corresponding GMSCollisionBehavior. + var gmsCollisionBehavior: GMSCollisionBehavior { + switch self { + case .requiredDisplay: + return .required + case .optionalAndHidesLowerPriority: + return .optionalAndHidesLowerPriority + case .requiredAndHidesOptional: + return .requiredAndHidesOptional + @unknown default: + return .required + } + } +} + +extension FGMPlatformGroundOverlay { + /// Converts a GMSGroundOverlay to its Pigeon representation. + static func make( + from groundOverlay: GMSGroundOverlay, + overlayId: String, + isCreatedWithBounds: Bool, + zoomLevel: NSNumber? + ) -> FGMPlatformGroundOverlay { + let placeholderImage = FGMPlatformBitmap.make( + withBitmap: FGMPlatformBitmapDefaultMarker.make(withHue: 0)) + if isCreatedWithBounds, let bounds = groundOverlay.bounds { + return FGMPlatformGroundOverlay.make( + withGroundOverlayId: overlayId, + image: placeholderImage, + position: nil, + bounds: FGMPlatformLatLngBounds.make(from: bounds), + anchor: FGMPlatformPoint.make(from: groundOverlay.anchor), + transparency: 1.0 - Double(groundOverlay.opacity), + bearing: groundOverlay.bearing, + zIndex: Int(groundOverlay.zIndex), + visible: groundOverlay.map != nil, + clickable: groundOverlay.isTappable, + zoomLevel: zoomLevel + ) + } else { + return FGMPlatformGroundOverlay.make( + withGroundOverlayId: overlayId, + image: placeholderImage, + position: FGMPlatformLatLng.make(from: groundOverlay.position), + bounds: nil, + anchor: FGMPlatformPoint.make(from: groundOverlay.anchor), + transparency: 1.0 - Double(groundOverlay.opacity), + bearing: groundOverlay.bearing, + zIndex: Int(groundOverlay.zIndex), + visible: groundOverlay.map != nil, + clickable: groundOverlay.isTappable, + zoomLevel: zoomLevel + ) + } + } +} + +extension FGMPlatformHeatmapGradient { + /// Converts a GMUGradient to its Pigeon representation. + static func make(from gradient: GMUGradient) -> FGMPlatformHeatmapGradient { + let colors = gradient.colors.map { FGMPlatformColor.make(from: $0) } + return FGMPlatformHeatmapGradient.make( + with: colors, + startPoints: gradient.startPoints, + colorMapSize: Int(gradient.mapSize) + ) + } + + /// Returns the equivalent GMUGradient. + func toGMUGradient() -> GMUGradient { + let colors = colors.map { $0.toUIColor() } + return GMUGradient( + colors: colors, + startPoints: startPoints, + colorMapSize: UInt(colorMapSize) + ) + } +} + +extension FGMPlatformWeightedLatLng { + /// Converts a GMUWeightedLatLng to its Pigeon representation. + static func make(from weightedLatLng: GMUWeightedLatLng) -> FGMPlatformWeightedLatLng { + let point = GMSMapPoint(x: weightedLatLng.point().x, y: weightedLatLng.point().y) + return FGMPlatformWeightedLatLng.make( + withPoint: FGMPlatformLatLng.make(from: GMSUnproject(point)), + weight: Double(weightedLatLng.intensity) + ) + } + + /// Returns the equivalent GMUWeightedLatLng. + func toGMUWeightedLatLng() -> GMUWeightedLatLng { + return GMUWeightedLatLng(coordinate: point.toCLLocationCoordinate2D(), intensity: Float(weight)) + } +} + +extension FGMPlatformCameraUpdate { + /// Creates a GMSCameraUpdate from its Pigeon equivalent. + func toGMSCameraUpdate() -> GMSCameraUpdate? { + // See note in messages.dart for why this is so loosely typed. + switch cameraUpdate { + case let newCameraPosition as FGMPlatformCameraUpdateNewCameraPosition: + return GMSCameraUpdate.setCamera(newCameraPosition.cameraPosition.toGMSCameraPosition()) + case let newLatLng as FGMPlatformCameraUpdateNewLatLng: + return GMSCameraUpdate.setTarget(newLatLng.latLng.toCLLocationCoordinate2D()) + case let newLatLngBounds as FGMPlatformCameraUpdateNewLatLngBounds: + return GMSCameraUpdate.fit( + newLatLngBounds.bounds.toGMSCoordinateBounds(), + withPadding: CGFloat(newLatLngBounds.padding) + ) + case let newLatLngZoom as FGMPlatformCameraUpdateNewLatLngZoom: + return GMSCameraUpdate.setTarget( + newLatLngZoom.latLng.toCLLocationCoordinate2D(), + zoom: Float(newLatLngZoom.zoom) + ) + case let scrollBy as FGMPlatformCameraUpdateScrollBy: + return GMSCameraUpdate.scrollBy(x: scrollBy.dx, y: scrollBy.dy) + case let zoomBy as FGMPlatformCameraUpdateZoomBy: + if let focus = zoomBy.focus { + return GMSCameraUpdate.zoom(by: Float(zoomBy.amount), at: focus.toCGPoint()) + } else { + return GMSCameraUpdate.zoom(by: Float(zoomBy.amount)) + } + case let zoom as FGMPlatformCameraUpdateZoom: + return zoom.out ? GMSCameraUpdate.zoomOut() : GMSCameraUpdate.zoomIn() + case let zoomTo as FGMPlatformCameraUpdateZoomTo: + return GMSCameraUpdate.zoom(to: Float(zoomTo.zoom)) + default: + return nil + } + } +} + +extension FGMPlatformColor { + /// Converts a UIColor to its Pigeon representation. + static func make(from color: UIColor) -> FGMPlatformColor { + var red: CGFloat = 0 + var green: CGFloat = 0 + var blue: CGFloat = 0 + var alpha: CGFloat = 0 + color.getRed(&red, green: &green, blue: &blue, alpha: &alpha) + return FGMPlatformColor.make( + withRed: Double(red), green: Double(green), blue: Double(blue), alpha: Double(alpha)) + } + + /// Returns the equivalent UIColor. + func toUIColor() -> UIColor { + return UIColor(red: red, green: green, blue: blue, alpha: alpha) + } +} + +extension FGMPlatformPatternItem { + /// The GMSStrokeStyle expression of this pattern, using the given stroke color. + func gmsStrokeStyle(strokeColor: UIColor) -> GMSStrokeStyle { + let color = type == .gap ? UIColor.clear : strokeColor + return GMSStrokeStyle.solidColor(color) + } + + /// The span length for this pattern, in the form expected by GMSStyleSpans. + func gmsStyleSpanLength() -> NSNumber { + return length ?? 0 + } +} + +extension FGMPlatformCluster { + /// Converts a GMUCluster to its Pigeon representation. + static func make( + from cluster: GMUCluster, + clusterManagerIdentifier: String + ) -> FGMPlatformCluster { + var bounds = GMSCoordinateBounds() + for item in cluster.items { + bounds = bounds.includingCoordinate(item.position) + } + + let markerIds = cluster.items.compactMap { $0 as? GMSMarker }.compactMap { + markerIdentifierFromMarker($0) + } + + return FGMPlatformCluster.make( + withClusterManagerId: clusterManagerIdentifier, + position: FGMPlatformLatLng.make(from: cluster.position), + bounds: FGMPlatformLatLngBounds.make(from: bounds), + markerIds: markerIds + ) + } } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapController.swift index 1759687bfc8..3349fb89ca3 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapController.swift @@ -127,7 +127,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV let polygonsController: PolygonsController let polylinesController: PolylinesController let circlesController: CirclesController - let heatmapsController: FGMHeatmapsController + let heatmapsController: HeatmapsController let tileOverlaysController: TileOverlaysController let groundOverlaysController: GroundOverlaysController @@ -146,8 +146,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV creationParameters: FGMPlatformMapViewCreationParams, registrar: FlutterPluginRegistrar ) { - let camera = FGMGetCameraPositionForPigeonCameraPosition( - creationParameters.initialCameraPosition) + let camera = creationParameters.initialCameraPosition.toGMSCameraPosition() let options = GMSMapViewOptions() options.frame = frame @@ -221,7 +220,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV mapView: mapView, eventDelegate: mapEventHandler ) - heatmapsController = FGMHeatmapsController(mapView: mapView) + heatmapsController = HeatmapsController(mapView: mapView) tileProvider = ConcreteTileProvider(dartCallbackHandler: dartCallbackHandler) tileOverlaysController = TileOverlaysController( mapView: mapView, @@ -361,7 +360,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV public func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) { if trackCameraPosition { - mapEventHandler.didMoveCamera(to: FGMGetPigeonCameraPositionForPosition(position)) + mapEventHandler.didMoveCamera(to: FGMPlatformCameraPosition.make(from: position)) } } @@ -422,11 +421,11 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV } public func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) { - mapEventHandler.didTap(atPosition: FGMGetPigeonLatLngForCoordinate(coordinate)) + mapEventHandler.didTap(atPosition: FGMPlatformLatLng.make(from: coordinate)) } public func mapView(_ mapView: GMSMapView, didLongPressAt coordinate: CLLocationCoordinate2D) { - mapEventHandler.didLongPress(atPosition: FGMGetPigeonLatLngForCoordinate(coordinate)) + mapEventHandler.didLongPress(atPosition: FGMPlatformLatLng.make(from: coordinate)) } func interpretMapConfiguration(_ config: FGMPlatformMapConfiguration) { @@ -452,7 +451,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV ) -> (Bool, String?) { if let cameraTargetBounds = config.cameraTargetBounds { if let bounds = cameraTargetBounds.bounds { - mapView.cameraTargetBounds = FGMGetCoordinateBoundsForPigeonLatLngBounds(bounds) + mapView.cameraTargetBounds = bounds.toGMSCoordinateBounds() } else { mapView.cameraTargetBounds = nil } @@ -470,7 +469,7 @@ public class GoogleMapController: NSObject, GMSMapViewDelegate, FlutterPlatformV mapView.isBuildingsEnabled = buildingsEnabled.boolValue } if let mapType = config.mapType { - mapView.mapType = FGMGetMapViewTypeForPigeonMapType(mapType.value) + mapView.mapType = mapType.value.gmsMapViewType } if let zoomData = config.minMaxZoomPreference { let minZoom = zoomData.min?.floatValue ?? kGMSMinZoomLevel @@ -651,9 +650,9 @@ class MapCallHandler: NSObject, FGMMapsApi { ) return nil } - let point = FGMGetCGPointForPigeonPoint(screenCoordinate) + let point = screenCoordinate.toCGPoint() let latlng = mapView.projection.coordinate(for: point) - return FGMGetPigeonLatLngForCoordinate(latlng) + return FGMPlatformLatLng.make(from: latlng) } func screenCoordinates( @@ -667,9 +666,9 @@ class MapCallHandler: NSObject, FGMMapsApi { ) return nil } - let location = FGMGetCoordinateForPigeonLatLng(latLng) + let location = latLng.toCLLocationCoordinate2D() let point = mapView.projection.point(for: location) - return FGMGetPigeonPointForCGPoint(point) + return FGMPlatformPoint.make(from: point) } func visibleMapRegion(_ error: AutoreleasingUnsafeMutablePointer) @@ -685,14 +684,14 @@ class MapCallHandler: NSObject, FGMMapsApi { } let visibleRegion = mapView.projection.visibleRegion() let bounds = GMSCoordinateBounds(region: visibleRegion) - return FGMGetPigeonLatLngBoundsForCoordinateBounds(bounds) + return FGMPlatformLatLngBounds.make(from: bounds) } func moveCamera( with cameraUpdate: FGMPlatformCameraUpdate, error: AutoreleasingUnsafeMutablePointer ) { - guard let update = FGMGetCameraUpdateForPigeonCameraUpdate(cameraUpdate) else { + guard let update = cameraUpdate.toGMSCameraUpdate() else { error.pointee = FlutterError( code: "Invalid update", message: "Unrecognized camera update", @@ -707,7 +706,7 @@ class MapCallHandler: NSObject, FGMMapsApi { with cameraUpdate: FGMPlatformCameraUpdate, duration durationMilliseconds: NSNumber?, error: AutoreleasingUnsafeMutablePointer ) { - guard let update = FGMGetCameraUpdateForPigeonCameraUpdate(cameraUpdate) else { + guard let update = cameraUpdate.toGMSCameraUpdate() else { error.pointee = FlutterError( code: "Invalid update", message: "Unrecognized camera update", @@ -935,6 +934,6 @@ class MapInspector: NSObject, FGMMapsInspectorApi { guard let mapView = controller?.mapView else { return nil } - return FGMGetPigeonCameraPositionForPosition(mapView.camera) + return FGMPlatformCameraPosition.make(from: mapView.camera) } } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GroundOverlayController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GroundOverlayController.swift index 8150d8c9054..633e0525cbc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GroundOverlayController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GroundOverlayController.swift @@ -66,7 +66,8 @@ class GroundOverlayController: NSObject { if let anchor = platformGroundOverlay.anchor { groundOverlay.anchor = CGPoint(x: anchor.x, y: anchor.y) } - groundOverlay.icon = FGMIconFromBitmap(platformGroundOverlay.image, assetProvider, screenScale) + groundOverlay.icon = makeIcon( + from: platformGroundOverlay.image, assetProvider: assetProvider, screenScale: screenScale) groundOverlay.bearing = platformGroundOverlay.bearing groundOverlay.opacity = Float(1.0 - platformGroundOverlay.transparency) if useBounds { @@ -220,11 +221,11 @@ class GroundOverlaysController: NSObject { guard let controller = groundOverlayControllerByIdentifier[identifier] else { return nil } - return FGMGetPigeonGroundOverlay( - controller.groundOverlay, - identifier, - controller.createdWithBounds, - controller.zoomLevel + return FGMPlatformGroundOverlay.make( + from: controller.groundOverlay, + overlayId: identifier, + isCreatedWithBounds: controller.createdWithBounds, + zoomLevel: controller.zoomLevel ) } } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/MarkerController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/MarkerController.swift index 66085371431..f13f1418c07 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/MarkerController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/MarkerController.swift @@ -82,25 +82,25 @@ class MarkerController: NSObject { screenScale: CGFloat, usingOpacityForVisibility useOpacityForVisibility: Bool ) { - marker.groundAnchor = FGMGetCGPointForPigeonPoint(platformMarker.anchor) + marker.groundAnchor = platformMarker.anchor.toCGPoint() marker.isDraggable = platformMarker.draggable - marker.icon = FGMIconFromBitmap(platformMarker.icon, assetProvider, screenScale) + marker.icon = makeIcon( + from: platformMarker.icon, assetProvider: assetProvider, screenScale: screenScale) marker.isFlat = platformMarker.flat - marker.position = FGMGetCoordinateForPigeonLatLng(platformMarker.position) + marker.position = platformMarker.position.toCLLocationCoordinate2D() marker.rotation = platformMarker.rotation marker.zIndex = Int32(platformMarker.zIndex) let infoWindow = platformMarker.infoWindow - marker.infoWindowAnchor = FGMGetCGPointForPigeonPoint(infoWindow.anchor) + marker.infoWindowAnchor = infoWindow.anchor.toCGPoint() if let title = infoWindow.title { marker.title = title marker.snippet = infoWindow.snippet } if let advancedMarker = marker as? GMSAdvancedMarker, - let collisionBehavior = platformMarker.collisionBehavior + let collisionBehaviorValue = platformMarker.collisionBehavior { - advancedMarker.collisionBehavior = FGMGetCollisionBehaviorForPigeonCollisionBehavior( - collisionBehavior.value) + advancedMarker.collisionBehavior = collisionBehaviorValue.value.gmsCollisionBehavior } // This must be done last, to avoid visual flickers of default property values. @@ -145,7 +145,7 @@ class MarkersController: NSObject { private func addMarker(_ markerToAdd: FGMPlatformMarker) { guard let mapView = mapView else { return } - let position = FGMGetCoordinateForPigeonLatLng(markerToAdd.position) + let position = markerToAdd.position.toCLLocationCoordinate2D() let markerIdentifier = markerToAdd.markerId let clusterManagerIdentifier = markerToAdd.clusterManagerId @@ -229,7 +229,7 @@ class MarkersController: NSObject { guard markerIdentifierToController[identifier] != nil else { return } eventDelegate?.didStartDragForMarker( withIdentifier: identifier, - atPosition: FGMGetPigeonLatLngForCoordinate(location) + atPosition: FGMPlatformLatLng.make(from: location) ) } @@ -237,7 +237,7 @@ class MarkersController: NSObject { guard markerIdentifierToController[identifier] != nil else { return } eventDelegate?.didDragMarker( withIdentifier: identifier, - atPosition: FGMGetPigeonLatLngForCoordinate(location) + atPosition: FGMPlatformLatLng.make(from: location) ) } @@ -245,7 +245,7 @@ class MarkersController: NSObject { guard markerIdentifierToController[identifier] != nil else { return } eventDelegate?.didEndDragForMarker( withIdentifier: identifier, - atPosition: FGMGetPigeonLatLngForCoordinate(location) + atPosition: FGMPlatformLatLng.make(from: location) ) } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/PolygonController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/PolygonController.swift index bec60a0be0d..a8424fea978 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/PolygonController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/PolygonController.swift @@ -41,12 +41,10 @@ class PolygonController: NSObject { ) { polygon.isTappable = platformPolygon.consumesTapEvents polygon.zIndex = Int32(platformPolygon.zIndex) - polygon.path = FGMGetPathFromPoints(FGMGetPointsForPigeonLatLngs(platformPolygon.points)) - polygon.holes = FGMGetHolesForPigeonLatLngArrays(platformPolygon.holes).map { - FGMGetPathFromPoints($0) - } - polygon.fillColor = FGMGetColorForPigeonColor(platformPolygon.fillColor) - polygon.strokeColor = FGMGetColorForPigeonColor(platformPolygon.strokeColor) + polygon.path = makePath(from: platformPolygon.points.map({ $0.toCLLocation() })) + polygon.holes = platformPolygon.holes.map { makePath(from: $0.map({ $0.toCLLocation() })) } + polygon.fillColor = platformPolygon.fillColor.toUIColor() + polygon.strokeColor = platformPolygon.strokeColor.toUIColor() polygon.strokeWidth = CGFloat(platformPolygon.strokeWidth) // This must be done last, to avoid visual flickers of default property values. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/PolylineController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/PolylineController.swift index 3da57c4557b..0a7a1147b70 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/PolylineController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/PolylineController.swift @@ -41,16 +41,16 @@ class PolylineController: NSObject { ) { polyline.isTappable = platformPolyline.consumesTapEvents polyline.zIndex = Int32(platformPolyline.zIndex) - let path = FGMGetPathFromPoints(FGMGetPointsForPigeonLatLngs(platformPolyline.points)) - polyline.path = path - let strokeColor = FGMGetColorForPigeonColor(platformPolyline.color) + let gmsPath = makePath(from: platformPolyline.points.map({ $0.toCLLocation() })) + polyline.path = gmsPath + let strokeColor = platformPolyline.color.toUIColor() polyline.strokeColor = strokeColor polyline.strokeWidth = CGFloat(platformPolyline.width) polyline.geodesic = platformPolyline.geodesic polyline.spans = GMSStyleSpans( - path, - FGMGetStrokeStylesFromPatterns(platformPolyline.patterns, strokeColor), - FGMGetSpanLengthsFromPatterns(platformPolyline.patterns), + gmsPath, + platformPolyline.patterns.map { $0.gmsStrokeStyle(strokeColor: strokeColor) }, + platformPolyline.patterns.map { $0.gmsStyleSpanLength() }, .rhumb ) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/FGMConversionUtils.m b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/FGMConversionUtils.m deleted file mode 100644 index 219d8df44a1..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/FGMConversionUtils.m +++ /dev/null @@ -1,275 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "FGMConversionUtils.h" - -CGPoint FGMGetCGPointForPigeonPoint(FGMPlatformPoint *point) { - return CGPointMake(point.x, point.y); -} - -FGMPlatformPoint *FGMGetPigeonPointForCGPoint(CGPoint point) { - return [FGMPlatformPoint makeWithX:point.x y:point.y]; -} - -CLLocationCoordinate2D FGMGetCoordinateForPigeonLatLng(FGMPlatformLatLng *latLng) { - return CLLocationCoordinate2DMake(latLng.latitude, latLng.longitude); -} - -FGMPlatformLatLng *FGMGetPigeonLatLngForCoordinate(CLLocationCoordinate2D coord) { - 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) - southwest:FGMGetPigeonLatLngForCoordinate(bounds.southWest)]; -} - -FGMPlatformCameraPosition *FGMGetPigeonCameraPositionForPosition(GMSCameraPosition *position) { - return [FGMPlatformCameraPosition makeWithBearing:position.bearing - target:FGMGetPigeonLatLngForCoordinate(position.target) - tilt:position.viewingAngle - zoom:position.zoom]; -} - -GMSCameraPosition *FGMGetCameraPositionForPigeonCameraPosition( - FGMPlatformCameraPosition *position) { - return [GMSCameraPosition cameraWithTarget:FGMGetCoordinateForPigeonLatLng(position.target) - zoom:position.zoom - bearing:position.bearing - viewingAngle:position.tilt]; -} - -NSArray *FGMGetPointsForPigeonLatLngs(NSArray *pigeonPoints) { - NSMutableArray *points = [[NSMutableArray alloc] initWithCapacity:pigeonPoints.count]; - for (FGMPlatformLatLng *point in pigeonPoints) { - [points addObject:[[CLLocation alloc] initWithLatitude:point.latitude - longitude:point.longitude]]; - } - return points; -} - -NSArray *> *FGMGetHolesForPigeonLatLngArrays( - NSArray *> *pigeonHolePoints) { - NSMutableArray *> *holes = - [[NSMutableArray alloc] initWithCapacity:pigeonHolePoints.count]; - for (NSArray *holePoints in pigeonHolePoints) { - [holes addObject:FGMGetPointsForPigeonLatLngs(holePoints)]; - } - return holes; -} - -GMSMutablePath *FGMGetPathFromPoints(NSArray *points) { - GMSMutablePath *path = [GMSMutablePath path]; - for (CLLocation *location in points) { - [path addCoordinate:location.coordinate]; - } - return path; -} - -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; - } -} - -GMSCollisionBehavior FGMGetCollisionBehaviorForPigeonCollisionBehavior( - FGMPlatformMarkerCollisionBehavior collisionBehavior) { - switch (collisionBehavior) { - case FGMPlatformMarkerCollisionBehaviorRequiredDisplay: - return GMSCollisionBehaviorRequired; - case FGMPlatformMarkerCollisionBehaviorOptionalAndHidesLowerPriority: - return GMSCollisionBehaviorOptionalAndHidesLowerPriority; - case FGMPlatformMarkerCollisionBehaviorRequiredAndHidesOptional: - return GMSCollisionBehaviorRequiredAndHidesOptional; - } -} - -FGMPlatformGroundOverlay *FGMGetPigeonGroundOverlay(GMSGroundOverlay *groundOverlay, - NSString *overlayId, BOOL isCreatedWithBounds, - NSNumber *zoomLevel) { - // Image is mandatory field on FGMPlatformGroundOverlay (and it should be kept - // non-nullable), therefore image must be set for the object. The image is - // description either contains set of bytes, or path to asset. This info is - // converted to format google maps uses (BitmapDescription), and the original - // data is not stored on native code. Therefore placeholder image is used for - // the image field. - FGMPlatformBitmap *placeholderImage = - [FGMPlatformBitmap makeWithBitmap:[FGMPlatformBitmapDefaultMarker makeWithHue:0]]; - if (isCreatedWithBounds) { - return [FGMPlatformGroundOverlay - makeWithGroundOverlayId:overlayId - image:placeholderImage - position:nil - bounds:[FGMPlatformLatLngBounds - makeWithNortheast:[FGMPlatformLatLng - makeWithLatitude:groundOverlay.bounds - .northEast.latitude - longitude:groundOverlay.bounds - .northEast.longitude] - southwest:[FGMPlatformLatLng - makeWithLatitude:groundOverlay.bounds - .southWest.latitude - longitude:groundOverlay.bounds - .southWest - .longitude]] - anchor:[FGMPlatformPoint makeWithX:groundOverlay.anchor.x - y:groundOverlay.anchor.y] - transparency:1.0f - groundOverlay.opacity - bearing:groundOverlay.bearing - zIndex:groundOverlay.zIndex - visible:groundOverlay.map != nil - clickable:groundOverlay.isTappable - zoomLevel:zoomLevel]; - } else { - return [FGMPlatformGroundOverlay - makeWithGroundOverlayId:overlayId - image:placeholderImage - position:[FGMPlatformLatLng - makeWithLatitude:groundOverlay.position.latitude - longitude:groundOverlay.position.longitude] - bounds:nil - anchor:[FGMPlatformPoint makeWithX:groundOverlay.anchor.x - y:groundOverlay.anchor.y] - transparency:1.0f - groundOverlay.opacity - bearing:groundOverlay.bearing - zIndex:groundOverlay.zIndex - visible:groundOverlay.map != nil - clickable:groundOverlay.isTappable - zoomLevel:zoomLevel]; - } -} - -GMUGradient *FGMGetGradientForPigeonHeatmapGradient(FGMPlatformHeatmapGradient *gradient) { - NSMutableArray *colors = [[NSMutableArray alloc] initWithCapacity:gradient.colors.count]; - for (FGMPlatformColor *color in gradient.colors) { - [colors addObject:FGMGetColorForPigeonColor(color)]; - } - return [[GMUGradient alloc] initWithColors:colors - startPoints:gradient.startPoints - colorMapSize:gradient.colorMapSize]; -} - -FGMPlatformHeatmapGradient *FGMGetPigeonHeatmapGradientForGradient(GMUGradient *gradient) { - NSMutableArray *colors = [[NSMutableArray alloc] initWithCapacity:gradient.colors.count]; - for (UIColor *color in gradient.colors) { - [colors addObject:FGMGetPigeonColorForColor(color)]; - } - return [FGMPlatformHeatmapGradient makeWithColors:colors - startPoints:gradient.startPoints - colorMapSize:gradient.mapSize]; -} - -NSArray *FGMGetWeightedDataForPigeonWeightedData( - NSArray *weightedLatLngs) { - NSMutableArray *weightedData = [[NSMutableArray alloc] initWithCapacity:weightedLatLngs.count]; - for (FGMPlatformWeightedLatLng *weightedLatLng in weightedLatLngs) { - [weightedData - addObject:[[GMUWeightedLatLng alloc] - initWithCoordinate:FGMGetCoordinateForPigeonLatLng(weightedLatLng.point) - intensity:weightedLatLng.weight]]; - } - return weightedData; -} - -NSArray *FGMGetPigeonWeightedDataForWeightedData( - NSArray *weightedLatLngs) { - NSMutableArray *weightedData = [[NSMutableArray alloc] initWithCapacity:weightedLatLngs.count]; - for (GMUWeightedLatLng *weightedLatLng in weightedLatLngs) { - GMSMapPoint point = {weightedLatLng.point.x, weightedLatLng.point.y}; - [weightedData addObject:[FGMPlatformWeightedLatLng - makeWithPoint:FGMGetPigeonLatLngForCoordinate(GMSUnproject(point)) - weight:weightedLatLng.intensity]]; - } - return weightedData; -} - -GMSCameraUpdate *FGMGetCameraUpdateForPigeonCameraUpdate(FGMPlatformCameraUpdate *cameraUpdate) { - // See note in messages.dart for why this is so loosely typed. - id update = cameraUpdate.cameraUpdate; - if ([update isKindOfClass:[FGMPlatformCameraUpdateNewCameraPosition class]]) { - return [GMSCameraUpdate - setCamera:FGMGetCameraPositionForPigeonCameraPosition( - ((FGMPlatformCameraUpdateNewCameraPosition *)update).cameraPosition)]; - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateNewLatLng class]]) { - return [GMSCameraUpdate setTarget:FGMGetCoordinateForPigeonLatLng( - ((FGMPlatformCameraUpdateNewLatLng *)update).latLng)]; - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateNewLatLngBounds class]]) { - FGMPlatformCameraUpdateNewLatLngBounds *typedUpdate = - (FGMPlatformCameraUpdateNewLatLngBounds *)update; - return - [GMSCameraUpdate fitBounds:FGMGetCoordinateBoundsForPigeonLatLngBounds(typedUpdate.bounds) - withPadding:typedUpdate.padding]; - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateNewLatLngZoom class]]) { - FGMPlatformCameraUpdateNewLatLngZoom *typedUpdate = - (FGMPlatformCameraUpdateNewLatLngZoom *)update; - return [GMSCameraUpdate setTarget:FGMGetCoordinateForPigeonLatLng(typedUpdate.latLng) - zoom:typedUpdate.zoom]; - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateScrollBy class]]) { - FGMPlatformCameraUpdateScrollBy *typedUpdate = (FGMPlatformCameraUpdateScrollBy *)update; - return [GMSCameraUpdate scrollByX:typedUpdate.dx Y:typedUpdate.dy]; - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateZoomBy class]]) { - FGMPlatformCameraUpdateZoomBy *typedUpdate = (FGMPlatformCameraUpdateZoomBy *)update; - if (typedUpdate.focus) { - return [GMSCameraUpdate zoomBy:typedUpdate.amount - atPoint:FGMGetCGPointForPigeonPoint(typedUpdate.focus)]; - } else { - return [GMSCameraUpdate zoomBy:typedUpdate.amount]; - } - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateZoom class]]) { - if (((FGMPlatformCameraUpdateZoom *)update).out) { - return [GMSCameraUpdate zoomOut]; - } else { - return [GMSCameraUpdate zoomIn]; - } - } else if ([update isKindOfClass:[FGMPlatformCameraUpdateZoomTo class]]) { - return [GMSCameraUpdate zoomTo:((FGMPlatformCameraUpdateZoomTo *)update).zoom]; - } - return nil; -} - -UIColor *FGMGetColorForPigeonColor(FGMPlatformColor *color) { - return [UIColor colorWithRed:color.red green:color.green blue:color.blue alpha:color.alpha]; -} - -FGMPlatformColor *FGMGetPigeonColorForColor(UIColor *color) { - double red, green, blue, alpha; - [color getRed:&red green:&green blue:&blue alpha:&alpha]; - return [FGMPlatformColor makeWithRed:red green:green blue:blue alpha:alpha]; -} - -NSArray *FGMGetStrokeStylesFromPatterns( - NSArray *patterns, UIColor *strokeColor) { - NSMutableArray *strokeStyles = [[NSMutableArray alloc] initWithCapacity:[patterns count]]; - for (FGMPlatformPatternItem *pattern in patterns) { - UIColor *color = - pattern.type == FGMPlatformPatternItemTypeGap ? UIColor.clearColor : strokeColor; - [strokeStyles addObject:[GMSStrokeStyle solidColor:color]]; - } - return strokeStyles; -} - -NSArray *FGMGetSpanLengthsFromPatterns(NSArray *patterns) { - NSMutableArray *lengths = [[NSMutableArray alloc] initWithCapacity:[patterns count]]; - for (FGMPlatformPatternItem *pattern in patterns) { - NSNumber *length = pattern.length ?: @0; - [lengths addObject:length]; - } - return lengths; -} diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/FGMHeatmapController.m b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/FGMHeatmapController.m deleted file mode 100644 index 49ec16dff82..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/FGMHeatmapController.m +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "FGMHeatmapController.h" -#import "FGMHeatmapController_Test.h" - -@import GoogleMapsUtils; - -#import "FGMConversionUtils.h" - -@interface FGMHeatmapController () - -/// The heatmap tile layer this controller handles. -@property(nonatomic, strong) GMUHeatmapTileLayer *heatmapTileLayer; - -/// The GMSMapView to which the heatmaps are added. -@property(nonatomic, weak) GMSMapView *mapView; - -@end - -@implementation FGMHeatmapController -- (instancetype)initWithHeatmap:(FGMPlatformHeatmap *)heatmap - tileLayer:(GMUHeatmapTileLayer *)heatmapTileLayer - mapView:(GMSMapView *)mapView { - self = [super init]; - if (self) { - _heatmapTileLayer = heatmapTileLayer; - _mapView = mapView; - - [FGMHeatmapController updateHeatmap:_heatmapTileLayer - fromPlatformHeatmap:heatmap - withMapView:_mapView]; - } - return self; -} - -- (void)removeHeatmap { - _heatmapTileLayer.map = nil; -} - -- (void)clearTileCache { - [_heatmapTileLayer clearTileCache]; -} - -- (void)updateFromPlatformHeatmap:(FGMPlatformHeatmap *)platformHeatmap { - [FGMHeatmapController updateHeatmap:_heatmapTileLayer - fromPlatformHeatmap:platformHeatmap - withMapView:_mapView]; -} - -+ (void)updateHeatmap:(GMUHeatmapTileLayer *)heatmapTileLayer - fromPlatformHeatmap:(FGMPlatformHeatmap *)platformHeatmap - withMapView:(GMSMapView *)mapView { - heatmapTileLayer.weightedData = FGMGetWeightedDataForPigeonWeightedData(platformHeatmap.data); - if (platformHeatmap.gradient) { - heatmapTileLayer.gradient = FGMGetGradientForPigeonHeatmapGradient(platformHeatmap.gradient); - } - heatmapTileLayer.opacity = platformHeatmap.opacity; - heatmapTileLayer.radius = platformHeatmap.radius; - heatmapTileLayer.minimumZoomIntensity = platformHeatmap.minimumZoomIntensity; - heatmapTileLayer.maximumZoomIntensity = platformHeatmap.maximumZoomIntensity; - - // The map must be set each time for options to update. - // This must be done last, to avoid visual flickers of default property values. - heatmapTileLayer.map = mapView; -} -@end - -@interface FGMHeatmapsController () - -/// A map from heatmapId to the controller that manages it. -@property(nonatomic, strong) - NSMutableDictionary *heatmapIdToController; - -/// The map view owned by GoogmeMapController. -@property(nonatomic, weak) GMSMapView *mapView; - -@end - -@implementation FGMHeatmapsController -- (instancetype)initWithMapView:(GMSMapView *)mapView { - self = [super init]; - if (self) { - _mapView = mapView; - _heatmapIdToController = [NSMutableDictionary dictionary]; - } - return self; -} - -- (void)addHeatmaps:(NSArray *)heatmapsToAdd { - for (FGMPlatformHeatmap *heatmap in heatmapsToAdd) { - GMUHeatmapTileLayer *heatmapTileLayer = [[GMUHeatmapTileLayer alloc] init]; - FGMHeatmapController *controller = - [[FGMHeatmapController alloc] initWithHeatmap:heatmap - tileLayer:heatmapTileLayer - mapView:_mapView]; - _heatmapIdToController[heatmap.heatmapId] = controller; - } -} - -- (void)changeHeatmaps:(NSArray *)heatmapsToChange { - for (FGMPlatformHeatmap *heatmap in heatmapsToChange) { - FGMHeatmapController *controller = _heatmapIdToController[heatmap.heatmapId]; - - [controller updateFromPlatformHeatmap:heatmap]; - [controller clearTileCache]; - } -} - -- (void)removeHeatmapsWithIdentifiers:(NSArray *)identifiers { - for (NSString *heatmapId in identifiers) { - FGMHeatmapController *controller = _heatmapIdToController[heatmapId]; - if (!controller) { - continue; - } - [controller removeHeatmap]; - [_heatmapIdToController removeObjectForKey:heatmapId]; - } -} - -- (BOOL)hasHeatmapWithIdentifier:(NSString *)identifier { - return _heatmapIdToController[identifier] != nil; -} - -- (FGMPlatformHeatmap *)heatmapWithIdentifier:(NSString *)identifier { - GMUHeatmapTileLayer *heatmap = self.heatmapIdToController[identifier].heatmapTileLayer; - if (!heatmap) { - return nil; - } - return [FGMPlatformHeatmap - makeWithHeatmapId:identifier - data:FGMGetPigeonWeightedDataForWeightedData(heatmap.weightedData) - gradient:FGMGetPigeonHeatmapGradientForGradient(heatmap.gradient) - opacity:heatmap.opacity - radius:heatmap.radius - minimumZoomIntensity:heatmap.minimumZoomIntensity - maximumZoomIntensity:heatmap.maximumZoomIntensity]; -} -@end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/FGMImageUtils.m b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/FGMImageUtils.m deleted file mode 100644 index 03eb36eeb40..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/FGMImageUtils.m +++ /dev/null @@ -1,271 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -@import Flutter; - -#import "FGMImageUtils.h" -#import "FGMConversionUtils.h" - -@import Foundation; - -/// This method is deprecated within the context of `BitmapDescriptor.fromBytes` handling in the -/// flutter google_maps_flutter_platform_interface package which has been replaced by 'bytes' -/// message handling. It will be removed when the deprecated image bitmap description type -/// 'fromBytes' is removed from the platform interface. -static UIImage *scaledImage(UIImage *image, double scale); - -/// Creates a scaled version of the provided UIImage based on a specified scale factor. If the -/// scale factor differs from the image's current scale by more than a small epsilon-delta (to -/// account for minor floating-point inaccuracies), a new UIImage object is created with the -/// specified scale. Otherwise, the original image is returned. -/// -/// @param image The UIImage to scale. -/// @param scale The factor by which to scale the image. -/// @return UIImage Returns the scaled UIImage. -static UIImage *scaledImageWithScale(UIImage *image, CGFloat scale); - -/// Scales an input UIImage to a specified size. If the aspect ratio of the input image -/// closely matches the target size, indicated by a small epsilon-delta, the image's scale -/// property is updated instead of resizing the image. If the aspect ratios differ beyond this -/// threshold, the method redraws the image at the target size. -/// -/// @param image The UIImage to scale. -/// @param size The target CGSize to scale the image to. -/// @return UIImage Returns the scaled UIImage. -static UIImage *scaledImageWithSize(UIImage *image, CGSize size); - -/// Scales an input UIImage to a specified width and height preserving aspect ratio if both -/// widht and height are not given.. -/// -/// @param image The UIImage to scale. -/// @param width The target width to scale the image to. -/// @param height The target height to scale the image to. -/// @param screenScale The current screen scale. -/// @return UIImage Returns the scaled UIImage. -static UIImage *scaledImageWithWidthHeight(UIImage *image, NSNumber *width, NSNumber *height, - CGFloat screenScale); - -UIImage *FGMIconFromBitmap(FGMPlatformBitmap *platformBitmap, - NSObject *assetProvider, CGFloat screenScale) { - assert(screenScale > 0 && "Screen scale must be greater than 0"); - // See comment in messages.dart for why this is so loosely typed. See also - // https://github.com/flutter/flutter/issues/117819. - id bitmap = platformBitmap.bitmap; - UIImage *image; - if ([bitmap isKindOfClass:[FGMPlatformBitmapDefaultMarker class]]) { - FGMPlatformBitmapDefaultMarker *bitmapDefaultMarker = bitmap; - CGFloat hue = bitmapDefaultMarker.hue.doubleValue; - image = [GMSMarker markerImageWithColor:[UIColor colorWithHue:hue / 360.0 - saturation:1.0 - brightness:0.7 - alpha:1.0]]; - } else if ([bitmap isKindOfClass:[FGMPlatformBitmapAsset class]]) { - // Deprecated: This message handling for 'fromAsset' has been replaced by 'asset'. - // Refer to the flutter google_maps_flutter_platform_interface package for details. - FGMPlatformBitmapAsset *bitmapAsset = bitmap; - if (bitmapAsset.pkg) { - image = [assetProvider imageNamed:[assetProvider lookupKeyForAsset:bitmapAsset.name - fromPackage:bitmapAsset.pkg]]; - } else { - image = [assetProvider imageNamed:[assetProvider lookupKeyForAsset:bitmapAsset.name]]; - } - } else if ([bitmap isKindOfClass:[FGMPlatformBitmapAssetImage class]]) { - // Deprecated: This message handling for 'fromAssetImage' has been replaced by 'asset'. - // Refer to the flutter google_maps_flutter_platform_interface package for details. - FGMPlatformBitmapAssetImage *bitmapAssetImage = bitmap; - image = [assetProvider imageNamed:[assetProvider lookupKeyForAsset:bitmapAssetImage.name]]; - image = scaledImage(image, bitmapAssetImage.scale); - } else if ([bitmap isKindOfClass:[FGMPlatformBitmapBytes class]]) { - // Deprecated: This message handling for 'fromBytes' has been replaced by 'bytes'. - // Refer to the flutter google_maps_flutter_platform_interface package for details. - FGMPlatformBitmapBytes *bitmapBytes = bitmap; - @try { - image = [UIImage imageWithData:bitmapBytes.byteData.data scale:screenScale]; - } @catch (NSException *exception) { - @throw [NSException exceptionWithName:@"InvalidByteDescriptor" - reason:@"Unable to interpret bytes as a valid image." - userInfo:nil]; - } - } else if ([bitmap isKindOfClass:[FGMPlatformBitmapAssetMap class]]) { - FGMPlatformBitmapAssetMap *bitmapAssetMap = bitmap; - - image = [assetProvider imageNamed:[assetProvider lookupKeyForAsset:bitmapAssetMap.assetName]]; - - if (bitmapAssetMap.bitmapScaling == FGMPlatformMapBitmapScalingAuto) { - NSNumber *width = bitmapAssetMap.width; - NSNumber *height = bitmapAssetMap.height; - if (width || height) { - image = scaledImageWithScale(image, screenScale); - image = scaledImageWithWidthHeight(image, width, height, screenScale); - } else { - image = scaledImageWithScale(image, bitmapAssetMap.imagePixelRatio); - } - } - } else if ([bitmap isKindOfClass:[FGMPlatformBitmapBytesMap class]]) { - FGMPlatformBitmapBytesMap *bitmapBytesMap = bitmap; - FlutterStandardTypedData *bytes = bitmapBytesMap.byteData; - - @try { - image = [UIImage imageWithData:bytes.data scale:screenScale]; - if (bitmapBytesMap.bitmapScaling == FGMPlatformMapBitmapScalingAuto) { - NSNumber *width = bitmapBytesMap.width; - NSNumber *height = bitmapBytesMap.height; - - if (width || height) { - // Before scaling the image, image must be in screenScale. - image = scaledImageWithScale(image, screenScale); - image = scaledImageWithWidthHeight(image, width, height, screenScale); - } else { - image = scaledImageWithScale(image, bitmapBytesMap.imagePixelRatio); - } - } else { - // No scaling, load image from bytes without scale parameter. - image = [UIImage imageWithData:bytes.data]; - } - } @catch (NSException *exception) { - @throw [NSException exceptionWithName:@"InvalidByteDescriptor" - reason:@"Unable to interpret bytes as a valid image." - userInfo:nil]; - } - } else if ([bitmap isKindOfClass:[FGMPlatformBitmapPinConfig class]]) { - FGMPlatformBitmapPinConfig *pinConfig = bitmap; - - GMSPinImageOptions *options = [[GMSPinImageOptions alloc] init]; - FGMPlatformColor *backgroundColor = pinConfig.backgroundColor; - if (backgroundColor) { - options.backgroundColor = FGMGetColorForPigeonColor(backgroundColor); - } - - FGMPlatformColor *borderColor = pinConfig.borderColor; - if (borderColor) { - options.borderColor = FGMGetColorForPigeonColor(borderColor); - } - - GMSPinImageGlyph *glyph; - NSString *glyphText = pinConfig.glyphText; - FGMPlatformColor *glyphColor = pinConfig.glyphColor; - FGMPlatformBitmap *glyphBitmap = pinConfig.glyphBitmap; - if (glyphText) { - FGMPlatformColor *glyphTextColorValue = pinConfig.glyphTextColor; - UIColor *glyphTextColor = glyphTextColorValue ? FGMGetColorForPigeonColor(glyphTextColorValue) - : [UIColor blackColor]; - glyph = [[GMSPinImageGlyph alloc] initWithText:glyphText textColor:glyphTextColor]; - } else if (glyphColor) { - UIColor *color = FGMGetColorForPigeonColor(glyphColor); - glyph = [[GMSPinImageGlyph alloc] initWithGlyphColor:color]; - } else if (glyphBitmap) { - UIImage *glyphImage = FGMIconFromBitmap(glyphBitmap, assetProvider, screenScale); - glyph = [[GMSPinImageGlyph alloc] initWithImage:glyphImage]; - } - - options.glyph = glyph; - - image = [GMSPinImage pinImageWithOptions:options]; - } - - return image; -} - -UIImage *scaledImage(UIImage *image, double scale) { - if (fabs(scale - 1) > 1e-3) { - return [UIImage imageWithCGImage:[image CGImage] - scale:(image.scale * scale) - orientation:(image.imageOrientation)]; - } - return image; -} - -UIImage *scaledImageWithScale(UIImage *image, CGFloat scale) { - if (fabs(scale - image.scale) > DBL_EPSILON) { - return [UIImage imageWithCGImage:[image CGImage] - scale:scale - orientation:(image.imageOrientation)]; - } - return image; -} - -UIImage *scaledImageWithSize(UIImage *image, CGSize size) { - CGFloat originalPixelWidth = image.size.width * image.scale; - CGFloat originalPixelHeight = image.size.height * image.scale; - - // Return original image if either original image size or target size is so small that - // image cannot be resized or displayed. - if (originalPixelWidth <= 0 || originalPixelHeight <= 0 || size.width <= 0 || size.height <= 0) { - return image; - } - - // Check if the image's size, accounting for scale, matches the target size. - if (fabs(originalPixelWidth - size.width) <= DBL_EPSILON && - fabs(originalPixelHeight - size.height) <= DBL_EPSILON) { - // No need for resizing, return the original image - return image; - } - - // Check if the aspect ratios are approximately equal. - CGSize originalPixelSize = CGSizeMake(originalPixelWidth, originalPixelHeight); - if (FGMIsScalableWithScaleFactorFromSize(originalPixelSize, size)) { - // Scaled image has close to same aspect ratio, - // updating image scale instead of resizing image. - CGFloat factor = originalPixelWidth / size.width; - return scaledImageWithScale(image, image.scale * factor); - } else { - // Aspect ratios differ significantly, resize the image. - UIGraphicsImageRendererFormat *format = [UIGraphicsImageRendererFormat defaultFormat]; - format.scale = 1.0; - format.opaque = NO; - UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:size - format:format]; - UIImage *newImage = - [renderer imageWithActions:^(UIGraphicsImageRendererContext *_Nonnull context) { - [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; - }]; - - // Return image with proper scaling. - return scaledImageWithScale(newImage, image.scale); - } -} - -UIImage *scaledImageWithWidthHeight(UIImage *image, NSNumber *width, NSNumber *height, - CGFloat screenScale) { - if ((width == nil) && (height == nil)) { - return image; - } - - CGFloat targetWidth = width == nil ? image.size.width : width.doubleValue; - CGFloat targetHeight = height == nil ? image.size.height : height.doubleValue; - - if ((width != nil) && (height == nil)) { - // Calculate height based on aspect ratio if only width is provided. - double aspectRatio = image.size.height / image.size.width; - targetHeight = round(targetWidth * aspectRatio); - } else if ((width == nil) && (height != nil)) { - // Calculate width based on aspect ratio if only height is provided. - double aspectRatio = image.size.width / image.size.height; - targetWidth = round(targetHeight * aspectRatio); - } - - CGSize targetSize = - CGSizeMake(round(targetWidth * screenScale), round(targetHeight * screenScale)); - return scaledImageWithSize(image, targetSize); -} - -BOOL FGMIsScalableWithScaleFactorFromSize(CGSize originalSize, CGSize targetSize) { - // Select the scaling factor based on the longer side to have good precision. - CGFloat scaleFactor = (originalSize.width > originalSize.height) - ? (targetSize.width / originalSize.width) - : (targetSize.height / originalSize.height); - - // Calculate the scaled dimensions. - CGFloat scaledWidth = originalSize.width * scaleFactor; - CGFloat scaledHeight = originalSize.height * scaleFactor; - - // Check if the scaled dimensions are within a one-pixel - // threshold of the target dimensions. - BOOL widthWithinThreshold = fabs(scaledWidth - targetSize.width) <= 1.0; - BOOL heightWithinThreshold = fabs(scaledHeight - targetSize.height) <= 1.0; - - // The image is considered scalable with scale factor - // if both dimensions are within the threshold. - return widthWithinThreshold && heightWithinThreshold; -} diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/include/google_maps_flutter_ios_objc/FGMConversionUtils.h b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/include/google_maps_flutter_ios_objc/FGMConversionUtils.h deleted file mode 100644 index b7344e6b492..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/include/google_maps_flutter_ios_objc/FGMConversionUtils.h +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -@import Foundation; -@import GoogleMaps; - -#import "GoogleMapsUtilsTrampoline.h" -#import "google_maps_flutter_pigeon_messages.g.h" - -NS_ASSUME_NONNULL_BEGIN - -/// Creates a CGPoint from its Pigeon equivalent. -extern CGPoint FGMGetCGPointForPigeonPoint(FGMPlatformPoint *point); - -/// Converts a CGPoint to its Pigeon equivalent. -extern FGMPlatformPoint *FGMGetPigeonPointForCGPoint(CGPoint point); - -/// Creates a CLLocationCoordinate2D from its Pigeon representation. -extern CLLocationCoordinate2D FGMGetCoordinateForPigeonLatLng(FGMPlatformLatLng *latLng); - -/// 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); - -/// Converts a GMSCameraPosition to its Pigeon representation. -extern FGMPlatformCameraPosition *FGMGetPigeonCameraPositionForPosition( - GMSCameraPosition *position); - -/// Creates a GMSCameraPosition from its Pigeon representation. -extern GMSCameraPosition *FGMGetCameraPositionForPigeonCameraPosition( - FGMPlatformCameraPosition *position); - -/// Creates a CLLocation array from its Pigeon equivalent. -extern NSArray *FGMGetPointsForPigeonLatLngs(NSArray *points); - -/// Creates a CLLocation arary array, representing a set of holes, from its Pigeon equivalent. -extern NSArray *> *FGMGetHolesForPigeonLatLngArrays( - NSArray *> *points); - -extern GMSMutablePath *FGMGetPathFromPoints(NSArray *points); - -/// Creates a GMSMapViewType from its Pigeon representation. -extern GMSMapViewType FGMGetMapViewTypeForPigeonMapType(FGMPlatformMapType type); - -/// Creates a GMSCollisionBehavior from its Pigeon representation. -extern GMSCollisionBehavior FGMGetCollisionBehaviorForPigeonCollisionBehavior( - FGMPlatformMarkerCollisionBehavior collisionBehavior); - -/// Converts a GMSGroundOverlay to its Pigeon representation. -extern FGMPlatformGroundOverlay *FGMGetPigeonGroundOverlay(GMSGroundOverlay *groundOverlay, - NSString *overlayId, - BOOL isCreatedWithBounds, - NSNumber *_Nullable zoomLevel); - -extern GMUGradient *FGMGetGradientForPigeonHeatmapGradient(FGMPlatformHeatmapGradient *gradient); - -extern FGMPlatformHeatmapGradient *FGMGetPigeonHeatmapGradientForGradient(GMUGradient *gradient); - -/// Creates a GMUWeightedLatLng array from its Pigeon equivalent. -extern NSArray *FGMGetWeightedDataForPigeonWeightedData( - NSArray *weightedLatLngs); - -/// Converts a GMUWeightedLatLng array to its Pigeon equivalent. -extern NSArray *FGMGetPigeonWeightedDataForWeightedData( - NSArray *weightedLatLngs); - -/// Creates a GMSCameraUpdate from its Pigeon equivalent. -extern GMSCameraUpdate *_Nullable FGMGetCameraUpdateForPigeonCameraUpdate( - FGMPlatformCameraUpdate *update); - -/// Creates a UIColor from its Pigeon representation. -extern UIColor *FGMGetColorForPigeonColor(FGMPlatformColor *color); - -/// Converts a UIColor to its Pigeon representation. -extern FGMPlatformColor *FGMGetPigeonColorForColor(UIColor *color); - -/// Creates an array of GMSStrokeStyles using the given patterns and stroke color. -extern NSArray *FGMGetStrokeStylesFromPatterns( - NSArray *patterns, UIColor *strokeColor); - -/// Creates an array of span lengths using the given patterns. -extern NSArray *FGMGetSpanLengthsFromPatterns( - NSArray *patterns); - -NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/include/google_maps_flutter_ios_objc/FGMHeatmapController.h b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/include/google_maps_flutter_ios_objc/FGMHeatmapController.h deleted file mode 100644 index c8fce13543c..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/include/google_maps_flutter_ios_objc/FGMHeatmapController.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -@import GoogleMaps; - -#import "GoogleMapsUtilsTrampoline.h" -#import "google_maps_flutter_pigeon_messages.g.h" - -NS_ASSUME_NONNULL_BEGIN - -/// Controller of a single Heatmap on the map. -@interface FGMHeatmapController : NSObject - -/// Initializes an instance of this class with a heatmap tile layer, a map view, and additional -/// configuration options. -/// -/// @param heatmap The heatmap data to display. -/// @param heatmapTileLayer The heatmap tile layer that will be used to display heatmap data on the -/// map. -/// @param mapView The map view where the heatmap layer will be overlaid. -/// -/// @return An initialized instance of this class, configured with the specified heatmap tile layer, -/// map view, and additional options. -- (instancetype)initWithHeatmap:(FGMPlatformHeatmap *)heatmap - tileLayer:(GMUHeatmapTileLayer *)heatmapTileLayer - mapView:(GMSMapView *)mapView; - -/// Removes this heatmap from the map. -- (void)removeHeatmap; - -/// Clears the tile cache in order to visually udpate this heatmap. -- (void)clearTileCache; -@end - -/// Controller of multiple Heatmaps on the map. -@interface FGMHeatmapsController : NSObject - -/// Initializes the controller with a GMSMapView. -- (instancetype)initWithMapView:(GMSMapView *)mapView; - -/// Adds heatmaps to the map. -- (void)addHeatmaps:(NSArray *)heatmapsToAdd; - -/// Updates heatmaps on the map. -- (void)changeHeatmaps:(NSArray *)heatmapsToChange; - -/// Removes heatmaps from the map. -- (void)removeHeatmapsWithIdentifiers:(NSArray *)identifiers; - -/// Returns true if a heatmap with the given identifier exists on the map. -- (BOOL)hasHeatmapWithIdentifier:(NSString *)identifier; - -/// Returns the heatmap with the given identifier. -- (nullable FGMPlatformHeatmap *)heatmapWithIdentifier:(NSString *)identifier; -@end - -NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/include/google_maps_flutter_ios_objc/FGMHeatmapController_Test.h b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/include/google_maps_flutter_ios_objc/FGMHeatmapController_Test.h deleted file mode 100644 index 797c309dbb2..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/include/google_maps_flutter_ios_objc/FGMHeatmapController_Test.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "FGMHeatmapController.h" - -/// Internal APIs exposed for unit testing -@interface FGMHeatmapController (Test) - -/// Updates the underlying GMUHeatmapTileLayer with the properties from the given platform heatmap. -/// -/// Setting the heatmap to visible will set its map to the given mapView. -+ (void)updateHeatmap:(GMUHeatmapTileLayer *)heatmapTileLayer - fromPlatformHeatmap:(FGMPlatformHeatmap *)platformHeatmap - withMapView:(GMSMapView *)mapView; - -@end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/include/google_maps_flutter_ios_objc/FGMImageUtils.h b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/include/google_maps_flutter_ios_objc/FGMImageUtils.h deleted file mode 100644 index a8fd0c82c68..00000000000 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios_objc/include/google_maps_flutter_ios_objc/FGMImageUtils.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -@import GoogleMaps; -@import UIKit; - -#import "FGMAssetProvider.h" -#import "google_maps_flutter_pigeon_messages.g.h" - -NS_ASSUME_NONNULL_BEGIN - -/// Creates a UIImage from Pigeon bitmap. -UIImage *_Nullable FGMIconFromBitmap(FGMPlatformBitmap *platformBitmap, - NSObject *assetProvider, - CGFloat screenScale); -/// Returns a BOOL indicating whether image is considered scalable with the given scale factor from -/// size. -BOOL FGMIsScalableWithScaleFactorFromSize(CGSize originalSize, CGSize targetSize); - -NS_ASSUME_NONNULL_END From 04717d4b0be6f82a37a04424348a1e8a322489c4 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Tue, 1 Sep 2026 12:45:04 -0400 Subject: [PATCH 12/17] Versino bump --- .../google_maps_flutter_ios_sdk10/CHANGELOG.md | 4 ++++ .../google_maps_flutter_ios_sdk10/pubspec.yaml | 2 +- .../google_maps_flutter_ios_sdk9/CHANGELOG.md | 4 ++++ .../google_maps_flutter_ios_sdk9/pubspec.yaml | 2 +- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/CHANGELOG.md index 34481ba9d7b..da4a2a3785c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.18.11 + +* Converts heatmap controller and data conversion to Swift. + ## 2.18.10 * Converts marker controllers to Swift. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/pubspec.yaml index e3603a04e42..387b927e952 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/pubspec.yaml @@ -2,7 +2,7 @@ name: google_maps_flutter_ios_sdk10 description: iOS implementation of the google_maps_flutter plugin using Google Maps SDK 10. repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter_ios_sdk10 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 2.18.10 +version: 2.18.11 environment: sdk: ^3.10.0 diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/CHANGELOG.md index f468794f676..8918af1d9e1 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.18.12 + +* Converts heatmap controller and data conversion to Swift. + ## 2.18.11 * Converts marker controllers to Swift. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/pubspec.yaml index 2243b438b6d..b1ad8871281 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/pubspec.yaml @@ -2,7 +2,7 @@ name: google_maps_flutter_ios_sdk9 description: iOS implementation of the google_maps_flutter plugin using Google Maps SDK 9. repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter_ios_sdk9 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 2.18.11 +version: 2.18.12 environment: sdk: ^3.10.0 From fc98a33dda6b9dcf2a76bfadeb4d397bc3f27944 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Tue, 1 Sep 2026 12:53:59 -0400 Subject: [PATCH 13/17] Add the new synced files, make import conditional --- .../HeatmapController.swift | 118 ++++++++ .../ImageUtils.swift | 263 ++++++++++++++++++ .../HeatmapController.swift | 5 +- .../HeatmapController.swift | 118 ++++++++ .../google_maps_flutter_ios/ImageUtils.swift | 263 ++++++++++++++++++ 5 files changed, 766 insertions(+), 1 deletion(-) create mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/HeatmapController.swift create mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/ImageUtils.swift create mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/HeatmapController.swift create mode 100644 packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/ImageUtils.swift diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/HeatmapController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/HeatmapController.swift new file mode 100644 index 00000000000..f88aad2ed96 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/HeatmapController.swift @@ -0,0 +1,118 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import GoogleMaps + +#if canImport(google_maps_flutter_ios_sdk10_objc) + import google_maps_flutter_ios_sdk10_objc +#endif + +/// Controller of a single Heatmap on the map. +class HeatmapController: NSObject { + let heatmapTileLayer: GMUHeatmapTileLayer + private weak var mapView: GMSMapView? + + init(heatmap: FGMPlatformHeatmap, tileLayer: GMUHeatmapTileLayer, mapView: GMSMapView) { + self.heatmapTileLayer = tileLayer + self.mapView = mapView + super.init() + HeatmapController.update(tileLayer, from: heatmap, mapView: mapView) + } + + func removeHeatmap() { + heatmapTileLayer.map = nil + } + + func clearTileCache() { + heatmapTileLayer.clearTileCache() + } + + func update(from platformHeatmap: FGMPlatformHeatmap) { + if let mapView = mapView { + HeatmapController.update(heatmapTileLayer, from: platformHeatmap, mapView: mapView) + } + } + + /// Updates the underlying GMUHeatmapTileLayer with the properties from the given platform heatmap. + /// + /// Setting the heatmap to visible will set its map to the given mapView. + static func update( + _ heatmapTileLayer: GMUHeatmapTileLayer, + from platformHeatmap: FGMPlatformHeatmap, + mapView: GMSMapView + ) { + heatmapTileLayer.weightedData = platformHeatmap.data.map({ $0.toGMUWeightedLatLng() }) + if let gradient = platformHeatmap.gradient { + heatmapTileLayer.gradient = gradient.toGMUGradient() + } + heatmapTileLayer.opacity = Float(platformHeatmap.opacity) + heatmapTileLayer.radius = UInt(platformHeatmap.radius) + heatmapTileLayer.minimumZoomIntensity = UInt(platformHeatmap.minimumZoomIntensity) + heatmapTileLayer.maximumZoomIntensity = UInt(platformHeatmap.maximumZoomIntensity) + + // The map must be set each time for options to update. + // This must be done last, to avoid visual flickers of default property values. + heatmapTileLayer.map = mapView + } +} + +/// Controller of multiple Heatmaps on the map. +class HeatmapsController: NSObject { + private var heatmapIdToController: [String: HeatmapController] = [:] + private weak var mapView: GMSMapView? + + init(mapView: GMSMapView) { + self.mapView = mapView + super.init() + } + + func add(_ heatmapsToAdd: [FGMPlatformHeatmap]) { + guard let mapView = mapView else { return } + for heatmap in heatmapsToAdd { + let heatmapTileLayer = GMUHeatmapTileLayer() + let controller = HeatmapController( + heatmap: heatmap, + tileLayer: heatmapTileLayer, + mapView: mapView + ) + heatmapIdToController[heatmap.heatmapId] = controller + } + } + + func change(_ heatmapsToChange: [FGMPlatformHeatmap]) { + for heatmap in heatmapsToChange { + if let controller = heatmapIdToController[heatmap.heatmapId] { + controller.update(from: heatmap) + controller.clearTileCache() + } + } + } + + func removeHeatmaps(withIdentifiers identifiers: [String]) { + for heatmapId in identifiers { + if let controller = heatmapIdToController[heatmapId] { + controller.removeHeatmap() + heatmapIdToController.removeValue(forKey: heatmapId) + } + } + } + + func hasHeatmap(withIdentifier identifier: String) -> Bool { + return heatmapIdToController[identifier] != nil + } + + func heatmap(withIdentifier identifier: String) -> FGMPlatformHeatmap? { + guard let controller = heatmapIdToController[identifier] else { return nil } + let heatmap = controller.heatmapTileLayer + return FGMPlatformHeatmap.make( + withHeatmapId: identifier, + data: heatmap.weightedData.map { FGMPlatformWeightedLatLng.make(from: $0) }, + gradient: FGMPlatformHeatmapGradient.make(from: heatmap.gradient), + opacity: Double(heatmap.opacity), + radius: Int(heatmap.radius), + minimumZoomIntensity: Int(heatmap.minimumZoomIntensity), + maximumZoomIntensity: Int(heatmap.maximumZoomIntensity) + ) + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/ImageUtils.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/ImageUtils.swift new file mode 100644 index 00000000000..996c80b3c27 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/ImageUtils.swift @@ -0,0 +1,263 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import Flutter +import GoogleMaps +import UIKit + +#if canImport(google_maps_flutter_ios_sdk10_objc) + import google_maps_flutter_ios_sdk10_objc +#endif + +/// Creates a UIImage from a Pigeon bitmap representation. +func makeIcon( + from platformBitmap: FGMPlatformBitmap?, + assetProvider: FGMAssetProvider, + screenScale: CGFloat +) -> UIImage? { + assert(screenScale > 0, "Screen scale must be greater than 0") + + guard let platformBitmap = platformBitmap else { + return nil + } + + let bitmap = platformBitmap.bitmap + var image: UIImage? + + switch bitmap { + case let bitmap as FGMPlatformBitmapDefaultMarker: + let hue = bitmap.hue?.doubleValue ?? 0 + image = GMSMarker.markerImage( + with: UIColor( + hue: CGFloat(hue) / 360.0, + saturation: 1.0, + brightness: 0.7, + alpha: 1.0)) + case let bitmap as FGMPlatformBitmapAsset: + // Deprecated: This message handling for 'fromAsset' has been replaced by 'asset'. + // Refer to the flutter google_maps_flutter_platform_interface package for details. + if let pkg = bitmap.pkg { + if let key = assetProvider.lookupKey(forAsset: bitmap.name, fromPackage: pkg) { + image = assetProvider.imageNamed(key) + } + } else { + if let key = assetProvider.lookupKey(forAsset: bitmap.name) { + image = assetProvider.imageNamed(key) + } + } + case let bitmap as FGMPlatformBitmapAssetImage: + // Deprecated: This message handling for 'fromAssetImage' has been replaced by 'asset'. + // Refer to the flutter google_maps_flutter_platform_interface package for details. + if let key = assetProvider.lookupKey(forAsset: bitmap.name) { + if let assetImage = assetProvider.imageNamed(key) { + image = scaledImage(assetImage, scale: bitmap.scale) + } + } + case let bitmap as FGMPlatformBitmapBytes: + // Deprecated: This message handling for 'fromBytes' has been replaced by 'bytes'. + // Refer to the flutter google_maps_flutter_platform_interface package for details. + image = UIImage(data: bitmap.byteData.data, scale: screenScale) + case let bitmap as FGMPlatformBitmapAssetMap: + if let key = assetProvider.lookupKey(forAsset: bitmap.assetName) { + image = assetProvider.imageNamed(key) + } + if let currentImage = image, bitmap.bitmapScaling == .auto { + let width = bitmap.width + let height = bitmap.height + if width != nil || height != nil { + let tempImage = scaledImage(currentImage, scale: screenScale) + image = scaledImage(tempImage, width: width, height: height, screenScale: screenScale) + } else { + image = scaledImage(currentImage, scale: CGFloat(bitmap.imagePixelRatio)) + } + } + case let bitmap as FGMPlatformBitmapBytesMap: + let bytes = bitmap.byteData + image = UIImage(data: bytes.data, scale: screenScale) + if let currentImage = image { + if bitmap.bitmapScaling == .auto { + let width = bitmap.width + let height = bitmap.height + if width != nil || height != nil { + // Before scaling the image, image must be in screenScale. + let tempImage = scaledImage(currentImage, scale: screenScale) + image = scaledImage(tempImage, width: width, height: height, screenScale: screenScale) + } else { + image = scaledImage(currentImage, scale: CGFloat(bitmap.imagePixelRatio)) + } + } else { + // No scaling, load image from bytes without scale parameter. + image = UIImage(data: bytes.data) + } + } + case let bitmap as FGMPlatformBitmapPinConfig: + let options = GMSPinImageOptions() + if let backgroundColor = bitmap.backgroundColor { + options.backgroundColor = backgroundColor.toUIColor() + } + if let borderColor = bitmap.borderColor { + options.borderColor = borderColor.toUIColor() + } + + var glyph: GMSPinImageGlyph? + if let glyphText = bitmap.glyphText { + let glyphTextColor: UIColor + if let textColor = bitmap.glyphTextColor { + glyphTextColor = textColor.toUIColor() + } else { + glyphTextColor = .black + } + glyph = GMSPinImageGlyph(text: glyphText, textColor: glyphTextColor) + } else if let glyphColorValue = bitmap.glyphColor { + glyph = GMSPinImageGlyph(glyphColor: glyphColorValue.toUIColor()) + } else if let glyphBitmap = bitmap.glyphBitmap { + if let glyphImage = makeIcon( + from: glyphBitmap, assetProvider: assetProvider, screenScale: screenScale) + { + glyph = GMSPinImageGlyph(image: glyphImage) + } + } + options.glyph = glyph + image = GMSPinImage(options: options) + default: + break + } + + return image +} + +/// Creates a scaled version of the provided UIImage based on a specified scale factor. +/// +/// This method is deprecated within the context of `BitmapDescriptor.fromBytes` handling in the +/// flutter google_maps_flutter_platform_interface package which has been replaced by 'bytes' +/// message handling. +private func scaledImage(_ image: UIImage, scale: Double) -> UIImage { + if abs(scale - 1.0) > 1e-3 { + if let cgImage = image.cgImage { + return UIImage( + cgImage: cgImage, + scale: image.scale * CGFloat(scale), + orientation: image.imageOrientation + ) + } + } + return image +} + +/// Creates a scaled version of the provided UIImage based on a specified scale factor. +/// +/// If the scale factor differs from the image's current scale by more than a small epsilon-delta +/// (to account for minor floating-point inaccuracies), a new UIImage object is created with the +/// specified scale. Otherwise, the original image is returned. +private func scaledImage(_ image: UIImage, scale: CGFloat) -> UIImage { + if abs(scale - image.scale) > .ulpOfOne { + if let cgImage = image.cgImage { + return UIImage( + cgImage: cgImage, + scale: scale, + orientation: image.imageOrientation + ) + } + } + return image +} + +/// Scales an input UIImage to a specified size. +/// +/// If the aspect ratio of the input image closely matches the target size, indicated by a +/// small epsilon-delta, the image's scale property is updated instead of resizing the image. If +/// the aspect ratios differ beyond this threshold, the method redraws the image at the target +/// size. +private func scaledImage(_ image: UIImage, to size: CGSize) -> UIImage { + let originalPixelWidth = image.size.width * image.scale + let originalPixelHeight = image.size.height * image.scale + + // Return original image if either original image size or target size is so small that + // image cannot be resized or displayed. + if originalPixelWidth <= 0 || originalPixelHeight <= 0 || size.width <= 0 || size.height <= 0 { + return image + } + + // Check if the image's size, accounting for scale, matches the target size. + if abs(originalPixelWidth - size.width) <= .ulpOfOne + && abs(originalPixelHeight - size.height) <= .ulpOfOne + { + return image + } + + // Check if the aspect ratios are approximately equal. + let originalPixelSize = CGSize(width: originalPixelWidth, height: originalPixelHeight) + if isScalableWithScaleFactor(from: originalPixelSize, to: size) { + // Scaled image has close to same aspect ratio, + // updating image scale instead of resizing image. + let factor = originalPixelWidth / size.width + return scaledImage(image, scale: image.scale * factor) + } else { + // Aspect ratios differ significantly, resize the image. + let format = UIGraphicsImageRendererFormat.default() + format.scale = 1.0 + format.opaque = false + let renderer = UIGraphicsImageRenderer(size: size, format: format) + let newImage = renderer.image { _ in + image.draw(in: CGRect(origin: .zero, size: size)) + } + return scaledImage(newImage, scale: image.scale) + } +} + +/// Scales an input UIImage to a specified width and height, preserving aspect ratio if both +/// widht and height are not given. +private func scaledImage( + _ image: UIImage, + width: NSNumber?, + height: NSNumber?, + screenScale: CGFloat +) -> UIImage { + if width == nil && height == nil { + return image + } + + let targetWidth = width == nil ? image.size.width : CGFloat(width!.doubleValue) + let targetHeight = height == nil ? image.size.height : CGFloat(height!.doubleValue) + + var calculatedWidth = targetWidth + var calculatedHeight = targetHeight + + if width != nil && height == nil { + // Calculate height based on aspect ratio if only width is provided. + let aspectRatio = image.size.height / image.size.width + calculatedHeight = (targetWidth * aspectRatio).rounded() + } else if width == nil && height != nil { + // Calculate width based on aspect ratio if only height is provided. + let aspectRatio = image.size.width / image.size.height + calculatedWidth = (targetHeight * aspectRatio).rounded() + } + + let targetSize = CGSize( + width: (calculatedWidth * screenScale).rounded(), + height: (calculatedHeight * screenScale).rounded() + ) + return scaledImage(image, to: targetSize) +} + +func isScalableWithScaleFactor(from originalSize: CGSize, to targetSize: CGSize) -> Bool { + // Select the scaling factor based on the longer side to have good precision. + let scaleFactor = + (originalSize.width > originalSize.height) + ? (targetSize.width / originalSize.width) + : (targetSize.height / originalSize.height) + + // Calculate the scaled dimensions. + let scaledWidth = originalSize.width * scaleFactor + let scaledHeight = originalSize.height * scaleFactor + + // Check if the scaled dimensions are within a one-pixel + // threshold of the target dimensions. + let widthWithinThreshold = abs(scaledWidth - targetSize.width) <= 1.0 + let heightWithinThreshold = abs(scaledHeight - targetSize.height) <= 1.0 + + // The image is considered scalable with scale factor + // if both dimensions are within the threshold. + return widthWithinThreshold && heightWithinThreshold +} diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift index 257c78512d5..10158847110 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/HeatmapController.swift @@ -3,7 +3,10 @@ // found in the LICENSE file. import GoogleMaps -import google_maps_flutter_ios_sdk9_objc + +#if canImport(google_maps_flutter_ios_sdk9_objc) + import google_maps_flutter_ios_sdk9_objc +#endif /// Controller of a single Heatmap on the map. class HeatmapController: NSObject { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/HeatmapController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/HeatmapController.swift new file mode 100644 index 00000000000..b8a3bc65c53 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/HeatmapController.swift @@ -0,0 +1,118 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import GoogleMaps + +#if canImport(google_maps_flutter_ios_objc) + import google_maps_flutter_ios_objc +#endif + +/// Controller of a single Heatmap on the map. +class HeatmapController: NSObject { + let heatmapTileLayer: GMUHeatmapTileLayer + private weak var mapView: GMSMapView? + + init(heatmap: FGMPlatformHeatmap, tileLayer: GMUHeatmapTileLayer, mapView: GMSMapView) { + self.heatmapTileLayer = tileLayer + self.mapView = mapView + super.init() + HeatmapController.update(tileLayer, from: heatmap, mapView: mapView) + } + + func removeHeatmap() { + heatmapTileLayer.map = nil + } + + func clearTileCache() { + heatmapTileLayer.clearTileCache() + } + + func update(from platformHeatmap: FGMPlatformHeatmap) { + if let mapView = mapView { + HeatmapController.update(heatmapTileLayer, from: platformHeatmap, mapView: mapView) + } + } + + /// Updates the underlying GMUHeatmapTileLayer with the properties from the given platform heatmap. + /// + /// Setting the heatmap to visible will set its map to the given mapView. + static func update( + _ heatmapTileLayer: GMUHeatmapTileLayer, + from platformHeatmap: FGMPlatformHeatmap, + mapView: GMSMapView + ) { + heatmapTileLayer.weightedData = platformHeatmap.data.map({ $0.toGMUWeightedLatLng() }) + if let gradient = platformHeatmap.gradient { + heatmapTileLayer.gradient = gradient.toGMUGradient() + } + heatmapTileLayer.opacity = Float(platformHeatmap.opacity) + heatmapTileLayer.radius = UInt(platformHeatmap.radius) + heatmapTileLayer.minimumZoomIntensity = UInt(platformHeatmap.minimumZoomIntensity) + heatmapTileLayer.maximumZoomIntensity = UInt(platformHeatmap.maximumZoomIntensity) + + // The map must be set each time for options to update. + // This must be done last, to avoid visual flickers of default property values. + heatmapTileLayer.map = mapView + } +} + +/// Controller of multiple Heatmaps on the map. +class HeatmapsController: NSObject { + private var heatmapIdToController: [String: HeatmapController] = [:] + private weak var mapView: GMSMapView? + + init(mapView: GMSMapView) { + self.mapView = mapView + super.init() + } + + func add(_ heatmapsToAdd: [FGMPlatformHeatmap]) { + guard let mapView = mapView else { return } + for heatmap in heatmapsToAdd { + let heatmapTileLayer = GMUHeatmapTileLayer() + let controller = HeatmapController( + heatmap: heatmap, + tileLayer: heatmapTileLayer, + mapView: mapView + ) + heatmapIdToController[heatmap.heatmapId] = controller + } + } + + func change(_ heatmapsToChange: [FGMPlatformHeatmap]) { + for heatmap in heatmapsToChange { + if let controller = heatmapIdToController[heatmap.heatmapId] { + controller.update(from: heatmap) + controller.clearTileCache() + } + } + } + + func removeHeatmaps(withIdentifiers identifiers: [String]) { + for heatmapId in identifiers { + if let controller = heatmapIdToController[heatmapId] { + controller.removeHeatmap() + heatmapIdToController.removeValue(forKey: heatmapId) + } + } + } + + func hasHeatmap(withIdentifier identifier: String) -> Bool { + return heatmapIdToController[identifier] != nil + } + + func heatmap(withIdentifier identifier: String) -> FGMPlatformHeatmap? { + guard let controller = heatmapIdToController[identifier] else { return nil } + let heatmap = controller.heatmapTileLayer + return FGMPlatformHeatmap.make( + withHeatmapId: identifier, + data: heatmap.weightedData.map { FGMPlatformWeightedLatLng.make(from: $0) }, + gradient: FGMPlatformHeatmapGradient.make(from: heatmap.gradient), + opacity: Double(heatmap.opacity), + radius: Int(heatmap.radius), + minimumZoomIntensity: Int(heatmap.minimumZoomIntensity), + maximumZoomIntensity: Int(heatmap.maximumZoomIntensity) + ) + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/ImageUtils.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/ImageUtils.swift new file mode 100644 index 00000000000..1a3937ae4c7 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/ImageUtils.swift @@ -0,0 +1,263 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import Flutter +import GoogleMaps +import UIKit + +#if canImport(google_maps_flutter_ios_objc) + import google_maps_flutter_ios_objc +#endif + +/// Creates a UIImage from a Pigeon bitmap representation. +func makeIcon( + from platformBitmap: FGMPlatformBitmap?, + assetProvider: FGMAssetProvider, + screenScale: CGFloat +) -> UIImage? { + assert(screenScale > 0, "Screen scale must be greater than 0") + + guard let platformBitmap = platformBitmap else { + return nil + } + + let bitmap = platformBitmap.bitmap + var image: UIImage? + + switch bitmap { + case let bitmap as FGMPlatformBitmapDefaultMarker: + let hue = bitmap.hue?.doubleValue ?? 0 + image = GMSMarker.markerImage( + with: UIColor( + hue: CGFloat(hue) / 360.0, + saturation: 1.0, + brightness: 0.7, + alpha: 1.0)) + case let bitmap as FGMPlatformBitmapAsset: + // Deprecated: This message handling for 'fromAsset' has been replaced by 'asset'. + // Refer to the flutter google_maps_flutter_platform_interface package for details. + if let pkg = bitmap.pkg { + if let key = assetProvider.lookupKey(forAsset: bitmap.name, fromPackage: pkg) { + image = assetProvider.imageNamed(key) + } + } else { + if let key = assetProvider.lookupKey(forAsset: bitmap.name) { + image = assetProvider.imageNamed(key) + } + } + case let bitmap as FGMPlatformBitmapAssetImage: + // Deprecated: This message handling for 'fromAssetImage' has been replaced by 'asset'. + // Refer to the flutter google_maps_flutter_platform_interface package for details. + if let key = assetProvider.lookupKey(forAsset: bitmap.name) { + if let assetImage = assetProvider.imageNamed(key) { + image = scaledImage(assetImage, scale: bitmap.scale) + } + } + case let bitmap as FGMPlatformBitmapBytes: + // Deprecated: This message handling for 'fromBytes' has been replaced by 'bytes'. + // Refer to the flutter google_maps_flutter_platform_interface package for details. + image = UIImage(data: bitmap.byteData.data, scale: screenScale) + case let bitmap as FGMPlatformBitmapAssetMap: + if let key = assetProvider.lookupKey(forAsset: bitmap.assetName) { + image = assetProvider.imageNamed(key) + } + if let currentImage = image, bitmap.bitmapScaling == .auto { + let width = bitmap.width + let height = bitmap.height + if width != nil || height != nil { + let tempImage = scaledImage(currentImage, scale: screenScale) + image = scaledImage(tempImage, width: width, height: height, screenScale: screenScale) + } else { + image = scaledImage(currentImage, scale: CGFloat(bitmap.imagePixelRatio)) + } + } + case let bitmap as FGMPlatformBitmapBytesMap: + let bytes = bitmap.byteData + image = UIImage(data: bytes.data, scale: screenScale) + if let currentImage = image { + if bitmap.bitmapScaling == .auto { + let width = bitmap.width + let height = bitmap.height + if width != nil || height != nil { + // Before scaling the image, image must be in screenScale. + let tempImage = scaledImage(currentImage, scale: screenScale) + image = scaledImage(tempImage, width: width, height: height, screenScale: screenScale) + } else { + image = scaledImage(currentImage, scale: CGFloat(bitmap.imagePixelRatio)) + } + } else { + // No scaling, load image from bytes without scale parameter. + image = UIImage(data: bytes.data) + } + } + case let bitmap as FGMPlatformBitmapPinConfig: + let options = GMSPinImageOptions() + if let backgroundColor = bitmap.backgroundColor { + options.backgroundColor = backgroundColor.toUIColor() + } + if let borderColor = bitmap.borderColor { + options.borderColor = borderColor.toUIColor() + } + + var glyph: GMSPinImageGlyph? + if let glyphText = bitmap.glyphText { + let glyphTextColor: UIColor + if let textColor = bitmap.glyphTextColor { + glyphTextColor = textColor.toUIColor() + } else { + glyphTextColor = .black + } + glyph = GMSPinImageGlyph(text: glyphText, textColor: glyphTextColor) + } else if let glyphColorValue = bitmap.glyphColor { + glyph = GMSPinImageGlyph(glyphColor: glyphColorValue.toUIColor()) + } else if let glyphBitmap = bitmap.glyphBitmap { + if let glyphImage = makeIcon( + from: glyphBitmap, assetProvider: assetProvider, screenScale: screenScale) + { + glyph = GMSPinImageGlyph(image: glyphImage) + } + } + options.glyph = glyph + image = GMSPinImage(options: options) + default: + break + } + + return image +} + +/// Creates a scaled version of the provided UIImage based on a specified scale factor. +/// +/// This method is deprecated within the context of `BitmapDescriptor.fromBytes` handling in the +/// flutter google_maps_flutter_platform_interface package which has been replaced by 'bytes' +/// message handling. +private func scaledImage(_ image: UIImage, scale: Double) -> UIImage { + if abs(scale - 1.0) > 1e-3 { + if let cgImage = image.cgImage { + return UIImage( + cgImage: cgImage, + scale: image.scale * CGFloat(scale), + orientation: image.imageOrientation + ) + } + } + return image +} + +/// Creates a scaled version of the provided UIImage based on a specified scale factor. +/// +/// If the scale factor differs from the image's current scale by more than a small epsilon-delta +/// (to account for minor floating-point inaccuracies), a new UIImage object is created with the +/// specified scale. Otherwise, the original image is returned. +private func scaledImage(_ image: UIImage, scale: CGFloat) -> UIImage { + if abs(scale - image.scale) > .ulpOfOne { + if let cgImage = image.cgImage { + return UIImage( + cgImage: cgImage, + scale: scale, + orientation: image.imageOrientation + ) + } + } + return image +} + +/// Scales an input UIImage to a specified size. +/// +/// If the aspect ratio of the input image closely matches the target size, indicated by a +/// small epsilon-delta, the image's scale property is updated instead of resizing the image. If +/// the aspect ratios differ beyond this threshold, the method redraws the image at the target +/// size. +private func scaledImage(_ image: UIImage, to size: CGSize) -> UIImage { + let originalPixelWidth = image.size.width * image.scale + let originalPixelHeight = image.size.height * image.scale + + // Return original image if either original image size or target size is so small that + // image cannot be resized or displayed. + if originalPixelWidth <= 0 || originalPixelHeight <= 0 || size.width <= 0 || size.height <= 0 { + return image + } + + // Check if the image's size, accounting for scale, matches the target size. + if abs(originalPixelWidth - size.width) <= .ulpOfOne + && abs(originalPixelHeight - size.height) <= .ulpOfOne + { + return image + } + + // Check if the aspect ratios are approximately equal. + let originalPixelSize = CGSize(width: originalPixelWidth, height: originalPixelHeight) + if isScalableWithScaleFactor(from: originalPixelSize, to: size) { + // Scaled image has close to same aspect ratio, + // updating image scale instead of resizing image. + let factor = originalPixelWidth / size.width + return scaledImage(image, scale: image.scale * factor) + } else { + // Aspect ratios differ significantly, resize the image. + let format = UIGraphicsImageRendererFormat.default() + format.scale = 1.0 + format.opaque = false + let renderer = UIGraphicsImageRenderer(size: size, format: format) + let newImage = renderer.image { _ in + image.draw(in: CGRect(origin: .zero, size: size)) + } + return scaledImage(newImage, scale: image.scale) + } +} + +/// Scales an input UIImage to a specified width and height, preserving aspect ratio if both +/// widht and height are not given. +private func scaledImage( + _ image: UIImage, + width: NSNumber?, + height: NSNumber?, + screenScale: CGFloat +) -> UIImage { + if width == nil && height == nil { + return image + } + + let targetWidth = width == nil ? image.size.width : CGFloat(width!.doubleValue) + let targetHeight = height == nil ? image.size.height : CGFloat(height!.doubleValue) + + var calculatedWidth = targetWidth + var calculatedHeight = targetHeight + + if width != nil && height == nil { + // Calculate height based on aspect ratio if only width is provided. + let aspectRatio = image.size.height / image.size.width + calculatedHeight = (targetWidth * aspectRatio).rounded() + } else if width == nil && height != nil { + // Calculate width based on aspect ratio if only height is provided. + let aspectRatio = image.size.width / image.size.height + calculatedWidth = (targetHeight * aspectRatio).rounded() + } + + let targetSize = CGSize( + width: (calculatedWidth * screenScale).rounded(), + height: (calculatedHeight * screenScale).rounded() + ) + return scaledImage(image, to: targetSize) +} + +func isScalableWithScaleFactor(from originalSize: CGSize, to targetSize: CGSize) -> Bool { + // Select the scaling factor based on the longer side to have good precision. + let scaleFactor = + (originalSize.width > originalSize.height) + ? (targetSize.width / originalSize.width) + : (targetSize.height / originalSize.height) + + // Calculate the scaled dimensions. + let scaledWidth = originalSize.width * scaleFactor + let scaledHeight = originalSize.height * scaleFactor + + // Check if the scaled dimensions are within a one-pixel + // threshold of the target dimensions. + let widthWithinThreshold = abs(scaledWidth - targetSize.width) <= 1.0 + let heightWithinThreshold = abs(scaledHeight - targetSize.height) <= 1.0 + + // The image is considered scalable with scale factor + // if both dimensions are within the threshold. + return widthWithinThreshold && heightWithinThreshold +} From fc54e5a3357fbab9136b397fda0372a54503c15a Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Tue, 1 Sep 2026 13:08:33 -0400 Subject: [PATCH 14/17] Extension-ify makeIcon --- .../ExtractIconFromDataTests.swift | 3 +- .../GroundOverlayController.swift | 6 +- .../ImageUtils.swift | 189 +++++++++--------- .../MarkerController.swift | 6 +- .../ExtractIconFromDataTests.swift | 41 ++-- .../GroundOverlayController.swift | 6 +- .../ImageUtils.swift | 189 +++++++++--------- .../MarkerController.swift | 6 +- .../ExtractIconFromDataTests.swift | 3 +- .../GroundOverlayController.swift | 6 +- .../google_maps_flutter_ios/ImageUtils.swift | 189 +++++++++--------- .../MarkerController.swift | 6 +- 12 files changed, 319 insertions(+), 331 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ExtractIconFromDataTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ExtractIconFromDataTests.swift index d0533616e2b..bdcbd7defab 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ExtractIconFromDataTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ExtractIconFromDataTests.swift @@ -25,8 +25,7 @@ import google_maps_flutter_ios_sdk10_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: assetProvider, screenScale: screenScale ) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/GroundOverlayController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/GroundOverlayController.swift index 7e52a01d0d8..d3bd9ffc09f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/GroundOverlayController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/GroundOverlayController.swift @@ -66,8 +66,10 @@ class GroundOverlayController: NSObject { if let anchor = platformGroundOverlay.anchor { groundOverlay.anchor = CGPoint(x: anchor.x, y: anchor.y) } - groundOverlay.icon = makeIcon( - from: platformGroundOverlay.image, assetProvider: assetProvider, screenScale: screenScale) + groundOverlay.icon = platformGroundOverlay.image.createIcon( + assetProvider: assetProvider, + screenScale: screenScale + ) groundOverlay.bearing = platformGroundOverlay.bearing groundOverlay.opacity = Float(1.0 - platformGroundOverlay.transparency) if useBounds { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/ImageUtils.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/ImageUtils.swift index 996c80b3c27..1dfecf66740 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/ImageUtils.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/ImageUtils.swift @@ -10,121 +10,118 @@ import UIKit import google_maps_flutter_ios_sdk10_objc #endif -/// Creates a UIImage from a Pigeon bitmap representation. -func makeIcon( - from platformBitmap: FGMPlatformBitmap?, - assetProvider: FGMAssetProvider, - screenScale: CGFloat -) -> UIImage? { - assert(screenScale > 0, "Screen scale must be greater than 0") - - guard let platformBitmap = platformBitmap else { - return nil - } +extension FGMPlatformBitmap { + /// Creates a UIImage from the Pigeon bitmap representation, suitable for use as a marker icon. + func createIcon( + assetProvider: FGMAssetProvider, + screenScale: CGFloat + ) -> UIImage? { + assert(screenScale > 0, "Screen scale must be greater than 0") - let bitmap = platformBitmap.bitmap - var image: UIImage? + var image: UIImage? - switch bitmap { - case let bitmap as FGMPlatformBitmapDefaultMarker: - let hue = bitmap.hue?.doubleValue ?? 0 - image = GMSMarker.markerImage( - with: UIColor( - hue: CGFloat(hue) / 360.0, - saturation: 1.0, - brightness: 0.7, - alpha: 1.0)) - case let bitmap as FGMPlatformBitmapAsset: - // Deprecated: This message handling for 'fromAsset' has been replaced by 'asset'. - // Refer to the flutter google_maps_flutter_platform_interface package for details. - if let pkg = bitmap.pkg { - if let key = assetProvider.lookupKey(forAsset: bitmap.name, fromPackage: pkg) { - image = assetProvider.imageNamed(key) + switch bitmap { + case let bitmap as FGMPlatformBitmapDefaultMarker: + let hue = bitmap.hue?.doubleValue ?? 0 + image = GMSMarker.markerImage( + with: UIColor( + hue: CGFloat(hue) / 360.0, + saturation: 1.0, + brightness: 0.7, + alpha: 1.0)) + case let bitmap as FGMPlatformBitmapAsset: + // Deprecated: This message handling for 'fromAsset' has been replaced by 'asset'. + // Refer to the flutter google_maps_flutter_platform_interface package for details. + if let pkg = bitmap.pkg { + if let key = assetProvider.lookupKey(forAsset: bitmap.name, fromPackage: pkg) { + image = assetProvider.imageNamed(key) + } + } else { + if let key = assetProvider.lookupKey(forAsset: bitmap.name) { + image = assetProvider.imageNamed(key) + } } - } else { + case let bitmap as FGMPlatformBitmapAssetImage: + // Deprecated: This message handling for 'fromAssetImage' has been replaced by 'asset'. + // Refer to the flutter google_maps_flutter_platform_interface package for details. if let key = assetProvider.lookupKey(forAsset: bitmap.name) { - image = assetProvider.imageNamed(key) - } - } - case let bitmap as FGMPlatformBitmapAssetImage: - // Deprecated: This message handling for 'fromAssetImage' has been replaced by 'asset'. - // Refer to the flutter google_maps_flutter_platform_interface package for details. - if let key = assetProvider.lookupKey(forAsset: bitmap.name) { - if let assetImage = assetProvider.imageNamed(key) { - image = scaledImage(assetImage, scale: bitmap.scale) + if let assetImage = assetProvider.imageNamed(key) { + image = scaledImage(assetImage, scale: bitmap.scale) + } } - } - case let bitmap as FGMPlatformBitmapBytes: - // Deprecated: This message handling for 'fromBytes' has been replaced by 'bytes'. - // Refer to the flutter google_maps_flutter_platform_interface package for details. - image = UIImage(data: bitmap.byteData.data, scale: screenScale) - case let bitmap as FGMPlatformBitmapAssetMap: - if let key = assetProvider.lookupKey(forAsset: bitmap.assetName) { - image = assetProvider.imageNamed(key) - } - if let currentImage = image, bitmap.bitmapScaling == .auto { - let width = bitmap.width - let height = bitmap.height - if width != nil || height != nil { - let tempImage = scaledImage(currentImage, scale: screenScale) - image = scaledImage(tempImage, width: width, height: height, screenScale: screenScale) - } else { - image = scaledImage(currentImage, scale: CGFloat(bitmap.imagePixelRatio)) + case let bitmap as FGMPlatformBitmapBytes: + // Deprecated: This message handling for 'fromBytes' has been replaced by 'bytes'. + // Refer to the flutter google_maps_flutter_platform_interface package for details. + image = UIImage(data: bitmap.byteData.data, scale: screenScale) + case let bitmap as FGMPlatformBitmapAssetMap: + if let key = assetProvider.lookupKey(forAsset: bitmap.assetName) { + image = assetProvider.imageNamed(key) } - } - case let bitmap as FGMPlatformBitmapBytesMap: - let bytes = bitmap.byteData - image = UIImage(data: bytes.data, scale: screenScale) - if let currentImage = image { - if bitmap.bitmapScaling == .auto { + if let currentImage = image, bitmap.bitmapScaling == .auto { let width = bitmap.width let height = bitmap.height if width != nil || height != nil { - // Before scaling the image, image must be in screenScale. let tempImage = scaledImage(currentImage, scale: screenScale) image = scaledImage(tempImage, width: width, height: height, screenScale: screenScale) } else { image = scaledImage(currentImage, scale: CGFloat(bitmap.imagePixelRatio)) } - } else { - // No scaling, load image from bytes without scale parameter. - image = UIImage(data: bytes.data) } - } - case let bitmap as FGMPlatformBitmapPinConfig: - let options = GMSPinImageOptions() - if let backgroundColor = bitmap.backgroundColor { - options.backgroundColor = backgroundColor.toUIColor() - } - if let borderColor = bitmap.borderColor { - options.borderColor = borderColor.toUIColor() - } - - var glyph: GMSPinImageGlyph? - if let glyphText = bitmap.glyphText { - let glyphTextColor: UIColor - if let textColor = bitmap.glyphTextColor { - glyphTextColor = textColor.toUIColor() - } else { - glyphTextColor = .black + case let bitmap as FGMPlatformBitmapBytesMap: + let bytes = bitmap.byteData + image = UIImage(data: bytes.data, scale: screenScale) + if let currentImage = image { + if bitmap.bitmapScaling == .auto { + let width = bitmap.width + let height = bitmap.height + if width != nil || height != nil { + // Before scaling the image, image must be in screenScale. + let tempImage = scaledImage(currentImage, scale: screenScale) + image = scaledImage(tempImage, width: width, height: height, screenScale: screenScale) + } else { + image = scaledImage(currentImage, scale: CGFloat(bitmap.imagePixelRatio)) + } + } else { + // No scaling, load image from bytes without scale parameter. + image = UIImage(data: bytes.data) + } } - glyph = GMSPinImageGlyph(text: glyphText, textColor: glyphTextColor) - } else if let glyphColorValue = bitmap.glyphColor { - glyph = GMSPinImageGlyph(glyphColor: glyphColorValue.toUIColor()) - } else if let glyphBitmap = bitmap.glyphBitmap { - if let glyphImage = makeIcon( - from: glyphBitmap, assetProvider: assetProvider, screenScale: screenScale) - { - glyph = GMSPinImageGlyph(image: glyphImage) + case let bitmap as FGMPlatformBitmapPinConfig: + let options = GMSPinImageOptions() + if let backgroundColor = bitmap.backgroundColor { + options.backgroundColor = backgroundColor.toUIColor() } + if let borderColor = bitmap.borderColor { + options.borderColor = borderColor.toUIColor() + } + + var glyph: GMSPinImageGlyph? + if let glyphText = bitmap.glyphText { + let glyphTextColor: UIColor + if let textColor = bitmap.glyphTextColor { + glyphTextColor = textColor.toUIColor() + } else { + glyphTextColor = .black + } + glyph = GMSPinImageGlyph(text: glyphText, textColor: glyphTextColor) + } else if let glyphColorValue = bitmap.glyphColor { + glyph = GMSPinImageGlyph(glyphColor: glyphColorValue.toUIColor()) + } else if let glyphBitmap = bitmap.glyphBitmap { + if let glyphImage = glyphBitmap.createIcon( + assetProvider: assetProvider, + screenScale: screenScale + ) { + glyph = GMSPinImageGlyph(image: glyphImage) + } + } + options.glyph = glyph + image = GMSPinImage(options: options) + default: + break } - options.glyph = glyph - image = GMSPinImage(options: options) - default: - break - } - return image + return image + } } /// Creates a scaled version of the provided UIImage based on a specified scale factor. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/MarkerController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/MarkerController.swift index d1c1608ffed..9200d0a4b17 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/MarkerController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/MarkerController.swift @@ -84,8 +84,10 @@ class MarkerController: NSObject { ) { marker.groundAnchor = platformMarker.anchor.toCGPoint() marker.isDraggable = platformMarker.draggable - marker.icon = makeIcon( - from: platformMarker.icon, assetProvider: assetProvider, screenScale: screenScale) + marker.icon = platformMarker.icon.createIcon( + assetProvider: assetProvider, + screenScale: screenScale + ) marker.isFlat = platformMarker.flat marker.position = platformMarker.position.toCLLocationCoordinate2D() marker.rotation = platformMarker.rotation diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ExtractIconFromDataTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ExtractIconFromDataTests.swift index 2e50149f2c5..b9e05e9d51d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ExtractIconFromDataTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ExtractIconFromDataTests.swift @@ -25,8 +25,7 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: assetProvider, screenScale: screenScale ) @@ -53,8 +52,7 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: assetProvider, screenScale: screenScale ) @@ -83,8 +81,7 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: assetProvider, screenScale: screenScale ) @@ -118,8 +115,7 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: assetProvider, screenScale: screenScale ) @@ -145,8 +141,7 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: assetProvider, screenScale: screenScale ) @@ -172,8 +167,7 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: TestAssetProvider(), screenScale: screenScale ) @@ -199,8 +193,7 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: TestAssetProvider(), screenScale: screenScale ) @@ -227,8 +220,7 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: TestAssetProvider(), screenScale: screenScale ) @@ -262,8 +254,7 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: TestAssetProvider(), screenScale: screenScale ) @@ -288,8 +279,7 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: TestAssetProvider(), screenScale: screenScale ) @@ -300,7 +290,7 @@ import google_maps_flutter_ios_sdk9_objc } /// Tests for PinConfig (GMSPinImageOptions) - requires iOS 16.0+ and Google Maps SDK 9.0+. - /// On earlier versions, makeIcon returns nil for PinConfig, which is expected behavior. + /// On earlier versions, createIcon returns nil for PinConfig, which is expected behavior. @Test func extractIconFromPinConfigWithGlyphColor() { let assetProvider = TestAssetProvider() @@ -319,8 +309,7 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: pinConfig), + let resultImage = FGMPlatformBitmap.make(withBitmap: pinConfig).createIcon( assetProvider: assetProvider, screenScale: screenScale ) @@ -348,8 +337,7 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: pinConfig), + let resultImage = FGMPlatformBitmap.make(withBitmap: pinConfig).createIcon( assetProvider: assetProvider, screenScale: screenScale ) @@ -390,8 +378,7 @@ import google_maps_flutter_ios_sdk9_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: pinConfig), + let resultImage = FGMPlatformBitmap.make(withBitmap: pinConfig).createIcon( assetProvider: assetProvider, screenScale: screenScale ) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GroundOverlayController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GroundOverlayController.swift index 616824fe4a1..32a7c165b55 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GroundOverlayController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/GroundOverlayController.swift @@ -66,8 +66,10 @@ class GroundOverlayController: NSObject { if let anchor = platformGroundOverlay.anchor { groundOverlay.anchor = CGPoint(x: anchor.x, y: anchor.y) } - groundOverlay.icon = makeIcon( - from: platformGroundOverlay.image, assetProvider: assetProvider, screenScale: screenScale) + groundOverlay.icon = platformGroundOverlay.image.createIcon( + assetProvider: assetProvider, + screenScale: screenScale + ) groundOverlay.bearing = platformGroundOverlay.bearing groundOverlay.opacity = Float(1.0 - platformGroundOverlay.transparency) if useBounds { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift index b2c577c149c..2daaa824dcd 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift @@ -10,121 +10,118 @@ import UIKit import google_maps_flutter_ios_sdk9_objc #endif -/// Creates a UIImage from a Pigeon bitmap representation. -func makeIcon( - from platformBitmap: FGMPlatformBitmap?, - assetProvider: FGMAssetProvider, - screenScale: CGFloat -) -> UIImage? { - assert(screenScale > 0, "Screen scale must be greater than 0") - - guard let platformBitmap = platformBitmap else { - return nil - } +extension FGMPlatformBitmap { + /// Creates a UIImage from the Pigeon bitmap representation, suitable for use as a marker icon. + func createIcon( + assetProvider: FGMAssetProvider, + screenScale: CGFloat + ) -> UIImage? { + assert(screenScale > 0, "Screen scale must be greater than 0") - let bitmap = platformBitmap.bitmap - var image: UIImage? + var image: UIImage? - switch bitmap { - case let bitmap as FGMPlatformBitmapDefaultMarker: - let hue = bitmap.hue?.doubleValue ?? 0 - image = GMSMarker.markerImage( - with: UIColor( - hue: CGFloat(hue) / 360.0, - saturation: 1.0, - brightness: 0.7, - alpha: 1.0)) - case let bitmap as FGMPlatformBitmapAsset: - // Deprecated: This message handling for 'fromAsset' has been replaced by 'asset'. - // Refer to the flutter google_maps_flutter_platform_interface package for details. - if let pkg = bitmap.pkg { - if let key = assetProvider.lookupKey(forAsset: bitmap.name, fromPackage: pkg) { - image = assetProvider.imageNamed(key) + switch bitmap { + case let bitmap as FGMPlatformBitmapDefaultMarker: + let hue = bitmap.hue?.doubleValue ?? 0 + image = GMSMarker.markerImage( + with: UIColor( + hue: CGFloat(hue) / 360.0, + saturation: 1.0, + brightness: 0.7, + alpha: 1.0)) + case let bitmap as FGMPlatformBitmapAsset: + // Deprecated: This message handling for 'fromAsset' has been replaced by 'asset'. + // Refer to the flutter google_maps_flutter_platform_interface package for details. + if let pkg = bitmap.pkg { + if let key = assetProvider.lookupKey(forAsset: bitmap.name, fromPackage: pkg) { + image = assetProvider.imageNamed(key) + } + } else { + if let key = assetProvider.lookupKey(forAsset: bitmap.name) { + image = assetProvider.imageNamed(key) + } } - } else { + case let bitmap as FGMPlatformBitmapAssetImage: + // Deprecated: This message handling for 'fromAssetImage' has been replaced by 'asset'. + // Refer to the flutter google_maps_flutter_platform_interface package for details. if let key = assetProvider.lookupKey(forAsset: bitmap.name) { - image = assetProvider.imageNamed(key) - } - } - case let bitmap as FGMPlatformBitmapAssetImage: - // Deprecated: This message handling for 'fromAssetImage' has been replaced by 'asset'. - // Refer to the flutter google_maps_flutter_platform_interface package for details. - if let key = assetProvider.lookupKey(forAsset: bitmap.name) { - if let assetImage = assetProvider.imageNamed(key) { - image = scaledImage(assetImage, scale: bitmap.scale) + if let assetImage = assetProvider.imageNamed(key) { + image = scaledImage(assetImage, scale: bitmap.scale) + } } - } - case let bitmap as FGMPlatformBitmapBytes: - // Deprecated: This message handling for 'fromBytes' has been replaced by 'bytes'. - // Refer to the flutter google_maps_flutter_platform_interface package for details. - image = UIImage(data: bitmap.byteData.data, scale: screenScale) - case let bitmap as FGMPlatformBitmapAssetMap: - if let key = assetProvider.lookupKey(forAsset: bitmap.assetName) { - image = assetProvider.imageNamed(key) - } - if let currentImage = image, bitmap.bitmapScaling == .auto { - let width = bitmap.width - let height = bitmap.height - if width != nil || height != nil { - let tempImage = scaledImage(currentImage, scale: screenScale) - image = scaledImage(tempImage, width: width, height: height, screenScale: screenScale) - } else { - image = scaledImage(currentImage, scale: CGFloat(bitmap.imagePixelRatio)) + case let bitmap as FGMPlatformBitmapBytes: + // Deprecated: This message handling for 'fromBytes' has been replaced by 'bytes'. + // Refer to the flutter google_maps_flutter_platform_interface package for details. + image = UIImage(data: bitmap.byteData.data, scale: screenScale) + case let bitmap as FGMPlatformBitmapAssetMap: + if let key = assetProvider.lookupKey(forAsset: bitmap.assetName) { + image = assetProvider.imageNamed(key) } - } - case let bitmap as FGMPlatformBitmapBytesMap: - let bytes = bitmap.byteData - image = UIImage(data: bytes.data, scale: screenScale) - if let currentImage = image { - if bitmap.bitmapScaling == .auto { + if let currentImage = image, bitmap.bitmapScaling == .auto { let width = bitmap.width let height = bitmap.height if width != nil || height != nil { - // Before scaling the image, image must be in screenScale. let tempImage = scaledImage(currentImage, scale: screenScale) image = scaledImage(tempImage, width: width, height: height, screenScale: screenScale) } else { image = scaledImage(currentImage, scale: CGFloat(bitmap.imagePixelRatio)) } - } else { - // No scaling, load image from bytes without scale parameter. - image = UIImage(data: bytes.data) } - } - case let bitmap as FGMPlatformBitmapPinConfig: - let options = GMSPinImageOptions() - if let backgroundColor = bitmap.backgroundColor { - options.backgroundColor = backgroundColor.toUIColor() - } - if let borderColor = bitmap.borderColor { - options.borderColor = borderColor.toUIColor() - } - - var glyph: GMSPinImageGlyph? - if let glyphText = bitmap.glyphText { - let glyphTextColor: UIColor - if let textColor = bitmap.glyphTextColor { - glyphTextColor = textColor.toUIColor() - } else { - glyphTextColor = .black + case let bitmap as FGMPlatformBitmapBytesMap: + let bytes = bitmap.byteData + image = UIImage(data: bytes.data, scale: screenScale) + if let currentImage = image { + if bitmap.bitmapScaling == .auto { + let width = bitmap.width + let height = bitmap.height + if width != nil || height != nil { + // Before scaling the image, image must be in screenScale. + let tempImage = scaledImage(currentImage, scale: screenScale) + image = scaledImage(tempImage, width: width, height: height, screenScale: screenScale) + } else { + image = scaledImage(currentImage, scale: CGFloat(bitmap.imagePixelRatio)) + } + } else { + // No scaling, load image from bytes without scale parameter. + image = UIImage(data: bytes.data) + } } - glyph = GMSPinImageGlyph(text: glyphText, textColor: glyphTextColor) - } else if let glyphColorValue = bitmap.glyphColor { - glyph = GMSPinImageGlyph(glyphColor: glyphColorValue.toUIColor()) - } else if let glyphBitmap = bitmap.glyphBitmap { - if let glyphImage = makeIcon( - from: glyphBitmap, assetProvider: assetProvider, screenScale: screenScale) - { - glyph = GMSPinImageGlyph(image: glyphImage) + case let bitmap as FGMPlatformBitmapPinConfig: + let options = GMSPinImageOptions() + if let backgroundColor = bitmap.backgroundColor { + options.backgroundColor = backgroundColor.toUIColor() } + if let borderColor = bitmap.borderColor { + options.borderColor = borderColor.toUIColor() + } + + var glyph: GMSPinImageGlyph? + if let glyphText = bitmap.glyphText { + let glyphTextColor: UIColor + if let textColor = bitmap.glyphTextColor { + glyphTextColor = textColor.toUIColor() + } else { + glyphTextColor = .black + } + glyph = GMSPinImageGlyph(text: glyphText, textColor: glyphTextColor) + } else if let glyphColorValue = bitmap.glyphColor { + glyph = GMSPinImageGlyph(glyphColor: glyphColorValue.toUIColor()) + } else if let glyphBitmap = bitmap.glyphBitmap { + if let glyphImage = glyphBitmap.createIcon( + assetProvider: assetProvider, + screenScale: screenScale + ) { + glyph = GMSPinImageGlyph(image: glyphImage) + } + } + options.glyph = glyph + image = GMSPinImage(options: options) + default: + break } - options.glyph = glyph - image = GMSPinImage(options: options) - default: - break - } - return image + return image + } } /// Creates a scaled version of the provided UIImage based on a specified scale factor. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/MarkerController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/MarkerController.swift index 8e38cd8f4b5..c9c5a6f0712 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/MarkerController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/MarkerController.swift @@ -84,8 +84,10 @@ class MarkerController: NSObject { ) { marker.groundAnchor = platformMarker.anchor.toCGPoint() marker.isDraggable = platformMarker.draggable - marker.icon = makeIcon( - from: platformMarker.icon, assetProvider: assetProvider, screenScale: screenScale) + marker.icon = platformMarker.icon.createIcon( + assetProvider: assetProvider, + screenScale: screenScale + ) marker.isFlat = platformMarker.flat marker.position = platformMarker.position.toCLLocationCoordinate2D() marker.rotation = platformMarker.rotation diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ExtractIconFromDataTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ExtractIconFromDataTests.swift index 57ad2ab7b1f..7d1e4e766f4 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ExtractIconFromDataTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ExtractIconFromDataTests.swift @@ -25,8 +25,7 @@ import google_maps_flutter_ios_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: assetProvider, screenScale: screenScale ) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GroundOverlayController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GroundOverlayController.swift index 633e0525cbc..e9c5778bbab 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GroundOverlayController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GroundOverlayController.swift @@ -66,8 +66,10 @@ class GroundOverlayController: NSObject { if let anchor = platformGroundOverlay.anchor { groundOverlay.anchor = CGPoint(x: anchor.x, y: anchor.y) } - groundOverlay.icon = makeIcon( - from: platformGroundOverlay.image, assetProvider: assetProvider, screenScale: screenScale) + groundOverlay.icon = platformGroundOverlay.image.createIcon( + assetProvider: assetProvider, + screenScale: screenScale + ) groundOverlay.bearing = platformGroundOverlay.bearing groundOverlay.opacity = Float(1.0 - platformGroundOverlay.transparency) if useBounds { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/ImageUtils.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/ImageUtils.swift index 1a3937ae4c7..7fca86753c0 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/ImageUtils.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/ImageUtils.swift @@ -10,121 +10,118 @@ import UIKit import google_maps_flutter_ios_objc #endif -/// Creates a UIImage from a Pigeon bitmap representation. -func makeIcon( - from platformBitmap: FGMPlatformBitmap?, - assetProvider: FGMAssetProvider, - screenScale: CGFloat -) -> UIImage? { - assert(screenScale > 0, "Screen scale must be greater than 0") - - guard let platformBitmap = platformBitmap else { - return nil - } +extension FGMPlatformBitmap { + /// Creates a UIImage from the Pigeon bitmap representation, suitable for use as a marker icon. + func createIcon( + assetProvider: FGMAssetProvider, + screenScale: CGFloat + ) -> UIImage? { + assert(screenScale > 0, "Screen scale must be greater than 0") - let bitmap = platformBitmap.bitmap - var image: UIImage? + var image: UIImage? - switch bitmap { - case let bitmap as FGMPlatformBitmapDefaultMarker: - let hue = bitmap.hue?.doubleValue ?? 0 - image = GMSMarker.markerImage( - with: UIColor( - hue: CGFloat(hue) / 360.0, - saturation: 1.0, - brightness: 0.7, - alpha: 1.0)) - case let bitmap as FGMPlatformBitmapAsset: - // Deprecated: This message handling for 'fromAsset' has been replaced by 'asset'. - // Refer to the flutter google_maps_flutter_platform_interface package for details. - if let pkg = bitmap.pkg { - if let key = assetProvider.lookupKey(forAsset: bitmap.name, fromPackage: pkg) { - image = assetProvider.imageNamed(key) + switch bitmap { + case let bitmap as FGMPlatformBitmapDefaultMarker: + let hue = bitmap.hue?.doubleValue ?? 0 + image = GMSMarker.markerImage( + with: UIColor( + hue: CGFloat(hue) / 360.0, + saturation: 1.0, + brightness: 0.7, + alpha: 1.0)) + case let bitmap as FGMPlatformBitmapAsset: + // Deprecated: This message handling for 'fromAsset' has been replaced by 'asset'. + // Refer to the flutter google_maps_flutter_platform_interface package for details. + if let pkg = bitmap.pkg { + if let key = assetProvider.lookupKey(forAsset: bitmap.name, fromPackage: pkg) { + image = assetProvider.imageNamed(key) + } + } else { + if let key = assetProvider.lookupKey(forAsset: bitmap.name) { + image = assetProvider.imageNamed(key) + } } - } else { + case let bitmap as FGMPlatformBitmapAssetImage: + // Deprecated: This message handling for 'fromAssetImage' has been replaced by 'asset'. + // Refer to the flutter google_maps_flutter_platform_interface package for details. if let key = assetProvider.lookupKey(forAsset: bitmap.name) { - image = assetProvider.imageNamed(key) - } - } - case let bitmap as FGMPlatformBitmapAssetImage: - // Deprecated: This message handling for 'fromAssetImage' has been replaced by 'asset'. - // Refer to the flutter google_maps_flutter_platform_interface package for details. - if let key = assetProvider.lookupKey(forAsset: bitmap.name) { - if let assetImage = assetProvider.imageNamed(key) { - image = scaledImage(assetImage, scale: bitmap.scale) + if let assetImage = assetProvider.imageNamed(key) { + image = scaledImage(assetImage, scale: bitmap.scale) + } } - } - case let bitmap as FGMPlatformBitmapBytes: - // Deprecated: This message handling for 'fromBytes' has been replaced by 'bytes'. - // Refer to the flutter google_maps_flutter_platform_interface package for details. - image = UIImage(data: bitmap.byteData.data, scale: screenScale) - case let bitmap as FGMPlatformBitmapAssetMap: - if let key = assetProvider.lookupKey(forAsset: bitmap.assetName) { - image = assetProvider.imageNamed(key) - } - if let currentImage = image, bitmap.bitmapScaling == .auto { - let width = bitmap.width - let height = bitmap.height - if width != nil || height != nil { - let tempImage = scaledImage(currentImage, scale: screenScale) - image = scaledImage(tempImage, width: width, height: height, screenScale: screenScale) - } else { - image = scaledImage(currentImage, scale: CGFloat(bitmap.imagePixelRatio)) + case let bitmap as FGMPlatformBitmapBytes: + // Deprecated: This message handling for 'fromBytes' has been replaced by 'bytes'. + // Refer to the flutter google_maps_flutter_platform_interface package for details. + image = UIImage(data: bitmap.byteData.data, scale: screenScale) + case let bitmap as FGMPlatformBitmapAssetMap: + if let key = assetProvider.lookupKey(forAsset: bitmap.assetName) { + image = assetProvider.imageNamed(key) } - } - case let bitmap as FGMPlatformBitmapBytesMap: - let bytes = bitmap.byteData - image = UIImage(data: bytes.data, scale: screenScale) - if let currentImage = image { - if bitmap.bitmapScaling == .auto { + if let currentImage = image, bitmap.bitmapScaling == .auto { let width = bitmap.width let height = bitmap.height if width != nil || height != nil { - // Before scaling the image, image must be in screenScale. let tempImage = scaledImage(currentImage, scale: screenScale) image = scaledImage(tempImage, width: width, height: height, screenScale: screenScale) } else { image = scaledImage(currentImage, scale: CGFloat(bitmap.imagePixelRatio)) } - } else { - // No scaling, load image from bytes without scale parameter. - image = UIImage(data: bytes.data) } - } - case let bitmap as FGMPlatformBitmapPinConfig: - let options = GMSPinImageOptions() - if let backgroundColor = bitmap.backgroundColor { - options.backgroundColor = backgroundColor.toUIColor() - } - if let borderColor = bitmap.borderColor { - options.borderColor = borderColor.toUIColor() - } - - var glyph: GMSPinImageGlyph? - if let glyphText = bitmap.glyphText { - let glyphTextColor: UIColor - if let textColor = bitmap.glyphTextColor { - glyphTextColor = textColor.toUIColor() - } else { - glyphTextColor = .black + case let bitmap as FGMPlatformBitmapBytesMap: + let bytes = bitmap.byteData + image = UIImage(data: bytes.data, scale: screenScale) + if let currentImage = image { + if bitmap.bitmapScaling == .auto { + let width = bitmap.width + let height = bitmap.height + if width != nil || height != nil { + // Before scaling the image, image must be in screenScale. + let tempImage = scaledImage(currentImage, scale: screenScale) + image = scaledImage(tempImage, width: width, height: height, screenScale: screenScale) + } else { + image = scaledImage(currentImage, scale: CGFloat(bitmap.imagePixelRatio)) + } + } else { + // No scaling, load image from bytes without scale parameter. + image = UIImage(data: bytes.data) + } } - glyph = GMSPinImageGlyph(text: glyphText, textColor: glyphTextColor) - } else if let glyphColorValue = bitmap.glyphColor { - glyph = GMSPinImageGlyph(glyphColor: glyphColorValue.toUIColor()) - } else if let glyphBitmap = bitmap.glyphBitmap { - if let glyphImage = makeIcon( - from: glyphBitmap, assetProvider: assetProvider, screenScale: screenScale) - { - glyph = GMSPinImageGlyph(image: glyphImage) + case let bitmap as FGMPlatformBitmapPinConfig: + let options = GMSPinImageOptions() + if let backgroundColor = bitmap.backgroundColor { + options.backgroundColor = backgroundColor.toUIColor() } + if let borderColor = bitmap.borderColor { + options.borderColor = borderColor.toUIColor() + } + + var glyph: GMSPinImageGlyph? + if let glyphText = bitmap.glyphText { + let glyphTextColor: UIColor + if let textColor = bitmap.glyphTextColor { + glyphTextColor = textColor.toUIColor() + } else { + glyphTextColor = .black + } + glyph = GMSPinImageGlyph(text: glyphText, textColor: glyphTextColor) + } else if let glyphColorValue = bitmap.glyphColor { + glyph = GMSPinImageGlyph(glyphColor: glyphColorValue.toUIColor()) + } else if let glyphBitmap = bitmap.glyphBitmap { + if let glyphImage = glyphBitmap.createIcon( + assetProvider: assetProvider, + screenScale: screenScale + ) { + glyph = GMSPinImageGlyph(image: glyphImage) + } + } + options.glyph = glyph + image = GMSPinImage(options: options) + default: + break } - options.glyph = glyph - image = GMSPinImage(options: options) - default: - break - } - return image + return image + } } /// Creates a scaled version of the provided UIImage based on a specified scale factor. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/MarkerController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/MarkerController.swift index f13f1418c07..c4880530e56 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/MarkerController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/MarkerController.swift @@ -84,8 +84,10 @@ class MarkerController: NSObject { ) { marker.groundAnchor = platformMarker.anchor.toCGPoint() marker.isDraggable = platformMarker.draggable - marker.icon = makeIcon( - from: platformMarker.icon, assetProvider: assetProvider, screenScale: screenScale) + marker.icon = platformMarker.icon.createIcon( + assetProvider: assetProvider, + screenScale: screenScale + ) marker.isFlat = platformMarker.flat marker.position = platformMarker.position.toCLLocationCoordinate2D() marker.rotation = platformMarker.rotation From 7602e3940f92fab6abb8b046af98c151590f7f00 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Tue, 1 Sep 2026 14:14:08 -0400 Subject: [PATCH 15/17] Avoid unnecessary CLLocations --- .../example/ios/RunnerTests/ConversionsUtilsTests.swift | 6 +++--- .../google_maps_flutter_ios_sdk9/ConversionUtils.swift | 9 ++------- .../google_maps_flutter_ios_sdk9/PolygonController.swift | 6 ++++-- .../PolylineController.swift | 2 +- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ConversionsUtilsTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ConversionsUtilsTests.swift index c73da79c62b..b6970b5597f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ConversionsUtilsTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ConversionsUtilsTests.swift @@ -48,9 +48,9 @@ import google_maps_flutter_ios_sdk9_objc @Test func pointFromLatLong() { let latlong = FGMPlatformLatLng.make(withLatitude: 1, longitude: 2) - let location = latlong.toCLLocation() - #expect(location.coordinate.latitude == 1) - #expect(location.coordinate.longitude == 2) + let location = latlong.toCLLocationCoordinate2D() + #expect(location.latitude == 1) + #expect(location.longitude == 2) } @Test func getPigeonCameraPositionForPosition() { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift index 6b770e82e08..fa2d2cd4678 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift @@ -33,11 +33,6 @@ extension FGMPlatformLatLng { func toCLLocationCoordinate2D() -> CLLocationCoordinate2D { return CLLocationCoordinate2D(latitude: latitude, longitude: longitude) } - - /// Returns the equivalent CLLocation. - func toCLLocation() -> CLLocation { - return CLLocation(latitude: latitude, longitude: longitude) - } } extension FGMPlatformLatLngBounds { @@ -81,10 +76,10 @@ extension FGMPlatformCameraPosition { } /// Creates a GMSMutablePath from points. -func makePath(from points: [CLLocation]) -> GMSMutablePath { +func makePath(from points: [CLLocationCoordinate2D]) -> GMSMutablePath { let path = GMSMutablePath() for location in points { - path.add(location.coordinate) + path.add(location) } return path } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolygonController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolygonController.swift index dd758e57544..a24da0fae3f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolygonController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolygonController.swift @@ -41,8 +41,10 @@ class PolygonController: NSObject { ) { polygon.isTappable = platformPolygon.consumesTapEvents polygon.zIndex = Int32(platformPolygon.zIndex) - polygon.path = makePath(from: platformPolygon.points.map({ $0.toCLLocation() })) - polygon.holes = platformPolygon.holes.map { makePath(from: $0.map({ $0.toCLLocation() })) } + polygon.path = makePath(from: platformPolygon.points.map({ $0.toCLLocationCoordinate2D() })) + polygon.holes = platformPolygon.holes.map { + makePath(from: $0.map({ $0.toCLLocationCoordinate2D() })) + } polygon.fillColor = platformPolygon.fillColor.toUIColor() polygon.strokeColor = platformPolygon.strokeColor.toUIColor() polygon.strokeWidth = CGFloat(platformPolygon.strokeWidth) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolylineController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolylineController.swift index caef84694a0..77116a5157e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolylineController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/PolylineController.swift @@ -41,7 +41,7 @@ class PolylineController: NSObject { ) { polyline.isTappable = platformPolyline.consumesTapEvents polyline.zIndex = Int32(platformPolyline.zIndex) - let gmsPath = makePath(from: platformPolyline.points.map({ $0.toCLLocation() })) + let gmsPath = makePath(from: platformPolyline.points.map({ $0.toCLLocationCoordinate2D() })) polyline.path = gmsPath let strokeColor = platformPolyline.color.toUIColor() polyline.strokeColor = strokeColor From 17d19c8865362609701feff2c82aa10eca777aa4 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Tue, 1 Sep 2026 14:14:43 -0400 Subject: [PATCH 16/17] Resync --- .../RunnerTests/ConversionsUtilsTests.swift | 6 +-- .../ExtractIconFromDataTests.swift | 38 +++++++------------ .../ConversionUtils.swift | 9 +---- .../PolygonController.swift | 6 ++- .../PolylineController.swift | 2 +- .../RunnerTests/ConversionsUtilsTests.swift | 6 +-- .../ExtractIconFromDataTests.swift | 38 +++++++------------ .../ConversionUtils.swift | 9 +---- .../PolygonController.swift | 6 ++- .../PolylineController.swift | 2 +- 10 files changed, 46 insertions(+), 76 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ConversionsUtilsTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ConversionsUtilsTests.swift index 73276e09cce..c4e8cb3f6bc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ConversionsUtilsTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ConversionsUtilsTests.swift @@ -48,9 +48,9 @@ import google_maps_flutter_ios_sdk10_objc @Test func pointFromLatLong() { let latlong = FGMPlatformLatLng.make(withLatitude: 1, longitude: 2) - let location = latlong.toCLLocation() - #expect(location.coordinate.latitude == 1) - #expect(location.coordinate.longitude == 2) + let location = latlong.toCLLocationCoordinate2D() + #expect(location.latitude == 1) + #expect(location.longitude == 2) } @Test func getPigeonCameraPositionForPosition() { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ExtractIconFromDataTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ExtractIconFromDataTests.swift index bdcbd7defab..7dd8c7d818e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ExtractIconFromDataTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/RunnerTests/ExtractIconFromDataTests.swift @@ -52,8 +52,7 @@ import google_maps_flutter_ios_sdk10_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: assetProvider, screenScale: screenScale ) @@ -82,8 +81,7 @@ import google_maps_flutter_ios_sdk10_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: assetProvider, screenScale: screenScale ) @@ -117,8 +115,7 @@ import google_maps_flutter_ios_sdk10_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: assetProvider, screenScale: screenScale ) @@ -144,8 +141,7 @@ import google_maps_flutter_ios_sdk10_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: assetProvider, screenScale: screenScale ) @@ -171,8 +167,7 @@ import google_maps_flutter_ios_sdk10_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: TestAssetProvider(), screenScale: screenScale ) @@ -198,8 +193,7 @@ import google_maps_flutter_ios_sdk10_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: TestAssetProvider(), screenScale: screenScale ) @@ -226,8 +220,7 @@ import google_maps_flutter_ios_sdk10_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: TestAssetProvider(), screenScale: screenScale ) @@ -261,8 +254,7 @@ import google_maps_flutter_ios_sdk10_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: TestAssetProvider(), screenScale: screenScale ) @@ -287,8 +279,7 @@ import google_maps_flutter_ios_sdk10_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: TestAssetProvider(), screenScale: screenScale ) @@ -299,7 +290,7 @@ import google_maps_flutter_ios_sdk10_objc } /// Tests for PinConfig (GMSPinImageOptions) - requires iOS 16.0+ and Google Maps SDK 9.0+. - /// On earlier versions, makeIcon returns nil for PinConfig, which is expected behavior. + /// On earlier versions, createIcon returns nil for PinConfig, which is expected behavior. @Test func extractIconFromPinConfigWithGlyphColor() { let assetProvider = TestAssetProvider() @@ -318,8 +309,7 @@ import google_maps_flutter_ios_sdk10_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: pinConfig), + let resultImage = FGMPlatformBitmap.make(withBitmap: pinConfig).createIcon( assetProvider: assetProvider, screenScale: screenScale ) @@ -347,8 +337,7 @@ import google_maps_flutter_ios_sdk10_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: pinConfig), + let resultImage = FGMPlatformBitmap.make(withBitmap: pinConfig).createIcon( assetProvider: assetProvider, screenScale: screenScale ) @@ -389,8 +378,7 @@ import google_maps_flutter_ios_sdk10_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: pinConfig), + let resultImage = FGMPlatformBitmap.make(withBitmap: pinConfig).createIcon( assetProvider: assetProvider, screenScale: screenScale ) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/ConversionUtils.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/ConversionUtils.swift index a1f26b733f8..0860497073c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/ConversionUtils.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/ConversionUtils.swift @@ -33,11 +33,6 @@ extension FGMPlatformLatLng { func toCLLocationCoordinate2D() -> CLLocationCoordinate2D { return CLLocationCoordinate2D(latitude: latitude, longitude: longitude) } - - /// Returns the equivalent CLLocation. - func toCLLocation() -> CLLocation { - return CLLocation(latitude: latitude, longitude: longitude) - } } extension FGMPlatformLatLngBounds { @@ -81,10 +76,10 @@ extension FGMPlatformCameraPosition { } /// Creates a GMSMutablePath from points. -func makePath(from points: [CLLocation]) -> GMSMutablePath { +func makePath(from points: [CLLocationCoordinate2D]) -> GMSMutablePath { let path = GMSMutablePath() for location in points { - path.add(location.coordinate) + path.add(location) } return path } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/PolygonController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/PolygonController.swift index 06b4d722f77..ab5c16652ed 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/PolygonController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/PolygonController.swift @@ -41,8 +41,10 @@ class PolygonController: NSObject { ) { polygon.isTappable = platformPolygon.consumesTapEvents polygon.zIndex = Int32(platformPolygon.zIndex) - polygon.path = makePath(from: platformPolygon.points.map({ $0.toCLLocation() })) - polygon.holes = platformPolygon.holes.map { makePath(from: $0.map({ $0.toCLLocation() })) } + polygon.path = makePath(from: platformPolygon.points.map({ $0.toCLLocationCoordinate2D() })) + polygon.holes = platformPolygon.holes.map { + makePath(from: $0.map({ $0.toCLLocationCoordinate2D() })) + } polygon.fillColor = platformPolygon.fillColor.toUIColor() polygon.strokeColor = platformPolygon.strokeColor.toUIColor() polygon.strokeWidth = CGFloat(platformPolygon.strokeWidth) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/PolylineController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/PolylineController.swift index 1d6efa1c4d5..278c6a336ff 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/PolylineController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/ios/google_maps_flutter_ios_sdk10/Sources/google_maps_flutter_ios_sdk10/PolylineController.swift @@ -41,7 +41,7 @@ class PolylineController: NSObject { ) { polyline.isTappable = platformPolyline.consumesTapEvents polyline.zIndex = Int32(platformPolyline.zIndex) - let gmsPath = makePath(from: platformPolyline.points.map({ $0.toCLLocation() })) + let gmsPath = makePath(from: platformPolyline.points.map({ $0.toCLLocationCoordinate2D() })) polyline.path = gmsPath let strokeColor = platformPolyline.color.toUIColor() polyline.strokeColor = strokeColor diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ConversionsUtilsTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ConversionsUtilsTests.swift index deb8571c955..4c8f4d86b66 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ConversionsUtilsTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ConversionsUtilsTests.swift @@ -48,9 +48,9 @@ import google_maps_flutter_ios_objc @Test func pointFromLatLong() { let latlong = FGMPlatformLatLng.make(withLatitude: 1, longitude: 2) - let location = latlong.toCLLocation() - #expect(location.coordinate.latitude == 1) - #expect(location.coordinate.longitude == 2) + let location = latlong.toCLLocationCoordinate2D() + #expect(location.latitude == 1) + #expect(location.longitude == 2) } @Test func getPigeonCameraPositionForPosition() { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ExtractIconFromDataTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ExtractIconFromDataTests.swift index 7d1e4e766f4..0b9e8c92feb 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ExtractIconFromDataTests.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/example/ios/RunnerTests/ExtractIconFromDataTests.swift @@ -52,8 +52,7 @@ import google_maps_flutter_ios_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: assetProvider, screenScale: screenScale ) @@ -82,8 +81,7 @@ import google_maps_flutter_ios_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: assetProvider, screenScale: screenScale ) @@ -117,8 +115,7 @@ import google_maps_flutter_ios_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: assetProvider, screenScale: screenScale ) @@ -144,8 +141,7 @@ import google_maps_flutter_ios_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: assetProvider, screenScale: screenScale ) @@ -171,8 +167,7 @@ import google_maps_flutter_ios_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: TestAssetProvider(), screenScale: screenScale ) @@ -198,8 +193,7 @@ import google_maps_flutter_ios_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: TestAssetProvider(), screenScale: screenScale ) @@ -226,8 +220,7 @@ import google_maps_flutter_ios_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: TestAssetProvider(), screenScale: screenScale ) @@ -261,8 +254,7 @@ import google_maps_flutter_ios_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: TestAssetProvider(), screenScale: screenScale ) @@ -287,8 +279,7 @@ import google_maps_flutter_ios_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: bitmap), + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( assetProvider: TestAssetProvider(), screenScale: screenScale ) @@ -299,7 +290,7 @@ import google_maps_flutter_ios_objc } /// Tests for PinConfig (GMSPinImageOptions) - requires iOS 16.0+ and Google Maps SDK 9.0+. - /// On earlier versions, makeIcon returns nil for PinConfig, which is expected behavior. + /// On earlier versions, createIcon returns nil for PinConfig, which is expected behavior. @Test func extractIconFromPinConfigWithGlyphColor() { let assetProvider = TestAssetProvider() @@ -318,8 +309,7 @@ import google_maps_flutter_ios_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: pinConfig), + let resultImage = FGMPlatformBitmap.make(withBitmap: pinConfig).createIcon( assetProvider: assetProvider, screenScale: screenScale ) @@ -347,8 +337,7 @@ import google_maps_flutter_ios_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: pinConfig), + let resultImage = FGMPlatformBitmap.make(withBitmap: pinConfig).createIcon( assetProvider: assetProvider, screenScale: screenScale ) @@ -389,8 +378,7 @@ import google_maps_flutter_ios_objc let screenScale: CGFloat = 3.0 - let resultImage = makeIcon( - from: FGMPlatformBitmap.make(withBitmap: pinConfig), + let resultImage = FGMPlatformBitmap.make(withBitmap: pinConfig).createIcon( assetProvider: assetProvider, screenScale: screenScale ) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/ConversionUtils.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/ConversionUtils.swift index dcb85c57f46..eae05405897 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/ConversionUtils.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/ConversionUtils.swift @@ -33,11 +33,6 @@ extension FGMPlatformLatLng { func toCLLocationCoordinate2D() -> CLLocationCoordinate2D { return CLLocationCoordinate2D(latitude: latitude, longitude: longitude) } - - /// Returns the equivalent CLLocation. - func toCLLocation() -> CLLocation { - return CLLocation(latitude: latitude, longitude: longitude) - } } extension FGMPlatformLatLngBounds { @@ -81,10 +76,10 @@ extension FGMPlatformCameraPosition { } /// Creates a GMSMutablePath from points. -func makePath(from points: [CLLocation]) -> GMSMutablePath { +func makePath(from points: [CLLocationCoordinate2D]) -> GMSMutablePath { let path = GMSMutablePath() for location in points { - path.add(location.coordinate) + path.add(location) } return path } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/PolygonController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/PolygonController.swift index a8424fea978..9f2fcb58db7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/PolygonController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/PolygonController.swift @@ -41,8 +41,10 @@ class PolygonController: NSObject { ) { polygon.isTappable = platformPolygon.consumesTapEvents polygon.zIndex = Int32(platformPolygon.zIndex) - polygon.path = makePath(from: platformPolygon.points.map({ $0.toCLLocation() })) - polygon.holes = platformPolygon.holes.map { makePath(from: $0.map({ $0.toCLLocation() })) } + polygon.path = makePath(from: platformPolygon.points.map({ $0.toCLLocationCoordinate2D() })) + polygon.holes = platformPolygon.holes.map { + makePath(from: $0.map({ $0.toCLLocationCoordinate2D() })) + } polygon.fillColor = platformPolygon.fillColor.toUIColor() polygon.strokeColor = platformPolygon.strokeColor.toUIColor() polygon.strokeWidth = CGFloat(platformPolygon.strokeWidth) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/PolylineController.swift b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/PolylineController.swift index 0a7a1147b70..42d41cee189 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/PolylineController.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_shared_code/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/PolylineController.swift @@ -41,7 +41,7 @@ class PolylineController: NSObject { ) { polyline.isTappable = platformPolyline.consumesTapEvents polyline.zIndex = Int32(platformPolyline.zIndex) - let gmsPath = makePath(from: platformPolyline.points.map({ $0.toCLLocation() })) + let gmsPath = makePath(from: platformPolyline.points.map({ $0.toCLLocationCoordinate2D() })) polyline.path = gmsPath let strokeColor = platformPolyline.color.toUIColor() polyline.strokeColor = strokeColor From 44bcf7ae4dfc716e1317c97cd9654a049b454e63 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 2 Sep 2026 15:40:15 -0400 Subject: [PATCH 17/17] Review, test fix --- .../Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift | 2 +- .../Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift index fa2d2cd4678..751cfee96d3 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ConversionUtils.swift @@ -123,7 +123,7 @@ extension FGMPlatformGroundOverlay { zoomLevel: NSNumber? ) -> FGMPlatformGroundOverlay { let placeholderImage = FGMPlatformBitmap.make( - withBitmap: FGMPlatformBitmapDefaultMarker.make(withHue: 0)) + withBitmap: FGMPlatformBitmapDefaultMarker.make(withHue: nil)) if isCreatedWithBounds, let bounds = groundOverlay.bounds { return FGMPlatformGroundOverlay.make( withGroundOverlayId: overlayId, diff --git a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift index 2daaa824dcd..25ad7c11d1f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift +++ b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/ios/google_maps_flutter_ios_sdk9/Sources/google_maps_flutter_ios_sdk9/ImageUtils.swift @@ -20,6 +20,8 @@ extension FGMPlatformBitmap { var image: UIImage? + // See comment in messages.dart for why this is so loosely typed. See also + // https://github.com/flutter/flutter/issues/117819. switch bitmap { case let bitmap as FGMPlatformBitmapDefaultMarker: let hue = bitmap.hue?.doubleValue ?? 0