GMSOverlay zIndex issue on tap: Swift iOS Google Maps SDK - ios

I have been trying to implement GMSOverlay on map with overlapping overlays. Setting zIndex did work on displaying overlays on top of each other. But when tapping on top overlay, it is not working as it should. The one behind is overtaking tap.
Can someone help me debug and fix this issue:
Here is the code snippet of overlay implementation:
Overlay Custom class
class OrbisMapOverlayMarker: GMSGroundOverlay {
var mapPlaceBaseColor: UIColor!
var mapPlaceId: String!
var placeCoordinate: CLLocationCoordinate2D!
var lastCheckinTimeStamp: Date!
var radius: CLLocationDistance!
var fixedRadius: CLLocationDistance!
var imageView: UIImageView!
private var pulseMaxSize: CLLocationDistance = 100
var increment: CLLocationDistance = 10
private let maxSizeReference: CLLocationDistance = 100
private let referenceRadius: CLLocationDistance = 500
var fixedOpacity: Float = 1
var isProgressing = true
var imageUrlName: String = ""
init(bounds: GMSCoordinateBounds, icon: UIImage?, radius: CLLocationDistance) {
super.init()
self.imageView = UIImageView()
self.bounds = bounds
self.icon = icon
self.radius = radius
self.fixedRadius = radius
pulseMaxSize = (maxSizeReference / referenceRadius) * radius
increment = (maxSizeReference * 0.1 / referenceRadius) * radius
}
}
Implementation:
.
.
.
let placeSize = orbisPlace.calculatedSize
let clDistance = CLLocationDistance(placeSize)
let coordinate = CLLocationCoordinate2D(latitude: orbisPlace.coordinates?.latitude ?? 0, longitude: orbisPlace.coordinates?.longitude ?? 0)
let topLeftCoordinate = CLHelper.coordinate(from: coordinate, distance: -clDistance)
let bottomRightCoordinate = CLHelper.coordinate(from: coordinate, distance: clDistance)
let circleZIndex = Int32(1600 - placeSize)
var color = UIColor(named: AppColors.appBlue.rawValue)
if let colorHex = orbisPlace.placeDominantGroup?.strokeColorHexString {
color = UIColor.hexStringToUIColor(hex: colorHex)
}
let customMarker = OrbisMapOverlayMarker(bounds: GMSCoordinateBounds(coordinate: topLeftCoordinate, coordinate: bottomRightCoordinate), icon: nil, radius: clDistance)
let mapZoomRadius = mapView.getRadius()
customMarker.mapPlaceId = orbisPlace.placeKey
customMarker.position = CLLocationCoordinate2D(latitude: orbisPlace.coordinates?.latitude ?? 0, longitude: orbisPlace.coordinates?.longitude ?? 0)
let placeOpacity = Float(getPlaceCircleOpacity(forCircle: customMarker, withSize: placeSize, mapRadius: mapZoomRadius))
if let activeMarker = self.activeGlowOverlay {
if activeMarker.mapPlaceId == orbisPlace.placeKey {
customMarker.opacity = 1
customMarker.fixedOpacity = Float(1)
}
else {
customMarker.opacity = 0.1
customMarker.fixedOpacity = Float(0.1)
}
}
else {
customMarker.opacity = placeOpacity
customMarker.fixedOpacity = Float(placeOpacity)
}
customMarker.isTappable = true
mapMarkers.append(customMarker)
customMarker.icon = image
customMarker.zIndex = circleZIndex
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1, qos: .userInteractive, flags: .enforceQoS) {
customMarker.map = mapView
}
.
.
.
I have also submitted issue on map sdk repo:
https://github.com/googlemaps/maps-sdk-for-ios-samples/issues/118

Related

MKMapView - Show Customizable Gridlines

I want these lines to be visible on a regular map in such a way where each square represents 1x1m.
I looked into MKTileOverlay but didn't find too much about it. Is it possible to show the gridline on the map as well as change the color?
I've done something very similar for an app I've been playing around with. Mine is for putting a coloured grid over a map so that there are 15 columns and rows in a square mile around a home location, so you'll need to adjust the calculations for your distances but the same general approach should work. The app is only a prototype at the moment, and hasnt been optimised (could refactor code out of viewDidLoad for a start!), but the code should be good enough to get you started.
var homeLocation: CLLocationCoordinate2D!
let metresPerMile = 1609.344
var degPerHorizEdge: Double!
var degPerVertEdge: Double!
override func viewDidLoad() {
homeLocation = CLLocationCoordinate2D(latitude: 53.7011, longitude: -2.1071)
let hd = CLLocation(latitude: homeLocation.latitude, longitude: homeLocation.longitude).distance(from: CLLocation(latitude: homeLocation.latitude + 1, longitude: homeLocation.longitude))
let vd = CLLocation(latitude: homeLocation.latitude, longitude: homeLocation.longitude).distance(from: CLLocation(latitude: homeLocation.latitude, longitude: homeLocation.longitude + 1))
let degPerHMile = 1 / (hd / metresPerMile)
let degPerVMile = 1 / (vd / metresPerMile)
degPerHorizEdge = degPerHMile / 15
degPerVertEdge = degPerVMile / 15
super.viewDidLoad()
let gridController = GridController(for: gameID!)
gridController.delegate = self
let mapSize = CLLocationDistance(1.2 * metresPerMile)
let region = MKCoordinateRegion(center: homeLocation, latitudinalMeters: mapSize, longitudinalMeters: mapSize)
mapView.delegate = self
mapView.showsUserLocation = true
mapView.showsBuildings = true
mapView.mapType = .standard
mapView.setRegion(region, animated: true)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if let overlays = prepareOverlays() {
mapView.addOverlays(overlays)
}
}
func prepareOverlays() -> [MKPolygon]? {
let topLeft = CLLocationCoordinate2D(latitude: homeLocation.latitude - 7.5 * degPerHorizEdge, longitude: homeLocation.longitude - degPerVertEdge * 7.5)
var overlays = [MKPolygon]()
var locations = [CLLocationCoordinate2D]()
for y in 0...14 {
for x in 0...14 {
locations.append(CLLocationCoordinate2D(latitude: topLeft.latitude + Double(x) * degPerHorizEdge, longitude: topLeft.longitude + Double(y) * degPerVertEdge))
}
}
for coord in locations.enumerated() {
let location = coord.element
var corners = [location, //has to be a var due to using pointer in next line
CLLocationCoordinate2D(latitude: location.latitude + degPerHorizEdge, longitude: location.longitude),
CLLocationCoordinate2D(latitude: location.latitude + degPerHorizEdge, longitude: location.longitude + degPerVertEdge),
CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude + degPerVertEdge)]
let overlay = MKPolygon(coordinates: &corners, count: 4)
overlay.title = "\(coord.offset)"
overlays.append(overlay)
}
return overlays.count > 0 ? overlays : ni
}
//MARK:- MKMapViewDelegate
extension MapViewController: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
// overlay is a WSW zone
if let polygon = overlay as? MKPolygon {
let renderer = MKPolygonRenderer(polygon: polygon)
renderer.strokeColor = UIColor.gray.withAlphaComponent(0.4)
renderer.fillColor = UIColor.orange.withAlphaComponent(0.5)
renderer.lineWidth = 2
return renderer
}
// overlay is a line segment from the run (only remaining overlay type)
else {
let renderer = MKPolylineRenderer(polyline: overlay as! MKPolyline)
renderer.strokeColor = UIColor.blue.withAlphaComponent(0.8)
renderer.lineWidth = 3
return renderer
}
}
}

How to cluster custom icons markers in GoogleMaps for iOS

I'm developing an app on which I want to show a lot of event on the map. The user can click on an event and see a lot of information about it.
I customized the marker icon of each event with a custom image and now I want to cluster each custom markers.
I'm able to cluster the default icon of GoogleMaps API but if I want to cluster my own marker icon I'm not able to do it.
Here's my current code :
var mapView: GMSMapView!
var clusterManager: GMUClusterManager!
let isClustering: Bool = true
let isCustom: Bool = true
override func viewDidLoad() {
super.viewDidLoad()
mapView = GMSMapView(frame: view.frame)
mapView.camera = GMSCameraPosition.camera(withLatitude: 13.756331, longitude: 100.501765, zoom: 12.0)
mapView.mapType = .normal
mapView.delegate = self
view.addSubview(mapView)
if isClustering {
var iconGenerator: GMUDefaultClusterIconGenerator!
if isCustom { // Here's my image if the event are clustered
var images: [UIImage] = [UIImage(named: "m1.png")!, UIImage(named: "m2.png")!, UIImage(named: "m3.png")!, UIImage(named: "m4.png")!, UIImage(named: "m5.png")!]
iconGenerator = GMUDefaultClusterIconGenerator(buckets: [5, 10, 15, 20, 25], backgroundImages: images)
} else {
iconGenerator = GMUDefaultClusterIconGenerator()
}
let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
let renderer = GMUDefaultClusterRenderer(mapView: mapView, clusterIconGenerator: iconGenerator)
clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, renderer: renderer)
clusterManager.cluster()
clusterManager.setDelegate(self, mapDelegate: self)
} else {
}
// Here's my personal marker icon (for one location)
let firstLocation = CLLocationCoordinate2DMake(48.898902, 2.282664)
let marker = GMSMarker(position: firstLocation)
marker.icon = UIImage(named: "pointeurx1") //Apply custom marker
marker.map = mapView
let secondLocation = CLLocationCoordinate2DMake(48.924572, 2.360207)
let secondMarker = GMSMarker(position: secondLocation)
secondMarker.icon = UIImage(named: "pointeurx1")
secondMarker.map = mapView
let threeLocation = CLLocationCoordinate2DMake(48.841619, 2.253113)
let threeMarker = GMSMarker(position: threeLocation)
threeMarker.icon = UIImage(named: "pointeurx1")
threeMarker.map = mapView
let fourLocation = CLLocationCoordinate2DMake(48.858575, 2.294556)
let fourMarker = GMSMarker(position: fourLocation)
fourMarker.icon = UIImage(named: "pointeurx1")
fourMarker.map = mapView
let fiveLocation = CLLocationCoordinate2DMake(48.873819, 2.295200)
let fiveMarker = GMSMarker(position: fiveLocation)
fiveMarker.icon = UIImage(named: "pointeurx1")
fiveMarker.map = mapView
}
/// Point of Interest Item which implements the GMUClusterItem protocol.
class POIItem: NSObject, GMUClusterItem {
var position: CLLocationCoordinate2D
var name: String!
init(position: CLLocationCoordinate2D, name: String) {
self.position = position
self.name = name
}
}
func clusterManager(_ clusterManager: GMUClusterManager, didTap cluster: GMUCluster) {
let newCamera = GMSCameraPosition.camera(withTarget: cluster.position, zoom: mapView.camera.zoom + 1)
let update = GMSCameraUpdate.setCamera(newCamera)
mapView.moveCamera(update)
}
}
How can I do it?
Look at these screenshots of my app then maybe you could understand better my issue.
First one there are the red default markers icons of the Google Maps, you can see in blue the cluster icon I was added in my project. Then you understand I added some locations on the viewDidLoad(), then the red markers are that. You can also see two others differents markers, the google one is orange and another one is my personal marker icon that I want to use for each marker icon of a location. But you can also see the issue, the issue is the blue cluster icon don't add the markers icons I added on the map (it shows 4 inside the blue cluster icon, it's the 4 icons around it but when the blue cluster icon appears the markers icons around it don't disappear.
Second image, if I make a zoom, the blue cluster icon disappears but you can also see another issue, the locations I was added have another red default markers icons of the Google Maps appears above them (you can see it at less because of my personal orange marker icon
You are actually clustering first then adding markers thats why this is happening.
What you should actually do is
class MarkerModel: NSObject, GMUClusterItem {
var position: CLLocationCoordinate2D
var name: String
init(position: CLLocationCoordinate2D, name: String) {
self.position = position
self.name = name
}
}
override func viewDidLoad() {
super.viewDidLoad()
mapView = GMSMapView(frame: view.frame)
mapView.camera = GMSCameraPosition.camera(withLatitude: 13.756331, longitude: 100.501765, zoom: 12.0)
mapView.mapType = .normal
mapView.delegate = self
view.addSubview(mapView)
if isClustering {
var iconGenerator: GMUDefaultClusterIconGenerator!
if isCustom { // Here's my image if the event are clustered
var images: [UIImage] = [UIImage(named: "m1.png")!, UIImage(named: "m2.png")!, UIImage(named: "m3.png")!, UIImage(named: "m4.png")!, UIImage(named: "m5.png")!]
iconGenerator = GMUDefaultClusterIconGenerator(buckets: [5, 10, 15, 20, 25], backgroundImages: images)
} else {
iconGenerator = GMUDefaultClusterIconGenerator()
}
let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
let renderer = GMUDefaultClusterRenderer(mapView: mapView, clusterIconGenerator: iconGenerator)
clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, renderer: renderer)
} else {
}
}
func addMarkers(cameraLatitude : Float, cameraLongitude : Float) {
let extent = 0.01
for index in 1...clusterItemCount {
let lat = cameraLatitude + extent * randomScale()
let lng = cameraLongitude + extent * randomScale()
let name = "Item \(index)"
let position = CLLocationCoordinate2DMake(lat, lng)
let item = MarkerModel(position: position, name: name)
item.icon = #imageLiteral(resourceName: "marker")
clusterManager.add(item)
}
clusterManager.cluster()
clusterManager.setDelegate(self, mapDelegate: self)
}
func randomScale() -> Double {
return Double(arc4random()) / Double(UINT32_MAX) * 2.0 - 1.0
}
func renderer(_ renderer: GMUClusterRenderer, markerFor object: Any) -> GMSMarker? {
let marker = GMSMarker()
if let model = object as? MarkerModel {
// set image view for gmsmarker
}
return marker
}
func clusterManager(_ clusterManager: GMUClusterManager, didTap cluster: GMUCluster) -> Bool {
let newCamera = GMSCameraPosition.camera(withTarget: cluster.position, zoom: mapView.camera.zoom + 1)
let update = GMSCameraUpdate.setCamera(newCamera)
mapView.moveCamera(update)
return false
}

Calculate centre coordinate point for CLLocation array

How to calculate the centre point for MapView if we have multiple CLLocation points?
func zoomToFitPolyLine(pointsArr : NSArray) {
if (pointsArr.count == 0) {
return
}
var topLeftCoord : CLLocationCoordinate2D? = CLLocationCoordinate2DMake(-90, 180 )
var bottomRightCoord : CLLocationCoordinate2D? = CLLocationCoordinate2DMake(90, -180 )
for (index,_) in (pointsArr.enumerated()) {
let tempLoc : CLLocation? = pointsArr.object(at: index) as? CLLocation
topLeftCoord?.latitude = fmax((topLeftCoord?.latitude)!, (tempLoc?.coordinate.latitude)!)
topLeftCoord?.longitude = fmin((topLeftCoord?.longitude)!, (tempLoc?.coordinate.longitude)!)
bottomRightCoord?.latitude = fmin((bottomRightCoord?.latitude)!, (tempLoc?.coordinate.latitude)!)
bottomRightCoord?.longitude = fmax((bottomRightCoord?.longitude)!, (tempLoc?.coordinate.longitude)!)
}
var centerCoordinate : CLLocationCoordinate2D? = CLLocationCoordinate2DMake(0, 0)
centerCoordinate?.latitude = (topLeftCoord?.latitude)! - ((topLeftCoord?.latitude)! - (bottomRightCoord?.latitude)!) * 0.5;
centerCoordinate?.longitude = (topLeftCoord?.longitude)! + ((bottomRightCoord?.longitude)! - (topLeftCoord?.longitude)!) * 0.5;
self.zoomToRegion(location: centerCoordinate!)
}
func zoomToRegion(location:CLLocationCoordinate2D)
{
let camera : MKMapCamera = MKMapCamera.init(lookingAtCenter: location, fromEyeCoordinate: location, eyeAltitude: CLLocationDegrees(10));
myMap?.setCamera(camera, animated: true);
}

Swift - How Can I Show The MKPolyline For A Tracked Event

My problem is that when a jog has been completed, I can not present the recordedMapView with a full polyline that had tracked the location in an after exercise report.
Currently I am able to persist the data from tracking a run in the first view controller appearing in app, then in the detail view controller I fetch the data and unwrap/assign them to the respective variables, however, I am not sure where I go wrong in the code that is not allowing a polyline to appear. The map region does seem to be getting set properly as the map zooms in and out dynamically to fit the entire journey.
What could be the issue for why the polyline is not being presented and is there a solution to the code that I have provided to correct this problem?
var context : NSManagedObjectContext?
var runTimestamp : NSDate?
var runDuration : NSNumber?
var runDistance : NSNumber?
var runLocations : NSOrderedSet?
var locationTimeStamp : NSDate?
var locationLatitude : NSNumber?
var locationLongitude : NSNumber?
override func viewDidLoad()
{
super.viewDidLoad()
guard let context = context, finishedLocations = fetchLocation ( context ), finishedRun = fetchRun ( context ) else { return }
for location in finishedLocations
{
if let timestamp = location.timestamp, latitude = location.latitude, longitude = location.longitude
{
locationTimeStamp = timestamp
locationLatitude = latitude
locationLongitude = longitude
}
}
for run in finishedRun
{
if let timeStamp = run.timestamp, duration = run.duration, distance = run.distance, locations = run.locations
{
runTimestamp = timeStamp
runDuration = duration
runDistance = distance
runLocations = locations
}
}
updateUI ()
}
func loadMapView()
{
if runLocations!.count > 0
{
recordedMapView.region = mapRegion()
let colorSegments = MulticolorPolylineSegment.colorSegments(forLocations: runLocations!.array as! [Location])
recordedMapView.addOverlays(colorSegments)
}
else
{
let alertController = UIAlertController( title: "Error", message: "No Locations Saved", preferredStyle: .Alert )
let alertAction = UIAlertAction ( title: "Error", style : .Default , handler : nil )
alertController.addAction( alertAction )
presentViewController ( alertController, animated: true, completion: nil )
}
}
func mapRegion() -> MKCoordinateRegion
{
let initialLocation = runLocations!.firstObject as! Location
var minLat = initialLocation.latitude! .doubleValue
var minLng = initialLocation.longitude!.doubleValue
var maxLat = minLat
var maxLng = minLng
let locations = runLocations!.array as! [Location]
for location in locations
{
minLat = min( minLat, location.latitude! .doubleValue )
minLng = min( minLng, location.longitude!.doubleValue )
maxLat = max( maxLat, location.latitude! .doubleValue )
maxLng = max( maxLng, location.longitude!.doubleValue )
}
return MKCoordinateRegion(
center: CLLocationCoordinate2D( latitude : ( (minLat + maxLat)/2 ) , longitude : ( (minLng + maxLng)/2 ) ),
span : MKCoordinateSpan ( latitudeDelta: ( (maxLat - minLat)*1.1) , longitudeDelta: ( (maxLng - minLng)*1.1) )
)
}
func polyline() -> MKPolyline
{
var coordinates = [CLLocationCoordinate2D]()
let locations = runLocations!.array as! [Location]
for location in locations
{
coordinates.append( CLLocationCoordinate2D(latitude: (location.latitude!.doubleValue), longitude: (location.longitude!.doubleValue)) )
}
return MKPolyline(coordinates: &coordinates, count: runLocations!.count)
}
func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer
{
let polyline = overlay as! MulticolorPolylineSegment
let renderer = MKPolylineRenderer(polyline: polyline)
renderer.strokeColor = polyline.color
renderer.lineWidth = 3
return renderer
}
Swift 3.x:
What I see you don't add the polyLine properly into mapView.
Change your polyline function like below;
func polyline()
{
if theJourney != nil && theJourney!.coords != nil{
var coordinates = [CLLocationCoordinate2D]()
let locations = runLocations!.array as! [Location]
for location in locations
{
coordinates.append( CLLocationCoordinate2D(latitude: (location.latitude!.doubleValue), longitude: (location.longitude!.doubleValue)) )
}
}
let polyline = MKPolyline(coordinates: &coordinates, count: runLocations!.count)
mapView.add(polyline)
}
And MKMapView's rendererFor method with code below;
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = UIColor.green
renderer.lineWidth = 3
return renderer
}
That's should work. Please let me know.

Swift 2 MapKit Annotations - How to group annotations?

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!
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)
}
}
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
//....
}
//....

Resources