Skip to content

Commit

Permalink
feat: Implement Querier interface based on OSRM table service
Browse files Browse the repository at this point in the history
issue: #291
  • Loading branch information
CodeBear801 committed Apr 21, 2020
1 parent c82e542 commit 1a654ba
Show file tree
Hide file tree
Showing 5 changed files with 597 additions and 243 deletions.
7 changes: 6 additions & 1 deletion integration/service/oasis/connectivitymap/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "github.com/Telenav/osrm-backend/integration/pkg/api/nav"
// QueryResult records topological query result
type QueryResult struct {
StationID string
StationLocation nav.Location
StationLocation *nav.Location
Distance float64
Duration float64
}
Expand All @@ -14,5 +14,10 @@ type QueryResult struct {
type Querier interface {

// NearByStationQuery finds near by stations by given stationID and return them in recorded sequence
// Returns nil if given stationID is not found or no connectivity
NearByStationQuery(stationID string) []*QueryResult

// GetLocation returns location of given station id
// Returns nil if given stationID is not found
GetLocation(stationID string) *nav.Location
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package stationfinderalg

import (
"github.com/Telenav/osrm-backend/integration/pkg/api/nav"
"github.com/Telenav/osrm-backend/integration/service/oasis/connectivitymap"
"github.com/Telenav/osrm-backend/integration/service/oasis/stationfinder/stationfindertype"
"github.com/golang/glog"
)

type stationID2QueryResults map[string][]*connectivitymap.QueryResult
type stationID2Location map[string]*nav.Location

type querier struct {
id2QueryResults stationID2QueryResults
id2Location stationID2Location
}

func NewQuerierBasedOnWeightBetweenNeighborsChan(c chan stationfindertype.WeightBetweenNeighbors) connectivitymap.Querier {
querier := &querier{
id2QueryResults: make(stationID2QueryResults),
id2Location: make(stationID2Location),
}

for item := range c {
if item.Err != nil {
glog.Errorf("Met error during constructing stationgraph, error = %v", item.Err)
return nil
}

for _, neighborInfo := range item.NeighborsInfo {

if _, ok := querier.id2QueryResults[neighborInfo.FromID]; !ok {
results := make([]*connectivitymap.QueryResult, 0, 10)
querier.id2QueryResults[neighborInfo.FromID] = results
}
querier.id2QueryResults[neighborInfo.FromID] = append(querier.id2QueryResults[neighborInfo.FromID],
&connectivitymap.QueryResult{
StationID: neighborInfo.ToID,
StationLocation: &nav.Location{
Lat: neighborInfo.ToLocation.Lat,
Lon: neighborInfo.ToLocation.Lon,
},
Distance: neighborInfo.Distance,
Duration: neighborInfo.Duration,
})

if _, ok := querier.id2Location[neighborInfo.FromID]; !ok {
querier.id2Location[neighborInfo.FromID] = &nav.Location{
Lat: neighborInfo.FromLocation.Lat,
Lon: neighborInfo.FromLocation.Lon,
}
}

if _, ok := querier.id2Location[neighborInfo.ToID]; !ok {
querier.id2Location[neighborInfo.ToID] = &nav.Location{
Lat: neighborInfo.ToLocation.Lat,
Lon: neighborInfo.ToLocation.Lon,
}
}
}
}

return querier
}

func (q *querier) NearByStationQuery(stationID string) []*connectivitymap.QueryResult {
if results, ok := q.id2QueryResults[stationID]; ok {
return results
} else {
return nil
}
}

func (q *querier) GetLocation(stationID string) *nav.Location {
if location, ok := q.id2Location[stationID]; ok {
return location
} else {
return nil
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
package stationfinderalg

import (
"reflect"
"testing"

"github.com/Telenav/osrm-backend/integration/pkg/api/nav"
"github.com/Telenav/osrm-backend/integration/service/oasis/connectivitymap"
"github.com/Telenav/osrm-backend/integration/service/oasis/stationfinder/stationfindertype"
)

// orig_location -> station1, station2, station3, station4
// station1 -> station6, station7
// station2 -> station6, station7
// station3 -> station6, station7
// station4 -> station6, station7
// station6 -> destination
// station7 -> destination
func TestQuerierBasedOnWeightBetweenNeighborsChan(t *testing.T) {
cases := []struct {
stationID string
expectQueryResult []*connectivitymap.QueryResult
expectLocation *nav.Location
}{
{
"orig_location",
[]*connectivitymap.QueryResult{
{
StationID: "station1",
StationLocation: &nav.Location{
Lat: 32.333,
Lon: 122.333,
},
Distance: 22.2,
Duration: 22.2,
},
{
StationID: "station2",
StationLocation: &nav.Location{
Lat: -32.333,
Lon: -122.333,
},
Distance: 11.1,
Duration: 11.1,
},
{
StationID: "station3",
StationLocation: &nav.Location{
Lat: 32.333,
Lon: -122.333,
},
Distance: 33.3,
Duration: 33.3,
},
{
StationID: "station4",
StationLocation: &nav.Location{
Lat: -32.333,
Lon: 122.333,
},
Distance: 44.4,
Duration: 44.4,
},
},
&nav.Location{
Lat: 1.1,
Lon: 1.1,
},
},
{
"station1",
[]*connectivitymap.QueryResult{
{
StationID: "station6",
StationLocation: &nav.Location{
Lat: 30.333,
Lon: 122.333,
},
Distance: 2,
Duration: 2,
},
{
StationID: "station7",
StationLocation: &nav.Location{
Lat: -10.333,
Lon: 122.333,
},
Distance: 3,
Duration: 3,
},
},
&nav.Location{
Lat: 32.333,
Lon: 122.333,
},
},
{
"station2",
[]*connectivitymap.QueryResult{
{
StationID: "station6",
StationLocation: &nav.Location{
Lat: 30.333,
Lon: 122.333,
},
Distance: 4,
Duration: 4,
},
{
StationID: "station7",
StationLocation: &nav.Location{
Lat: -10.333,
Lon: 122.333,
},
Distance: 5,
Duration: 5,
},
},
&nav.Location{
Lat: -32.333,
Lon: -122.333,
},
},
{
"station3",
[]*connectivitymap.QueryResult{
{
StationID: "station6",
StationLocation: &nav.Location{
Lat: 30.333,
Lon: 122.333,
},
Distance: 6,
Duration: 6,
},
{
StationID: "station7",
StationLocation: &nav.Location{
Lat: -10.333,
Lon: 122.333,
},
Distance: 7,
Duration: 7,
},
},
&nav.Location{
Lat: 32.333,
Lon: -122.333,
},
},
{
"station4",
[]*connectivitymap.QueryResult{
{
StationID: "station6",
StationLocation: &nav.Location{
Lat: 30.333,
Lon: 122.333,
},
Distance: 8,
Duration: 8,
},
{
StationID: "station7",
StationLocation: &nav.Location{
Lat: -10.333,
Lon: 122.333,
},
Distance: 9,
Duration: 9,
},
},
&nav.Location{
Lat: -32.333,
Lon: 122.333,
},
},
{
"station6",
[]*connectivitymap.QueryResult{
{
StationID: "dest_location",
StationLocation: &nav.Location{
Lat: 4.4,
Lon: 4.4,
},
Distance: 66.6,
Duration: 66.6,
},
},
&nav.Location{
Lat: 30.333,
Lon: 122.333,
},
},
{
"station7",
[]*connectivitymap.QueryResult{
{
StationID: "dest_location",
StationLocation: &nav.Location{
Lat: 4.4,
Lon: 4.4,
},
Distance: 11.1,
Duration: 11.1,
},
},
&nav.Location{
Lat: -10.333,
Lon: 122.333,
},
},
{
"dest_location",
nil,
&nav.Location{
Lat: 4.4,
Lon: 4.4,
},
},
}

c := generateNeighborsChan()

q := NewQuerierBasedOnWeightBetweenNeighborsChan(c)

for _, c := range cases {
acturalQueryResult := q.NearByStationQuery(c.stationID)
if !reflect.DeepEqual(acturalQueryResult, c.expectQueryResult) {
t.Errorf("Generate incorrect for NearByStationQuery, expect \n%#v\n but got \n%#v\n", c.expectQueryResult, acturalQueryResult)
}

actualLocation := q.GetLocation(c.stationID)
if !reflect.DeepEqual(actualLocation, c.expectLocation) {
t.Errorf("Generate incorrect for GetLocation, expect \n%#v\n but got \n%#v\n", c.expectLocation, actualLocation)
}

}
}

func generateNeighborsChan() chan stationfindertype.WeightBetweenNeighbors {
c := make(chan stationfindertype.WeightBetweenNeighbors, 3)

go func() {
c <- stationfindertype.WeightBetweenNeighbors{
NeighborsInfo: stationfindertype.NeighborInfoArray0,
Err: nil,
}
c <- stationfindertype.WeightBetweenNeighbors{
NeighborsInfo: stationfindertype.NeighborInfoArray1,
Err: nil,
}
c <- stationfindertype.WeightBetweenNeighbors{
NeighborsInfo: stationfindertype.NeighborInfoArray2,
Err: nil,
}

close(c)
}()

return c
}
Loading

0 comments on commit 1a654ba

Please sign in to comment.