菜鸟教程小白 发表于 2022-12-11 21:47:41

ios - 如何使用 MapKit 显示该地区多家医院的注释?


                                            <p><p>我试图在 mapView 中只显示医院,但我无法让它工作。我怎样才能做到这一点?请帮忙。目前,我正在使用注释并单独对其进行编程来实现这一点,这就是为什么我想要一种更快的方式来显示该地区的所有医院。注释的部分是我尝试搜索医院然后显示它们的代码,但我只得到一个注释,我想要多个注释。</p>

<pre><code>//
//ViewController.swift
//aidkit
//
//Created by Roberto Guarneros on 1/18/19.
//Copyright © 2019 Roberto Guarneros. All rights reserved.
//

import UIKit
import MapKit
import CoreLocation

class MapScreen: UIViewController{

    @IBOutlet weak var mapView: MKMapView!
    @IBOutlet weak var addressLabel: UILabel!
    @IBOutlet weak var goButton: UIButton!

    let locationManager = CLLocationManager()
    let regionInMeters: Double = 5000
    var previousLocation: CLLocation?

    let geoCoder = CLGeocoder()
    var directionsArray: = []


    override func viewDidLoad() {
      super.viewDidLoad()
      checkLocationServices()
    }

    func setupLocationManager() {
      locationManager.delegate = self
      locationManager.desiredAccuracy = kCLLocationAccuracyBest
    }


    func centerViewOnUserLocation() {
      if let location = locationManager.location?.coordinate {
            let region = MKCoordinateRegion.init(center: location, latitudinalMeters: regionInMeters, longitudinalMeters: regionInMeters)
            mapView.setRegion(region, animated: true)
      }
    }


    func checkLocationServices() {
      if CLLocationManager.locationServicesEnabled() {
            setupLocationManager()
            checkLocationAuthorization()
      } else {
            // Show alert letting the user know they have to turn this on.
      }
    }


    func checkLocationAuthorization() {
      switch CLLocationManager.authorizationStatus() {
      case .authorizedWhenInUse:
            startTackingUserLocation()
      case .denied:
            // Show alert instructing them how to turn on permissions
            break
      case .notDetermined:
            locationManager.requestWhenInUseAuthorization()
      case .restricted:
            // Show an alert letting them know what&#39;s up
            break
      case .authorizedAlways:
            break
      }
    }


    func startTackingUserLocation() {
      mapView.showsUserLocation = true
      centerViewOnUserLocation()
      locationManager.startUpdatingLocation()
      previousLocation = getCenterLocation(for: mapView)
    }


    func getCenterLocation(for mapView: MKMapView) -&gt; CLLocation {
      let latitude = mapView.centerCoordinate.latitude
      let longitude = mapView.centerCoordinate.longitude

      return CLLocation(latitude: latitude, longitude: longitude)
    }


    func getDirections() {
      guard let location = locationManager.location?.coordinate else {
            //TODO: Inform user we don&#39;t have their current location
            return
      }

      let request = createDirectionsRequest(from: location)
      let directions = MKDirections(request: request)
      resetMapView(withNew: directions)

      directions.calculate { (response, error) in
            //TODO: Handle error if needed
            guard let response = response else { return } //TODO: Show response not available in an alert

            for route in response.routes {
                self.mapView.addOverlay(route.polyline)
                  self.mapView.setVisibleMapRect(route.polyline.boundingMapRect, animated: true)
            }
      }
   }


   func createDirectionsRequest(from coordinate: CLLocationCoordinate2D) -&gt; MKDirections.Request {
      let destinationCoordinate       = getCenterLocation(for: mapView).coordinate
      let startingLocation            = MKPlacemark(coordinate: coordinate)
      let destination               = MKPlacemark(coordinate: destinationCoordinate)

      let request                     = MKDirections.Request()
      request.source                  = MKMapItem(placemark: startingLocation)
      request.destination             = MKMapItem(placemark: destination)
      request.transportType         = .automobile
      request.requestsAlternateRoutes = true

      return request
   }


   func resetMapView(withNew directions: MKDirections) {
      mapView.removeOverlays(mapView.overlays)
      directionsArray.append(directions)
      let _ = directionsArray.map { $0.cancel() }
   }

   @IBAction func goButtonTapped(_ sender: UIButton) {
      getDirections()
      print(&#34;hello&#34;)
   }

    //    func startSearchingForHospitals(){
    //      UIApplication.shared.beginIgnoringInteractionEvents()
    //
    //      let activityIndicator = UIActivityIndicatorView()
    //      activityIndicator.style = UIActivityIndicatorView.Style.gray
    //      activityIndicator.center = self.view.center
    //      activityIndicator.hidesWhenStopped = true
    //      activityIndicator.startAnimating()
    //
    //      self.view.addSubview(activityIndicator)
    //
    //      let searchRequest = MKLocalSearch.Request()
    //      searchRequest.naturalLanguageQuery = &#34;Hospital&#34;
    //
    //      let activeSearch = MKLocalSearch(request: searchRequest)
    //
    //      activeSearch.start { ( response, error) in
    //            activityIndicator.stopAnimating()
    //            UIApplication.shared.endIgnoringInteractionEvents()
    //
    //
    //            if response == nil{
    //                print(&#34;Error&#34;)
    //            } else {
    //                let annotations = self.mapView.annotations
    //                self.mapView.removeAnnotations(annotations)
    //
    //                let latitude = response?.boundingRegion.center.latitude
    //                let longitude = response?.boundingRegion.center.longitude
    //
    //                let annotation = MKPointAnnotation()
    //                annotation.title = &#34;Hospital&#34;
    //                annotation.coordinate = CLLocationCoordinate2D(latitude: latitude!, longitude: longitude!)
    //    self.mapView.addAnnotation(annotation)
    //
    //            }
    //      }
    //




      private func addAnnotations(){
      let hospitalLaPaz = MKPointAnnotation()
      hospitalLaPaz.title = &#34;Hospital La Paz&#34;
      hospitalLaPaz.coordinate = CLLocationCoordinate2D(latitude: 19.058851, longitude: -98.226132)

      let hospitalSalutem = MKPointAnnotation()
      hospitalSalutem.title = &#34;Hospital Salutem&#34;
      hospitalSalutem.coordinate = CLLocationCoordinate2D(latitude: 19.058962, longitude: -98.230976)

      let hospitalPuebla = MKPointAnnotation()
      hospitalPuebla.title = &#34;Hospital Puebla&#34;
      hospitalPuebla.coordinate = CLLocationCoordinate2D(latitude: 19.030592, longitude: -98.229141)

      let hospitalAngeles = MKPointAnnotation()
      hospitalAngeles.title = &#34;Hospital Ángeles-Puebla&#34;
      hospitalAngeles.coordinate = CLLocationCoordinate2D(latitude: 19.021676, longitude: -98.235278)

      let hospitalDelNiñoPoblano = MKPointAnnotation()
      hospitalDelNiñoPoblano.title = &#34;Hospital del Niño Poblano&#34;
      hospitalDelNiñoPoblano.coordinate = CLLocationCoordinate2D(latitude: 19.034798, longitude: -98.244053)

      let hospitalBUAP = MKPointAnnotation()
      hospitalBUAP.title = &#34;Hospital Universitario de Puebla&#34;
      hospitalBUAP.coordinate = CLLocationCoordinate2D(latitude: 19.039964, longitude: -98.213331)

      let hospitalAngelopolitano = MKPointAnnotation()
      hospitalAngelopolitano.title = &#34;Hospital Angelopolitano&#34;
      hospitalAngelopolitano.coordinate = CLLocationCoordinate2D(latitude: 98.213331, longitude: -98.215445)

      let hospitalUPAEP = MKPointAnnotation()
      hospitalUPAEP.title = &#34;Hospital UPAEP&#34;
      hospitalUPAEP.coordinate = CLLocationCoordinate2D(latitude: 19.045732, longitude: -19.045732)

      let hospitalBeneficenciaEspañola = MKPointAnnotation()
      hospitalBeneficenciaEspañola.title = &#34;Beneficencia Española&#34;
      hospitalBeneficenciaEspañola.coordinate = CLLocationCoordinate2D(latitude: 19.055711, longitude: -98.209555)

      let hospitalBetania = MKPointAnnotation()
      hospitalBetania.title = &#34;Hospital Betania&#34;
      hospitalBetania.coordinate = CLLocationCoordinate2D(latitude: 19.034998, longitude: -98.188137)

      let hospitalVilaseca = MKPointAnnotation()
      hospitalVilaseca.title = &#34;Hospital A. Vilaseca Esparza C.&#34;
      hospitalVilaseca.coordinate = CLLocationCoordinate2D(latitude: 19.047538, longitude: -98.187644)

      let hospitalGeneralIMSS = MKPointAnnotation()
      hospitalGeneralIMSS.title = &#34;IMSS San José&#34;
      hospitalGeneralIMSS.coordinate = CLLocationCoordinate2D(latitude: 19.050631, longitude: -98.192300)

      let hospitalGeneralZonaNorte = MKPointAnnotation()
      hospitalGeneralZonaNorte.title = &#34;Hospital General Zona Norte&#34;
      hospitalGeneralZonaNorte.coordinate = CLLocationCoordinate2D(latitude: 19.079432, longitude: -98.184495)

      let hospitalGeneralCholula = MKPointAnnotation()
      hospitalGeneralCholula.title = &#34;Hospital General Cholula&#34;
      hospitalGeneralCholula.coordinate = CLLocationCoordinate2D(latitude: 19.017239, longitude: -98.266399)

      let hospitalGeneralZonaSur = MKPointAnnotation()
      hospitalGeneralZonaSur.title = &#34;Hospital General Del Sur&#34;
      hospitalGeneralZonaSur.coordinate = CLLocationCoordinate2D(latitude: 18.986133, longitude: -98.242405)

      let hospitalRegionalISSSTE = MKPointAnnotation()
      hospitalRegionalISSSTE.title = &#34;Hospital Regional ISSSTE&#34;
      hospitalRegionalISSSTE.coordinate = CLLocationCoordinate2D(latitude: 19.020526, longitude: -98.197853)

      let hospitalGeneralZona20IMSS = MKPointAnnotation()
      hospitalGeneralZona20IMSS.title = &#34;Hospital General IMSS Zona 20 La Margarita&#34;
      hospitalGeneralZona20IMSS.coordinate = CLLocationCoordinate2D(latitude: 19.008275, longitude: -98.182857)

      mapView.addAnnotation(hospitalLaPaz)
      mapView.addAnnotation(hospitalSalutem)
      mapView.addAnnotation(hospitalPuebla)
      mapView.addAnnotation(hospitalAngeles)
      mapView.addAnnotation(hospitalDelNiñoPoblano)
      mapView.addAnnotation(hospitalBUAP)
      mapView.addAnnotation(hospitalAngelopolitano)
      mapView.addAnnotation(hospitalUPAEP)
      mapView.addAnnotation(hospitalBeneficenciaEspañola)
      mapView.addAnnotation(hospitalBetania)
      mapView.addAnnotation(hospitalGeneralIMSS)
      mapView.addAnnotation(hospitalGeneralZonaNorte)
      mapView.addAnnotation(hospitalGeneralCholula)
      mapView.addAnnotation(hospitalGeneralZonaSur)
      mapView.addAnnotation(hospitalRegionalISSSTE)
      mapView.addAnnotation(hospitalGeneralZona20IMSS)
    }
}

extension MapScreen: CLLocationManagerDelegate {

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
      checkLocationAuthorization()
       addAnnotations()
    }
}

extension MapScreen: MKMapViewDelegate {
    func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
      let center = getCenterLocation(for: mapView)

      guard let previousLocation = self.previousLocation else { return }

      guard center.distance(from: previousLocation) &gt; 50 else { return }
      self.previousLocation = center

      geoCoder.cancelGeocode()

      geoCoder.reverseGeocodeLocation(center) { (placemarks, error) in
            guard let self = self else { return }

            if let _ = error {
                //TODO: Show alert informing the user
                return
            }

            guard let placemark = placemarks?.first else {
                //TODO: Show alert informing the user
                return
            }

            let streetNumber = placemark.subThoroughfare ?? &#34;&#34;
            let streetName = placemark.thoroughfare ?? &#34;&#34;

            DispatchQueue.main.async {
                self.addressLabel.text = &#34;\(streetNumber) \(streetName)&#34;
            }
      }
    }


    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -&gt; MKOverlayRenderer {
      let renderer = MKPolylineRenderer(overlay: overlay as! MKPolyline)
      renderer.strokeColor = .blue

      return renderer
    }
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><pre><code>let request = MKLocalSearchRequest()
request.naturalLanguageQuery = &#34;Hospital&#34;
request.region = mapView.region

let search = MKLocalSearch(request: request)
search.startWithCompletionHandler { response, error in
    guard let response = response else {
      print(&#34;There was an error searching for: \(request.naturalLanguageQuery) error: \(error)&#34;)
      return
    }

    for mapItem in response.mapItems {
      // Display the received items
      let latitude = mapItem.placemark.location.coordinate.latitude
      let longitude = mapItem.placemark.location.coordinate.longitude

      let hospital = MKPointAnnotation()
      hospital.title = mapItem.name! //Only do `!` if you are sure that it isn&#39;t nil
      hospital.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
      mapView.addAnnotation(hospital)
    }
}
</code></pre>

<p>现在你有了这些坐标,你可以创建你需要的任何东西。</p>

<p>您所做的是使用边界框(您找到的所有医院的区域)作为位置,它提供的信息不正确。 </p>

<p>这种方式会遍历响应中找到的每个项目,并从它们的类 <code>MKMapItem</code> 中获取它们的位置和您可能需要的任何其他信息。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 如何使用 MapKit 显示该地区多家医院的注释?,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/54273789/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/54273789/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 如何使用 MapKit 显示该地区多家医院的注释?