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 34481ba9d7bc..da4a2a3785c9 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/example/ios/Runner.xcodeproj/project.pbxproj b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/example/ios/Runner.xcodeproj/project.pbxproj index 2d79e5c1f3af..f0b1d078a8df 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 d8cfa6ead24d..8276502818ca 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 cf68af2150a5..797e78859ec3 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 8bcb2f5a5da6..c4e8cb3f6bc1 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.toCLLocationCoordinate2D() + #expect(location.latitude == 1) + #expect(location.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 5d8a3bd2d74f..7dd8c7d818e2 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,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) @@ -52,10 +52,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) @@ -82,10 +81,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) #expect(testImage.scale == 1.0) @@ -117,10 +115,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == screenScale) @@ -144,10 +141,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) @@ -171,10 +167,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) @@ -198,10 +193,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == 10) @@ -226,10 +220,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) @@ -261,10 +254,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == screenScale) @@ -287,10 +279,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == 1.0) @@ -299,7 +290,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, createIcon returns nil for PinConfig, which is expected behavior. @Test func extractIconFromPinConfigWithGlyphColor() { let assetProvider = TestAssetProvider() @@ -318,10 +309,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: pinConfig), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: pinConfig).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) // PinConfig may return nil on old Google Maps SDK versions (<=8.4.0). @@ -347,10 +337,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: pinConfig), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: pinConfig).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) // PinConfig returns nil on iOS versions without GMSPinImageOptions support (< iOS 16.0). @@ -389,10 +378,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: pinConfig), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: pinConfig).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) // PinConfig returns nil on iOS versions without GMSPinImageOptions support (< iOS 16.0). @@ -406,43 +394,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 e763082ad1b0..c0d68c649ff5 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 ce80ddfe68f8..22180d018073 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 1af11a144c20..cd37fc83c7ee 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 c052a5ee5863..5cc8c4fa6ae2 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 7125108589fa..0eef55ee3f07 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 702d5171599c..c346ca4c1ada 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 050c9ce00b26..000000000000 --- 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 2db2bdc1d749..745075545d87 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 86b567e6adcc..f1ea77a9ecc5 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 99a5cca7802b..065ef5ace5df 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 90da6a4ef357..95d93c98ae17 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 23aaefeacf0e..12685084077c 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 59177bcd5b3e..c1ed35fffa67 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 430d2237d1bb..0860497073c8 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,286 @@ // 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) + } + + /// Returns the equivalent CLLocationCoordinate2D. + func toCLLocationCoordinate2D() -> CLLocationCoordinate2D { + return CLLocationCoordinate2D(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: [CLLocationCoordinate2D]) -> GMSMutablePath { + let path = GMSMutablePath() + for location in points { + path.add(location) } + return path +} - let markerIds = cluster.items.filter { $0 is GMSMarker }.compactMap { - markerIdentifierFromMarker($0 as! GMSMarker) +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 + } } +} - return FGMPlatformCluster.make( - withClusterManagerId: clusterManagerIdentifier, - position: FGMGetPigeonLatLngForCoordinate(cluster.position), - bounds: FGMGetPigeonLatLngBoundsForCoordinateBounds(bounds), - markerIds: markerIds - ) +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 5a9088af435c..1407ca72bab1 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 450472dc6380..d3bd9ffc09f3 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,10 @@ 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 = platformGroundOverlay.image.createIcon( + assetProvider: assetProvider, + screenScale: screenScale + ) groundOverlay.bearing = platformGroundOverlay.bearing groundOverlay.opacity = Float(1.0 - platformGroundOverlay.transparency) if useBounds { @@ -220,11 +223,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/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 000000000000..f88aad2ed965 --- /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 000000000000..1dfecf66740c --- /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,260 @@ +// 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 + +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") + + 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 = glyphBitmap.createIcon( + 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_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 ce63a5be7cf5..9200d0a4b171 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,27 @@ 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 = platformMarker.icon.createIcon( + 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 +147,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 +231,7 @@ class MarkersController: NSObject { guard markerIdentifierToController[identifier] != nil else { return } eventDelegate?.didStartDragForMarker( withIdentifier: identifier, - atPosition: FGMGetPigeonLatLngForCoordinate(location) + atPosition: FGMPlatformLatLng.make(from: location) ) } @@ -237,7 +239,7 @@ class MarkersController: NSObject { guard markerIdentifierToController[identifier] != nil else { return } eventDelegate?.didDragMarker( withIdentifier: identifier, - atPosition: FGMGetPigeonLatLngForCoordinate(location) + atPosition: FGMPlatformLatLng.make(from: location) ) } @@ -245,7 +247,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 0808d878462e..ab5c16652ed1 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,12 @@ 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.path = makePath(from: platformPolygon.points.map({ $0.toCLLocationCoordinate2D() })) + polygon.holes = platformPolygon.holes.map { + makePath(from: $0.map({ $0.toCLLocationCoordinate2D() })) } - polygon.fillColor = FGMGetColorForPigeonColor(platformPolygon.fillColor) - polygon.strokeColor = FGMGetColorForPigeonColor(platformPolygon.strokeColor) + 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 b6c0d57aef19..278c6a336ff4 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.toCLLocationCoordinate2D() })) + 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 219d8df44a1b..000000000000 --- 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 49ec16dff827..000000000000 --- 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 03eb36eeb404..000000000000 --- 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 b7344e6b492e..000000000000 --- 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 c8fce13543c7..000000000000 --- 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 797c309dbb2c..000000000000 --- 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 a8fd0c82c688..000000000000 --- 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_sdk10/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_ios_sdk10/pubspec.yaml index e3603a04e423..387b927e9529 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 f468794f676d..8918af1d9e15 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/example/ios/Runner.xcodeproj/project.pbxproj b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/Runner.xcodeproj/project.pbxproj index 8a78da2b15ec..df7519a7282a 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 @@ -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_sdk9/example/ios/RunnerTests/CircleControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/CircleControllerTests.swift index 3bc49073a671..b65e95836cf5 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,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 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 888bdb1d4f4e..c28a6f1f74c8 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,6 +5,7 @@ import Flutter import GoogleMaps import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 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 585f4e128b95..b6970b5597fb 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,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 @@ -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.toCLLocationCoordinate2D() + #expect(location.latitude == 1) + #expect(location.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_sdk9/example/ios/RunnerTests/ExtractIconFromDataTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/ExtractIconFromDataTests.swift index 3eec318cb866..b9e05e9d51de 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,6 +4,7 @@ import Flutter import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 @@ -24,10 +25,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) @@ -52,10 +52,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) @@ -82,10 +81,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) #expect(testImage.scale == 1.0) @@ -117,10 +115,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == screenScale) @@ -144,10 +141,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) @@ -171,10 +167,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) @@ -198,10 +193,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == 10) @@ -226,10 +220,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) @@ -261,10 +254,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == screenScale) @@ -287,10 +279,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == 1.0) @@ -299,7 +290,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, createIcon returns nil for PinConfig, which is expected behavior. @Test func extractIconFromPinConfigWithGlyphColor() { let assetProvider = TestAssetProvider() @@ -318,10 +309,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: pinConfig), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: pinConfig).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) // PinConfig may return nil on old Google Maps SDK versions (<=8.4.0). @@ -347,10 +337,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: pinConfig), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: pinConfig).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) // PinConfig returns nil on iOS versions without GMSPinImageOptions support (< iOS 16.0). @@ -389,10 +378,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: pinConfig), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: pinConfig).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) // PinConfig returns nil on iOS versions without GMSPinImageOptions support (< iOS 16.0). @@ -406,43 +394,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_sdk9/example/ios/RunnerTests/GoogleMapsTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/GoogleMapsTests.swift index b3ceda9c58b5..5268b227e74e 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,6 +5,7 @@ import Flutter import GoogleMaps import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 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 a29701732465..8223f32486b3 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,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 @@ -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_sdk9/example/ios/RunnerTests/HeatmapControllerTests.swift b/packages/google_maps_flutter/google_maps_flutter_ios_sdk9/example/ios/RunnerTests/HeatmapControllerTests.swift index 060649855562..bbfe98e7857e 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,6 +5,7 @@ import GoogleMaps import GoogleMapsUtils import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 @@ -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 8957f6fa89fb..6cff56be74e0 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,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 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 bddd33f07577..4ce8f46fe6e2 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,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 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 3ad393d37109..6012e3d9d6e4 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,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 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 dbf1fceec6c1..000000000000 --- 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 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 79986f957947..97720ed2b333 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 2c8fa8248be6..5dec204caf45 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 889371b8df38..2f44cbfb166e 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,6 +4,7 @@ import GoogleMaps import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 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 bc2a6d1885bf..d17866f837a9 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,6 +5,7 @@ import Flutter import GoogleMaps import Testing +import google_maps_flutter_ios_sdk9_objc @testable import google_maps_flutter_ios_sdk9 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 362372a3f32a..cec0abb3cbbe 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 = 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_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 62340b9db559..5c6fea53c631 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 1c0f6dbbaf52..751cfee96d30 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,28 +2,286 @@ // 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 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) + } + + /// Returns the equivalent CLLocationCoordinate2D. + func toCLLocationCoordinate2D() -> CLLocationCoordinate2D { + return CLLocationCoordinate2D(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: [CLLocationCoordinate2D]) -> GMSMutablePath { + let path = GMSMutablePath() + for location in points { + path.add(location) } + return path +} - let markerIds = cluster.items.filter { $0 is GMSMarker }.compactMap { - markerIdentifierFromMarker($0 as! GMSMarker) +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 + } } +} - return FGMPlatformCluster.make( - withClusterManagerId: clusterManagerIdentifier, - position: FGMGetPigeonLatLngForCoordinate(cluster.position), - bounds: FGMGetPigeonLatLngBoundsForCoordinateBounds(bounds), - markerIds: markerIds - ) +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: nil)) + 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_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 68c16f7dbf93..06949262ec87 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 @@ -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_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 6b6d66bddf60..32a7c165b554 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,10 @@ 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 = platformGroundOverlay.image.createIcon( + assetProvider: assetProvider, + screenScale: screenScale + ) groundOverlay.bearing = platformGroundOverlay.bearing groundOverlay.opacity = Float(1.0 - platformGroundOverlay.transparency) if useBounds { @@ -220,11 +223,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_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 000000000000..10158847110a --- /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,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_sdk9_objc) + import google_maps_flutter_ios_sdk9_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_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 000000000000..25ad7c11d1fe --- /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,262 @@ +// 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 + +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") + + 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 + 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 = glyphBitmap.createIcon( + 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/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 417023190c33..c9c5a6f0712b 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,27 @@ 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 = platformMarker.icon.createIcon( + 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 +147,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 +231,7 @@ class MarkersController: NSObject { guard markerIdentifierToController[identifier] != nil else { return } eventDelegate?.didStartDragForMarker( withIdentifier: identifier, - atPosition: FGMGetPigeonLatLngForCoordinate(location) + atPosition: FGMPlatformLatLng.make(from: location) ) } @@ -237,7 +239,7 @@ class MarkersController: NSObject { guard markerIdentifierToController[identifier] != nil else { return } eventDelegate?.didDragMarker( withIdentifier: identifier, - atPosition: FGMGetPigeonLatLngForCoordinate(location) + atPosition: FGMPlatformLatLng.make(from: location) ) } @@ -245,7 +247,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_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 36ba6c91091d..a24da0fae3fb 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,12 @@ 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.path = makePath(from: platformPolygon.points.map({ $0.toCLLocationCoordinate2D() })) + polygon.holes = platformPolygon.holes.map { + makePath(from: $0.map({ $0.toCLLocationCoordinate2D() })) } - polygon.fillColor = FGMGetColorForPigeonColor(platformPolygon.fillColor) - polygon.strokeColor = FGMGetColorForPigeonColor(platformPolygon.strokeColor) + 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 dda82e6c7031..77116a5157e8 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 = makePath(from: platformPolyline.points.map({ $0.toCLLocationCoordinate2D() })) + 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_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 219d8df44a1b..000000000000 --- 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/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 49ec16dff827..000000000000 --- 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/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 03eb36eeb404..000000000000 --- 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/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 b7344e6b492e..000000000000 --- 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 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 c8fce13543c7..000000000000 --- 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 797c309dbb2c..000000000000 --- 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 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 a8fd0c82c688..000000000000 --- 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 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 2243b438b6d5..b1ad8871281e 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 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 063e12d4c3c3..5be000f1d2a9 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 bf24cecb1a37..0d2cf1f8a891 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 4e72b8fbc4c5..4c8f4d86b668 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.toCLLocationCoordinate2D() + #expect(location.latitude == 1) + #expect(location.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 da3978359e44..0b9e8c92feb7 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,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) @@ -52,10 +52,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) @@ -82,10 +81,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) #expect(testImage.scale == 1.0) @@ -117,10 +115,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == screenScale) @@ -144,10 +141,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) #expect(resultImage != nil) @@ -171,10 +167,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) @@ -198,10 +193,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == 10) @@ -226,10 +220,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) @@ -261,10 +254,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == screenScale) @@ -287,10 +279,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: bitmap), - TestAssetProvider(), - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: bitmap).createIcon( + assetProvider: TestAssetProvider(), + screenScale: screenScale ) #expect(resultImage != nil) #expect(resultImage?.scale == 1.0) @@ -299,7 +290,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, createIcon returns nil for PinConfig, which is expected behavior. @Test func extractIconFromPinConfigWithGlyphColor() { let assetProvider = TestAssetProvider() @@ -318,10 +309,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: pinConfig), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: pinConfig).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) // PinConfig may return nil on old Google Maps SDK versions (<=8.4.0). @@ -347,10 +337,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: pinConfig), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: pinConfig).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) // PinConfig returns nil on iOS versions without GMSPinImageOptions support (< iOS 16.0). @@ -389,10 +378,9 @@ import Testing let screenScale: CGFloat = 3.0 - let resultImage = FGMIconFromBitmap( - FGMPlatformBitmap.make(withBitmap: pinConfig), - assetProvider, - screenScale + let resultImage = FGMPlatformBitmap.make(withBitmap: pinConfig).createIcon( + assetProvider: assetProvider, + screenScale: screenScale ) // PinConfig returns nil on iOS versions without GMSPinImageOptions support (< iOS 16.0). @@ -406,43 +394,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 3d1e74a59dde..9178990a73ba 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 84110580525e..05ebaa988ce1 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 5cefabeef37a..649d7311b640 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 2aa8e9228e5b..4c3d751062ac 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 ad46bf96235e..921f095db538 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 ed693262a003..2b8d9d4f75a7 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 5a7800a1a7b8..000000000000 --- 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 9dc3fe4c1b4e..e32bc617a111 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 121738f6c540..e40d4244a163 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 4320f3a0fbbe..61c2e853bfcc 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 073d696f1906..e333c633c9cb 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 809bc3a9700d..4fdae6200fc6 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 5cd22b3bd78d..e4db55d05d34 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 04950aad2e08..eae05405897f 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,286 @@ // 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) + } + + /// Returns the equivalent CLLocationCoordinate2D. + func toCLLocationCoordinate2D() -> CLLocationCoordinate2D { + return CLLocationCoordinate2D(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: [CLLocationCoordinate2D]) -> GMSMutablePath { + let path = GMSMutablePath() + for location in points { + path.add(location) } + return path +} - let markerIds = cluster.items.filter { $0 is GMSMarker }.compactMap { - markerIdentifierFromMarker($0 as! GMSMarker) +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 + } } +} - return FGMPlatformCluster.make( - withClusterManagerId: clusterManagerIdentifier, - position: FGMGetPigeonLatLngForCoordinate(cluster.position), - bounds: FGMGetPigeonLatLngBoundsForCoordinateBounds(bounds), - markerIds: markerIds - ) +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 1759687bfc86..3349fb89ca37 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 8150d8c90542..e9c5778bbab0 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,10 @@ 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 = platformGroundOverlay.image.createIcon( + assetProvider: assetProvider, + screenScale: screenScale + ) groundOverlay.bearing = platformGroundOverlay.bearing groundOverlay.opacity = Float(1.0 - platformGroundOverlay.transparency) if useBounds { @@ -220,11 +223,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/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 000000000000..b8a3bc65c539 --- /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 000000000000..7fca86753c09 --- /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,260 @@ +// 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 + +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") + + 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 = glyphBitmap.createIcon( + 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_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 660853714313..c4880530e56a 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,27 @@ 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 = platformMarker.icon.createIcon( + 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 +147,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 +231,7 @@ class MarkersController: NSObject { guard markerIdentifierToController[identifier] != nil else { return } eventDelegate?.didStartDragForMarker( withIdentifier: identifier, - atPosition: FGMGetPigeonLatLngForCoordinate(location) + atPosition: FGMPlatformLatLng.make(from: location) ) } @@ -237,7 +239,7 @@ class MarkersController: NSObject { guard markerIdentifierToController[identifier] != nil else { return } eventDelegate?.didDragMarker( withIdentifier: identifier, - atPosition: FGMGetPigeonLatLngForCoordinate(location) + atPosition: FGMPlatformLatLng.make(from: location) ) } @@ -245,7 +247,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 bec60a0be0d7..9f2fcb58db72 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,12 @@ 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.path = makePath(from: platformPolygon.points.map({ $0.toCLLocationCoordinate2D() })) + polygon.holes = platformPolygon.holes.map { + makePath(from: $0.map({ $0.toCLLocationCoordinate2D() })) } - polygon.fillColor = FGMGetColorForPigeonColor(platformPolygon.fillColor) - polygon.strokeColor = FGMGetColorForPigeonColor(platformPolygon.strokeColor) + 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 3da57c4557b6..42d41cee189f 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.toCLLocationCoordinate2D() })) + 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 219d8df44a1b..000000000000 --- 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 49ec16dff827..000000000000 --- 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 03eb36eeb404..000000000000 --- 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 b7344e6b492e..000000000000 --- 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 c8fce13543c7..000000000000 --- 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 797c309dbb2c..000000000000 --- 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 a8fd0c82c688..000000000000 --- 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