Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Linux #55

Merged
merged 4 commits into from
Nov 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
language: objective-c
language: bash
os:
- linux
- osx
osx_image: xcode12.2
before_script:
- export LANG=en_US.UTF-8
- export SWIFT_VERSION=5.0
script:
- xcodebuild $ACTION -project Polyline.xcodeproj -scheme "$SCHEME" -destination "$DESTINATION" ONLY_ACTIVE_ARCH=NO
- swift build && swift test
env:
- SCHEME=Polyline ACTION=test DESTINATION='platform=iOS Simulator,name=iPhone 11,OS=14.2' ONLY_ACTIVE_ARCH=NO
- SCHEME=PolylineMac ACTION=test DESTINATION='platform=OS X'
- SCHEME=PolylineTV ACTION=test DESTINATION='platform=tvOS Simulator,name=Apple TV,OS=14.2'
- SCHEME=PolylineWatch ACTION=build DESTINATION='platform=watchOS Simulator,name=Apple Watch Series 6 - 44mm,OS=7.1'
- ./.travis/build.sh
matrix:
include:
- os: osx
env: SCHEME=Polyline ACTION=test DESTINATION='platform=iOS Simulator,name=iPhone 11,OS=14.2' ONLY_ACTIVE_ARCH=NO
- os: osx
env: SCHEME=PolylineMac ACTION=test DESTINATION='platform=OS X'
- os: osx
env: SCHEME=PolylineTV ACTION=test DESTINATION='platform=tvOS Simulator,name=Apple TV,OS=14.2'
- os: osx
env: SCHEME=PolylineWatch ACTION=build DESTINATION='platform=watchOS Simulator,name=Apple Watch Series 6 - 44mm,OS=7.1'
exclude:
- os: osx
12 changes: 12 additions & 0 deletions .travis/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

if [[ $TRAVIS_OS_NAME == 'osx' ]]; then
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Travis never seems to get here. Travis is effectively only building the library on Linux and never testing it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #66.

xcodebuild $ACTION -project Polyline.xcodeproj -scheme "$SCHEME" -destination "$DESTINATION" ONLY_ACTIVE_ARCH=NO
swift build
swift test
fi

if [[ $TRAVIS_OS_NAME == 'linux' ]]; then
eval "$(curl -sL https://swiftenv.fuller.li/install.sh)"
swift build
fi
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ Polyline encoder / decoder in Swift
## Requirements

- Xcode 11+
- iOS 10.0+ / Mac OS X 10.12+ / tvOS 10.0+ / watchOS 3.0+
- iOS 10.0+ / Mac OS X 10.12+ / tvOS 10.0+ / watchOS 3.0+ / Linux
- Swift 5.0

---


## Integration
To use this library in your project you can use CocoaPods, Carthage, and/or integrate it manually :
To use this library in your project you can use CocoaPods, Carthage, Swift Package Manager, and/or integrate it manually :

### CocoaPods
You can integrate Polyline in your `Podfile` like this:
Expand All @@ -70,7 +70,7 @@ github "raphaelmor/Polyline" ~> 4.0
You can integrate Polyline using the [Swift Package Manager](https://swift.org/package-manager/), add the following package to the `dependencies` in your Package.swift file:

```swift
.Package(url: "https://github.com/raphaelmor/Polyline.git", .upToNextMinor(from: "4.2.1"))
.package(url: "https://github.com/raphaelmor/Polyline.git", from: "4.2.1")
```

### Manual
Expand Down
48 changes: 48 additions & 0 deletions Sources/Polyline/CoreLocation.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Polyline.swift
//
// Copyright (c) 2015 Raphaël Mor
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

import Foundation
#if canImport(CoreLocation)
import CoreLocation
#endif

#if canImport(CoreLocation)
/**
A geographic coordinate.

This is a compatibility shim to keep the library’s public interface consistent between Apple and non-Apple platforms that lack Core Location. On Apple platforms, you can use `CLLocationCoordinate2D` anywhere you see this type.
*/
public typealias LocationCoordinate2D = CLLocationCoordinate2D
#else
/**
A geographic coordinate.
*/
public struct LocationCoordinate2D {
let latitude: Double
let longitude: Double

public init(latitude: Double, longitude: Double) {
self.latitude = latitude
self.longitude = longitude
}
}
#endif
32 changes: 23 additions & 9 deletions Sources/Polyline/Polyline.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@
// SOFTWARE.

import Foundation
#if canImport(CoreLocation)
import CoreLocation
#endif
#if canImport(MapKit)
import MapKit
#endif

// MARK: - Public Classes -

Expand All @@ -41,7 +45,7 @@ import MapKit
public struct Polyline {

/// The array of coordinates (nil if polyline cannot be decoded)
public let coordinates: [CLLocationCoordinate2D]?
public let coordinates: [LocationCoordinate2D]?
/// The encoded polyline
public let encodedPolyline: String

Expand All @@ -51,11 +55,13 @@ public struct Polyline {
public let encodedLevels: String?

/// The array of location (computed from coordinates)
#if canImport(CoreLocation)
public var locations: [CLLocation]? {
return self.coordinates.map(toLocations)
}
#endif

#if !os(watchOS)
#if canImport(MapKit)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On watchOS, MapKit can be imported, but its symbols are marked as unavailable, triggering the following compiler error:

/path/to/Polyline/Sources/Polyline/Polyline.swift:67:28: 'MKPolyline' is unavailable in watchOS
/MapKit.MKPolyline:2:12: 'MKPolyline' has been explicitly marked unavailable here

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #67.

/// Convert polyline to MKPolyline to use with MapKit (nil if polyline cannot be decoded)
@available(tvOS 9.2, *)
public var mkPolyline: MKPolyline? {
Expand All @@ -69,10 +75,10 @@ public struct Polyline {

/// This designated initializer encodes a `[CLLocationCoordinate2D]`
///
/// - parameter coordinates: The `Array` of `CLLocationCoordinate2D` that you want to encode
/// - parameter coordinates: The `Array` of `LocationCoordinate2D`s (that is, `CLLocationCoordinate2D`s) that you want to encode
/// - parameter levels: The optional `Array` of levels that you want to encode (default: `nil`)
/// - parameter precision: The precision used for encoding (default: `1e5`)
public init(coordinates: [CLLocationCoordinate2D], levels: [UInt32]? = nil, precision: Double = 1e5) {
public init(coordinates: [LocationCoordinate2D], levels: [UInt32]? = nil, precision: Double = 1e5) {

self.coordinates = coordinates
self.levels = levels
Expand All @@ -97,6 +103,7 @@ public struct Polyline {
levels = self.encodedLevels.flatMap(decodeLevels)
}

#if canImport(CoreLocation)
/// This init encodes a `[CLLocation]`
///
/// - parameter locations: The `Array` of `CLLocation` that you want to encode
Expand All @@ -107,17 +114,18 @@ public struct Polyline {
let coordinates = toCoordinates(locations)
self.init(coordinates: coordinates, levels: levels, precision:precision)
}
#endif
}

// MARK: - Public Functions -

/// This function encodes an `[CLLocationCoordinate2D]` to a `String`
///
/// - parameter coordinates: The `Array` of `CLLocationCoordinate2D` that you want to encode
/// - parameter coordinates: The `Array` of `LocationCoordinate2D`s (that is, `CLLocationCoordinate2D`s) that you want to encode
/// - parameter 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 {
public func encodeCoordinates(_ coordinates: [LocationCoordinate2D], precision: Double = 1e5) -> String {

var previousCoordinate = IntegerCoordinates(0, 0)
var encodedPolyline = ""
Expand All @@ -136,6 +144,7 @@ public func encodeCoordinates(_ coordinates: [CLLocationCoordinate2D], precision
return encodedPolyline
}

#if canImport(CoreLocation)
/// This function encodes an `[CLLocation]` to a `String`
///
/// - parameter coordinates: The `Array` of `CLLocation` that you want to encode
Expand All @@ -146,6 +155,7 @@ public func encodeLocations(_ locations: [CLLocation], precision: Double = 1e5)

return encodeCoordinates(toCoordinates(locations), precision: precision)
}
#endif

/// This function encodes an `[UInt32]` to a `String`
///
Expand All @@ -164,15 +174,15 @@ public func encodeLevels(_ levels: [UInt32]) -> String {
/// - parameter 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]? {
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 = [CLLocationCoordinate2D]()
var decodedCoordinates = [LocationCoordinate2D]()

var lat = 0.0
var lon = 0.0
Expand All @@ -189,12 +199,13 @@ public func decodePolyline(_ encodedPolyline: String, precision: Double = 1e5) -
return nil
}

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

return decodedCoordinates
}

#if canImport(CoreLocation)
/// This function decodes a String to a [CLLocation]?
///
/// - parameter encodedPolyline: String representing the encoded Polyline
Expand All @@ -205,6 +216,7 @@ public func decodePolyline(_ encodedPolyline: String, precision: Double = 1e5) -

return decodePolyline(encodedPolyline, precision: precision).map(toLocations)
}
#endif

/// This function decodes a `String` to an `[UInt32]`
///
Expand Down Expand Up @@ -370,6 +382,7 @@ enum PolylineError: Error {
case chunkExtractingError
}

#if canImport(CoreLocation)
private func toCoordinates(_ locations: [CLLocation]) -> [CLLocationCoordinate2D] {
return locations.map {location in location.coordinate}
}
Expand All @@ -379,6 +392,7 @@ private func toLocations(_ coordinates: [CLLocationCoordinate2D]) -> [CLLocation
CLLocation(latitude:coordinate.latitude, longitude:coordinate.longitude)
}
}
#endif

private func isSeparator(_ value: Int32) -> Bool {
return (value - 63) & 0x20 != 0x20
Expand Down
5 changes: 3 additions & 2 deletions Tests/LinuxMain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ import XCTest
import PolylineTests

var tests = [XCTestCaseEntry]()
tests += PolylineTests.allTests()
XCTMain(tests)
tests += PolylineTests.__allTests()

XCTMain(tests)
4 changes: 4 additions & 0 deletions Tests/PolylineTests/FunctionalPolylineTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#if canImport(CoreLocation)
import CoreLocation
#endif
import XCTest

import Polyline
Expand Down Expand Up @@ -172,10 +174,12 @@ class FunctionalPolylineTests : XCTestCase {

// MARK: - Encoding Locations
func testLocationsArrayShouldBeEncodedProperly() {
#if canImport(CoreLocation)
let locations = [CLLocation(latitude: 0.00001, longitude: 0.00001),
CLLocation(latitude: 0.00000, longitude: 0.00000)]

XCTAssertEqual(encodeLocations(locations), "AA@@")
#endif
}

}
Loading