Calculate Total Traveled Distance iOS Swift

Calculate Total Traveled Distance iOS Swift

update: Xcode 8.3.2 • Swift 3.1

The problem there is because you are always getting the same location over and over again. Try like this:

import UIKit
import MapKit

class ViewController: UIViewController, CLLocationManagerDelegate {
@IBOutlet weak var mapView: MKMapView!
let locationManager = CLLocationManager()
var startLocation: CLLocation!
var lastLocation: CLLocation!
var startDate: Date!
var traveledDistance: Double = 0
override func viewDidLoad() {
super.viewDidLoad()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
locationManager.startMonitoringSignificantLocationChanges()
locationManager.distanceFilter = 10
mapView.showsUserLocation = true
mapView.userTrackingMode = .follow
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if startDate == nil {
startDate = Date()
} else {
print("elapsedTime:", String(format: "%.0fs", Date().timeIntervalSince(startDate)))
}
if startLocation == nil {
startLocation = locations.first
} else if let location = locations.last {
traveledDistance += lastLocation.distance(from: location)
print("Traveled Distance:", traveledDistance)
print("Straight Distance:", startLocation.distance(from: locations.last!))
}
lastLocation = locations.last
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
if (error as? CLError)?.code == .denied {
manager.stopUpdatingLocation()
manager.stopMonitoringSignificantLocationChanges()
}
}
}

Sample Project

Calculating trip distance core location swift

If you get the distance like this using the first and last coordinate it always returns the wrong value because it can't identify the actual traveling path.

I did resolve the same issue with using the following code.

use GoogleMaps

> pod 'GoogleMaps'

Make the coordinates array while the driver is moving on a route.

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.

I did it in this app and it's working fine.
Hope it will helps you :)

OR without GoogleMaps

You have to come with locations, an array of CLLocationCoordinate2D, for yourself, as per your code, though.

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)
}
}

Output

Sample Image

Calculate total distance swift iOS

Make sure you have the following in your info.plist. Then you should get prompted to allow access to the location services.

<key>NSLocationAlwaysUsageDescription</key>
<string>Needs access to access GPS</string>
<key>NSLocationUsageDescription</key>
<string>Needs access to access GPS</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Needs access to access GPS</string>

You should have some thing like this in viewDidLoad.

override func viewDidLoad() {
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
}

Swift Getting total distance traveled ios 9

Isn't it trivial? You are printing the distance which is calculated over and over from the startLocation which will never change in your code. If I start in point A and go to B (there will be some distance in meters) and then go back to A and calculate from the startLocation (which is always A) it should be zero. :D

I didn't try your code but it seems to me this is what happens there. Print traveledDistance instead, this is the value that will always increase as you move around.

Fix your code like this:

print("\(traveledDistance)")
distanceLabel.text = "\(traveledDistance)"

If you only need the total distance I would change the code to look like this:

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [AnyObject]) {

/* for the ever first call the if check should fail because lastLocation is initially nil in your code (I assume) */
if lastLocation != nil {

/* this will start adding a distance at the second call of the callback */
traveledDistance += lastLocation.distanceFromLocation(locations.last as! CLLocation)

print("\(traveledDistance)")
distanceLabel.text = "\(traveledDistance)"
}

/* here we are saving the current location to our variable for later calculation */
lastLocation = locations.last as! CLLocation
}

Calculate travel time CLLocation Swift

You can save the startDate when you set the startLocation and use NSDate timeIntervalSinceDate method to calculate the travel elapsed time:

First add a startDate object and a computed property to your view controller:

var startDate: NSDate!
var traveledTime: Double { return NSDate().timeIntervalSinceDate(startDate) }

Then set the startDate after setting your startLocation:

if startLocation == nil {
startLocation = locations.first
startDate = NSDate()
// code ...
}

Create an extension to format your time using NSDateComponentsFormatter:

extension NSTimeInterval {
struct DateComponents {
static let formatterPositional: NSDateComponentsFormatter = {
let dateComponentsFormatter = NSDateComponentsFormatter()
dateComponentsFormatter.unitsStyle = .Positional
dateComponentsFormatter.allowedUnits = [.Hour,.Minute,.Second]
dateComponentsFormatter.zeroFormattingBehavior = .DropLeading
return dateComponentsFormatter
}()
}
var positionalTime: String {
return DateComponents.formatterPositional.stringFromTimeInterval(self) ?? ""
}
}

Now you can just check the traveledTime:

print("travel elapsed time: \(traveledTime.positionalTime)")


Related Topics



Leave a reply



Submit