2

I have close to 8.000 annotations in my map and I'd like to group them depending of the zoom that the user do in the app.

All the latitudes and longitudes are already into the CoreData as Double.

Case I have two different annotation images in the same point, I'd like to show two groups, one with the cross and one with the heart.

When the user click over the annotation and if this annotation is a grouped annotation, I'd like to show to the user how many annotations has at this location, "forcing" the user to zoom in to see the annotations individually.

Bellow are the images of my app and the current annotations.

Thank you!

enter image description here

enter image description here

enter image description here

enter image description here

2 Answers2

0

I already got it.

var zoomLevel = Double()
var iphoneScaleFactorLatitude = Double()
var iphoneScaleFactorLongitude = Double()
var CanUpdateMap: Bool = false

static func getLatitudeLongitudeLimitsFromMap(mapView: MKMapView) -> [String: Double] {
    var coord = [String: Double]()

    let MinLat: Double = mapView.region.center.latitude - (mapView.region.span.latitudeDelta / 2)
    let MaxLat: Double = mapView.region.center.latitude + (mapView.region.span.latitudeDelta / 2)
    let MinLon: Double = mapView.region.center.longitude - (mapView.region.span.longitudeDelta / 2)
    let MaxLon: Double = mapView.region.center.longitude + (mapView.region.span.longitudeDelta / 2)

    coord["MinLat"] = MinLat
    coord["MaxLat"] = MaxLat
    coord["MinLon"] = MinLon
    coord["MaxLon"] = MaxLon

    return coord
}

func LoadMap(mapView: MKMapView) {
    // Get the limits after move or resize the map
    let coord: [String: Double] = getLatitudeLongitudeLimitsFromMap(mapView)
    let MinLat: Double = coord["MinLat"]! as Double
    let MaxLat: Double = coord["MaxLat"]! as Double
    let MinLon: Double = coord["MinLon"]! as Double
    let MaxLon: Double = coord["MaxLon"]! as Double
    var arrAnnotations = [MKAnnotation]()

    let FilterMinLat = arrDicListPinsWithLatitudeLongitude.filter({
        if let item = $0["Latitude"] as? Double {
            return item > MinLat
        } else {
            return false
        }
    })
    let FilterMaxLat = FilterMinLat.filter({
        if let item = $0["Latitude"] as? Double {
            return item < MaxLat
        } else {
            return false
        }
    })
    let FilterMinLon = FilterMaxLat.filter({
        if let item = $0["Longitude"] as? Double {
            return item > MinLon
        } else {
            return false
        }
    })
    let FilterMaxLon = FilterMinLon.filter({
        if let item = $0["Longitude"] as? Double {
            return item < MaxLon
        } else {
            return false
        }
    })

    for Item in FilterMaxLon {
        let dic:[String:AnyObject] = Item
        var Name = String()
        var Address = String()
        var IconPNG = String()

        if let Latitude = dic["Latitude"] as? Double {
            if let Longitude = dic["Longitude"] as? Double {

                    if let item = dic["Name"] {
                        Name = item as! String
                    }
                    if let item = dic["Address"] {
                        Address = item as! String
                    }

                    if let item = dic["TypeID"] as? Int {
                        if item == 11 {
                            IconPNG = "icon-cross.png"
                        } else {
                            IconPNG = "icon-heart.png"
                        }
                    }
                    arrAnnotations.append(CreateAnnotation(Address, Title: Name, Latitude: Latitude, Longitude: Longitude, IconPNG: IconPNG))
                }
            }
        }
    }

    // Show in the map only the annotations from that specific region
    iphoneScaleFactorLatitude = mapView.region.center.latitude
    iphoneScaleFactorLongitude = mapView.region.center.longitude

    if zoomLevel != mapView.region.span.longitudeDelta {
        filterAnnotations(arrAnnotations)

        zoomLevel = mapView.region.span.longitudeDelta

        CanUpdateMap = true
    }
}

func filterAnnotations(arrAnnotations: [MKAnnotation]) {
    let latDelta: Double = 0.04 / iphoneScaleFactorLatitude
    let lonDelta: Double = 0.04 / iphoneScaleFactorLongitude
    var shopsToShow = [AnyObject]()
    var arrAnnotationsNew = [MKAnnotation]()

    for var i = 0; i < arrAnnotations.count; i++ {
        let checkingLocation: MKAnnotation = arrAnnotations[i]
        let latitude: Double = checkingLocation.coordinate.latitude
        let longitude: Double = checkingLocation.coordinate.longitude
        var found: Bool = false

        for tempPlacemark: MKAnnotation in shopsToShow as! [MKAnnotation] {
            if fabs(tempPlacemark.coordinate.latitude - latitude) < fabs(latDelta) && fabs(tempPlacemark.coordinate.longitude - longitude) < fabs(lonDelta) {
                found = true
            }
        }

        if !found {
            shopsToShow.append(checkingLocation)
            arrAnnotationsNew.append(checkingLocation)
        }
    }

    // Clean the map
    for item: MKAnnotation in self.mapRedes.annotations {
        myMap.removeAnnotation(item)
    }

    // Add new annotations to the map
    for item: MKAnnotation in arrAnnotationsNew {
        myMap.addAnnotation(item)
    }
}

func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
    // This validation should be added, because it will find all the annotations before the map resize
    if CanUpdateMap == true {
        LoadMap(mapView)
    }
}
0

Just a correction to my code:

//....

func LoadMap(mapView: MKMapView) {
    //....

    // Show in the map only the annotations from that specific region
    iphoneScaleFactorLatitude = Double(mapView.bounds.size.width / 30) // 30 = width of the annotation
    iphoneScaleFactorLongitude = Double(mapView.bounds.size.height / 30) // 30 = height of the annotation

    //....
}

func filterAnnotations(mapView: MKMapView, arrAnnotations: [MKAnnotation]) {
    let latDelta: Double = mapView.region.span.longitudeDelta / iphoneScaleFactorLatitude
    let lonDelta: Double = mapView.region.span.longitudeDelta / iphoneScaleFactorLongitude

    //....
}

//....