#ios #swift #mapkit #mkdirection
#iOS #swift #mapkit #mkdirection
Вопрос:
Я делаю запросы на вычисление расстояния от моего текущего местоположения до мест расположения кемпинга в массиве countySites
, используя calculate()
метод MKDirections
класса в for
цикле. Когда у меня есть массив длиной 47 кемпингов, вычисляются только некоторые расстояния до кемпинга, остальные выдают сообщение об ошибке, предполагающее, что выполняется слишком много запросов. Я не знаю, как проверить, что calculate()
он не слишком занят, прежде чем я сделаю запрос в for
цикле.
Я попытался поместить while
цикл в код, чтобы повторно проверять, выполняется ли вычисление, все еще обрабатываемое с использованием isCalculating
Bool
свойства, но не удается остановить сообщения об ошибках.
countySites = england.counties[selectedCounty!]!
let sourcePlacemark = MKPlacemark(coordinate: currentCoordinate!)
let request = MKDirections.Request()
request.source = MKMapItem(placemark: sourcePlacemark)
request.transportType = .automobile
request.requestsAlternateRoutes = false
let group = DispatchGroup()
activityIndicator.startAnimating()
// Step through sites one by one
for siteIndex in 0..<countySites.count {
var selectedSite = countySites[siteIndex]
let destinationPlacemark = MKPlacemark(coordinate: selectedSite.locationCoordinate)
request.destination = MKMapItem(placemark: destinationPlacemark)
let distanceAndDirections = MKDirections(request: request)
if currentCoordinate != nil {
group.enter()
distanceAndDirections.calculate { (response, error) in
if error == nil {
let distanceInMetres = response?.routes.first?.distance
let distanceInMiles = distanceInMetres! / 1610
let roundedDistanceInMiles = Int(distanceInMiles.rounded())
let distanceToSite = roundedDistanceInMiles
selectedSite.distance = distanceToSite
self.countySites[siteIndex] = selectedSite
} else {
print(error.debugDescription)
}
group.leave()
}
}
}
group.notify(queue: .main) {
self.countySites = self.sortByDistance(sites: self.countySites)
self.tableView.reloadData()
self.activityIndicator.stopAnimating()
}
}
}
Комментарии:
1. Я получаю сообщение об ошибке из
print(error.debugDescription)
инструкцииOptional(Error Domain=MKErrorDomain Code=3 "Directions Not Available" UserInfo={NSLocalizedFailureReason=Route information is not available at this moment., MKErrorGEOError=-3, MKErrorGEOErrorUserInfo={ }, MKDirectionsErrorCode=3, NSLocalizedDescription=Directions Not Available})
2. Когда я пытаюсь использовать
while
решение цикла, значениеisCalculating
всегда равно false, поэтому он никогда не выполняет код внутриwhile
блока цикла.isCalculating
только когда-либоtrue
вelse
инструкции в замыкании, когда есть ненулевое значение дляerror
3. Возможно, вы ищете ограничитель скорости. Используйте это ключевое слово для поиска, и вы найдете решения.
4. @Gerd Castan Спасибо, я посмотрю это.
5. @Gerd Castan Я попробовал ограничитель скорости, но установка скорости на 1 токен каждую секунду по-прежнему не помогает слишком многим запросам
Ответ №1:
Единственное решение этой проблемы — просто сохранить массив MKRoute, и всякий раз, когда вы сталкиваетесь с новым путем, просто сохраните в этом массиве и используйте тот же массив для рисования пути, используя этот метод, вы также можете сохранять вызовы расстояния MapKit
Проверьте приведенный ниже фрагмент, который сработал для меня
var distanceArray: [MKRoute]? // like this create an array inside the class
func drawPath(destination: CLLocationCoordinate2D, source: CLLocationCoordinate2D) {
let sourcePlacemark = MKPlacemark(coordinate: source, addressDictionary: nil)
let destinationPlacemark = MKPlacemark(coordinate: destination, addressDictionary: nil)
let sourceMapItem = MKMapItem(placemark: sourcePlacemark)
let destinationMapItem = MKMapItem(placemark: destinationPlacemark)
let directionRequest = MKDirectionsRequest()
directionRequest.source = sourceMapItem
directionRequest.destination = destinationMapItem
directionRequest.transportType = .walking
let directions = MKDirections(request: directionRequest)
if distanceArray.count > 0 {
guard let route = distanceArray.first?.routes else {return}
self.showPath(route: route)
} else {
directions.calculate { (response, error) -> Void in
guard let response = response else {
if let error = error {
print("Error YuluMapView: (error)")
}
return
}
guard let route = response.routes.first else {return}
distanceArray.append(route)
self.showPath(route: route)
}
}
}
func showPath(route: MKRoute) {
self.add((route.polyline), level: MKOverlayLevel.aboveRoads)
let rect = route.polyline.boundingMapRect
self.setVisibleMapRect(rect, edgePadding: defaultEdgeInsets, animated: true)
}
У меня это сработало на 100%, и я надеюсь, что вы сможете использовать эту логику, чтобы избежать этой проблемы.
Комментарии:
1. как мы можем показать отслеживание в реальном времени, используя то же решение?
2. Да, вы можете это сделать, но сохраняйте таймер на каждые X секунд и вызывайте этот метод для обновления карты.