Forked from jakehawken/SmoothedLocationPlayground2.swift
Created
September 16, 2017 05:36
-
-
Save jakebromberg/9c3ff0862904a9f300ae8a8c65d2e3e8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import CoreLocation | |
extension CLLocation { | |
public static func +(lhs: CLLocation, rhs: CLLocation) -> CLLocation { | |
let summedLat = lhs.coordinate.latitude + rhs.coordinate.latitude | |
let summedLong = lhs.coordinate.longitude + rhs.coordinate.longitude | |
return CLLocation(latitude: summedLat, longitude: summedLong) | |
} | |
public static func /(lhs: CLLocation, rhs: Double) -> CLLocation { | |
let dividedLat = lhs.coordinate.latitude / rhs | |
let dividedLong = lhs.coordinate.longitude / rhs | |
return CLLocation(latitude: dividedLat, longitude: dividedLong) | |
} | |
} | |
extension Collection { | |
/// Splits a collection into its first element and a SubSequence of the rest of its elements. | |
func split() -> (head: Element, tail: SubSequence)? { | |
guard let first = first else { | |
return nil | |
} | |
return (first, dropFirst()) | |
} | |
/// A simpler form of reduce. E.g., `[1, 2, 3].reduce(+) == 6` | |
func reduce(_ nextPartialResult: (Element, Element) throws -> Element) rethrows -> Element? { | |
guard let (head, tail) = split() else { | |
return nil | |
} | |
return try tail.reduce(head, nextPartialResult) | |
} | |
} | |
let coordinates = [ | |
(438.0, 236.0), | |
(439.0, 237.0), | |
(440.0, 238.0), | |
(450.0, 250.0), | |
(442.0, 240.0), | |
(444.0, 242.0) | |
] | |
// initialize the locations and sort them by distance to the origin | |
let locations = coordinates | |
.map(CLLocation.init) | |
.sorted { (loc1, loc2) -> Bool in | |
loc1.coordinate.latitude * loc1.coordinate.longitude < loc2.coordinate.latitude * loc2.coordinate.longitude | |
} | |
// discard the bottom quartile, which probably contains outliers | |
let realisticLocations = locations.prefix(3 * locations.count / 4) | |
let averageLocation = realisticLocations.reduce(+)! / Double(realisticLocations.count) | |
print(averageLocation.coordinate) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment