// // Copyright Amazon.com Inc. or its affiliates. // All Rights Reserved. // // SPDX-License-Identifier: Apache-2.0 // import Foundation import CoreLocation import Mapbox import SwiftUI public extension AMLMapView { /// View modifier to enable showing the user's location on the map. /// /// To access the user's locaiton, location access must be enabled in the app, and /// the user must choose to allow access. /// - Parameter showLocation: Enables showing the user's location on the map. /// - Returns: An instance of `AMLMapView`. func showUserLocation(_ showLocation: Bool) -> AMLMapView { mapSettings.showUserLocation = showLocation return self } /// View modifier to set the map's maximum and minimum zoom levels. /// /// Zoom Level Approximation Reference: /// - 0 -> The Earth /// - 3 -> A continent /// - 4 -> Large islands /// - 6 -> Large rivers /// - 10 -> Large roads /// - 15 -> Buildings /// /// - Parameter zoomLevels: A closed range of `Double` where the lower bound is the min and /// the upper bound the max zoom level. /// - Important: /// The minimum allowable zoom level is 0 and the maximum allowable zoom level is 22. /// Any value set below 0 or above 22 will revert to 0 or 22 accordingly. /// - Returns: An instance of `AMLMapView`. func allowedZoomLevels(_ zoomLevels: ClosedRange) -> AMLMapView { mapSettings.minZoomLevel = max(zoomLevels.lowerBound, 0) mapSettings.maxZoomLevel = min(zoomLevels.upperBound, 22) return self } /// View modifier to set the map's maximum zoom level. /// /// Zoom Level Approximation Reference: /// - 0 -> The Earth /// - 3 -> A continent /// - 4 -> Large islands /// - 6 -> Large rivers /// - 10 -> Large roads /// - 15 -> Buildings /// /// - Parameter maxZoomLevel: The maximum zoom level allowed by the map. /// - Important: /// The maximum zoom level is 22. Any value set above 22 will revert to 22. /// - Returns: An instance of `AMLMapView`. func maxZoomLevel(_ maxZoomLevel: Double) -> AMLMapView { mapSettings.maxZoomLevel = min(maxZoomLevel, 22) return self } /// View modifier to set the map's minimum zoom level. /// /// Zoom Level Approximation Reference: /// - 0 -> The Earth /// - 3 -> A continent /// - 4 -> Large islands /// - 6 -> Large rivers /// - 10 -> Large roads /// - 15 -> Buildings /// /// - Parameter minZoomLevel: The minimum zoom level allowed by the map. /// - Important: /// The minimum allowable zoom level is 0. Any value set below 0 revert to 0. /// - Returns: An instance of `AMLMapView`. func minZoomLevel(_ minZoomLevel: Double) -> AMLMapView { mapSettings.minZoomLevel = max(minZoomLevel, 0) return self } /// Provide an SwiftUI view that represents a point on a map. /// /// - Important: Because the underlying `MGLMapView` consumes `UIImage`s, /// this method turns a `SwiftUI` view into a `UIImage`. /// There may be hidden cost to using this. If you experience performance and / or /// rendering issues, please use the `featureImage(_:)` view modifier instead. /// - Parameter view: The view to be displayed. /// - Returns: An instance of `AMLMapView`. func featureView(_ view: () -> T) -> AMLMapView { mapSettings.featureImage = view().snapshot() return self } /// Provide an UIImage that represents a point on a map. /// - Parameter image: The image to be displayed. /// - Returns: An instance of `AMLMapView`. func featureImage(_ image: () -> UIImage) -> AMLMapView { mapSettings.featureImage = image() return self } /// Define the behavior when a feature is tapped. /// /// The default implementation pans the feature to the center of the screen and presents an `AMLCalloutView`. /// Defining an implementation here will override this behavior. /// /// - Parameter implementation: Closure provided a `MGLMapView` and `MGLPointFeature`. /// Define your desired behavior on the `mapView` using information from the `pointFeature` as needed. /// - Returns: An instance of `AMLMapView`. func featureTapped( _ implementation: @escaping ( _ mapView: MGLMapView, _ pointFeature: MGLPointFeature ) -> Void ) -> AMLMapView { mapSettings.proxyDelegate.featureTapped = implementation return self } /// Define the behavior when a feature cluster is tapped. /// /// The default implementation zooms in on the map. /// Defining an implementation here will override this behavior. /// /// - Parameter implementation: Closure provided a `MGLMapView` and `MGLPointFeatureCluster`. /// Define your desired behavior on the `mapView` using information from the `pointFeatureCluster` as needed. /// - Returns: An instance of `AMLMapView`. func featureClusterTapped( _ implementation: @escaping ( _ mapView: MGLMapView, _ pointFeatureCluster: MGLPointFeatureCluster ) -> Void ) -> AMLMapView { mapSettings.proxyDelegate.clusterTapped = implementation return self } /// Set the position of the compass on the `MGLMapView`. /// - Parameter position: `MGLOrnamentPosition` defining the location. /// - Returns: An instance of `AMLMapView`. func compassPosition(_ position: MGLOrnamentPosition) -> AMLMapView { mapSettings.compassPosition = position return self } /// Set whether the map features should cluster. /// - Parameter shouldCluster: Features displayed on the map should cluster. /// Corresponds to the `MGLShapeSourceOption` `.clustered`. /// - Returns: An instance of `AMLMapView`. func shouldCluster(_ shouldCluster: Bool) -> AMLMapView { mapSettings.clusteringBehavior.shouldCluster = shouldCluster return self } /// Specifies the maximum zoom level at which to cluster points if clustering is enabled. /// - Parameter maxZoom: The maximum zoom level of clustering. /// Corresponds to `MGLShapeSourceOption` `.maximumZoomLevelForClustering`. /// - Returns: An instance of `AMLMapView`. func maximumClusterZoomLevel(_ maxZoom: Int) -> AMLMapView { mapSettings.clusteringBehavior.maximumZoomLevel = maxZoom return self } /// Set the fill color of the circle cluster. /// - Parameter color: The fill color of the circle cluster. /// Sets the `MGLCircleStyleLayer` `circleColor` property. /// - Returns: An instance of `AMLMapView`. func clusterColor(_ color: UIColor) -> AMLMapView { mapSettings.clusteringBehavior.clusterColor = color return self } /// The text color of the number displayed in the circle cluster. /// - Parameter color: The color of text displaying the number within a cluster. /// Sets the `MGLSymbolStyleLayer` `textColor` property. /// - Returns: An instance of `AMLMapView`. func clusterNumberColor(_ color: UIColor) -> AMLMapView { mapSettings.clusteringBehavior.clusterNumberColor = color return self } /// Set colors for different cluster steps. /// - Parameter steps: Dictionary representation of cluster color steps where the /// `key` is the number of features in a cluster and the `value` is the color for that corresponding number /// - Returns: An instance of `AMLMapView`. func clusterColorSteps(_ steps: [Int: UIColor]) -> AMLMapView { mapSettings.clusteringBehavior.clusterColorSteps = steps return self } /// Set the radius of each cluster if clustering is enabled. /// - Parameter radius: The cluster radius. /// Corresponds to the `MGLShapeSourceOption` `.clusterRadius`. /// - Returns: An instance of `AMLMapView`. func clusterRadius(_ radius: Int) -> AMLMapView { mapSettings.clusteringBehavior.clusterRadius = radius return self } }