передать массив координат карты, чтобы нарисовать маршрут на карте в swift

#ios #swift #dictionary #mapkit

#iOS #swift #словарь #mapkit

Вопрос:

привет, у меня есть массив данных координат, подобных этому, который извлекается из вызова API, и я использую цикл for для добавления данных в массив, подобный этому:

 extension TripListViewController: UITableViewDelegate {


    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        performSegue(withIdentifier: Constants.segueTripListToTripMap, sender: indexPath)

        tableView.deselectRow(at: indexPath, animated: true)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        if segue.identifier == Constants.segueTripListToTripMap {
            if let destinationVC = segue.destination as? TripMapViewController,
                let indexPath = sender as? IndexPath {
                
                
                for i in 0...(tripList[indexPath.section][indexPath.row].coordinates.count-1) {
                    self.coodinates.append(tripList[indexPath.section][indexPath.row].coordinates[i])
                }
                
                destinationVC.coodinatePoints = coodinates
                
                
                 
            }
        } else {
            if let destinationVC = segue.destination as? PolicyOverviewViewController,
                let indexPath = sender as? IndexPath {
                // do something
            }
        }

    }

}

  

у него ошибка… Я не знаю, как передать этот массив переменной, которую я объявил на другом экране, кажется, что тип данных не совпадает.

введите описание изображения здесь

Исходный тип данных выглядит следующим образом:

 struct Trips: Codable {
    let id: String
    let userId: String
    let coordinates: [Coordinates]

}

struct Coordinates: Codable {
    let lat: Double?
    let lng: Double?
    let time: String?
}

  
 [
["time": "timestampes"
"lat": 40.213
"lon": 5.203],
["time": "timestampes"
"lat": 40.213
"lon": 5.203],
["time": "timestampes"
"lat": 40.213
"lon": 5.203],
["time": "timestampes"
"lat": 40.213
"lon": 5.203]

]
  

как я могу передать эти данные в точечную переменную моей функции рисования маршрута. в настоящее время он жестко запрограммирован с некоторыми фиктивными данными.

 func drawRoutes() {

        var points = [CLLocationCoordinate2DMake(51.079980, 4.349850),
                      CLLocationCoordinate2DMake(51.079060, 4.350830),
                      CLLocationCoordinate2DMake(51.078210, 4.350490),
                      CLLocationCoordinate2DMake(51.077750, 4.350890),
                      CLLocationCoordinate2DMake(51.076760, 4.354600),
                      CLLocationCoordinate2DMake(51.075130, 4.351000),
                      CLLocationCoordinate2DMake(51.073800, 4.350690),
                      CLLocationCoordinate2DMake(52.071850, 4.352880),
                      CLLocationCoordinate2DMake(52.069320, 4.355940),
                      CLLocationCoordinate2DMake(52.069120, 4.356130),
                      CLLocationCoordinate2DMake(52.069120, 4.356130),
                      CLLocationCoordinate2DMake(52.069120, 4.356130),
                      CLLocationCoordinate2DMake(52.068570, 4.356950),
                      CLLocationCoordinate2DMake(52.067840, 4.358440),
                      CLLocationCoordinate2DMake(52.066730, 4.357490),
                      CLLocationCoordinate2DMake(52.066590, 4.358680),
                      CLLocationCoordinate2DMake(52.066580, 4.358680),
                      CLLocationCoordinate2DMake(52.066580, 4.358680),
                      CLLocationCoordinate2DMake(52.066830, 4.357490),
                      CLLocationCoordinate2DMake(52.067600, 4.358520),
                      CLLocationCoordinate2DMake(52.068650, 4.356920),
                      CLLocationCoordinate2DMake(52.074330, 4.350360),
                      CLLocationCoordinate2DMake(52.075520, 4.351880),
                      CLLocationCoordinate2DMake(52.076950, 4.355350),
                      CLLocationCoordinate2DMake(52.078000, 4.350690),
                      CLLocationCoordinate2DMake(52.078010, 4.350710),
                      CLLocationCoordinate2DMake(52.079520, 4.351560),
                      CLLocationCoordinate2DMake(52.080680, 4.350220),
                      CLLocationCoordinate2DMake(52.080760, 4.348890),
                      CLLocationCoordinate2DMake(52.079890, 4.349980),
                      CLLocationCoordinate2DMake(52.079890, 4.350000)]

        let polygon = MKPolyline(coordinates: amp;points, count: points.count)

        self.mapView.addOverlay(polygon)
        self.mapView.setVisibleMapRect(polygon.boundingMapRect, animated: true)

        var startPoint = points[0]
        
        for i in 1...(points.count-1) {
            
            guard let request = createRequest(c1:startPoint, c2:points[i]) else { return }
            let directions = MKDirections(request: request)

            directions.calculate { [unowned self] (response, error) in
                guard let response = response else { return }
                let routes = response.routes
                let bestDest = routes[0]
                startPoint = points[i]
            }
        }
    }

  

большое спасибо!

Ответ №1:

Вы можете использовать map для преобразования ваших координат

 let points: [CLLocationCoordinate2D] = coordinates.compactMap {
    guard let latitude = $0.lat, let longitude = $0.lng else { return nil }
    return CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
}
  

Это преобразует все объекты координат, для которых заданы как широта, так и долгота.

Вы уверены, что свойства могут быть нулевыми в координатах, если нет, то вышесказанное можно упростить до

 let points: [CLLocationCoordinate2D] = coordinates.map {
    CLLocationCoordinate2D(latitude: $0.lat, longitude: $0.lng)
}
  

Ответ №2:

основываясь на ответе Йоакима, я нашел полное решение для этого:

Итак, что вы делаете, чтобы передать некоторые данные координат с экрана A (скажем, у вас есть TableView) на экран B (у вас есть карта).

Итак, на экране A (ViewControllerA):

Вы определяете переменную координат (в соответствии с вашей моделью данных, конечно, обычно это должен быть массив)

 var coordinates = [Coordinates]()

  

Затем в вашем расширении UITableViewDelegate вы добавляете свои координаты в свой массив координат. Затем используйте prepare segue, чтобы передать его вашему целевому ViewController.

     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        if segue.identifier == Constants.segueTripListToTripMap {
            if let destinationVC = segue.destination as? TripMapViewController,
                let indexPath = sender as? IndexPath {
                
                
                for i in 0...(tripList[indexPath.section][indexPath.row].coordinates.count-1) {
                    self.coordinates.append(tripList[indexPath.section][indexPath.row].coordinates[i])
                }
                
       
                
                destinationVC.coordinatePoints = coordinates
                coordinates = []
                
                 
            }
        } else {
            if let destinationVC = segue.destination as? PolicyOverviewViewController,
                let indexPath = sender as? IndexPath {
                // do something
            }
        }

    }
  

На вашем экране B (где находится ваша карта). Вы определяете переменную для отслеживания передачи данных с экрана A, которая coordinatePoints

 var coordinatePoints: [Coordinates]?
  

затем в вашей функции рисования маршрута (или любым другим именем, которое вы ее называете). Вы преобразуете это coordinatePoints в CLLocationCoordinate2D тип, как показано ниже:

     func drawRoutes() {

        var points:[CLLocationCoordinate2D] = coordinatePoints?.compactMap {
            guard let latitude = $0.lat, let longitude = $0.lng else { return nil }
            return CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
            } ?? [CLLocationCoordinate2DMake(52.3676, 4.9041)]
                

        let polygon = MKPolyline(coordinates: amp;points, count: points.count)

        self.mapView.addOverlay(polygon)
        self.mapView.setVisibleMapRect(polygon.boundingMapRect, animated: true)

        var startPoint = points[0]
        
        for i in 1...(points.count-1) {
            
            guard let request = createRequest(c1:startPoint, c2:points[i]) else { return }
            let directions = MKDirections(request: request)

            directions.calculate { [unowned self] (response, error) in
                guard let response = response else { return }
                let routes = response.routes
                let bestDest = routes[0]
                startPoint = points[i]
            }
        }
    }

  

вот так, когда вы щелкаете ячейку таблицы на экране A, она должна передавать правильные координаты на экран B и отображать их на карте.

введите описание изображения здесь