MapKit Display Annotation Clusters and Along With Non-Clustered Annotations
Asked Answered
B

0

3

I am new to iOS development and currently using the FBAnnotationClusteringSwift to cluster makers. My app needs to have two annotations which will not be clustered, as they indicate the source and destination addresses. The remaining annotations must be clustered as they represent stations.

What I want to achieve is something like the image bellow, where "A" is my source address, and the clusters represent stations:

That is my goal

However what is happening is, as the clusters are created, the Annotation that represents a non-clustered annotation (the source address) disappears as following:

Real

If the library is mixing all annotations together, that is pretty bad, there should be a way to separate those that I've added through clusteredAnnotationsWithinMapRect (stations) and those markers that were already added before (addresses). Here is the relevant part of the current code:

var markerClusterer: FBClusteringManager?

ViewController ... {

  override func viewDidLoad() {
    super.viewDidLoad()
    ...
    self.markerClusterer = FBClusteringManager()
    self.markerClusterer!.delegate = self
  }

  func cellSizeFactorForCoordinator(coordinator:FBClusteringManager) -> CGFloat{
    return 1.0
  }

  func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
      // Here is just like the example code from FBAnnotationClusterSwift
      var stations: [MKAnnotation] = fetchStations(...)
      if (stations.count > 0) {
          NSOperationQueue().addOperationWithBlock({
              let scale:Double = Double(self.mapView.bounds.size.width) / self.mapView.visibleMapRect.size.width
              self.markerClusterer!.addAnnotations(stations)
              var annotationArray = stations
              // Needed to do that otherwise the clusters never "explode" into pins
              if (scale <= 0.06) {
                  annotationArray = self.markerClusterer!.clusteredAnnotationsWithinMapRect(self.mapView.visibleMapRect, withZoomScale:scale)
              }
              self.markerClusterer!.displayAnnotations(annotationArray, onMapView: self.mapView)
            })
        }              
    }

    func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {

        var reuseId = ""

        if (annotation.isKindOfClass(FBAnnotationCluster)) {
            reuseId = "Cluster"
            var clusterView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)
            if clusterView == nil {
                clusterView = FBAnnotationClusterView(annotation: annotation, reuseIdentifier: reuseId, options: nil)
            } else {
                clusterView!.annotation = annotation
            }
            return clusterView
        } else if (annotation.isKindOfClass(AddressPointAnnotation)) {
            reuseId = "AddressPin"
            var addressPinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)
            if addressPinView == nil {
                addressPinView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
                addressPinView!.canShowCallout = true
            }
            else {
                addressPinView!.annotation = annotation
            }
            let addressPin = annotation as! AddressPointAnnotation
            addressPinView!.image = UIImage(named: addressPin.icon)
            return addressPinView
        } else if (annotation is Station) {
            reuseId = "StationPin"
            var stationPinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)
            if stationPinView == nil {
                stationPinView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
            }
            else {
                stationPinView!.annotation = annotation
            }
            let stationPin = annotation as! Station
            stationPinView!.image = UIImage(named: "station")
            return stationPinView
        } else {
            return nil
        }
    }

}

// Annotation for the stations
class Station: NSObject, MKAnnotation {
   var id: Int = 0
   var availableBikes: Int = 0
   var availableBikeStands: Int = 0
   var coordinate: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: 39.208407, longitude: -76.799555)
}

// Annotations for addresses
class AddressPointAnnotation: MKPointAnnotation {
  var icon: String!
}

class Address: NSObject {

    var marker: AddressPointAnnotation?

    func addMarker(coordinate: CLLocationCoordinate2D) {
        marker = AddressPointAnnotation()
        marker!.coordinate = coordinate
        // ViewController is passed to the Address, so it can add itself to the map
        self.controller.mapView.addAnnotation(marker!)
        if (self.direction == SOURCE) {
            marker!.title = "Starting address"
            marker!.icon = "from"
        } else {
            marker!.title = "Destination address"
            marker!.icon = "to"
        }
        self.controller.mapView.addAnnotation(marker!)
    }
}

Any help, idea, or comment is more than welcome. Thanks.

Bifrost answered 10/6, 2016 at 11:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.