我想使用CLLocation
计算当前位置和MKDirections.calculate
列表之间的实际步行距离。但是,由于某种原因,函数末尾的return命令不会等待结果,而是尝试返回空变量。我的代码如下:
func getDistance (location1: CLLocation, location2: CLLocation) {
let coordinates1 = location1.coordinate
let placemark1 = MKPlacemark(coordinate: coordinates1)
let sourceItem = MKMapItem(placemark: placemark1)
let coordinates2 = location2.coordinate
let placemark2 = MKPlacemark(coordinate: coordinates2)
let destinationItem = MKMapItem(placemark: placemark2)
let request = MKDirectionsRequest()
request.source = sourceItem
request.destination = destinationItem
request.requestsAlternateRoutes = true
request.transportType = .walking
var distance: Double?
let directions = MKDirections(request: request)
directions.calculate { (response, error) in
if var routeResponse = response?.routes {
routeResponse.sort(by: {$0.expectedTravelTime < $1.expectedTravelTime})
let quickestRoute: MKRoute = routeResponse[0]
distance = Double(quickestRoute.distance)
}
}
return distance //returns nil
}
然后,我想在这样的代码中使用该函数:
let myLocation = CLLocation(latitude: 47.0, longitude: 17.0)
let destinationArray = [CLLocation(latitude: 47.1, longitude: 17.1), CLLocation(latitude: 47.2, longitude: 17.2), CLLocation(latitude: 47.3, longitude: 17.3)]
var distanceArray: [Double] = []
for destination in destinationArray {
distanceArray.append(getDistance(location1: myLocation, location2: destination))
}
return distanceArray
我尝试了闭包,但是它们没有用,因为我找不到返回distanceArray的方法(同样的错误,它没有等待闭包运行并返回空数组)。我也尝试了DispatchGroups,但它们没有效果(也许我以错误的方式实现了它们)。
非常感谢您的帮助。
谢谢。
答案 0 :(得分:0)
directions.calculate
是一个异步函数,因此您需要等待函数返回后才能返回计算出的距离。您应该使用完成处理程序来完成此操作……
func getDistance(location1: CLLocation, location2: CLLocation, completion: @escaping (Double) -> Void) {
// etc
directions.calculate { (response, error) in
if var routeResponse = response?.routes {
routeResponse.sort(by: {$0.expectedTravelTime < $1.expectedTravelTime})
let quickestRoute: MKRoute = routeResponse[0]
completion(Double(quickestRoute.distance))
}
}
}
,然后您应该对距离数组执行类似的操作。您需要等待所有getDistance
的调用返回,因此您可以为此使用DispatchGroup
…
func getDistanceArray(completion: @escaping ([Double]) -> Void) {
let group = DispatchGroup()
var distanceArray: [Double] = []
for destination in destinationArray {
group.enter()
getDistance(location1: myLocation, location2: destination) { distance in
distanceArray.append(distance)
group.leave()
}
}
group.wait()
completion(distanceArray)
}
您可以打电话给…
getDistanceArray { distanceArray in
print(distanceArray)
}
答案 1 :(得分:0)
尝试以下关闭操作:
func getDistance (location1: CLLocation, location2: CLLocation,
completion: @escaping(Double?) -> Void) {
let coordinates1 = location1.coordinate
let placemark1 = MKPlacemark(coordinate: coordinates1)
let sourceItem = MKMapItem(placemark: placemark1)
let coordinates2 = location2.coordinate
let placemark2 = MKPlacemark(coordinate: coordinates2)
let destinationItem = MKMapItem(placemark: placemark2)
let request = MKDirectionsRequest()
request.source = sourceItem
request.destination = destinationItem
request.requestsAlternateRoutes = true
request.transportType = .walking
var distance: Double?
let directions = MKDirections(request: request)
directions.calculate { (response, error) in
if var routeResponse = response?.routes {
routeResponse.sort(by: {$0.expectedTravelTime < $1.expectedTravelTime})
let quickestRoute: MKRoute = routeResponse[0]
distance = Double(quickestRoute.distance)
completion(distance)
}
}
}
用法:
let myLocation = CLLocation(latitude: 47.0, longitude: 17.0)
let destinationArray = [CLLocation(latitude: 47.1, longitude: 17.1), CLLocation(latitude: 47.2, longitude: 17.2), CLLocation(latitude: 47.3, longitude: 17.3)]
var distanceArray: [Double] = []
for destination in destinationArray {
getDistance(location1: myLocation, location2: destination) { distance in
print("distance", distance)
if let distance = distance {
distanceArray.append(distance)
}
}
}
return distanceArray
答案 2 :(得分:0)
使用MapKit和Swift 5
计算两个位置之间的距离,它将为任何人提供帮助
示例功能:我已经在Google Map和Apple Map中进行了测试
self.getDistance(departureDate: trip.departure.dateTime, arrivalDate: trip.arrival.dateTime, startLocation: startLocation, endLocation: endLocation) { (actualDistance) in
print("actualDistance : \(actualDistance)")
}
功能使用
func calculateDistancefrom(departureDate: Date, arrivalDate: Date, sourceLocation: MKMapItem, destinationLocation: MKMapItem, doneSearching: @escaping (_ distance: CLLocationDistance) -> Void) {
let request: MKDirections.Request = MKDirections.Request()
request.departureDate = departureDate
request.arrivalDate = arrivalDate
request.source = sourceLocation
request.destination = destinationLocation
request.requestsAlternateRoutes = true
request.transportType = .automobile
let directions = MKDirections(request: request)
directions.calculate { (directions, error) in
if var routeResponse = directions?.routes {
routeResponse.sort(by: {$0.expectedTravelTime <
$1.expectedTravelTime})
let quickestRouteForSegment: MKRoute = routeResponse[0]
doneSearching(quickestRouteForSegment.distance)
}
}
}
func getDistance(departureDate: Date, arrivalDate: Date, startLocation : CLLocation, endLocation : CLLocation, completionHandler: @escaping (_ distance: CLLocationDistance) -> Void) {
let destinationItem = MKMapItem(placemark: MKPlacemark(coordinate: startLocation.coordinate))
let sourceItem = MKMapItem(placemark: MKPlacemark(coordinate: endLocation.coordinate))
self.calculateDistancefrom(departureDate: departureDate, arrivalDate: arrivalDate, sourceLocation: sourceItem, destinationLocation: destinationItem, doneSearching: { distance in
completionHandler(distance)
})
}
我对上述功能进行了改进,并在此处添加了代码,希望对您有所帮助。
<fragment
android:id="@+id/youtube_frag"
android:name="com.google.android.youtube.player.YouTubePlayerFragment"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
/>