forked from gojuno/go.osrm
-
Notifications
You must be signed in to change notification settings - Fork 2
/
types.go
273 lines (222 loc) · 5.97 KB
/
types.go
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
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
package osrm
import (
"encoding/json"
"fmt"
"net/url"
"strings"
geo "github.com/paulmach/go.geo"
geojson "github.com/paulmach/go.geojson"
)
const (
polyline5Factor = 1.0e5
polyline6Factor = 1.0e6
)
// Geometry represents a points set
type Geometry struct {
geo.Path
}
// NewGeometryFromPath creates a geometry from a path.
func NewGeometryFromPath(path geo.Path) Geometry {
return Geometry{path}
}
// NewGeometryFromPointSet creates a geometry from points set.
func NewGeometryFromPointSet(ps geo.PointSet) Geometry {
return NewGeometryFromPath(geo.Path{PointSet: ps})
}
// Polyline generates a polyline in Google format
func (g *Geometry) Polyline(factor ...int) string {
if len(factor) == 0 {
return g.Encode(polyline5Factor)
}
return g.Encode(factor[0])
}
// UnmarshalJSON parses a geo path from points set or a polyline
func (g *Geometry) UnmarshalJSON(b []byte) error {
if len(b) == 0 {
return nil
}
var encoded string
if err := json.Unmarshal(b, &encoded); err == nil {
g.Path = *geo.NewPathFromEncoding(encoded, polyline6Factor)
return nil
}
geom, err := geojson.UnmarshalGeometry(b)
if err != nil {
return fmt.Errorf("failed to unmarshal geojson geometry, err: %v", err)
}
if !geom.IsLineString() {
return fmt.Errorf("unexpected geometry type: %v", geom.Type)
}
g.Path = *geo.NewPathFromXYSlice(geom.LineString)
return nil
}
// MarshalJSON generates a polyline in Google polyline6 format
func (g Geometry) MarshalJSON() ([]byte, error) {
return json.Marshal(g.Polyline(polyline6Factor))
}
// Tidy represents a tidy param for osrm5 match request
type Tidy string
// Supported tidy param values
const (
TidyTrue Tidy = "true"
TidyFalse Tidy = "false"
)
// String returns Tidy as a string
func (t Tidy) String() string {
return string(t)
}
// Annotations represents a annotations param for osrm5 request
type Annotations string
// Supported annotations param values
const (
AnnotationsTrue Annotations = "true"
AnnotationsFalse Annotations = "false"
AnnotationsNodes Annotations = "nodes"
AnnotationsDistance Annotations = "distance"
AnnotationsDuration Annotations = "duration"
AnnotationsDatasources Annotations = "datasources"
AnnotationsWeight Annotations = "weight"
AnnotationsSpeed Annotations = "speed"
)
// String returns Annotations as a string
func (a Annotations) String() string {
return string(a)
}
// Steps represents a steps param for osrm5 request
type Steps string
// Supported steps param values
const (
StepsTrue Steps = "true"
StepsFalse Steps = "false"
)
// String returns Steps as a string
func (s Steps) String() string {
return string(s)
}
// Gaps represents a gaps param for osrm5 match request
type Gaps string
// Supported gaps param values
const (
GapsSplit Gaps = "split"
GapsIgnore Gaps = "ignore"
)
// String returns Gaps as a string
func (g Gaps) String() string {
return string(g)
}
// Geometries represents a geometries param for osrm5
type Geometries string
// Supported geometries param values
const (
GeometriesPolyline6 Geometries = "polyline6"
GeometriesGeojson Geometries = "geojson"
)
// String returns Geometries as a string
func (g Geometries) String() string {
return string(g)
}
// Overview represents level of overview of geometry in a response
type Overview string
// Available overview values
const (
OverviewSimplified Overview = "simplified"
OverviewFull Overview = "full"
OverviewFalse Overview = "false"
)
// String returns Overview as a string
func (o Overview) String() string {
return string(o)
}
type FallbackCoordinate string
const (
FallbackCoordinateDefault FallbackCoordinate = "input"
FallbackCoordinateInput FallbackCoordinate = "input"
FallbackCoordinateSnapped FallbackCoordinate = "snapped"
)
func (f FallbackCoordinate) String() string {
return string(f)
}
// ContinueStraight represents continue_straight OSRM routing parameter
type ContinueStraight string
// ContinueStraight values
const (
ContinueStraightDefault ContinueStraight = "default"
ContinueStraightTrue ContinueStraight = "true"
ContinueStraightFalse ContinueStraight = "false"
)
// String returns ContinueStraight as string
func (c ContinueStraight) String() string {
return string(c)
}
type Roundtrip string
const (
RoundtripDefault Roundtrip = "true"
RoundtripTrue Roundtrip = "true"
RoundtripFalse Roundtrip = "false"
)
func (r Roundtrip) String() string {
return string(r)
}
type Source string
const (
SourceDefault Source = "any"
SourceAny Source = "any"
SourceFirst Source = "first"
)
func (s Source) String() string {
return string(s)
}
type Destination string
const (
DestinationDefault Destination = "any"
DestinationAny Destination = "any"
DestinationLast Destination = "last"
)
func (d Destination) String() string {
return string(d)
}
// request contains parameters for OSRM query
type request struct {
profile string
coords Geometry
service string
options options
}
// URL generates a url for OSRM request
func (r *request) URL(serverURL string) (string, error) {
if r.service == "" {
return "", ErrEmptyServiceName
}
if r.profile == "" {
return "", ErrEmptyProfileName
}
if r.coords.Length() == 0 {
return "", ErrNoCoordinates
}
// http://{server}/{service}/{version}/{profile}/{coordinates}[.{format}]?option=value&option=value
url := strings.Join([]string{
serverURL, // server
r.service, // service
version, // version
r.profile, // profile
"polyline(" + url.PathEscape(r.coords.Polyline(polyline5Factor)) + ")", // coordinates
}, "/")
if len(r.options) > 0 {
url += "?" + r.options.encode() // options
}
return url, nil
}
// Bearing limits the search to segments with given bearing in degrees towards true north in clockwise direction.
type Bearing struct {
Value, Range uint16
}
func (b Bearing) String() string {
return fmt.Sprintf("%d,%d", b.Value, b.Range)
}
func bearings(br []Bearing) string {
s := make([]string, len(br))
for i, b := range br {
s[i] = b.String()
}
return strings.Join(s, ";")
}