我正在尝试仅在地图视图中显示医院,但无法使其正常运行。我怎样才能做到这一点?请帮忙。目前,我正在使用批注并对它们进行单独编程来实现此目的,这就是为什么我想要一种更快的方式来显示该地区的所有医院。被注释的部分是我的代码,尝试搜索医院然后显示它们,但是我只得到一个注释,而我想要多个注释。
//
// 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: [MKDirections] = []
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's up
break
case .authorizedAlways:
break
}
}
func startTackingUserLocation() {
mapView.showsUserLocation = true
centerViewOnUserLocation()
locationManager.startUpdatingLocation()
previousLocation = getCenterLocation(for: mapView)
}
func getCenterLocation(for mapView: MKMapView) -> 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't have their current location
return
}
let request = createDirectionsRequest(from: location)
let directions = MKDirections(request: request)
resetMapView(withNew: directions)
directions.calculate { [unowned self] (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) -> 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("hello")
}
// 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 = "Hospital"
//
// let activeSearch = MKLocalSearch(request: searchRequest)
//
// activeSearch.start { ( response, error) in
// activityIndicator.stopAnimating()
// UIApplication.shared.endIgnoringInteractionEvents()
//
//
// if response == nil{
// print("Error")
// } 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 = "Hospital"
// annotation.coordinate = CLLocationCoordinate2D(latitude: latitude!, longitude: longitude!)
// self.mapView.addAnnotation(annotation)
//
// }
// }
//
private func addAnnotations(){
let hospitalLaPaz = MKPointAnnotation()
hospitalLaPaz.title = "Hospital La Paz"
hospitalLaPaz.coordinate = CLLocationCoordinate2D(latitude: 19.058851, longitude: -98.226132)
let hospitalSalutem = MKPointAnnotation()
hospitalSalutem.title = "Hospital Salutem"
hospitalSalutem.coordinate = CLLocationCoordinate2D(latitude: 19.058962, longitude: -98.230976)
let hospitalPuebla = MKPointAnnotation()
hospitalPuebla.title = "Hospital Puebla"
hospitalPuebla.coordinate = CLLocationCoordinate2D(latitude: 19.030592, longitude: -98.229141)
let hospitalAngeles = MKPointAnnotation()
hospitalAngeles.title = "Hospital Ángeles-Puebla"
hospitalAngeles.coordinate = CLLocationCoordinate2D(latitude: 19.021676, longitude: -98.235278)
let hospitalDelNiñoPoblano = MKPointAnnotation()
hospitalDelNiñoPoblano.title = "Hospital del Niño Poblano"
hospitalDelNiñoPoblano.coordinate = CLLocationCoordinate2D(latitude: 19.034798, longitude: -98.244053)
let hospitalBUAP = MKPointAnnotation()
hospitalBUAP.title = "Hospital Universitario de Puebla"
hospitalBUAP.coordinate = CLLocationCoordinate2D(latitude: 19.039964, longitude: -98.213331)
let hospitalAngelopolitano = MKPointAnnotation()
hospitalAngelopolitano.title = "Hospital Angelopolitano"
hospitalAngelopolitano.coordinate = CLLocationCoordinate2D(latitude: 98.213331, longitude: -98.215445)
let hospitalUPAEP = MKPointAnnotation()
hospitalUPAEP.title = "Hospital UPAEP"
hospitalUPAEP.coordinate = CLLocationCoordinate2D(latitude: 19.045732, longitude: -19.045732)
let hospitalBeneficenciaEspañola = MKPointAnnotation()
hospitalBeneficenciaEspañola.title = "Beneficencia Española"
hospitalBeneficenciaEspañola.coordinate = CLLocationCoordinate2D(latitude: 19.055711, longitude: -98.209555)
let hospitalBetania = MKPointAnnotation()
hospitalBetania.title = "Hospital Betania"
hospitalBetania.coordinate = CLLocationCoordinate2D(latitude: 19.034998, longitude: -98.188137)
let hospitalVilaseca = MKPointAnnotation()
hospitalVilaseca.title = "Hospital A. Vilaseca Esparza C."
hospitalVilaseca.coordinate = CLLocationCoordinate2D(latitude: 19.047538, longitude: -98.187644)
let hospitalGeneralIMSS = MKPointAnnotation()
hospitalGeneralIMSS.title = "IMSS San José"
hospitalGeneralIMSS.coordinate = CLLocationCoordinate2D(latitude: 19.050631, longitude: -98.192300)
let hospitalGeneralZonaNorte = MKPointAnnotation()
hospitalGeneralZonaNorte.title = "Hospital General Zona Norte"
hospitalGeneralZonaNorte.coordinate = CLLocationCoordinate2D(latitude: 19.079432, longitude: -98.184495)
let hospitalGeneralCholula = MKPointAnnotation()
hospitalGeneralCholula.title = "Hospital General Cholula"
hospitalGeneralCholula.coordinate = CLLocationCoordinate2D(latitude: 19.017239, longitude: -98.266399)
let hospitalGeneralZonaSur = MKPointAnnotation()
hospitalGeneralZonaSur.title = "Hospital General Del Sur"
hospitalGeneralZonaSur.coordinate = CLLocationCoordinate2D(latitude: 18.986133, longitude: -98.242405)
let hospitalRegionalISSSTE = MKPointAnnotation()
hospitalRegionalISSSTE.title = "Hospital Regional ISSSTE"
hospitalRegionalISSSTE.coordinate = CLLocationCoordinate2D(latitude: 19.020526, longitude: -98.197853)
let hospitalGeneralZona20IMSS = MKPointAnnotation()
hospitalGeneralZona20IMSS.title = "Hospital General IMSS Zona 20 La Margarita"
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) > 50 else { return }
self.previousLocation = center
geoCoder.cancelGeocode()
geoCoder.reverseGeocodeLocation(center) { [weak self] (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 ?? ""
let streetName = placemark.thoroughfare ?? ""
DispatchQueue.main.async {
self.addressLabel.text = "\(streetNumber) \(streetName)"
}
}
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay as! MKPolyline)
renderer.strokeColor = .blue
return renderer
}
}
答案 0 :(得分:0)
let request = MKLocalSearchRequest()
request.naturalLanguageQuery = "Hospital"
request.region = mapView.region
let search = MKLocalSearch(request: request)
search.startWithCompletionHandler { response, error in
guard let response = response else {
print("There was an error searching for: \(request.naturalLanguageQuery) error: \(error)")
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't nil
hospital.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
mapView.addAnnotation(hospital)
}
}
现在有了这些坐标,就可以创建所需的任何内容。
您正在做的是使用边界框(找到的所有医院的面积)作为位置,并且提供的信息不正确。
通过这种方式遍历响应中找到的每个项目,并从其课程MKMapItem
中获取其位置以及您可能需要的任何其他信息。
答案 1 :(得分:0)
如果要进行本地搜索并将结果添加到地图,只需在创建每个addAnnotation
之后调用MKPointAnnotation
:
let request = MKLocalSearch.Request()
request.naturalLanguageQuery = "Hospital"
request.region = mapView.region
let search = MKLocalSearch(request: request)
search.start { response, error in
guard let response = response else {
print(error ?? "Unknown error")
return
}
for mapItem in response.mapItems {
let hospital = MKPointAnnotation()
hospital.title = mapItem.name
hospital.coordinate = mapItem.placemark.coordinate
self.mapView.addAnnotation(hospital)
}
}
或者,当然,您可以构建注释数组并将其添加到末尾:
let search = MKLocalSearch(request: request)
search.start { response, error in
guard let response = response else {
print(error ?? "Unknown error")
return
}
let hospitals = response.mapItems.map { mapItem -> MKPointAnnotation in
let hospital = MKPointAnnotation()
hospital.title = mapItem.name
hospital.coordinate = mapItem.placemark.coordinate
return hospital
}
self.mapView.addAnnotations(hospitals)
}
我个人喜欢在那儿有街道地址,因此我个人还要在添加注释之前设置其subtitle
:
hospital.subtitle = [mapItem.placemark.subThoroughfare, mapItem.placemark.thoroughfare]
.compactMap { $0 }
.joined(separator: " ")