-
Notifications
You must be signed in to change notification settings - Fork 90
/
RoadClasses.swift
104 lines (89 loc) · 3.59 KB
/
RoadClasses.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import Foundation
/**
Option set that contains attributes of a road segment.
*/
public struct RoadClasses: OptionSet, CustomStringConvertible {
public var rawValue: Int
public init(rawValue: Int) {
self.rawValue = rawValue
}
/**
The road segment is [tolled](https://wiki.openstreetmap.org/wiki/Key:toll).
*/
public static let toll = RoadClasses(rawValue: 1 << 1)
/**
The road segment has access restrictions.
A road segment may have this class if there are [general access restrictions](https://wiki.openstreetmap.org/wiki/Key:access) or a [high-occupancy vehicle](https://wiki.openstreetmap.org/wiki/Key:hov) restriction.
*/
public static let restricted = RoadClasses(rawValue: 1 << 2)
/**
The road segment is a [freeway](https://wiki.openstreetmap.org/wiki/Tag:highway%3Dmotorway) or [freeway ramp](https://wiki.openstreetmap.org/wiki/Tag:highway%3Dmotorway_link).
It may be desirable to suppress the name of the freeway when giving instructions and give instructions at fixed distances before an exit (such as 1 mile or 1 kilometer ahead).
*/
public static let motorway = RoadClasses(rawValue: 1 << 3)
/**
The user must travel this segment of the route by ferry.
The user should verify that the ferry is in operation. For driving and cycling directions, the user should also verify that his or her vehicle is permitted onboard the ferry.
In general, the transport type of the step containing the road segment is also `TransportType.ferry`.
*/
public static let ferry = RoadClasses(rawValue: 1 << 4)
/**
The user must travel this segment of the route through a [tunnel](https://wiki.openstreetmap.org/wiki/Key:tunnel).
*/
public static let tunnel = RoadClasses(rawValue: 1 << 5)
/**
Creates a `RoadClasses` given an array of strings.
*/
public init?(descriptions: [String]) {
var roadClasses: RoadClasses = []
for description in descriptions {
switch description {
case "toll":
roadClasses.insert(.toll)
case "restricted":
roadClasses.insert(.restricted)
case "motorway":
roadClasses.insert(.motorway)
case "ferry":
roadClasses.insert(.ferry)
case "tunnel":
roadClasses.insert(.tunnel)
case "":
continue
default:
return nil
}
}
self.init(rawValue: roadClasses.rawValue)
}
public var description: String {
var descriptions: [String] = []
if contains(.toll) {
descriptions.append("toll")
}
if contains(.restricted) {
descriptions.append("restricted")
}
if contains(.motorway) {
descriptions.append("motorway")
}
if contains(.ferry) {
descriptions.append("ferry")
}
if contains(.tunnel) {
descriptions.append("tunnel")
}
return descriptions.joined(separator: ",")
}
}
extension RoadClasses: Codable {
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(description.components(separatedBy: ",").filter { !$0.isEmpty })
}
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let descriptions = try container.decode([String].self)
self = RoadClasses(descriptions: descriptions)!
}
}