multimodal-routing/handlers/carpool.go

105 lines
3.1 KiB
Go

package handlers
import (
"errors"
"fmt"
"sync"
"time"
"git.coopgo.io/coopgo-platform/multimodal-routing/libs/carpool"
"github.com/paulmach/orb"
"github.com/paulmach/orb/geojson"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
)
type CarpoolRoutingHandler struct {
OperatorAPIs []carpool.CarpoolOperatorAPI
}
func NewCarpoolRoutingHandler(cfg *viper.Viper) (*CarpoolRoutingHandler, error) {
operatorApis := []carpool.CarpoolOperatorAPI{}
operators := cfg.Get("operators").([]any)
for _, operator := range operators {
o := operator.(map[string]any)
operatorType, ok := o["type"].(string)
if !ok {
return nil, errors.New("missing operator type")
}
if operatorType == "blablacardaily" {
operatorId, ok := o["operator_id"].(string)
if !ok {
return nil, errors.New("missing operator_id")
}
apiKey, ok := o["api_key"].(string)
if !ok {
return nil, errors.New("missing api_key")
}
baseUrl, ok := o["base_url"].(string)
if !ok {
return nil, errors.New("missing base_url")
}
operatorapi, err := carpool.NewBBCDailyCarpoolAPI(operatorId, apiKey, baseUrl)
if err != nil {
return nil, fmt.Errorf("could not create Blablacar Daily API: %w", err)
}
operatorApis = append(operatorApis, operatorapi)
}
}
return &CarpoolRoutingHandler{
OperatorAPIs: operatorApis,
}, nil
}
// TODO add options (WithTimeDelta, etc...)
func (h CarpoolRoutingHandler) Search(results chan *geojson.FeatureCollection, departure geojson.Feature, destination geojson.Feature, departureDate time.Time) error {
defer close(results)
defaultTimeDelta := 3600 * time.Second
defaultDepartureRadius := int64(10)
defaultDestinationRadius := int64(10)
defaultCount := int64(10)
var wg2 sync.WaitGroup
for _, api := range h.OperatorAPIs {
wg2.Add(1)
go func(results chan *geojson.FeatureCollection, wg2 *sync.WaitGroup) {
defer wg2.Done()
r, err := api.GetDriverJourneys(departure.Point().Lat(), departure.Point().Lon(), destination.Point().Lat(), destination.Point().Lon(), departureDate, &defaultTimeDelta, defaultDepartureRadius, defaultDestinationRadius, defaultCount)
if err != nil {
log.Error().Err(err).Str("operator", api.GetOperatorId()).Msg("error in carpool api request")
return
}
for _, journey := range r {
// Departure
geo := geojson.NewFeatureCollection()
dep := geojson.NewFeature(orb.Point{journey.PassengerPickupLng, journey.PassengerPickupLat})
dep.Properties["type"] = "departure"
dep.Properties["label"] = journey.PassengerPickupAddress
// TODO Polyline to GeoJSON LineString
// Destination
dest := geojson.NewFeature(orb.Point{journey.PassengerDropLng, journey.PassengerDropLat})
dest.Properties["type"] = "destination"
dest.Properties["label"] = journey.PassengerDropAddress
// Carpool GeoJSON definition
geo.Features = append(geo.Features, dep)
geo.Features = append(geo.Features, dest)
geo.ExtraMembers = geojson.Properties{
"journey_type": "carpool",
"ocss": journey,
}
results <- geo
}
}(results, &wg2)
}
wg2.Wait()
return nil
}