Skip to content

Commit

Permalink
Merge pull request #21 from raphaelmor/v2.0.0
Browse files Browse the repository at this point in the history
V2.0.0
  • Loading branch information
raphaelmor committed May 7, 2015
2 parents bf722d6 + 00d5f8f commit df6e9d2
Show file tree
Hide file tree
Showing 5 changed files with 348 additions and 346 deletions.
4 changes: 2 additions & 2 deletions Polyline.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Pod::Spec.new do |s|
#

s.name = "Polyline"
s.version = "1.1.0"
s.version = "2.0.0"
s.summary = "Polyline encoder / decoder in swift"

s.description = <<-DESC
Expand Down Expand Up @@ -68,7 +68,7 @@ Pod::Spec.new do |s|
# Supports git, hg, bzr, svn and HTTP.
#

s.source = { :git => "https://github.com/raphaelmor/Polyline.git", :tag => "v1.1.0" }
s.source = { :git => "https://github.com/raphaelmor/Polyline.git", :tag => "v2.0.0" }


# ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
Expand Down
131 changes: 64 additions & 67 deletions Polyline/Polyline.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,78 +38,72 @@ import CoreLocation
///
/// :see: https://developers.google.com/maps/documentation/utilities/polylinealgorithm
public struct Polyline {
/// The array of coordinates
public let coordinates: [CLLocationCoordinate2D]
/// The encoded polyline
public let encodedPolyline: String = ""
/// The array of levels
public let levels: [UInt32]?
/// The encoded levels
public let encodedLevels: String = ""
/// The array of location (computed from coordinates)
public var locations: [CLLocation] {
return toLocations(coordinates)
}
/// The array of coordinates (nil if polyline cannot be decoded)
public let coordinates: [CLLocationCoordinate2D]?
/// The encoded polyline
public let encodedPolyline: String
/// The array of levels (nil if cannot be decoded, or is not provided)
public let levels: [UInt32]?
/// The encoded levels (nil if cannot be encoded, or is not provided)
public let encodedLevels: String?
/// The array of location (computed from coordinates)
public var locations: [CLLocation]? {
return self.coordinates.map(toLocations)
}
// MARK: - Public Methods -

/// This designated init encodes an [CLLocationCoordinate2D] to a String
///
/// :param: coordinates The array of CLLocationCoordinate2D that you want to encode
/// :param: levels The optional array of levels that you want to encode
/// This designated initializer encodes a [CLLocationCoordinate2D]
///
/// :param: coordinates The array of CLLocationCoordinate2D that you want to encode
/// :param: levels The optional array of levels that you want to encode (default: nil)
/// :param: precision The precision used for encoding (default: 1e5)
public init(coordinates: [CLLocationCoordinate2D], levels: [UInt32]? = nil, precision: Double = 1e5) {

self.coordinates = coordinates
self.levels = levels

encodedPolyline = encodeCoordinates(coordinates, precision: precision)

if let levelsToEncode = levels {
encodedLevels = encodeLevels(levelsToEncode)
}
}

/// This designated init decodes a polyline String to an [CLLocation]
///
/// :param: encodedPolyline The polyline that you want to decode
/// :param: encodedLevels The levels that you want to decode
public init(encodedPolyline: String, encodedLevels: String? = nil, precision: Double = 1e5) {

self.encodedPolyline = encodedPolyline
coordinates = []

if let decodedCoordinates: [CLLocationCoordinate2D] = decodePolyline(encodedPolyline, precision: precision) {
coordinates = decodedCoordinates
}

if let levelsToDecode = encodedLevels {
self.encodedLevels = levelsToDecode

if let decodedLevels = decodeLevels(levelsToDecode) {
levels = decodedLevels
}
}
}

/// This init encodes an [CLLocation] to a String
///
/// :param: locations The array of CLLocation that you want to encode
/// :param: levels The optional array of levels that you want to encode
public init(locations: [CLLocation], levels: [UInt32]? = nil, precision: Double = 1e5) {

let coordinates = toCoordinates(locations)

self.coordinates = coordinates
self.levels = levels

encodedPolyline = encodeCoordinates(coordinates, precision: precision)

encodedLevels = levels.map(encodeLevels)
}

/// This designated initializer decodes a polyline String
///
/// :param: encodedPolyline The polyline that you want to decode
/// :param: encodedLevels The levels that you want to decode (default: nil)
/// :param: precision The precision used for decoding (default: 1e5)
public init(encodedPolyline: String, encodedLevels: String? = nil, precision: Double = 1e5) {

self.encodedPolyline = encodedPolyline
self.encodedLevels = encodedLevels

coordinates = decodePolyline(encodedPolyline, precision: precision)

levels = self.encodedLevels.flatMap(decodeLevels)
}

/// This init encodes a [CLLocation]
///
/// :param: locations The array of CLLocation that you want to encode
/// :param: levels The optional array of levels that you want to encode (default: nil)
/// :param: precision The precision used for encoding (default: 1e5)
public init(locations: [CLLocation], levels: [UInt32]? = nil, precision: Double = 1e5) {

let coordinates = toCoordinates(locations)
self.init(coordinates: coordinates, levels: levels, precision:precision)
}
}
}

// MARK: - Public Functions -

/// This function encodes an [CLLocationCoordinate2D] to a String
///
/// :param: coordinates The array of CLLocationCoordinate2D that you want to encode
/// :param: precision The precision used to encode coordinates (default: 1e5)
///
/// :returns: A String representing the encoded Polyline
public func encodeCoordinates(coordinates: [CLLocationCoordinate2D], precision: Double = 1e5) -> String {
Expand All @@ -131,9 +125,10 @@ public func encodeCoordinates(coordinates: [CLLocationCoordinate2D], precision:
return encodedPolyline
}

/// This function encodes an [CLLocationCoordinate2D] to a String
/// This function encodes an [CLLocation] to a String
///
/// :param: coordinates The array of CLLocationCoordinate2D that you want to encode
/// :param: coordinates The array of CLLocation that you want to encode
/// :param: precision The precision used to encode locations (default: 1e5)
///
/// :returns: A String representing the encoded Polyline
public func encodeLocations(locations: [CLLocation], precision: Double = 1e5) -> String {
Expand All @@ -152,9 +147,10 @@ public func encodeLevels(levels: [UInt32]) -> String {
}
}

/// This function decodes a String to an [CLLocationCoordinate2D]
/// This function decodes a String to a [CLLocationCoordinate2D]?
///
/// :param: encodedPolyline String representing the encoded Polyline
/// :param: precision The precision used to decode coordinates (default: 1e5)
///
/// :returns: A [CLLocationCoordinate2D] representing the decoded polyline if valid, nil otherwise
public func decodePolyline(encodedPolyline: String, precision: Double = 1e5) -> [CLLocationCoordinate2D]? {
Expand Down Expand Up @@ -186,9 +182,10 @@ public func decodePolyline(encodedPolyline: String, precision: Double = 1e5) ->
return decodedCoordinates
}

/// This function decodes a String to an [CLLocation]
/// This function decodes a String to a [CLLocation]?
///
/// :param: encodedPolyline String representing the encoded Polyline
/// :param: precision The precision used to decode locations (default: 1e5)
///
/// :returns: A [CLLocation] representing the decoded polyline if valid, nil otherwise
public func decodePolyline(encodedPolyline: String, precision: Double = 1e5) -> [CLLocation]? {
Expand All @@ -205,7 +202,7 @@ public func decodeLevels(encodedLevels: String) -> [UInt32]? {
var remainingLevels = encodedLevels.unicodeScalars
var decodedLevels = [UInt32]()

while countElements(remainingLevels) > 0 {
while count(remainingLevels) > 0 {
var result = extractNextChunk(&remainingLevels)
if result.failed {
return nil
Expand Down Expand Up @@ -275,7 +272,7 @@ private func encodeFiveBitComponents(value: Int) -> String {

// MARK: Decode Coordinate

// We use a byte array (UnsafePointer<Int8>) here for performance reasons. Check with swift 1.2 if we can
// We use a byte array (UnsafePointer<Int8>) here for performance reasons. Check with swift 1.2 if we can
// go back to using [Int8]
private func decodeSingleCoordinate(#byteArray: UnsafePointer<Int8>, #length: Int, inout #position: Int, precision: Double = 1e5) -> Result<Double> {

Expand Down
12 changes: 6 additions & 6 deletions PolylineTests/FunctionalPolylineTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ class FunctionalPolylineTests : XCTestCase {

func testEmptyPolylineShouldBeEmptyLocationArray() {
let coordinates: [CLLocationCoordinate2D] = decodePolyline("")!

XCTAssertEqual(countElements(coordinates), 0)
XCTAssertEqual(count(coordinates), 0)
}

func testInvalidPolylineShouldReturnEmptyLocationArray() {
Expand All @@ -107,7 +107,7 @@ class FunctionalPolylineTests : XCTestCase {
func testValidPolylineShouldReturnValidLocationArray() {
let coordinates: [CLLocationCoordinate2D] = decodePolyline("_p~iF~ps|U_ulLnnqC_mqNvxq`@")!

XCTAssertEqual(countElements(coordinates), 3)
XCTAssertEqual(count(coordinates), 3)
XCTAssertEqualWithAccuracy(coordinates[0].latitude, 38.5, COORD_EPSILON)
XCTAssertEqualWithAccuracy(coordinates[0].longitude, -120.2, COORD_EPSILON)
XCTAssertEqualWithAccuracy(coordinates[1].latitude, 40.7, COORD_EPSILON)
Expand All @@ -119,7 +119,7 @@ class FunctionalPolylineTests : XCTestCase {
func testAnotherValidPolylineShouldReturnValidLocationArray() {
let coordinates: [CLLocationCoordinate2D] = decodePolyline("_ojiHa`tLh{IdCw{Gwc_@")!

XCTAssertEqual(countElements(coordinates), 3)
XCTAssertEqual(count(coordinates), 3)
XCTAssertEqualWithAccuracy(coordinates[0].latitude, 48.8832, COORD_EPSILON)
XCTAssertEqualWithAccuracy(coordinates[0].longitude, 2.23761, COORD_EPSILON)
XCTAssertEqualWithAccuracy(coordinates[1].latitude, 48.82747, COORD_EPSILON)
Expand All @@ -142,7 +142,7 @@ class FunctionalPolylineTests : XCTestCase {

func testEmptyLevelsShouldBeEmptyLevelArray() {
if let resultArray = decodeLevels("") {
XCTAssertEqual(countElements(resultArray), 0)
XCTAssertEqual(count(resultArray), 0)
} else {
XCTFail("Level array should not be nil for empty string")
}
Expand All @@ -158,7 +158,7 @@ class FunctionalPolylineTests : XCTestCase {

func testValidLevelsShouldReturnValidLevelArray() {
if let resultArray = decodeLevels("?@AB~F") {
XCTAssertEqual(countElements(resultArray), 5)
XCTAssertEqual(count(resultArray), 5)
XCTAssertEqual(resultArray[0], UInt32(0))
XCTAssertEqual(resultArray[1], UInt32(1))
XCTAssertEqual(resultArray[2], UInt32(2))
Expand Down
Loading

0 comments on commit df6e9d2

Please sign in to comment.