-
Notifications
You must be signed in to change notification settings - Fork 46
Expand file tree
/
Copy pathMBGeocodeOptions.swift
More file actions
257 lines (207 loc) · 11 KB
/
MBGeocodeOptions.swift
File metadata and controls
257 lines (207 loc) · 11 KB
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
#if !os(tvOS)
import Contacts
#endif
/**
A structure that specifies the criteria for results returned by the Mapbox Geocoding API.
You do not create instances of `GeocodeOptions` directly. Instead, you create instances of `ForwardGeocodeOptions` and `ReverseGeocodeOptions`, depending on the kind of geocoding you want to perform:
- _Forward geocoding_ takes a human-readable query, such as a place name or address, and produces any number of geographic coordinates that correspond to that query. To perform forward geocoding, use a `ForwardGeocodeOptions` object.
- _Reverse geocoding_ takes a geographic coordinate and produces a hierarchy of places, often beginning with an address, that describes the coordinate’s location. To perform reverse geocoding, use a `ReverseGeocodeOptions` object.
Pass an instance of either class into the `Geocoder.geocode(_:completionHandler:)` method.
*/
@objc(MBGeocodeOptions)
open class GeocodeOptions: NSObject {
// MARK: Specifying the Search Criteria
/**
An array of [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country codes specifying the countries in which the results may lie. The codes may appear in any order and are case-insensitive.
By default, no country codes are specified.
To find out what kinds of results are available for a particular country, consult [the Geocoding API’s coverage map](https://www.mapbox.com/geocoding/#coverage).
*/
@objc open var allowedISOCountryCodes: [String]?
/**
A location to use as a hint when looking up the specified address.
This property prioritizes results that are close to a specific location, which is typically the user’s current location. If the value of this property is `nil` – which it is by default – no specific location is prioritized.
*/
@objc open var focalLocation: CLLocation?
/**
The bitmask of placemark scopes, such as country and neighborhood, to include in the results.
The default value of this property is `PlacemarkScope.all`, which includes all scopes.
*/
@objc open var allowedScopes: PlacemarkScope = [.all]
/**
The region in which each resulting placemark must be located.
By default, no region is specified, so results may be located anywhere in the world.
*/
@objc open var allowedRegion: RectangularRegion?
/**
Limit the number of results returned. For forward geocoding, the default is `5` and the maximum is `10`. For reverse geocoding, the default is `1` and the maximum is `5`.
*/
@objc public var maximumResultCount: UInt
// MARK: Specifying the Output Format
/**
The locale in which results should be returned.
This property affects the language of returned results; generally speaking, it does not determine which results are found. If the Geocoding API does not recognize the language code, it may fall back to another language or the default language. Components other than the language code, such as the country and script codes, are ignored.
By default, this property is set to `nil`, causing results to be in the default language.
- experiment: This option is experimental.
*/
@objc open var locale: Locale?
/**
A Boolean value that determines whether the resulting placemarks have the `Placemark.routableLocation` property set.
*/
@objc open var includesRoutableLocations: Bool = false
fileprivate override init() {
self.maximumResultCount = 0
super.init()
}
/**
An array of geocoding query strings to include in the request URL.
*/
internal var queries: [String] = []
/**
The query mode of the forward or reverse geocoding request.
*/
internal var mode = "mapbox.places"
/**
An array of URL parameters to include in the request URL.
*/
internal var params: [URLQueryItem] {
var params: [URLQueryItem] = []
if let allowedISOCountryCodes = allowedISOCountryCodes {
assert(allowedISOCountryCodes.filter {
$0.count != 2 || $0.contains("-")
}.isEmpty, "Only ISO 3166-1 alpha-2 codes are allowed.")
let codeList = allowedISOCountryCodes.joined(separator: ",").lowercased()
params.append(URLQueryItem(name: "country", value: codeList))
}
if let focalLocation = focalLocation {
params.append(URLQueryItem(name: "proximity", value: "\(focalLocation.coordinate.longitude),\(focalLocation.coordinate.latitude)"))
}
if !allowedScopes.isEmpty && allowedScopes != .all {
params.append(URLQueryItem(name: "types", value: String(describing: allowedScopes)))
}
if let allowedRegion = allowedRegion {
params.append(URLQueryItem(name: "bbox", value: String(describing: allowedRegion)))
}
if maximumResultCount > 0 {
params.append(URLQueryItem(name: "limit", value: String(maximumResultCount)))
}
if let languageCode = (locale as NSLocale?)?.object(forKey: .languageCode) as? String {
params.append(URLQueryItem(name: "language", value: languageCode))
}
params.append(URLQueryItem(name: "routing", value: String(describing: includesRoutableLocations)))
return params
}
}
/**
A structure that specifies the criteria for forward geocoding results. Forward geocoding takes a human-readable query, such as a place name or address, and produces any number of geographic coordinates that correspond to that query.
*/
@objc(MBForwardGeocodeOptions)
open class ForwardGeocodeOptions: GeocodeOptions {
/**
A Boolean value that determines whether the results may include placemarks whose names match must match the whole query string exactly.
If true, a resulting placemark’s name may contain a word that begins with the query string. If false, the query string must match a whole word or phrase in the placemark’s name. The default value of this property is true, which is best suited for continuous search fields.
*/
open var autocompletesQuery = true
fileprivate init(queries: [String]) {
super.init()
self.queries = queries
self.maximumResultCount = 5
}
/**
Initializes a forward geocode options object with the given query string.
- parameter query: A place name or address to search for. The query may have a maximum of 20 words or numbers; it may have up to 256 characters including spaces and punctuation.
*/
@objc public convenience init(query: String) {
self.init(queries: [query])
}
#if !os(tvOS)
/**
Initializes a forward geocode options object with the given postal address object.
- parameter postalAddress: A `CNPostalAddress` object to search for.
*/
@available(iOS 9.0, OSX 10.11, *)
@objc public convenience init(postalAddress: CNPostalAddress) {
let formattedAddress = CNPostalAddressFormatter().string(from: postalAddress)
self.init(query: formattedAddress.replacingOccurrences(of: "\n", with: ", "))
}
#endif
override var params: [URLQueryItem] {
var params = super.params
if !autocompletesQuery {
params.append(URLQueryItem(name: "autocomplete", value: String(autocompletesQuery)))
}
return params
}
}
/**
A structure that specifies the criteria for reverse geocoding results. _Reverse geocoding_ takes a geographic coordinate and produces a hierarchy of places, often beginning with an address, that describes the coordinate’s location.
*/
@objc(MBReverseGeocodeOptions)
open class ReverseGeocodeOptions: GeocodeOptions {
/**
An array of coordinates to search for.
*/
open var coordinates: [CLLocationCoordinate2D]
fileprivate init(coordinates: [CLLocationCoordinate2D]) {
self.coordinates = coordinates
super.init()
self.maximumResultCount = 1
queries = coordinates.map { String(format: "%.5f,%.5f", $0.longitude, $0.latitude) }
}
/**
Initializes a reverse geocode options object with the given coordinate pair.
- parameter coordinate: A coordinate pair to search for.
*/
@objc public convenience init(coordinate: CLLocationCoordinate2D) {
self.init(coordinates: [coordinate])
}
/**
Initializes a reverse geocode options object with the given `CLLocation` object.
- parameter location: A `CLLocation` object to search for.
*/
@objc public convenience init(location: CLLocation) {
self.init(coordinate: location.coordinate)
}
}
/**
Objects that conform to the `BatchGeocodeOptions` protocol specify the criteria for batch geocoding results returned by the Mapbox Geocoding API.
You can include up to 50 forward geocoding queries in a single request. Each query in a batch request counts individually against your account’s rate limits.
Pass an object conforming to this protocol into the `Geocoder.batchGeocode(_:completionHandler:)` method.
*/
@objc(MBBatchGeocodeOptions)
public protocol BatchGeocodeOptions {}
/**
A structure that specifies the criteria for forward batch geocoding results. Forward geocoding takes a human-readable query, such as a place name or address, and produces any number of geographic coordinates that correspond to that query.
*/
@objc(MBForwardBatchGeocodeOptions)
open class ForwardBatchGeocodeOptions: ForwardGeocodeOptions, BatchGeocodeOptions {
/**
Initializes a forward batch geocode options object with the given query strings.
- parameter queries: An array of up to 50 place names or addresses to search for. An individual query may have a maximum of 20 words or numbers; it may have up to 256 characters including spaces and punctuation.
*/
@objc public override init(queries: [String]) {
super.init(queries: queries)
mode = "mapbox.places-permanent"
}
}
/**
A structure that specifies the criteria for reverse geocoding results. Reverse geocoding takes a geographic coordinate and produces a hierarchy of places, often beginning with an address, that describes the coordinate’s location.
*/
@objc(MBReverseBatchGeocodeOptions)
open class ReverseBatchGeocodeOptions: ReverseGeocodeOptions, BatchGeocodeOptions {
/**
Initializes a reverse batch geocode options object with the given coordinate pairs.
- parameter coordinates: An array of up to 50 coordinate pairs to search for.
*/
@objc public override init(coordinates: [CLLocationCoordinate2D]) {
super.init(coordinates: coordinates)
mode = "mapbox.places-permanent"
}
/**
Initializes a reverse batch geocode options object with the given `CLLocation` objects.
- parameter location: An array of up to 50 `CLLocation` objects to search for.
*/
@objc public convenience init(locations: [CLLocation]) {
self.init(coordinates: locations.map { $0.coordinate })
mode = "mapbox.places-permanent"
}
}