Skip to content

Commit

Permalink
Merge pull request #38 from HudHud-Maps/cluster-touch
Browse files Browse the repository at this point in the history
Expand Clusters on Tap
  • Loading branch information
ianthetechie authored Jun 12, 2024
2 parents 780730d + 857c1ce commit 50673f0
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 0 deletions.
7 changes: 7 additions & 0 deletions Sources/MapLibreSwiftUI/Examples/Layers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ let clustered = ShapeSource(identifier: "points", options: [.clustered: true, .c
.iconColor(.white)
.predicate(NSPredicate(format: "cluster != YES"))
}
.onTapMapGesture(on: ["simple-circles-non-clusters"], onTapChanged: { _, features in
print("Tapped on \(features.first)")
})
.expandClustersOnTapping(clusteredLayers: [ClusterLayer(
layerIdentifier: "simple-circles-clusters",
sourceIdentifier: "points"
)])
.ignoresSafeArea(.all)
}

Expand Down
34 changes: 34 additions & 0 deletions Sources/MapLibreSwiftUI/Extensions/MapView/MapViewGestures.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,29 @@ extension MapView {
return
}

if let clusteredLayers {
if let gestureRecognizer = sender as? UITapGestureRecognizer, gestureRecognizer.numberOfTouches == 1 {
let point = gestureRecognizer.location(in: sender.view)
for clusteredLayer in clusteredLayers {
let features = mapView.visibleFeatures(
at: point,
styleLayerIdentifiers: [clusteredLayer.layerIdentifier]
)
if let cluster = features.first as? MLNPointFeatureCluster,
let source = mapView.style?
.source(withIdentifier: clusteredLayer.sourceIdentifier) as? MLNShapeSource
{
let zoomLevel = source.zoomLevel(forExpanding: cluster)

if zoomLevel > 0 {
mapView.setCenter(cluster.coordinate, zoomLevel: zoomLevel, animated: true)
break // since we can only zoom on one thing, we can abort the for loop here
}
}
}
}
}

// Process the gesture into a context response.
let context = processContextFromGesture(mapView, gesture: gesture, sender: sender)
// Run the context through the gesture held on the MapView (emitting to the MapView modifier).
Expand Down Expand Up @@ -97,3 +120,14 @@ extension MapView {
coordinate: mapView.convert(point, toCoordinateFrom: mapView))
}
}

/// Provides the layer identifier and it's source identifier.
public struct ClusterLayer {
public let layerIdentifier: String
public let sourceIdentifier: String

public init(layerIdentifier: String, sourceIdentifier: String) {
self.layerIdentifier = layerIdentifier
self.sourceIdentifier = sourceIdentifier
}
}
2 changes: 2 additions & 0 deletions Sources/MapLibreSwiftUI/MapView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public struct MapView: UIViewRepresentable {

private var locationManager: MLNLocationManager?

var clusteredLayers: [ClusterLayer]?

public init(
styleURL: URL,
camera: Binding<MapViewCamera> = .constant(.default()),
Expand Down
12 changes: 12 additions & 0 deletions Sources/MapLibreSwiftUI/MapViewModifiers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,18 @@ public extension MapView {
return newMapView
}

/// Add a default implementation for tapping clustered features. When tapped, the map zooms so that the cluster is
/// expanded.
/// - Parameter clusteredLayers: An array of layers to monitor that can contain clustered features.
/// - Returns: The modified MapView
func expandClustersOnTapping(clusteredLayers: [ClusterLayer]) -> MapView {
var newMapView = self

newMapView.clusteredLayers = clusteredLayers

return newMapView
}

func mapViewContentInset(_ inset: UIEdgeInsets) -> Self {
var result = self

Expand Down

0 comments on commit 50673f0

Please sign in to comment.