如何在mapview上进行缩放时更新注释?

时间:2016-08-03 08:39:10

标签: swift mkmapview mapkit mkannotation

我正在尝试创建一个应用,您可以从Web API获取总线位置。当我得到数据时,我在mapview上为我从API获得的所有坐标添加了注释。然后,当点击注释时,我试图隐藏所有注释,这些注释与点击的注释不在同一条路线上。它工作正常,但是当我缩小原始区域中没有隐藏的注释时。有没有办法刷新用户放大地图视图时显示的内容?

import UIKit
import MapKit
import MBProgressHUD
import Alamofire


class MapViewController: UIViewController {

//MARK: Properties and Outlets

private var timer: NSTimer?

private lazy var dateFormatter = NSDateFormatter()

private var vehicles = [String: Vehicle]()

private var points = [CLLocationCoordinate2D]()

private let locationManager = CLLocationManager()

private var currentLocation: CLLocation?

@IBOutlet weak var mapView: MKMapView!


//MARK: Actions

@IBAction func getMyLocation(sender: UIBarButtonItem) {
    getLocation()
}

//MARK: Life Cycle

override func viewDidLoad() {
    super.viewDidLoad()

    dateFormatter.locale = NSLocale.currentLocale()
    dateFormatter.dateFormat = "HH:mm:ss"

    timer = NSTimer.scheduledTimerWithTimeInterval(30, target: self, selector: "fetchVehiclesLocations", userInfo: nil, repeats: true)
    fetchVehiclesLocations()

    getLocation()
}

//MARK: Get Location

private func getLocation() {

    let authStatus = CLLocationManager.authorizationStatus()

    if authStatus == .NotDetermined {
        locationManager.requestWhenInUseAuthorization()
        return
    }
    if authStatus == .Denied || authStatus == .Restricted {
        showLocationServicesDeniedAlert()
        return
    }

    startLocationManager()
}


//MARK: Helper methods

private func showLocationServicesDeniedAlert() {
    let alert = UIAlertController(title: "Location Services Disabled", message: "Please enable location services for this app in Settings.", preferredStyle: .Alert)

    let okAction = UIAlertAction(title: "OK", style: .Default, handler: nil)

    alert.addAction(okAction)

    presentViewController(alert, animated: true, completion: nil)
}

private func startLocationManager () {
    if CLLocationManager.locationServicesEnabled() {
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
        locationManager.startUpdatingLocation()
        showLoadingHUD()
    }
}

private func stopLocationManager() {
    locationManager.delegate = nil
    locationManager.stopUpdatingLocation()
    hideLoadingHUD()
}




private func rotateBus() {

    UIView.animateWithDuration(1.0, delay: 0, options: .CurveLinear, animations: {
        for (id, _) in self.vehicles {
            if self.vehicles[id]!.lastPosition != nil {
                let annotationView = self.mapView.viewForAnnotation(self.vehicles[id]!.annotation!)
                let currentLocationPoint = self.mapView.convertCoordinate(self.vehicles[id]!.lastPosition!, toPointToView: self.mapView)
                let destinationPoint = self.mapView.convertCoordinate(self.vehicles[id]!.coordinates, toPointToView: self.mapView)
                let yDiff = currentLocationPoint.y - destinationPoint.y
                let xDiff = destinationPoint.x - currentLocationPoint.x
                let arcTan = atan(yDiff / xDiff)
                var angle = CGFloat(M_PI / 2) - arcTan
                if xDiff < 0 {
                    angle = angle + CGFloat(M_PI)
                }
                if angle.isNaN || angle == 0.0 {
                    continue
                }
                else {
                    annotationView?.transform = CGAffineTransformMakeRotation(CGFloat(angle))
                }
            }
        }
        }, completion: nil)

    moveBus()
}

private func moveBus() {

    UIView.animateWithDuration(28.0, delay: 0, options: .CurveLinear, animations: {
        for(id, _) in self.vehicles {
            if self.vehicles[id]!.lastPosition != nil {
                self.vehicles[id]!.annotation?.coordinate = self.vehicles[id]!.coordinates
            }
        }
        }, completion: nil)
}


private func createVehicles() {
    print(vehicles.count)
    for (id, _) in vehicles {
        if vehicles[id]?.annotation == nil {
            let annotation = BusAnnotation()
            annotation.imageName = "bus"
            annotation.coordinate = vehicles[id]!.coordinates
            annotation.title = id
            vehicles[id]?.annotation = annotation
            mapView.addAnnotation(annotation)
        }
    }
    print(mapView.annotations.count)
    rotateBus()
}

private func drawPolyline() {
    let myPolyline = MKPolyline(coordinates: &points, count: points.count)
    mapView.addOverlay(myPolyline)
}

//MARK: HUD display methods

private func showLoadingHUD() {
    let hud = MBProgressHUD.showHUDAddedTo(mapView, animated: true)
    hud.labelText = "Getting Your Location..."
}

private func hideLoadingHUD() {
    MBProgressHUD.hideAllHUDsForView(mapView, animated: true)
}

//MARK: Networking

func fetchVehiclesLocations() {
    let URL = urlVehiclesLocations + apiKey

    if !vehicles.isEmpty {
        for (id , _) in vehicles {
            vehicles[id]?.lastPosition = vehicles[id]?.coordinates
        }
    }

    Alamofire.request(.GET, URL)
        .validate()
        .responseJSON {
            (request, response, result) in

            guard result.isSuccess else {
                print("Error while fetching \(result.error!)")
                return
            }

            let value = result.value as? [String: AnyObject]
            let responseDict = value?["response"] as? [String: AnyObject]
            let array = responseDict?["entity"] as? [[String: AnyObject]]

            for var i = 0; i < array?.count; i++ {
                let item = array?[i]["vehicle"] as? [String: AnyObject]
                let position = item?["position"] as? [String: AnyObject]
                let trip = item?["trip"] as? [String: AnyObject]
                let vehicle = Vehicle()
                vehicle.latitude = position?["latitude"] as! Double
                vehicle.longitude = position?["longitude"] as! Double
                vehicle.tripId = trip?["trip_id"] as! String
                let startTime = trip?["start_time"] as! String
                vehicle.startTime = self.dateFormatter.dateFromString(startTime)
                let vehicleId = item?["vehicle"] as? [String: AnyObject]
                let id = vehicleId?["id"] as! String
                if self.vehicles[id] == nil {
                    self.vehicles[id] = vehicle
                }
                else {
                    self.vehicles[id]?.latitude = vehicle.latitude
                    self.vehicles[id]?.longitude = vehicle.longitude
                }
            }
            self.createVehicles()
    }
}

func fetchPointsForTripPolyline() {
    let URL = urlTripPolyline + apiKey

    Alamofire.request(.GET, URL)
        .validate()
        .responseJSON {
            (request, response, result) in

            guard result.isSuccess else {
                print("Error while fetching \(result.error!)")
                return
            }

            let value = result.value as! [String: AnyObject]
            let responseArray = value["response"] as! [[String: AnyObject]]
            for var i = 0; i < responseArray.count; i++ {
                let longitude = responseArray[i]["shape_pt_lon"] as! CLLocationDegrees
                let latitude = responseArray[i]["shape_pt_lat"] as! CLLocationDegrees
                let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
                self.points.append(coordinate)
            }

            self.drawPolyline()
    }
}
}
extension MapViewController: CLLocationManagerDelegate {
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let newLocation = locations.last!

    if newLocation.timestamp.timeIntervalSinceNow < -5 {
        return
    }

    if newLocation.horizontalAccuracy < 0 {
        return
    }

    if newLocation.horizontalAccuracy <= locationManager.desiredAccuracy {
        stopLocationManager()
        currentLocation = newLocation
        let annotation = MKPointAnnotation()
        annotation.coordinate = newLocation.coordinate
        mapView.addAnnotation(annotation)
    }

    let center = CLLocationCoordinate2D(latitude: newLocation.coordinate.latitude, longitude: newLocation.coordinate.longitude)
    let region = MKCoordinateRegionMakeWithDistance(center, 1000, 1000)

    self.mapView.setRegion(region, animated: true)
}
}

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

    if !(annotation is BusAnnotation) {
        return nil
    }

    let reuseId = annotation.title!

    var busAnnotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId!)

    if busAnnotationView == nil {
        busAnnotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
        busAnnotationView?.canShowCallout = true
    }
    else {
        busAnnotationView?.annotation = annotation
    }

    let busAnnotation = annotation as! BusAnnotation

    busAnnotationView?.image = UIImage(named: busAnnotation.imageName)

    return busAnnotationView
}

func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
    if overlay is MKPolyline {
        let lineView = MKPolylineRenderer(overlay: overlay)
        lineView.lineWidth = 3.0
        lineView.strokeColor = UIColor.greenColor()
        return lineView
    }

    return MKOverlayRenderer()
}

func hideBuses(tripId: String) {
    for (_, vehicle) in vehicles {
        if vehicle.tripId != tripId {
            let annotationView = mapView.viewForAnnotation(vehicle.annotation!)
            annotationView?.hidden = true
        }
    }
}

func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
    let vehicleId = view.annotation?.title!
    let tripId = vehicles[vehicleId!]?.tripId
    hideBuses(tripId!)
}

}

0 个答案:

没有答案