Skip to content

Commit

Permalink
Outline support for Linux
Browse files Browse the repository at this point in the history
  • Loading branch information
frederoni committed Apr 10, 2019
1 parent 6daf1b0 commit da49354
Show file tree
Hide file tree
Showing 24 changed files with 174 additions and 93 deletions.
9 changes: 9 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ step-library:
command: bash <(curl -s https://codecov.io/bash)

jobs:
spm-linux-job:
docker:
- image: swift:5.0
steps:
- checkout
- run: swift build

spm-job:
parameters:
xcode:
Expand Down Expand Up @@ -126,3 +133,5 @@ workflows:
- spm-job:
name: "SPM_build"
xcode: "10.2.0"
- spm-linux-job:
name: "SPM_Ubuntu_build"
6 changes: 3 additions & 3 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
"pins": [
{
"package": "Polyline",
"repositoryURL": "https://github.com/raphaelmor/Polyline.git",
"repositoryURL": "https://github.com/frederoni/Polyline.git",
"state": {
"branch": "master",
"revision": "b5b6dff67db5d692c2253df79d9d6802953316b8",
"branch": "linux",
"revision": "5b189aca4675a442d280b93f0d6c16d76f297e48",
"version": null
}
}
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ let package = Package(
],
dependencies: [
// Dependencies declare other packages that this package depends on.
.package(url: "https://github.com/raphaelmor/Polyline.git", .branch("master"))
.package(url: "https://github.com/frederoni/Polyline.git", .branch("linux"))
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import Foundation
#if !os(Linux)
import CoreLocation
#endif

extension CLLocation {
/**
Initializes a CLLocation object with the given coordinate pair.
*/
internal convenience init(coordinate: CLLocationCoordinate2D) {
internal init(coordinate: CLLocationCoordinate2D) {
self.init(latitude: coordinate.latitude, longitude: coordinate.longitude)
}
}
Expand Down
3 changes: 1 addition & 2 deletions Sources/MapboxDirections/MBComponentRepresentable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ import Foundation
/**
The component representable protocol that comprises what the instruction banner should display.
*/
@objc(MBComponentRepresentable)
public protocol ComponentRepresentable: class, NSSecureCoding { }
public protocol ComponentRepresentable: NSObjectProtocol, NSSecureCoding { }
3 changes: 3 additions & 0 deletions Sources/MapboxDirections/MBCoordinateBounds.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import Foundation
#if !os(Linux)
import CoreLocation
#endif


/**
A bounding box represents a geographic region.
Expand Down
5 changes: 4 additions & 1 deletion Sources/MapboxDirections/MBDirections.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,12 @@ let userAgent: String = {
#elseif os(Linux)
system = "Linux"
#endif

#if !os(Linux) // TODO: Linux is missing ProcessInfo.operatingSystemVersion
let systemVersion = ProcessInfo().operatingSystemVersion
components.append("\(system)/\(systemVersion.majorVersion).\(systemVersion.minorVersion).\(systemVersion.patchVersion)")

#endif

let chip: String
#if arch(x86_64)
chip = "x86_64"
Expand Down
31 changes: 18 additions & 13 deletions Sources/MapboxDirections/MBDirectionsOptions.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Foundation
import Polyline
#if !os(Linux)
import CoreLocation
#endif


/**
Expand Down Expand Up @@ -67,19 +69,24 @@ extension RouteShapeFormat {
func coordinates(from geometry: Any?) -> [CLLocationCoordinate2D]? {
switch self {
case .geoJSON:
if let geometry = geometry as? JSONDictionary {
return CLLocationCoordinate2D.coordinates(geoJSON: geometry)
}
return nil
// TODO:
// if let geometry = geometry as? JSONDictionary {
// return CLLocationCoordinate2D.coordinates(geoJSON: geometry)
// }
case .polyline:
if let geometry = geometry as? String {
return decodePolyline(geometry, precision: 1e5)!
}
return nil
// TODO:
// if let geometry = geometry as? String {
// return decodePolyline(geometry, precision: 1e5)!
// }
case .polyline6:
if let geometry = geometry as? String {
return decodePolyline(geometry, precision: 1e6)!
}
return nil
// TODO:
// if let geometry = geometry as? String {
// return decodePolyline(geometry, precision: 1e6)!
// }
}
return nil
}
}

Expand Down Expand Up @@ -222,7 +229,6 @@ public enum InstructionFormat: UInt, CustomStringConvertible {
You do not create instances of this class directly. Instead, create instances of `MatchOptions` or `RouteOptions`.
*/
@objcMembers
@objc(MBDirectionsOptions)
open class DirectionsOptions: NSObject, NSSecureCoding, NSCopying {

/**
Expand All @@ -243,7 +249,7 @@ open class DirectionsOptions: NSObject, NSSecureCoding, NSCopying {
}

// MARK: NSCopying
@objc open func copy(with zone: NSZone? = nil) -> Any {
open func copy(with zone: NSZone? = nil) -> Any {
let copy = type(of: self).init(waypoints: waypoints, profileIdentifier: profileIdentifier)
copy.includesSteps = includesSteps
copy.shapeFormat = shapeFormat
Expand All @@ -262,7 +268,6 @@ open class DirectionsOptions: NSObject, NSSecureCoding, NSCopying {
return isEqual(to: opts)
}

@objc(isEqualToDirectionsOptions:)
open func isEqual(to directionsOptions: DirectionsOptions?) -> Bool {
guard let other = directionsOptions else { return false }
guard type(of: self) == type(of: other) else { return false }
Expand Down
24 changes: 13 additions & 11 deletions Sources/MapboxDirections/MBDirectionsResult.swift
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import Foundation
import Polyline
#if !os(Linux)
import CoreLocation
#endif


/**
A `DirectionsResult` represents a result returned from either the Mapbox Directions service.
You do not create instances of this class directly. Instead, you receive `Route` or `Match` objects when you request directions using the `Directions.calculate(_:completionHandler:)` or `Directions.calculateRoutes(matching:completionHandler:)` method.
*/
@objc(MBDirectionsResult)
@objcMembers
open class DirectionsResult: NSObject, NSSecureCoding {

public var json: [String: Any]?

@objc internal init(json: [String: Any]? = nil, legs: [RouteLeg], distance: CLLocationDistance, expectedTravelTime: TimeInterval, coordinates: [CLLocationCoordinate2D]?, speechLocale: Locale?, options: DirectionsOptions) {
internal init(json: [String: Any]? = nil, legs: [RouteLeg], distance: CLLocationDistance, expectedTravelTime: TimeInterval, coordinates: [CLLocationCoordinate2D]?, speechLocale: Locale?, options: DirectionsOptions) {
self.json = json
self.directionsOptions = options
self.legs = legs
Expand All @@ -23,7 +25,7 @@ open class DirectionsResult: NSObject, NSSecureCoding {
self.speechLocale = speechLocale
}

@objc public required init?(coder decoder: NSCoder) {
public required init?(coder decoder: NSCoder) {
accessToken = decoder.decodeObject(of: NSString.self, forKey: "accessToken") as String?
apiEndpoint = decoder.decodeObject(of: NSURL.self, forKey: "apiEndpoint") as URL?

Expand Down Expand Up @@ -55,7 +57,7 @@ open class DirectionsResult: NSObject, NSSecureCoding {
return true
}

@objc public func encode(with coder: NSCoder) {
public func encode(with coder: NSCoder) {
coder.encode(accessToken, forKey: "accessToken")
coder.encode(apiEndpoint, forKey: "apiEndpoint")

Expand All @@ -80,7 +82,7 @@ open class DirectionsResult: NSObject, NSSecureCoding {
Using the [Mapbox Maps SDK for iOS](https://docs.mapbox.com/ios/maps/) or [Mapbox Maps SDK for macOS](https://mapbox.github.io/mapbox-gl-native/macos/), you can create an `MGLPolyline` object using these coordinates to display an overview of the route on an `MGLMapView`.
*/
@objc public let coordinates: [CLLocationCoordinate2D]?
public let coordinates: [CLLocationCoordinate2D]?

/**
The number of coordinates.
Expand All @@ -89,7 +91,7 @@ open class DirectionsResult: NSObject, NSSecureCoding {
- note: This initializer is intended for Objective-C usage. In Swift code, use the `coordinates.count` property.
*/
@objc open var coordinateCount: UInt {
open var coordinateCount: UInt {
return UInt(coordinates?.count ?? 0)
}

Expand All @@ -106,7 +108,7 @@ open class DirectionsResult: NSObject, NSSecureCoding {
- note: This initializer is intended for Objective-C usage. In Swift code, use the `coordinates` property.
*/
@objc open func getCoordinates(_ coordinates: UnsafeMutablePointer<CLLocationCoordinate2D>) {
open func getCoordinates(_ coordinates: UnsafeMutablePointer<CLLocationCoordinate2D>) {
for i in 0..<(self.coordinates?.count ?? 0) {
coordinates.advanced(by: i).pointee = self.coordinates![i]
}
Expand All @@ -119,9 +121,9 @@ open class DirectionsResult: NSObject, NSSecureCoding {
To determine the name of the route, concatenate the names of the route’s legs.
*/
@objc public let legs: [RouteLeg]
public let legs: [RouteLeg]

@objc open override var description: String {
open override var description: String {
return legs.map { $0.name }.joined(separator: "")
}

Expand All @@ -132,7 +134,7 @@ open class DirectionsResult: NSObject, NSSecureCoding {
The value of this property accounts for the distance that the user must travel to traverse the path of the route. It is the sum of the `distance` properties of the route’s legs, not the sum of the direct distances between the route’s waypoints. You should not assume that the user would travel along this distance at a fixed speed.
*/
@objc public let distance: CLLocationDistance
public let distance: CLLocationDistance

/**
The route’s expected travel time, measured in seconds.
Expand All @@ -141,7 +143,7 @@ open class DirectionsResult: NSObject, NSSecureCoding {
Do not assume that the user would travel along the route at a fixed speed. For more granular travel times, use the `RouteLeg.expectedTravelTime` or `RouteStep.expectedTravelTime`. For even more granularity, specify the `AttributeOptions.expectedTravelTime` option and use the `RouteLeg.expectedSegmentTravelTimes` property.
*/
@objc public let expectedTravelTime: TimeInterval
public let expectedTravelTime: TimeInterval

/**
`RouteOptions` used to create the directions request.
Expand Down
4 changes: 3 additions & 1 deletion Sources/MapboxDirections/MBIntersection.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import Foundation
#if !os(Linux)
import CoreLocation
#endif


/**
A single cross street along a step.
*/
@objc(MBIntersection)
@objcMembers
public class Intersection: NSObject, NSSecureCoding {
/**
The geographic coordinates at the center of the intersection.
Expand Down
16 changes: 11 additions & 5 deletions Sources/MapboxDirections/MBRoute.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Foundation
#if !os(Linux)
import CoreLocation
#endif
import Polyline


Expand All @@ -8,11 +10,11 @@ import Polyline
Typically, you do not create instances of this class directly. Instead, you receive route objects when you request directions using the `Directions.calculate(_:completionHandler:)` method. However, if you use the `Directions.url(forCalculating:)` method instead, you can pass the results of the HTTP request into this class’s initializer.
*/
@objc(MBRoute)
@objcMembers
open class Route: DirectionsResult {
// MARK: Creating a Route

@objc internal override init(json: [String : Any]? = nil, legs: [RouteLeg], distance: CLLocationDistance, expectedTravelTime: TimeInterval, coordinates: [CLLocationCoordinate2D]?, speechLocale: Locale?, options: DirectionsOptions) {
internal override init(json: [String : Any]? = nil, legs: [RouteLeg], distance: CLLocationDistance, expectedTravelTime: TimeInterval, coordinates: [CLLocationCoordinate2D]?, speechLocale: Locale?, options: DirectionsOptions) {
super.init(json: json, legs: legs, distance: distance, expectedTravelTime: expectedTravelTime, coordinates: coordinates, speechLocale: speechLocale, options: options)
}

Expand All @@ -25,7 +27,6 @@ open class Route: DirectionsResult {
- parameter waypoints: An array of waypoints that the route visits in chronological order.
- parameter options: The options used when requesting the route.
*/
@objc(initWithJSON:waypoints:routeOptions:)
public init(json: [String: Any], waypoints: [Waypoint], options: RouteOptions) {
// Associate each leg JSON with a source and destination. The sequence of destinations is offset by one from the sequence of sources.
let legInfo = zip(zip(waypoints.prefix(upTo: waypoints.endIndex - 1), waypoints.suffix(from: 1)),
Expand All @@ -50,7 +51,7 @@ open class Route: DirectionsResult {
return super.directionsOptions as! RouteOptions
}

@objc public required init?(coder decoder: NSCoder) {
public required init?(coder decoder: NSCoder) {
super.init(coder: decoder)
}

Expand All @@ -72,7 +73,12 @@ internal class RouteV4: Route {
case let geometry as JSONDictionary:
coordinates = CLLocationCoordinate2D.coordinates(geoJSON: geometry)
case let geometry as String:
coordinates = decodePolyline(geometry, precision: 1e6)!
//let polylineCoords = decodePolyline(geometry, precision: 1e6)!
// TODO: MapboxDirections.CLLocationCoordinate2D for linux
// TODO: Polyline.CLLocationCoordinate2D
//coordinates = decodePolyline(geometry, precision: 1e6)!
print(geometry)
coordinates = nil
default:
coordinates = nil
}
Expand Down
8 changes: 4 additions & 4 deletions Sources/MapboxDirections/MBRouteLeg.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Foundation
#if !os(Linux)
import CoreLocation
#endif
import Polyline


Expand All @@ -9,12 +11,11 @@ import Polyline
You do not create instances of this class directly. Instead, you receive route leg objects as part of route objects when you request directions using the `Directions.calculate(_:completionHandler:)` method.
*/
@objcMembers
@objc(MBRouteLeg)
open class RouteLeg: NSObject, NSSecureCoding {

// MARK: Creating a Leg

@objc internal init(steps: [RouteStep], json: JSONDictionary, source: Waypoint, destination: Waypoint, options: RouteOptions) {
internal init(steps: [RouteStep], json: JSONDictionary, source: Waypoint, destination: Waypoint, options: RouteOptions) {
self.source = source
self.destination = destination
self.profileIdentifier = options.profileIdentifier
Expand Down Expand Up @@ -61,7 +62,6 @@ open class RouteLeg: NSObject, NSSecureCoding {
- parameter destination: The waypoint at the end of the leg.
- parameter options: The options used when requesting the route.
*/
@objc(initWithJSON:source:destination:options:)
public convenience init(json: [String: Any], source: Waypoint, destination: Waypoint, options: RouteOptions) {
let steps = (json["steps"] as? [JSONDictionary] ?? []).map { RouteStep(json: $0, options: options) }
self.init(steps: steps, json: json, source: source, destination: destination, options: options)
Expand Down Expand Up @@ -142,7 +142,7 @@ open class RouteLeg: NSObject, NSSecureCoding {
This array is empty if the `includesSteps` property of the original `RouteOptions` object is set to `false`.
*/
@objc public let steps: [RouteStep]
public let steps: [RouteStep]


/**
Expand Down
5 changes: 2 additions & 3 deletions Sources/MapboxDirections/MBRouteOptions.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Foundation
#if !os(Linux)
import CoreLocation
#endif

#if SWIFT_PACKAGE
public enum MBDirectionsProfileIdentifier: String {
Expand All @@ -16,7 +18,6 @@ public enum MBDirectionsProfileIdentifier: String {
Pass an instance of this class into the `Directions.calculate(_:completionHandler:)` method.
*/
@objcMembers
@objc(MBRouteOptions)
open class RouteOptions: DirectionsOptions {
/**
Initializes a route options object for routes between the given locations and an optional profile identifier.
Expand Down Expand Up @@ -208,7 +209,6 @@ open class RouteOptions: DirectionsOptions {
return isEqual(to: opts)
}

@objc(isEqualToRouteOptions:)
open func isEqual(to routeOptions: RouteOptions?) -> Bool {
guard let other = routeOptions else { return false }
guard super.isEqual(to: routeOptions) else { return false }
Expand All @@ -226,7 +226,6 @@ open class RouteOptions: DirectionsOptions {
Pass an instance of this class into the `Directions.calculate(_:completionHandler:)` method.
*/
@objcMembers
@objc(MBRouteOptionsV4)
open class RouteOptionsV4: RouteOptions {
// MARK: Specifying the Response Format

Expand Down
Loading

0 comments on commit da49354

Please sign in to comment.