I am having a hard time finding examples for mapbox sdk iOS v10 annotation clustering. Everything seems to be outdated. Using print statement it seems that the annotations are now clustering, but nothing displays on the map anymore. I am having trouble, this is my code.
class MapViewController: UIViewController {
internal var mapView: MapView!
var initialCamera: CameraOptions?
var locationToAnnotation: [CLLocation: CustomAnnotationWrapper] = [:]
var blockedFeed: [String] = []
var blockedFeeder: [String] = []
var mapUser: String = ""
override public func viewDidLoad() {
super.viewDidLoad()
let myResourceOptions = ResourceOptions(accessToken: "xxxxxxxxxxx")
let cameraOptions = CameraOptions(center: CLLocationCoordinate2D(latitude: 39.8, longitude: -86.2), zoom: 9, bearing: 0, pitch: 0)
let styleURI = StyleURI(rawValue: "mapbox://styles/xxxxxxxxx")
let myMapInitOptions = MapInitOptions(resourceOptions: myResourceOptions, cameraOptions: cameraOptions, styleURI: styleURI)
mapView = MapView(frame: view.bounds, mapInitOptions: myMapInitOptions)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.location.options.puckType = .puck2D()
mapView.annotations.makePointAnnotationManager().delegate = self
mapView.gestures.options.rotateEnabled = false
mapView.gestures.options.pitchEnabled = false
self.view.addSubview(mapView)
if let initialCamera = initialCamera {
mapView.camera.fly(to: initialCamera, duration: 1)
}
fetchPublic()
}
func fetchPublic(){
let pointManager = self.mapView.annotations.makePointAnnotationManager()
var clusters: [AnnotationCluster] = []
var clusterAnnotations: [AnnotationCluster] = []
let publicDB = CKContainer.default().publicCloudDatabase
let date = NSDate(timeInterval: 12 * 3600, since: NSDate() as Date)
let date1 = NSDate()
let predicate = NSPredicate(format: "start < %@ && end > %@", date, date1)
let query = CKQuery(recordType: "event", predicate:predicate)
publicDB.fetch(withQuery: query, inZoneWith: nil)
{ result in
switch result {
case .success((let matchResults, _)):
for matchResult in matchResults {
switch matchResult.1 {
case .success(let record):
if let location = record["location1"] as? CLLocation
{
let identified = record.recordID
var point = PointAnnotation(point: Point(LocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)))
point.image = .init(image: UIImage(named: "Image 2")!, name: "Image 2")
point.iconAnchor = .bottom
if let recordName = record["name"] as? String{
point.textField = recordName
point.textAnchor = .top
point.textSize = 10
}
let customAnnotation = CustomAnnotationWrapper(annotation: point, recordID: identified, identifier: UUID().uuidString)
var addedToCluster = false
for (index, cluster) in clusters.enumerated() {
let clusterLocation = CLLocation(latitude: cluster.center.latitude, longitude: cluster.center.longitude)
let annotationLocation = CLLocation(latitude: point.point.coordinates.latitude, longitude: point.point.coordinates.longitude)
let clusteringDistanceThreshold = 50.0
let distance = clusterLocation.distance(from: annotationLocation)
if distance < clusteringDistanceThreshold {
clusters[index].annotations.append(customAnnotation)
addedToCluster = true
break
}
}
if !addedToCluster {
clusters.append(AnnotationCluster(center: point.point.coordinates, annotations: [customAnnotation]))
print("clustering\(clusters)")
}
//
DispatchQueue.main.async {
for annotation in pointManager.annotations {
var addedToCluster = false
for (index, cluster) in clusterAnnotations.enumerated() {
let clusterLocation = CLLocation(latitude: cluster.center.latitude, longitude: cluster.center.longitude)
let annotationLocation = CLLocation(latitude: annotation.point.coordinates.latitude, longitude: annotation.point.coordinates.longitude)
let clusteringDistanceThreshold = 50.0
let distance = clusterLocation.distance(from: annotationLocation)
if distance < clusteringDistanceThreshold {
let customAnnotationWrapper = CustomAnnotationWrapper(annotation: annotation, recordID: nil, identifier: UUID().uuidString)
clusterAnnotations[index].annotations.append(customAnnotationWrapper)
addedToCluster = true
break
}
}
if !addedToCluster {
let customAnnotationWrapper = CustomAnnotationWrapper(annotation: annotation, recordID: nil, identifier: UUID().uuidString)
clusterAnnotations.append(AnnotationCluster(center: annotation.point.coordinates, annotations: [customAnnotationWrapper]))
}
}
for cluster in clusterAnnotations {
if cluster.annotations.count > 1 {
var clusterAnnotation = PointAnnotation(point: Point(LocationCoordinate2D(latitude: cluster.center.latitude, longitude: cluster.center.longitude)))
clusterAnnotation.image = .init(image: UIImage(named: "red_pin")!, name: "red_pin")
clusterAnnotation.iconAnchor = .bottom
pointManager.annotations.append(clusterAnnotation)
}
for (index, cluster) in clusters.enumerated() {
let clusterLocation = CLLocation(latitude: cluster.center.latitude, longitude: cluster.center.longitude)
let annotationLocation = CLLocation(latitude: point.point.coordinates.latitude, longitude: point.point.coordinates.longitude)
let clusteringDistanceThreshold = 50.0
let distance = clusterLocation.distance(from: annotationLocation)
if distance < clusteringDistanceThreshold {
clusters[index].annotations.append(customAnnotation)
addedToCluster = true
break
}
}
if !addedToCluster {
let newCluster = AnnotationCluster(center: point.point.coordinates, annotations: [customAnnotation])
clusters.append(newCluster)
}
}
pointManager.delegate = self
}
//
/*
DispatchQueue.main.async {
pointManager.annotations.append(point)
pointManager.delegate = self
self.locationToAnnotation[CLLocation(latitude: point.point.coordinates.latitude, longitude: point.point.coordinates.longitude)] = customAnnotation
}
*/
}
}
}
case .failure(let error): print(error)
}
}
case .failure(let error): print(error)
}
}
}
func fetchPrivateMap(){
let pointManager = self.mapView.annotations.makePointAnnotationManager()
let publicDB = CKContainer.default().publicCloudDatabase
let date = NSDate()
let predicate = NSPredicate(format: "endtime > %@", date)
let query = CKQuery(recordType: "private", predicate: predicate)
publicDB.fetch(withQuery: query, inZoneWith: nil)
{ result in
switch result {
case .success((let matchResults, _)):
for matchResult in matchResults {
switch matchResult.1 {
case .success(let record):
if let listed = record["invites"] as? [String],
let location = record["location2"] as? CLLocation,
let phost = record["host"] as? String
{
let identified = record.recordID
for attendant in listed{
if self.mapUser == attendant || self.mapUser == phost{
var point = PointAnnotation(point: Point(LocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)))
point.image = .init(image: UIImage(named: "red_pin")!, name: "red_pin")
point.iconAnchor = .bottom
if let recordName = record["title"] as? String{
point.textField = recordName
point.textAnchor = .top
point.textSize = 10
}
let customAnnotation = CustomAnnotationWrapper(annotation: point, recordID: identified, identifier: UUID().uuidString)
DispatchQueue.main.async {
pointManager.annotations.append(point)
pointManager.delegate = self
self.locationToAnnotation[CLLocation(latitude: point.point.coordinates.latitude, longitude: point.point.coordinates.longitude)] = customAnnotation
}
}
}
}
case .failure(let error): print(error)
}
}
case .failure(let error): print(error)
}
}
}
}
//
struct ClusterCenter: Hashable {
let latitude: Double
let longitude: Double
init(_ coordinate: CLLocationCoordinate2D) {
self.latitude = coordinate.latitude
self.longitude = coordinate.longitude
}
}
//
struct AnnotationCluster {
let center: CLLocationCoordinate2D
var annotations: [CustomAnnotationWrapper]
}
class CustomAnnotationWrapper {
var annotation: PointAnnotation
let recordID: CKRecord.ID?
let identifier: String
init(annotation: PointAnnotation, recordID: CKRecord.ID?, identifier: String) {
self.annotation = annotation
self.recordID = recordID
self.identifier = identifier
}
}
extension MapViewController: AnnotationInteractionDelegate {
func annotationManager(_ manager: MapboxMaps.AnnotationManager, didDetectTappedAnnotations annotations: [MapboxMaps.Annotation]) {
if let pointAnnotation = annotations.first as? PointAnnotation {
let tappedLocation = CLLocation(latitude: pointAnnotation.point.coordinates.latitude, longitude: pointAnnotation.point.coordinates.longitude)
if let closestAnnotation = locationToAnnotation.min(by: { (a, b) -> Bool in
return a.key.distance(from: tappedLocation) < b.key.distance(from: tappedLocation)
}) {
let customAnnotation = closestAnnotation.value
let recordID = customAnnotation.recordID
let sheetView = EventView(eventLoc: pointAnnotation.point.coordinates, identify: recordID!)
let hostingController = UIHostingController(rootView: sheetView)
hostingController.modalPresentationStyle = .popover
present(hostingController, animated: true, completion: nil)
} else {
print("Custom annotation not found")
}
}
}
private func presentSheet<Content: View>(with content: Content) {
let sheet = UIHostingController(rootView: content)
sheet.modalPresentationStyle = .popover
present(sheet, animated: true, completion: nil)
}
}
struct MapBoxMapView: UIViewControllerRepresentable {
@Binding var reloadMap: Bool
@ObservedObject var locationManager: LocationManager
func makeUIViewController(context: Context) -> MapViewController {
locationManager.requestLoc()
let viewController = MapViewController()
viewController.initialCamera = CameraOptions(center: locationManager.eventLocation.coordinate, zoom: 9)
return viewController
//return MapViewController()
}
func updateUIViewController(_ uiViewController: MapViewController, context: Context) {
if reloadMap {
uiViewController.initialCamera = CameraOptions(center: locationManager.eventLocation.coordinate, zoom: 9)
uiViewController.viewDidLoad()
DispatchQueue.main.async {
self.reloadMap = false
}
}
}
}