Расчет расстояния в пути - PullRequest
2 голосов
/ 08 марта 2019

У меня есть приложение, в котором я вычисляю пройденное расстояние, как приложение Uber. Когда водитель начинает поездку, местоположение начинает меняться, даже если в поиске поездки указана начальная точка, водитель может решить пройти альтернативный маршрут или пройти длинные места и маршруты, потому что он / она не знает кратчайший маршрут, как тогда рассчитать общее расстояние.

Начальное местоположение - это место, где водитель нажимает кнопку запуска. Конечное местоположение - это место, где водитель нажимает кнопку остановки

пока это мой код

    public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        lastLocation = locations.last!
        endTrip(locations.last)

        if !hasSetInitialLocation {

            let camera = GMSCameraPosition.camera(withTarget: lastLocation!.coordinate, zoom: 17)
            self.mapView.animate(to: camera)
            hasSetInitialLocation = true
            endTrip(lastLocation)
            MqttManager.instance.connectToServer()
        }
    }



func endTrip(endLoaction: CLLocation) {
        guard let statusChange = source.getStatusChange() else{return}
        var distanceTraveled: Double = 0.0
        let initialLocation = CLLocation(latitude: (statusChange.meta?.location?.lat)!, longitude: (statusChange.meta?.location?.lng)!)
        let distance = initialLocation.distance(from: endLoaction)
        distanceTraveled += distance
        let distanceInKM = Utility.convertCLLocationDistanceToKiloMeters(targetDistance: distanceTraveled)
}

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

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

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

enum DistanceValue: Int {
                case meters, miles
            }

            func calculateDistanceBetweenLocations(_ firstLocation: CLLocation, secondLocation: CLLocation, valueType: DistanceValue) -> Double {
                var distance = 0.0
                let meters = firstLocation.distance(from: secondLocation)
                distance += meters
                switch valueType {
                case .meters:
                    return distance
                case .miles:
                    let miles = distance
                    return miles
                }
            }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            if startLocation == nil {
                startLocation = locations.first
            } else if let location = locations.last {
                runDistance += lastLocation.distance(from: location)
                let calc = calculateDistanceBetweenLocations(lastLocation, secondLocation: location, valueType: .meters)

                print("TOTAL LOC 1 \(calc)")
                print("TOTAL LOC 2 \(runDistance)")
            }
            lastLocation = locations.last

        }

как показано в моих заявлениях для печати print("TOTAL LOC 1 \(calc)") print("TOTAL LOC 2 \(runDistance)") как я могу сделать

calc то же самое с runDistance

вот что напечатано в консоли

TOTAL LOC 10.29331530774379
TOTAL LOC 2 10.29331530774379
TOTAL LOC 2.2655118031831587
TOTAL LOC 2 12.558827110926948

1 Ответ

4 голосов
/ 12 марта 2019

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

Я решил ту же проблему с помощью следующего кода.

использовать GoogleMaps

> pod 'GoogleMaps'

Создать массив координат, пока водитель движется по маршруту.

var arr = [Any]() 
// Driving lat long co-ordinateds continues add in this array according to your expectation either update location or perticuler time duration.

// make GMSMutablePath of your co-ordinates
let path = GMSMutablePath()

    for obj in arr{

        print(obj)

        if let lat = (obj as? NSDictionary)?.value(forKey: PARAMETERS.LET) as? String{

            path.addLatitude(Double(lat)!, longitude: Double(((obj as? NSDictionary)?.value(forKey: PARAMETERS.LONG) as? String)!)!)

        }
    }

print(path) // Here is your traveling path
let km = GMSGeometryLength(path)
print(km) // your total traveling distance.

Я сделал это в этом приложении, и оно работает нормально. Надеюсь, это поможет вам:)

ИЛИ без GoogleMaps

Вы должны прийти с местоположениями, массивом CLLocationCoordinate2D, для себя, согласно вашему коду, однако.

class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
    // MARK: - Variables
    let locationManager = CLLocationManager()

    // MARK: - IBOutlet
    @IBOutlet weak var mapView: MKMapView!

    // MARK: - IBAction
    @IBAction func distanceTapped(_ sender: UIBarButtonItem) {
        let locations: [CLLocationCoordinate2D] = [...]
        var total: Double = 0.0
        for i in 0..<locations.count - 1 {
            let start = locations[i]
            let end = locations[i + 1]
            let distance = getDistance(from: start, to: end)
            total += distance
        }
        print(total)
    }

    func getDistance(from: CLLocationCoordinate2D, to: CLLocationCoordinate2D) -> CLLocationDistance {
        // By Aviel Gross
        // https://stackoverflow.com/questions/11077425/finding-distance-between-cllocationcoordinate2d-points
        let from = CLLocation(latitude: from.latitude, longitude: from.longitude)
        let to = CLLocation(latitude: to.latitude, longitude: to.longitude)
        return from.distance(from: to)
    }
}

выход

enter image description here

...