From 969b7c71984093ca413138b6fbe40b8355e3cd8a Mon Sep 17 00:00:00 2001 From: Mislav Kasner Date: Mon, 16 Sep 2019 15:03:18 +0200 Subject: [PATCH] Adds general options and missing options for table request --- match.go | 14 ++--------- match_test.go | 18 ++++++++++---- nearest.go | 6 ++--- nearest_test.go | 12 ++++++---- options.go | 32 +++++++++++++++++++++++++ options_test.go | 51 ++++++++++++++++++++++++++++++++++++++++ route.go | 6 ++--- route_test.go | 8 ++++--- table.go | 16 +++++++++++++ table_test.go | 62 +++++++++++++++++++++++++++++++++++++++++-------- types.go | 18 ++++++++++++++ 11 files changed, 201 insertions(+), 42 deletions(-) diff --git a/match.go b/match.go index 467f29b..59d881e 100644 --- a/match.go +++ b/match.go @@ -4,15 +4,13 @@ import geo "github.com/paulmach/go.geo" // MatchRequest represents a request to the match method type MatchRequest struct { + GeneralOptions Profile string Coordinates Geometry - Bearings []Bearing Steps Steps Annotations Annotations Tidy Tidy Timestamps []int64 - Radiuses []float64 - Hints []string Overview Overview Gaps Gaps Geometries Geometries @@ -41,15 +39,7 @@ func (r MatchRequest) request() *request { if len(r.Timestamps) > 0 { options.addInt64("timestamps", r.Timestamps...) } - if len(r.Radiuses) > 0 { - options.addFloat("radiuses", r.Radiuses...) - } - if len(r.Hints) > 0 { - options.add("hints", r.Hints...) - } - if len(r.Bearings) > 0 { - options.set("bearings", bearings(r.Bearings)) - } + options = r.GeneralOptions.options(options) return &request{ profile: r.Profile, diff --git a/match_test.go b/match_test.go index 379bd72..fc247a2 100644 --- a/match_test.go +++ b/match_test.go @@ -20,15 +20,19 @@ func TestEmptyMatchRequestOptions(t *testing.T) { name: "with timestamps and radiuses", request: MatchRequest{ Timestamps: []int64{0, 1, 2}, - Radiuses: []float64{0.123123, 0.12312}, + GeneralOptions: GeneralOptions{ + Radiuses: []float64{0.123123, 0.12312}, + }, }, expectedURI: "geometries=polyline6&radiuses=0.123123;0.12312×tamps=0;1;2", }, { name: "with gaps and tidy", request: MatchRequest{ + GeneralOptions: GeneralOptions{ + Radiuses: []float64{0.123123, 0.12312}, + }, Timestamps: []int64{0, 1, 2}, - Radiuses: []float64{0.123123, 0.12312}, Gaps: GapsSplit, Tidy: TidyTrue, }, @@ -37,15 +41,19 @@ func TestEmptyMatchRequestOptions(t *testing.T) { { name: "with hints", request: MatchRequest{ - Hints: []string{"a", "b", "c", "d"}, + GeneralOptions: GeneralOptions{ + Hints: []string{"a", "b", "c", "d"}, + }, }, expectedURI: "geometries=polyline6&hints=a;b;c;d", }, { name: "with bearings", request: MatchRequest{ - Bearings: []Bearing{ - {0, 20}, {10, 20}, + GeneralOptions: GeneralOptions{ + Bearings: []Bearing{ + {0, 20}, {10, 20}, + }, }, }, expectedURI: "bearings=0%2C20%3B10%2C20&geometries=polyline6", diff --git a/nearest.go b/nearest.go index 06172ba..509cd2d 100644 --- a/nearest.go +++ b/nearest.go @@ -4,9 +4,9 @@ import geo "github.com/paulmach/go.geo" // NearestRequest represents a request to the nearest method type NearestRequest struct { + GeneralOptions Profile string Coordinates Geometry - Bearings []Bearing Number int } @@ -31,9 +31,7 @@ func (r NearestRequest) request() *request { opts.addInt("number", r.Number) } - if len(r.Bearings) > 0 { - opts.set("bearings", bearings(r.Bearings)) - } + opts = r.GeneralOptions.options(opts) return &request{ profile: r.Profile, diff --git a/nearest_test.go b/nearest_test.go index b8c4005..0c271a4 100644 --- a/nearest_test.go +++ b/nearest_test.go @@ -9,8 +9,10 @@ import ( func TestNearestRequestOverviewOption(t *testing.T) { req := NearestRequest{ Number: 2, - Bearings: []Bearing{ - {60, 380}, + GeneralOptions: GeneralOptions{ + Bearings: []Bearing{ + {60, 380}, + }, }, } assert.Equal( @@ -19,8 +21,10 @@ func TestNearestRequestOverviewOption(t *testing.T) { req.request().options.encode()) req = NearestRequest{ - Bearings: []Bearing{ - {60, 380}, + GeneralOptions: GeneralOptions{ + Bearings: []Bearing{ + {60, 380}, + }, }, } assert.Equal( diff --git a/options.go b/options.go index 73726f4..c9ce34a 100644 --- a/options.go +++ b/options.go @@ -7,6 +7,38 @@ import ( "strconv" ) +type GeneralOptions struct { + Bearings []Bearing + Radiuses []float64 + GenerateHintsDisabled bool + Hints []string + Approaches []string + Exclude []string +} + +func (g GeneralOptions) options(opts options) options { + if len(g.Bearings) > 0 { + opts.add("bearings", bearings(g.Bearings)) + } + if len(g.Radiuses) > 0 { + opts.addFloat("radiuses", g.Radiuses...) + } + // generate_hints option default is true + if g.GenerateHintsDisabled { + opts.setBool("generate_hints", !g.GenerateHintsDisabled) + } + if len(g.Hints) > 0 { + opts.add("hints", g.Hints...) + } + if len(g.Approaches) > 0 { + opts.add("approaches", g.Approaches...) + } + if len(g.Exclude) > 0 { + opts.add("exclude", g.Exclude...) + } + return opts +} + // options represents OSRM query params to be encoded in URL type options map[string][]string diff --git a/options_test.go b/options_test.go index b92ef61..2952452 100644 --- a/options_test.go +++ b/options_test.go @@ -101,3 +101,54 @@ func TestOptionsAddFloatValsAsVariadic(t *testing.T) { opts.addFloat("foo", 1.1231312, 2.1233) assert.Equal(t, "foo=1.1231312;2.1233", opts.encode()) } + +func TestGeneralOptions(t *testing.T) { + cases := []struct { + name string + options GeneralOptions + expectedURI string + }{ + { + name: "empty", + options: GeneralOptions{}, + expectedURI: "", + }, + { + name: "with bearings", + options: GeneralOptions{ + Bearings: []Bearing{ + {0, 20}, {10, 20}, + }, + }, + expectedURI: "bearings=0%2C20%3B10%2C20", + }, + { + name: "with radiuses", + options: GeneralOptions{ + Radiuses: []float64{0.123123, 0.12312}, + }, + expectedURI: "radiuses=0.123123;0.12312", + }, + { + name: "generate hints disabled", + options: GeneralOptions{ + Radiuses: []float64{0.123123, 0.12312}, + GenerateHintsDisabled: true, + }, + expectedURI: "generate_hints=false&radiuses=0.123123;0.12312", + }, + { + name: "with approaches and exclude", + options: GeneralOptions{ + Exclude: []string{"toll", "highway"}, + Approaches: []string{"a", "b"}, + }, + expectedURI: "approaches=a;b&exclude=toll;highway", + }, + } + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + assert.Equal(t, c.expectedURI, c.options.options(options{}).encode()) + }) + } +} diff --git a/route.go b/route.go index 5791030..e57e476 100644 --- a/route.go +++ b/route.go @@ -8,9 +8,9 @@ import ( // RouteRequest represents a request to the route method type RouteRequest struct { + GeneralOptions Profile string Coordinates Geometry - Bearings []Bearing Steps Steps Annotations Annotations Overview Overview @@ -69,9 +69,7 @@ func (r RouteRequest) request() *request { opts := stepsOptions(r.Steps, r.Annotations, r.Overview, r.Geometries). setStringer("continue_straight", r.ContinueStraight) - if len(r.Bearings) > 0 { - opts.set("bearings", bearings(r.Bearings)) - } + opts = r.GeneralOptions.options(opts) return &request{ profile: r.Profile, diff --git a/route_test.go b/route_test.go index 49a4d59..0d7a822 100644 --- a/route_test.go +++ b/route_test.go @@ -16,9 +16,11 @@ func TestEmptyRouteRequestOptions(t *testing.T) { func TestRouteRequestOptionsWithBearings(t *testing.T) { req := RouteRequest{ - Bearings: []Bearing{ - {60, 380}, - {45, 180}, + GeneralOptions: GeneralOptions{ + Bearings: []Bearing{ + {60, 380}, + {45, 180}, + }, }, ContinueStraight: ContinueStraightTrue, } diff --git a/table.go b/table.go index a539131..6dc41c8 100644 --- a/table.go +++ b/table.go @@ -2,9 +2,14 @@ package osrm // TableRequest represents a request to the table method type TableRequest struct { + GeneralOptions Profile string Coordinates Geometry Sources, Destinations []int + Annotations Annotations + FallbackSpeed float64 + FallbackCoordinate FallbackCoordinate + ScaleFactor float64 } // TableResponse resresents a response from the table method @@ -21,6 +26,17 @@ func (r TableRequest) request() *request { if len(r.Destinations) > 0 { opts.addInt("destinations", r.Destinations...) } + if r.FallbackSpeed > 0 { + opts.addFloat("fallback_speed", r.FallbackSpeed) + } + if r.FallbackCoordinate.Valid() { + opts.setStringer("fallback_coordinate", r.FallbackCoordinate) + } + if r.ScaleFactor > 0 { + opts.addFloat("scale_factor", r.ScaleFactor) + } + + opts = r.GeneralOptions.options(opts) return &request{ profile: r.Profile, diff --git a/table_test.go b/table_test.go index cf8a55f..5a640bd 100644 --- a/table_test.go +++ b/table_test.go @@ -6,15 +6,57 @@ import ( "github.com/stretchr/testify/assert" ) -func TestEmptyTableRequestOptions(t *testing.T) { - req := TableRequest{} - assert.Empty(t, req.request().options.encode()) -} - -func TestNotEmptyTableRequestOptions(t *testing.T) { - req := TableRequest{ - Sources: []int{0, 1, 2}, - Destinations: []int{1, 3}, +func TestTableRequestOptions(t *testing.T) { + cases := []struct { + name string + request TableRequest + expectedURI string + }{ + { + name: "empty", + request: TableRequest{}, + expectedURI: "", + }, + { + name: "with sources and destinations", + request: TableRequest{ + Sources: []int{0, 1, 2}, + Destinations: []int{1, 3}, + }, + expectedURI: "destinations=1;3&sources=0;1;2", + }, + { + name: "scale_factor", + request: TableRequest{ + ScaleFactor: 0.8, + GeneralOptions: GeneralOptions{ + Exclude: []string{"toll"}, + }, + }, + expectedURI: "exclude=toll&scale_factor=0.8", + }, + { + name: "fallback_coordinate", + request: TableRequest{ + FallbackSpeed: 11.5, + GeneralOptions: GeneralOptions{ + Hints: []string{"a", "b"}, + }, + }, + expectedURI: "fallback_speed=11.5&hints=a;b", + }, + { + name: "fallback_coordinate", + request: TableRequest{ + FallbackSpeed: 11.5, + FallbackCoordinate: FallbackCoordinateInput, + }, + expectedURI: "fallback_coordinate=input&fallback_speed=11.5", + }, + } + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + assert.Equal(t, c.expectedURI, c.request.request().options.encode()) + }) } - assert.Equal(t, "destinations=1;3&sources=0;1;2", req.request().options.encode()) } diff --git a/types.go b/types.go index 3a1e886..c6040c5 100644 --- a/types.go +++ b/types.go @@ -203,3 +203,21 @@ func bearings(br []Bearing) string { } return strings.Join(s, ";") } + +type FallbackCoordinate string + +const ( + FallbackCoordinateInput FallbackCoordinate = "input" + FallbackCoordinateSnapped = "snapped" +) + +func (f FallbackCoordinate) String() string { + return string(f) +} + +func (f FallbackCoordinate) Valid() bool { + if f == FallbackCoordinateInput || f == FallbackCoordinateSnapped { + return true + } + return false +}