forked from devit-tel/go.osrm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
osrm.go
135 lines (115 loc) · 3.76 KB
/
osrm.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
package osrm
import (
"context"
"net/http"
"time"
)
const (
defaultTimeout = time.Second
defaultServerURL = "http://127.0.0.1:5000"
version = "v1"
)
// OSRM implements the common OSRM API v5.
// See https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md for details.
// TODO: implement (trip, tile) methods
type OSRM struct {
client
}
// Config represents OSRM client configuration options
type Config struct {
// ServerURL is OSRM server URL to be used for queries.
// Local http://127.0.0.1:5000 URL will be used as default if not set.
ServerURL string
// Client is custom pre-configured http client to be used for queries.
// New http.Client instance with default settings and one second timeout will be used if not set.
Client HTTPClient
}
// ResponseStatus represent OSRM API response
type ResponseStatus struct {
Code string `json:"code"`
Message string `json:"message"`
DataVersion string `json:"data_version"`
}
// ErrCode returns error code from OSRM response
func (r ResponseStatus) ErrCode() string {
return r.Code
}
func (r ResponseStatus) Error() string {
return r.Code + " - " + r.Message
}
func (r ResponseStatus) apiError() error {
if r.Code != errorCodeOK {
return r
}
return nil
}
type response interface {
apiError() error
}
// New creates a client with default server url and default timeout
func New() *OSRM {
return NewWithConfig(Config{})
}
// NewFromURL creates a client with custom server url and default timeout
func NewFromURL(serverURL string) *OSRM {
return NewWithConfig(Config{ServerURL: serverURL})
}
// NewFromURLWithTimeout creates a client with custom timeout connection
func NewFromURLWithTimeout(serverURL string, timeout time.Duration) *OSRM {
return NewWithConfig(Config{
ServerURL: serverURL,
Client: &http.Client{Timeout: timeout},
})
}
// NewWithConfig creates a client with given config
func NewWithConfig(cfg Config) *OSRM {
if cfg.ServerURL == "" {
cfg.ServerURL = defaultServerURL
}
if cfg.Client == nil {
cfg.Client = &http.Client{Timeout: defaultTimeout}
}
return &OSRM{client: newClient(cfg.ServerURL, cfg.Client)}
}
func (o OSRM) query(ctx context.Context, in *request, out response) error {
if err := o.client.doRequest(ctx, in, out); err != nil {
return err
}
return out.apiError()
}
// Route searches the shortest path between given coordinates.
// See https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md#route-service for details.
func (o OSRM) Route(ctx context.Context, r RouteRequest) (*RouteResponse, error) {
var resp RouteResponse
if err := o.query(ctx, r.request(), &resp); err != nil {
return nil, err
}
return &resp, nil
}
// Table computes duration tables for the given locations.
// See https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md#table-service for details.
func (o OSRM) Table(ctx context.Context, r TableRequest) (*TableResponse, error) {
var resp TableResponse
if err := o.query(ctx, r.request(), &resp); err != nil {
return nil, err
}
return &resp, nil
}
// Match matches given GPS points to the road network in the most plausible way.
// See https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md#match-service for details.
func (o OSRM) Match(ctx context.Context, r MatchRequest) (*MatchResponse, error) {
var resp MatchResponse
if err := o.query(ctx, r.request(), &resp); err != nil {
return nil, err
}
return &resp, nil
}
// Nearest matches given GPS point to the nearest road network.
// See https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md#nearest-service for details.
func (o OSRM) Nearest(ctx context.Context, r NearestRequest) (*NearestResponse, error) {
var resp NearestResponse
if err := o.query(ctx, r.request(), &resp); err != nil {
return nil, err
}
return &resp, nil
}