initial commit

This commit is contained in:
2025-04-29 06:31:39 +02:00
commit 5f63e312c9
19 changed files with 1458 additions and 0 deletions

103
handlers/carpool.go Normal file
View File

@@ -0,0 +1,103 @@
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, wg *sync.WaitGroup, departure geojson.Feature, destination geojson.Feature, departureDate time.Time) error {
defer wg.Done()
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")
}
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
}

47
handlers/handlers.go Normal file
View File

@@ -0,0 +1,47 @@
package handlers
import (
"fmt"
"sync"
"time"
"github.com/paulmach/orb/geojson"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
)
type MultimodalRoutingHandler struct {
Carpool *CarpoolRoutingHandler
}
func NewMultimodalRoutingHandler(cfg *viper.Viper) (*MultimodalRoutingHandler, error) {
carpoolHandler, err := NewCarpoolRoutingHandler(cfg.Sub("carpool"))
if err != nil {
return nil, fmt.Errorf("could not initialize carpool handler : %w", err)
}
return &MultimodalRoutingHandler{
Carpool: carpoolHandler,
}, nil
}
func (h *MultimodalRoutingHandler) Search(departure geojson.Feature, destination geojson.Feature, departureDate time.Time) ([]*geojson.FeatureCollection, error) {
ch := make(chan *geojson.FeatureCollection)
journeys := []*geojson.FeatureCollection{}
var wg sync.WaitGroup
// Carpool
wg.Add(1)
go h.Carpool.Search(ch, &wg, departure, destination, departureDate)
go func() {
wg.Wait()
close(ch)
}()
for journey := range ch {
log.Debug().Any("journey", journey).Msg("Received from channel")
journeys = append(journeys, journey)
}
return journeys, nil
}

29
handlers/transit.go Normal file
View File

@@ -0,0 +1,29 @@
package handlers
// import (
// "sync"
// "time"
//
// "git.coopgo.io/coopgo-platform/multimodal-routing/libs/transit"
// "github.com/paulmach/orb/geojson"
// "github.com/spf13/viper"
// )
//
// type TransitHandler struct {
// Routing *transit.TransitRouting
// }
//
// func NewTransitHandler(cfg *viper.Viper) (*TransitHandler, error) {
// routing, err := transit.NewTransitRouting(cfg)
// if err != nil {
// return nil, err
// }
// return &TransitHandler{
// Routing: routing,
// }, nil
// }
//
// func (h TransitHandler) Search(results chan *geojson.FeatureCollection, wg *sync.WaitGroup, departure geojson.Feature, destination geojson.Feature, departureDate time.Time) error {
// defer wg.Done()
// return nil
// }