forked from Project-OSRM/osrm-backend
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: initial implementation for osrm table connector issue: #137 * feat: implement request for table service issue: #137 * feat: implement osrm table response issue: #137 * fix: fix decoded problem related with table response issue: #137 * fix: remove comments issue: #137 * fix: fix typo. issue: #137 * fix: add default value for Request's element issue: #137 * fix: add comments issue: #137 * fix: modify comments issue: #137 * fix: refactor code. issue: #137 * fix: in table.response using osrmtype.waypoint instead of route.waypoint issue: #137
- Loading branch information
1 parent
dc103fa
commit c754036
Showing
7 changed files
with
330 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package osrmtype | ||
|
||
// Waypoint object used to describe waypoint used in route or table. | ||
type Waypoint struct { | ||
Name string `json:"name"` | ||
Location [2]float64 `json:"location,omitempty"` // [longitude, latitude] | ||
Distance float64 `json:"distance"` | ||
Hint string `json:"hint"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package options | ||
|
||
// Table service Query Parameter/Option Keys | ||
const ( | ||
KeySources = "sources" | ||
KeyDestinations = "destinations" | ||
KeyAnnotations = "annotations" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package options | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/Telenav/osrm-backend/integration/pkg/api" | ||
"github.com/golang/glog" | ||
) | ||
|
||
// ParseAnnotations parses table service Annotations option. | ||
func ParseAnnotations(s string) (string, error) { | ||
|
||
validAnnotationsValues := map[string]struct{}{ | ||
AnnotationsValueDistance: struct{}{}, | ||
AnnotationsValueDuration: struct{}{}, | ||
} | ||
|
||
splits := strings.Split(s, api.Comma) | ||
for _, split := range splits { | ||
if _, found := validAnnotationsValues[split]; !found { | ||
|
||
err := fmt.Errorf("invalid annotations value: %s", s) | ||
glog.Warning(err) | ||
return "", err | ||
} | ||
} | ||
|
||
return s, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package options | ||
|
||
// Annotations default value | ||
const ( | ||
AnnotationsDefaultValue = AnnotationsValueDuration | ||
) | ||
|
||
// Annotations values | ||
const ( | ||
AnnotationsValueDistance = "distance" | ||
AnnotationsValueDuration = "duration" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
package table | ||
|
||
import ( | ||
"fmt" | ||
"net/url" | ||
"strings" | ||
|
||
"github.com/Telenav/osrm-backend/integration/pkg/api" | ||
"github.com/Telenav/osrm-backend/integration/pkg/api/osrm/coordinate" | ||
"github.com/Telenav/osrm-backend/integration/pkg/api/osrm/genericoptions" | ||
"github.com/Telenav/osrm-backend/integration/pkg/api/osrm/table/options" | ||
"github.com/golang/glog" | ||
) | ||
|
||
// Request for OSRM table service | ||
// http://project-osrm.org/docs/v5.5.1/api/#table-service | ||
type Request struct { | ||
// Path | ||
Service string | ||
Version string | ||
Profile string | ||
Coordinates coordinate.Coordinates | ||
|
||
// Options | ||
Sources genericoptions.Elements | ||
Destinations genericoptions.Elements | ||
Annotations string | ||
} | ||
|
||
// NewRequest create an empty table Request. | ||
func NewRequest() *Request { | ||
|
||
return &Request{ | ||
// Path | ||
Service: "table", | ||
Version: "v1", | ||
Profile: "driving", | ||
Coordinates: coordinate.Coordinates{}, | ||
|
||
// Options | ||
Sources: genericoptions.Elements{}, | ||
Destinations: genericoptions.Elements{}, | ||
Annotations: options.AnnotationsDefaultValue, | ||
} | ||
|
||
} | ||
|
||
// ParseRequestURL parse Request URL to Request. | ||
func ParseRequestURL(u *url.URL) (*Request, error) { | ||
if u == nil { | ||
return nil, fmt.Errorf("empty URL input") | ||
} | ||
|
||
req := NewRequest() | ||
|
||
if err := req.parsePath(u.Path); err != nil { | ||
return nil, err | ||
} | ||
|
||
req.parseQuery(api.ParseQueryDiscardError(u.RawQuery)) | ||
|
||
return req, nil | ||
} | ||
|
||
func (r *Request) parsePath(path string) error { | ||
p := path | ||
p = strings.TrimPrefix(p, api.Slash) | ||
p = strings.TrimSuffix(p, api.Slash) | ||
|
||
s := strings.Split(p, api.Slash) | ||
if len(s) < 4 { | ||
return fmt.Errorf("invalid path values %v parsed from %s", s, path) | ||
} | ||
r.Service = s[0] | ||
r.Version = s[1] | ||
r.Profile = s[2] | ||
|
||
var err error | ||
if r.Coordinates, err = coordinate.ParseCoordinates(s[3]); err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (r *Request) parseQuery(values url.Values) { | ||
|
||
if v := values.Get(options.KeySources); len(v) > 0 { | ||
if sources, err := genericoptions.ParseElemenets(v); err == nil { | ||
r.Sources = sources | ||
} | ||
} | ||
|
||
if v := values.Get(options.KeyDestinations); len(v) > 0 { | ||
if destinations, err := genericoptions.ParseElemenets(v); err == nil { | ||
r.Destinations = destinations | ||
} | ||
} | ||
|
||
if v := values.Get(options.KeyAnnotations); len(v) > 0 { | ||
if annotations, err := options.ParseAnnotations(v); err == nil { | ||
r.Annotations = annotations | ||
} | ||
} | ||
} | ||
|
||
// RequestURI convert TableRequest to RequestURI (e.g. "/path?foo=bar"). | ||
// see more in https://golang.org/pkg/net/url/#URL.RequestURI | ||
func (r *Request) RequestURI() string { | ||
s := r.pathPrefix() | ||
|
||
coordinatesStr := r.Coordinates.String() | ||
if len(coordinatesStr) > 0 { | ||
s += coordinatesStr | ||
} | ||
|
||
queryStr := r.QueryString() | ||
if len(queryStr) > 0 { | ||
s += api.QuestionMark + queryStr | ||
} | ||
|
||
return s | ||
} | ||
|
||
func (r *Request) pathPrefix() string { | ||
//i.e. "/table/v1/driving/" | ||
return api.Slash + r.Service + api.Slash + r.Version + api.Slash + r.Profile + api.Slash | ||
} | ||
|
||
// QueryString convert TableRequest to "URL encoded" form ("bar=baz&foo=quux"), but NOT escape. | ||
func (r *Request) QueryString() string { | ||
rawQuery := r.QueryValues().Encode() | ||
query, err := url.QueryUnescape(rawQuery) | ||
if err != nil { | ||
glog.Warning(err) | ||
return rawQuery // use rawQuery if unescape fail | ||
} | ||
return query | ||
} | ||
|
||
// QueryValues convert table Request to url.Values. | ||
func (r *Request) QueryValues() (v url.Values) { | ||
v = make(url.Values) | ||
|
||
if len(r.Sources) > 0 { | ||
v.Add(options.KeySources, r.Sources.String()) | ||
} | ||
|
||
if len(r.Destinations) > 0 { | ||
v.Add(options.KeyDestinations, r.Destinations.String()) | ||
} | ||
|
||
if len(r.Annotations) > 0 { | ||
v.Add(options.KeyAnnotations, r.Annotations) | ||
} | ||
|
||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package table | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/Telenav/osrm-backend/integration/pkg/api/osrm/coordinate" | ||
"github.com/Telenav/osrm-backend/integration/pkg/api/osrm/genericoptions" | ||
) | ||
|
||
func TestTableRequestURI(t *testing.T) { | ||
cases := []struct { | ||
r Request | ||
expect string | ||
}{ | ||
{ | ||
Request{ | ||
Service: "table", | ||
Version: "v1", | ||
Profile: "driving", | ||
Coordinates: coordinate.Coordinates{coordinate.Coordinate{Lat: 37.364336, Lon: -122.006349}, coordinate.Coordinate{Lat: 37.313767, Lon: -121.875654}}, | ||
}, | ||
"/table/v1/driving/-122.006349,37.364336;-121.875654,37.313767", | ||
}, | ||
{ | ||
Request{ | ||
Service: "table", | ||
Version: "v1", | ||
Profile: "driving", | ||
Coordinates: coordinate.Coordinates{coordinate.Coordinate{Lat: 37.364336, Lon: -122.006349}, coordinate.Coordinate{Lat: 37.313767, Lon: -121.875654}, coordinate.Coordinate{Lat: 37.313769, Lon: -121.875655}}, | ||
}, | ||
"/table/v1/driving/-122.006349,37.364336;-121.875654,37.313767;-121.875655,37.313769", | ||
}, | ||
{ | ||
Request{ | ||
Service: "table", | ||
Version: "v1", | ||
Profile: "driving", | ||
Coordinates: coordinate.Coordinates{coordinate.Coordinate{Lat: 37.364336, Lon: -122.006349}, coordinate.Coordinate{Lat: 37.313767, Lon: -121.875654}, coordinate.Coordinate{Lat: 37.313769, Lon: -121.875655}}, | ||
Sources: genericoptions.Elements{"0"}, | ||
}, | ||
"/table/v1/driving/-122.006349,37.364336;-121.875654,37.313767;-121.875655,37.313769?sources=0", | ||
}, | ||
{ | ||
Request{ | ||
Service: "table", | ||
Version: "v1", | ||
Profile: "driving", | ||
Coordinates: coordinate.Coordinates{coordinate.Coordinate{Lat: 37.364336, Lon: -122.006349}, coordinate.Coordinate{Lat: 37.313767, Lon: -121.875654}, coordinate.Coordinate{Lat: 37.313769, Lon: -121.875655}}, | ||
Sources: genericoptions.Elements{"0"}, | ||
Destinations: genericoptions.Elements{"1", "2"}, | ||
}, | ||
"/table/v1/driving/-122.006349,37.364336;-121.875654,37.313767;-121.875655,37.313769?destinations=1;2&sources=0", | ||
}, | ||
{ | ||
Request{ | ||
Service: "table", | ||
Version: "v1", | ||
Profile: "driving", | ||
Coordinates: coordinate.Coordinates{coordinate.Coordinate{Lat: 37.364336, Lon: -122.006349}, coordinate.Coordinate{Lat: 37.313767, Lon: -121.875654}, coordinate.Coordinate{Lat: 37.313769, Lon: -121.875655}}, | ||
Sources: genericoptions.Elements{"0"}, | ||
Destinations: genericoptions.Elements{"1", "2"}, | ||
Annotations: "duration", | ||
}, | ||
"/table/v1/driving/-122.006349,37.364336;-121.875654,37.313767;-121.875655,37.313769?annotations=duration&destinations=1;2&sources=0", | ||
}, | ||
{ | ||
Request{ | ||
Service: "table", | ||
Version: "v1", | ||
Profile: "driving", | ||
Coordinates: coordinate.Coordinates{coordinate.Coordinate{Lat: 37.364336, Lon: -122.006349}, coordinate.Coordinate{Lat: 37.313767, Lon: -121.875654}, coordinate.Coordinate{Lat: 37.313769, Lon: -121.875655}}, | ||
Sources: genericoptions.Elements{"0"}, | ||
Destinations: genericoptions.Elements{"1", "2"}, | ||
Annotations: "distance", | ||
}, | ||
"/table/v1/driving/-122.006349,37.364336;-121.875654,37.313767;-121.875655,37.313769?annotations=distance&destinations=1;2&sources=0", | ||
}, | ||
{ | ||
Request{ | ||
Service: "table", | ||
Version: "v1", | ||
Profile: "driving", | ||
Coordinates: coordinate.Coordinates{coordinate.Coordinate{Lat: 37.364336, Lon: -122.006349}, coordinate.Coordinate{Lat: 37.313767, Lon: -121.875654}, coordinate.Coordinate{Lat: 37.313769, Lon: -121.875655}}, | ||
Sources: genericoptions.Elements{"0"}, | ||
Destinations: genericoptions.Elements{"1", "2"}, | ||
Annotations: "duration,distance", | ||
}, | ||
"/table/v1/driving/-122.006349,37.364336;-121.875654,37.313767;-121.875655,37.313769?annotations=duration,distance&destinations=1;2&sources=0", | ||
}, | ||
} | ||
|
||
for _, c := range cases { | ||
s := c.r.RequestURI() | ||
if s != c.expect { | ||
t.Errorf("%v QueryString(), expect %s, but got %s", c.r, c.expect, s) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package table | ||
|
||
import ( | ||
"github.com/Telenav/osrm-backend/integration/pkg/api/osrm/osrmtype" | ||
) | ||
|
||
// Response represents OSRM api v1 table response. | ||
type Response struct { | ||
Code string `json:"code"` | ||
Message string `json:"message,omitempty"` | ||
Sources []*osrmtype.Waypoint `json:"sources"` | ||
Destinations []*osrmtype.Waypoint `json:"destinations"` | ||
Durations [][]*float64 `json:"durations"` | ||
Distances [][]*float64 `json:"distances"` | ||
} |