Skip to content

Commit

Permalink
Modernized buffer access
Browse files Browse the repository at this point in the history
  • Loading branch information
1ec5 committed Nov 6, 2020
1 parent 0d13ff4 commit 0cd4499
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 27 deletions.
52 changes: 25 additions & 27 deletions Sources/Polyline/Polyline.swift
Original file line number Diff line number Diff line change
Expand Up @@ -175,34 +175,32 @@ public func encodeLevels(_ levels: [UInt32]) -> String {
///
/// - returns: A `[CLLocationCoordinate2D]` representing the decoded polyline if valid, `nil` otherwise
public func decodePolyline(_ encodedPolyline: String, precision: Double = 1e5) -> [LocationCoordinate2D]? {

let data = encodedPolyline.data(using: String.Encoding.utf8)!

let byteArray = (data as NSData).bytes.assumingMemoryBound(to: Int8.self)
let length = Int(data.count)
var position = Int(0)

var decodedCoordinates = [LocationCoordinate2D]()

var lat = 0.0
var lon = 0.0

while position < length {

do {
let resultingLat = try decodeSingleCoordinate(byteArray: byteArray, length: length, position: &position, precision: precision)
lat += resultingLat
let data = encodedPolyline.data(using: .utf8)!
return data.withUnsafeBytes { byteArray -> [LocationCoordinate2D]? in
let length = data.count
var position = 0

var decodedCoordinates = [LocationCoordinate2D]()

var lat = 0.0
var lon = 0.0

while position < length {
do {
let resultingLat = try decodeSingleCoordinate(byteArray: byteArray, length: length, position: &position, precision: precision)
lat += resultingLat

let resultingLon = try decodeSingleCoordinate(byteArray: byteArray, length: length, position: &position, precision: precision)
lon += resultingLon
} catch {
return nil
}

let resultingLon = try decodeSingleCoordinate(byteArray: byteArray, length: length, position: &position, precision: precision)
lon += resultingLon
} catch {
return nil
decodedCoordinates.append(LocationCoordinate2D(latitude: lat, longitude: lon))
}

decodedCoordinates.append(LocationCoordinate2D(latitude: lat, longitude: lon))
return decodedCoordinates
}

return decodedCoordinates
}

#if canImport(CoreLocation)
Expand Down Expand Up @@ -301,7 +299,7 @@ private func encodeFiveBitComponents(_ value: Int) -> String {

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

guard position < length else { throw PolylineError.singleCoordinateDecodingError }

Expand All @@ -314,7 +312,7 @@ private func decodeSingleCoordinate(byteArray: UnsafePointer<Int8>, length: Int,
var component: Int32 = 0

repeat {
currentChar = byteArray[position] - 63
currentChar = Int8(byteArray[position]) - 63
component = Int32(currentChar & bitMask)
coordinate |= (component << (5*componentCounter))
position += 1
Expand Down
9 changes: 9 additions & 0 deletions Tests/PolylineTests/FunctionalPolylineTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,13 @@ class FunctionalPolylineTests : XCTestCase {
#endif
}

func testDecodingPolyline() {
let coordinates = decodePolyline("afvnFdrebO@o@", precision: 1e5) as [LocationCoordinate2D]?
XCTAssertNotNil(coordinates)
XCTAssertEqual(coordinates?.count, 2)
XCTAssertEqual(coordinates?.first?.latitude ?? 0.0, 39.27665, accuracy: 1e-5)
XCTAssertEqual(coordinates?.first?.longitude ?? 0.0, -84.411389, accuracy: 1e-5)
XCTAssertEqual(coordinates?.last?.latitude ?? 0.0, 39.276635, accuracy: 1e-5)
XCTAssertEqual(coordinates?.last?.longitude ?? 0.0, -84.411148, accuracy: 1e-5)
}
}
1 change: 1 addition & 0 deletions Tests/PolylineTests/XCTestManifests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ extension FunctionalPolylineTests {
// to regenerate.
static let __allTests__FunctionalPolylineTests = [
("testAnotherValidPolylineShouldReturnValidLocationArray", testAnotherValidPolylineShouldReturnValidLocationArray),
("testDecodingPolyline", testDecodingPolyline),
("testEmptyArrayShouldBeEmptyString", testEmptyArrayShouldBeEmptyString),
("testEmptyLevelsShouldBeEmptyLevelArray", testEmptyLevelsShouldBeEmptyLevelArray),
("testEmptylevelsShouldBeEmptyString", testEmptylevelsShouldBeEmptyString),
Expand Down

0 comments on commit 0cd4499

Please sign in to comment.