Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pretty Print Distances for iOS

I have two CLLocation objects and I would like the show the distance between them in a nice and pretty format. Like "22 feet", "58 yards", or "2.3 miles"

CLLocation *location1 = [[CLLocation alloc] initWithLatitude:42.333297 longitude:-71.588858];
CLLocation *location2 = [[CLLocation alloc] initWithLatitude:42.353297 longitude:-71.578858];

float target = [location1 getDistanceFrom:location2];

Basically, is there anything in the iOS library that can convert a distance to a pretty string or do I have to do this manually?

like image 806
coudron Avatar asked Dec 19 '11 22:12

coudron


5 Answers

import Foundation

extension Double {
  var prettyDistance: String {
    guard self > -.infinity else { return "?" }

    let formatter = LengthFormatter()
    formatter.numberFormatter.maximumFractionDigits = 2

    if self >= 1000 {
      return formatter.string(fromValue: self / 1000, unit: LengthFormatter.Unit.kilometer)
    } else {
      let value = Double(Int(self))
      return formatter.string(fromValue: value, unit: LengthFormatter.Unit.meter)
    }
  }
}

Double(1).prettyDistance // 1 m
Double(10).prettyDistance // 10 m
Double(100).prettyDistance // 100 m
Double(999).prettyDistance // 999 m
Double(1000).prettyDistance // 1 km
Double(1111).prettyDistance // 1.11 km
Double(5555).prettyDistance // 5.56 km
Double(9999).prettyDistance // 10 km
Double(10000).prettyDistance // 10 km
Double(99999).prettyDistance // 100 km
Double(100000).prettyDistance // 100 km
Double(555555).prettyDistance // 555.56 km
Double(999999).prettyDistance // 1,000 km
Double(1000000).prettyDistance // 1,000 km
Double(1234567890).prettyDistance // 1,234,567.89 km
like image 142
Changhoon Avatar answered Sep 20 '22 14:09

Changhoon


I just wanted to note, that, as with the release of iOS8 there will be new NSFormatters for exactly this kind of problem.

There will be NSLengthFormatter, NSMassFormatter and NSEnergyFormatter which are very easy to use – see this iOS8 NSFormatter tutorial. Here is an example using the LengthFormatter with swift:

let lengthFormatter = LengthFormatter()
print("Kilometer: ", lengthFormatter.string(fromValue:1000, unit: .kilometer)) //Kilometer: 1,000 km

Like with DateFormatter, you will no longer necessarily have to use NSLocale for printing the unit itself.

like image 26
Alexander Avatar answered Oct 18 '22 03:10

Alexander


iOS 7 (and OS X 10.9) introduced MKDistanceFormatter that does exactly what you need:

CLLocationDistance distance = 1320.0;
MKDistanceFormatter *df = [[MKDistanceFormatter alloc]init];
df.unitStyle = MKDistanceFormatterUnitStyleFull;

NSString *prettyString = [df stringFromDistance:distance];

Swift version:

let distance = 1320.0
let df = MKDistanceFormatter()
df.unitStyle = .Full

let prettyString = df.stringFromDistance(distance)

Swift 5.4.2:

import MapKit

let distance = 1320.0
let df = MKDistanceFormatter()
df.unitStyle = .full
let prettyString = df.string(fromDistance: distance)
like image 47
Klaas Avatar answered Oct 18 '22 04:10

Klaas


Unfortunately, you have to do this manually.

And if you do so, please don't forget to check:

[[[NSLocale currentLocale] objectForKey:NSLocaleUsesMetricSystem] boolValue]

The rest of the world would appreciate.

like image 12
Nicolas Bachschmidt Avatar answered Oct 18 '22 03:10

Nicolas Bachschmidt


TTTLocationFormatter from FormatterKit might be exactly what you are looking for. If it isn't you can probably use it as a starting point.

like image 4
sroske Avatar answered Oct 18 '22 04:10

sroske