Skip to content

Commit

Permalink
refactor: Refactor station finder to support via Telenav search and v…
Browse files Browse the repository at this point in the history
…ia local search (#271)

issue: #270
  • Loading branch information
CodeBear801 authored Apr 10, 2020
1 parent f6be7b0 commit c5125d0
Show file tree
Hide file tree
Showing 33 changed files with 702 additions and 471 deletions.
2 changes: 2 additions & 0 deletions integration/cmd/oasis/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
var flags struct {
listenPort int
osrmBackendEndpoint string
finderType string
tnSearchEndpoint string
tnSearchAPIKey string
tnSearchAPISignature string
Expand All @@ -15,6 +16,7 @@ var flags struct {
func init() {
flag.IntVar(&flags.listenPort, "p", 8090, "Listen port.")
flag.StringVar(&flags.osrmBackendEndpoint, "osrm", "", "OSRM-backend endpoint")
flag.StringVar(&flags.finderType, "finder", "", "Specify search finder to search for nearby charge stations for given location, use TNSearchFinder or LocalIndexerFinder")
flag.StringVar(&flags.tnSearchEndpoint, "search", "", "TN-Search-backend endpoint")
flag.StringVar(&flags.tnSearchAPIKey, "searchApiKey", "", "API key for TN-Search-backend")
flag.StringVar(&flags.tnSearchAPISignature, "searchApiSignature", "", "API Signature for TN-Search-backend")
Expand Down
7 changes: 6 additions & 1 deletion integration/cmd/oasis/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ func main() {
defer glog.Flush()
mux := http.NewServeMux()

oasisService := oasis.New(flags.osrmBackendEndpoint, flags.tnSearchEndpoint, flags.tnSearchAPIKey, flags.tnSearchAPISignature)
oasisService, err := oasis.New(flags.osrmBackendEndpoint, flags.finderType, flags.tnSearchEndpoint, flags.tnSearchAPIKey, flags.tnSearchAPISignature)
if err != nil {
glog.Errorf("Failed to create oasis handler due to err %+v.\n", err)
return
}

mux.Handle("/oasis/v1/earliest/", oasisService)

// listen
Expand Down
30 changes: 21 additions & 9 deletions integration/service/oasis/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,35 @@ import (
"github.com/Telenav/osrm-backend/integration/pkg/api/oasis"
"github.com/Telenav/osrm-backend/integration/service/oasis/osrmconnector"
"github.com/Telenav/osrm-backend/integration/service/oasis/osrmhelper"
"github.com/Telenav/osrm-backend/integration/service/oasis/searchconnector"
"github.com/Telenav/osrm-backend/integration/service/oasis/stationfinder"
"github.com/golang/glog"
)

// Handler handles oasis request and provide response
type Handler struct {
osrmConnector *osrmconnector.OSRMConnector
tnSearchConnector *searchconnector.TNSearchConnector
osrmConnector *osrmconnector.OSRMConnector
finder stationfinder.StationFinder
}

// New creates new Handler object
func New(osrmBackend, searchEndpoint, apiKey, apiSignature string) *Handler {
func New(osrmBackend, finderType, searchEndpoint, apiKey, apiSignature string) (*Handler, error) {
// @todo: need make sure connectivity is on and continues available
return &Handler{
osrmConnector: osrmconnector.NewOSRMConnector(osrmBackend),
tnSearchConnector: searchconnector.NewTNSearchConnector(searchEndpoint, apiKey, apiSignature),
// simple request to guarantee server is alive after init
if len(osrmBackend) == 0 {
err := fmt.Errorf("empty osrmBackend end point")
return nil, err
}

finder, err := stationfinder.CreateStationsFinder(finderType, searchEndpoint, apiKey, apiSignature)
if err != nil {
glog.Errorf("Failed in Handler's New() when try to call CreateStationsFinder(), met error = %+v\n", err)
return nil, err
}

return &Handler{
osrmConnector: osrmconnector.NewOSRMConnector(osrmBackend),
finder: finder,
}, nil
}

func (h *Handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
Expand Down Expand Up @@ -71,14 +83,14 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}

// check whether could achieve by single charge
overlap := getOverlapChargeStations4OrigDest(oasisReq, routeResp.Routes[0].Distance, h.osrmConnector, h.tnSearchConnector)
overlap := getOverlapChargeStations4OrigDest(oasisReq, routeResp.Routes[0].Distance, h.osrmConnector, h.finder)
if len(overlap) > 0 {
generateResponse4SingleChargeStation(w, oasisReq, overlap, h.osrmConnector)
return
}

// generate result for multiple charge
generateSolutions4MultipleCharge(w, oasisReq, routeResp, h.osrmConnector, h.tnSearchConnector)
generateSolutions4MultipleCharge(w, oasisReq, routeResp, h.osrmConnector, h.finder)
return
}

Expand Down
10 changes: 5 additions & 5 deletions integration/service/oasis/reachable_by_multiple_charge.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ import (
"github.com/Telenav/osrm-backend/integration/service/oasis/chargingstrategy"
"github.com/Telenav/osrm-backend/integration/service/oasis/haversine"
"github.com/Telenav/osrm-backend/integration/service/oasis/osrmconnector"
"github.com/Telenav/osrm-backend/integration/service/oasis/searchconnector"
"github.com/Telenav/osrm-backend/integration/service/oasis/stationfinder"
"github.com/Telenav/osrm-backend/integration/service/oasis/stationfinder/stationfinderalg"
"github.com/Telenav/osrm-backend/integration/service/oasis/stationgraph"
"github.com/golang/glog"

"github.com/twpayne/go-polyline"
)

// @todo: handle negative situation
func generateSolutions4MultipleCharge(w http.ResponseWriter, oasisReq *oasis.Request, routeResp *route.Response, oc *osrmconnector.OSRMConnector, sc *searchconnector.TNSearchConnector) {
solutions := generateSolutionsWithEarlistArrival(oasisReq, routeResp, oc, sc)
func generateSolutions4MultipleCharge(w http.ResponseWriter, oasisReq *oasis.Request, routeResp *route.Response, oc *osrmconnector.OSRMConnector, finder stationfinder.StationFinder) {
solutions := generateSolutionsWithEarlistArrival(oasisReq, routeResp, oc, finder)

w.WriteHeader(http.StatusOK)
r := new(oasis.Response)
Expand All @@ -32,12 +32,12 @@ func generateSolutions4MultipleCharge(w http.ResponseWriter, oasisReq *oasis.Req
json.NewEncoder(w).Encode(r)
}

func generateSolutionsWithEarlistArrival(oasisReq *oasis.Request, routeResp *route.Response, oc *osrmconnector.OSRMConnector, sc *searchconnector.TNSearchConnector) []*oasis.Solution {
func generateSolutionsWithEarlistArrival(oasisReq *oasis.Request, routeResp *route.Response, oc *osrmconnector.OSRMConnector, finder stationfinder.StationFinder) []*oasis.Solution {
targetSolutions := make([]*oasis.Solution, 0)

chargeLocations := chargeLocationSelection(oasisReq, routeResp)
for _, locations := range chargeLocations {
c := stationfinder.CalculateWeightBetweenNeighbors(locations, oc, sc)
c := stationfinderalg.CalculateWeightBetweenNeighbors(locations, oc, finder)
internalSolutions := stationgraph.NewStationGraph(c, oasisReq.CurrRange, oasisReq.MaxRange,
chargingstrategy.NewFakeChargingStrategy(oasisReq.MaxRange)).GenerateChargeSolutions()

Expand Down
10 changes: 5 additions & 5 deletions integration/service/oasis/reachable_by_single_charge.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (
"github.com/Telenav/osrm-backend/integration/pkg/api/search/nearbychargestation"
"github.com/Telenav/osrm-backend/integration/service/oasis/osrmconnector"
"github.com/Telenav/osrm-backend/integration/service/oasis/osrmhelper"
"github.com/Telenav/osrm-backend/integration/service/oasis/searchconnector"
"github.com/Telenav/osrm-backend/integration/service/oasis/stationfinder"
"github.com/Telenav/osrm-backend/integration/service/oasis/stationfinder/stationfinderalg"
"github.com/golang/glog"
)

Expand All @@ -25,15 +25,15 @@ const maxOverlapPointsNum = 500
// The energy level is safeRange + nearest charge station's distance to destination
// If there is one or several charge stations could be found in both origStationsResp and destStationsResp
// We think the result is reachable by single charge station
func getOverlapChargeStations4OrigDest(req *oasis.Request, routedistance float64, osrmConnector *osrmconnector.OSRMConnector, tnSearchConnector *searchconnector.TNSearchConnector) coordinate.Coordinates {
func getOverlapChargeStations4OrigDest(req *oasis.Request, routedistance float64, osrmConnector *osrmconnector.OSRMConnector, finder stationfinder.StationFinder) coordinate.Coordinates {
// only possible when currRange + maxRange > distance + safeRange
if req.CurrRange+req.MaxRange < routedistance+req.SafeLevel {
return nil
}

origStations := stationfinder.NewOrigStationFinder(tnSearchConnector, req)
destStations := stationfinder.NewDestStationFinder(tnSearchConnector, req)
overlap := stationfinder.FindOverlapBetweenStations(origStations, destStations)
origStations := finder.NewOrigStationFinder(req)
destStations := finder.NewDestStationFinder(req)
overlap := stationfinderalg.FindOverlapBetweenStations(origStations, destStations)

if len(overlap) == 0 {
return nil
Expand Down
31 changes: 0 additions & 31 deletions integration/service/oasis/stationfinder/dest_iterator.go

This file was deleted.

This file was deleted.

53 changes: 34 additions & 19 deletions integration/service/oasis/stationfinder/doc.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,36 @@
// Package stationfinder provide functionality to find nearby charge stations and
// related algorithm.
// Finders:
// - origStationFinder holds logic for how to find reachable charge stations
// based on current energy level.
// - destStationFinder holds logic for how to find reachable charge stations
// based on safe energy level and distance to nearest charge station(todo).
// - lowEnergyLocationStationFinder holds logic for how to find reachable
// charge station near certain location.
// - orig_iterator and dest_iterator wraps single point of orig/dest which could
// be used for algorithms
/*
// Algorithm:
// - Each finder provide iterator to iterate charge station candidates.
// - The choice of channel as response makes algorithm could be asynchronous func.
// - FindOverlapBetweenStations provide functionality to find overlap
// between two iterator.
// - CalcWeightBetweenChargeStationsPair provide functionality to calculate
// cost between two group of charge stations which could construct a new
// graph as edges.
Package stationfinder provide functionality to find nearby charge stations and
related algorithm.
It's find functionality could be achieved by:
- TNSearchFinder, which is implemented by Telenav's search web service.
+ The data source is from professional data
+ Based on Lucence and hilbert value
+ Could potentially supports dynamic information
- LocalIndexerFinder
+ Support any kind of data sources as long as following format defined in https://github.com/Telenav/osrm-backend/issues/237#issue-585201041
+ For Telenav usage, uses the same source with Telenav search service
+ Spatial index is build based on google s2
Finders:
- origStationFinder holds logic for how to find reachable charge stations
based on current energy level.
- destStationFinder holds logic for how to find reachable charge stations
based on safe energy level and distance to nearest charge station(todo).
- lowEnergyLocationStationFinder holds logic for how to find reachable
charge station near certain location.
- orig_iterator and dest_iterator wraps single point of orig/dest which could
be used for algorithms
Algorithm:
- Each finder provide iterator to iterate charge station candidates.
- The choice of channel as response makes algorithm could be asynchronous func.
- FindOverlapBetweenStations provide functionality to find overlap
between two iterator.
- CalcWeightBetweenChargeStationsPair provide functionality to calculate
cost between two group of charge stations which could construct a new
graph as edges.
*/
package stationfinder
39 changes: 39 additions & 0 deletions integration/service/oasis/stationfinder/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package stationfinder

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

// StationFinder creates finders for different purpose, all finders must implement NearbyStationsIterator interface
type StationFinder interface {
// NewOrigStationFinder creates finder to search for nearby charge stations near orig
NewOrigStationFinder(oasisReq *oasis.Request) stationfindertype.NearbyStationsIterator

// NewDestStationFinder creates finder to search for nearby charge stations near destination
NewDestStationFinder(oasisReq *oasis.Request) stationfindertype.NearbyStationsIterator

// NewLowEnergyLocationStationFinder creates finder to search for nearby charge stations when energy is low
NewLowEnergyLocationStationFinder(location *nav.Location) stationfindertype.NearbyStationsIterator
}

// Algorithm contains algorithm implemented based on NearbyStationsIterator
type Algorithm interface {
// FindOverlapBetweenStations finds overlap charge stations based on two iterator
FindOverlapBetweenStations(iterF stationfindertype.NearbyStationsIterator,
iterS stationfindertype.NearbyStationsIterator) []stationfindertype.ChargeStationInfo

// CalcWeightBetweenChargeStationsPair accepts two iterators and calculates weights between each pair of iterators
CalcWeightBetweenChargeStationsPair(from stationfindertype.NearbyStationsIterator,
to stationfindertype.NearbyStationsIterator,
table osrmconnector.TableRequster) ([]stationfindertype.NeighborInfo, error)

// CalculateWeightBetweenNeighbors accepts locations array, which will search for nearby
// charge stations and then calculate weight between stations, the result is used to
// construct graph.
CalculateWeightBetweenNeighbors(locations []*nav.Location,
oc *osrmconnector.OSRMConnector,
finder StationFinder) chan stationfindertype.WeightBetweenNeighbors
}
Loading

0 comments on commit c5125d0

Please sign in to comment.