【问题标题】:Get geo location from city name从城市名称获取地理位置
【发布时间】:2021-07-16 18:12:09
【问题描述】:

我编写了在文本字段中输入时显示城市名称的代码。我可以使用 For Each 循环显示搜索结果。我需要单击其中一个结果并获取城市名称的地理位置。现在我正在努力从该城市名称中获取地理位置(纬度,经度)。是否有解决方案可以将其实现到我的代码中?

class LocationService: NSObject, ObservableObject {

enum LocationStatus: Equatable {
    case idle
    case noResults
    case isSearching
    case error(String)
    case result
}

@Published var queryFragment: String = ""
@Published private(set) var status: LocationStatus = .idle
@Published private(set) var searchResults: [MKLocalSearchCompletion] = []

private var queryCancellable: AnyCancellable?
private let searchCompleter: MKLocalSearchCompleter!

init(searchCompleter: MKLocalSearchCompleter = MKLocalSearchCompleter()) {
    self.searchCompleter = searchCompleter
    super.init()
    self.searchCompleter.delegate = self

    queryCancellable = $queryFragment
        .receive(on: DispatchQueue.main)
        // we're debouncing the search, because the search completer is rate limited.
        // feel free to play with the proper value here
        .debounce(for: .milliseconds(250), scheduler: RunLoop.main, options: nil)
        .sink(receiveValue: { fragment in
            self.status = .isSearching
            if !fragment.isEmpty {
                self.searchCompleter.queryFragment = fragment
            } else {
                self.status = .idle
                self.searchResults = []
            }
    })
}


extension LocationService: MKLocalSearchCompleterDelegate {
func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) {

    // out a lot of places and only shows cities and countries.
    self.searchResults = completer.results.filter({ $0.subtitle == "" })
    self.status = completer.results.isEmpty ? .noResults : .result
}

func completer(_ completer: MKLocalSearchCompleter, didFailWithError error: Error) {
    self.status = .error(error.localizedDescription)
}

}

【问题讨论】:

    标签: ios swift xcode swiftui


    【解决方案1】:

    CoreLocation 框架为您提供CLGeocoder,它可以尝试在坐标和地名之间双向转换。

    您可以在 Playground 中尝试一下,看看它是如何工作的:

    import Foundation
    import CoreLocation
    
    func getCoordinate( addressString : String,
                        completionHandler: @escaping(CLLocationCoordinate2D, NSError?) -> Void ) {
        let geocoder = CLGeocoder()
        geocoder.geocodeAddressString(addressString) { (placemarks, error) in
            if error == nil {
                if let placemark = placemarks?[0] {
                    let location = placemark.location!
    
                    completionHandler(location.coordinate, nil)
                    return
                }
            }
    
            completionHandler(kCLLocationCoordinate2DInvalid, error as NSError?)
        }
    }
    
    let valid = "New Orleans, Louisiana, USA"
    let invalid = "The Moon"
    
    getCoordinate(addressString: valid) { location, error in
        guard error == nil else {print("Error:"); return}
    
        print(location)
    }
    
    getCoordinate(addressString: invalid) { location, error in
        guard error == nil else {print("Error:"); return}
    
        print(location)
    }
    

    结果是异步返回的,因此您需要提供一个完成处理程序。

    【讨论】:

    • 谢谢!这对我有帮助。你知道如何在视图中实现 getCoordinate 吗?如果我尝试将 getCoordinate(...) 实现到我的视图中,使用 for each ist 会给我这个错误“包含控制流语句的闭包不能与结果生成器'CommandsBuilder'一起使用”
    • 这是进入视图模型的那种东西。另外,请注意,您不能在短时间内对 API 进行多次调用,它会受到 Apple 的速率限制。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-11
    • 1970-01-01
    • 2018-01-16
    • 1970-01-01
    相关资源
    最近更新 更多