2017-09-03 136 views
1

我想獲得兩個位置之間的距離。 我試過這段代碼:快速計算兩個位置之間的距離

func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) { 
    CLGeocoder().geocodeAddressString("ADDRESS OF LOC 2") { (placemarks, error) in 
    guard let placemarks = placemarks, let loc2 = placemarks.first?.location 
     else { 
     return 
     } 


    let loc1 = CLLocation(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude) 

    var distance = loc1.distance(from: loc2) 
    print((distance/1000).rounded(), " km") 
    } 
} 

我的問題是,我得到一個錯誤的距離。 打印結果將是「2公里」

如果我計算出「地圖」在同一地點之間的距離,我得到的長度「2,7公里」和「2.9公里」

兩個Route選項

我錯了什麼?

+0

您沒有發現任何問題,您只是通過使用四捨五入()方法丟棄了小數部分,即2.7公里變爲2公里,因爲您捨去了它! –

+0

如果我這樣做:'print(distance/1000)'結果將是:'1.74364568832' - 與2,7或2,9不一樣:/ – Ghost108

回答

1

the documentation

此方法通過跟蹤下面的地球曲率它們之間的線測量的兩個位置之間的距離。由此產生的弧線是一條平滑曲線,不考慮兩個位置之間的特定高度變化。

因此,您正在計算直線距離,「像烏鴉飛」,而不是跟隨道路,這將導致更長的路線,就像您在地圖中看到的那樣。您需要像MapKit的MKDirectionsRequest之類的內容來匹配您在地圖應用中看到的路線。 Ray Wenderlich has a good tutorial.

下面是一個例子,我只是敲了在MacOS的遊樂場工作:

//: Playground - noun: a place where people can play 

import Cocoa 
import MapKit 
import CoreLocation 

// As we're waiting for completion handlers, don't want the playground 
// to die on us just because we reach the end of the playground. 
// See https://stackoverflow.com/questions/40269573/xcode-error-domain-dvtplaygroundcommunicationerrordomain-code-1 
import PlaygroundSupport 
PlaygroundPage.current.needsIndefiniteExecution = true 

let geocoder = CLGeocoder() 
geocoder.geocodeAddressString("1 Pall Mall East, London SW1Y 5AU") { (placemarks: [CLPlacemark]? , error: Error?) in 
    if let placemarks = placemarks { 
     let start_placemark = placemarks[0] 
     geocoder.geocodeAddressString("Buckingham Palace, London SW1A 1AA", completionHandler: { (placemarks: [CLPlacemark]?, error: Error?) in 
      if let placemarks = placemarks { 
       let end_placemark = placemarks[0] 

       // Okay, we've geocoded two addresses as start_placemark and end_placemark. 
       let start = MKMapItem(placemark: MKPlacemark(coordinate: start_placemark.location!.coordinate)) 
       let end = MKMapItem(placemark: MKPlacemark(coordinate: end_placemark.location!.coordinate)) 

       // Now we've got start and end MKMapItems for MapKit, based on the placemarks. Build a request for 
       // a route by car. 
       let request: MKDirectionsRequest = MKDirectionsRequest() 
       request.source = start 
       request.destination = end 
       request.transportType = MKDirectionsTransportType.automobile 

       // Execute the request on an MKDirections object 
       let directions = MKDirections(request: request) 
       directions.calculate(completionHandler: { (response: MKDirectionsResponse?, error: Error?) in 
        // Now we should have a route. 
        if let routes = response?.routes { 
         let route = routes[0] 
         print(route.distance) // 2,307 metres. 
        } 
       }) 
      } 
     }) 
    } 
} 
+0

啊好吧,我怎樣才能得到距離與「以下道路」? – Ghost108

+0

Ray Weinerlich教程是針對iOS的,這是一個問題嗎? – Ghost108

+0

@ Ghost108嗯,我還沒有發現你使用的是macOS--我想到Swift的時候會想到iOS,因爲從我開發macOS開始已經很長時間了!不過,我相信MapKit原理在兩個平臺上都是相似的,所以它應該給你一個體面的提示,告訴你你需要做什麼。 –

1

如果你想旅行的距離,而不是「直線距離」,使用MKDirections,如:

func routes(to item: MKMapItem, completion: @escaping ([MKRoute]?, Error?) -> Void) { 
    let request = MKDirectionsRequest() 
    request.source = MKMapItem.forCurrentLocation() 
    request.destination = item 
    request.transportType = .automobile 

    let directions = MKDirections(request: request) 
    directions.calculate { response, error in 
     completion(response?.routes, error) 
    } 
} 

如果您想格式化爲小數點後一位,我建議您使用NumberFormatter,因此適用於小數點分隔符不是.的國際用戶格式:

self.routes(to: item) { routes, error in 
    guard let routes = routes, error == nil else { 
     print(error?.localizedDescription ?? "Unknown error") 
     return 
    } 

    let formatter = NumberFormatter() 
    formatter.numberStyle = .decimal 
    formatter.minimumFractionDigits = 1 
    formatter.maximumFractionDigits = 1 

    for route in routes { 
     let distance = route.distance/1000 
     print(formatter.string(from: NSNumber(value: distance))!, "km") 
    } 
} 
相關問題