carpool-service/handler/management.go

131 lines
3.9 KiB
Go

package handler
import (
"errors"
"time"
"git.coopgo.io/coopgo-platform/carpool-service/internal"
"git.coopgo.io/coopgo-platform/carpool-service/tiles"
"git.coopgo.io/coopgo-platform/routing-service/encoding/polylines"
"github.com/google/uuid"
"github.com/paulmach/orb"
"github.com/paulmach/orb/geojson"
"github.com/paulmach/orb/simplify"
"github.com/rs/zerolog/log"
)
// CreateRegularRoutes creates and stores a regular route
func (h *CarpoolServiceHandler) CreateRegularRoutes(routes []*geojson.FeatureCollection) error {
groupid := uuid.NewString()
for _, r := range routes {
r.ExtraMembers["id"] = uuid.NewString()
r.ExtraMembers["routes_group_id"] = groupid
properties, ok := r.ExtraMembers["properties"].(map[string]any)
if !ok {
return errors.New("no properties found in feature collection")
}
polyline, ok := properties["polyline"].(string)
if !ok {
return errors.New("no polyline found in properties from feature collection")
}
linestring := polylines.Decode(&polyline, 5)
simplified_linestring := simplify.DouglasPeucker(0.003).Simplify(linestring.Clone())
// Simplification tests
// Antibes -> Rennes
// Without Simplify : 12230
// 0.01 -> 129
// 0.005 -> 230
// 0.003 -> 338
lsFeature := geojson.NewFeature(simplified_linestring)
lsFeature.Properties["encoded_polyline"] = polyline
r.Append(lsFeature)
gridids := tiles.LineStringGridIds(simplified_linestring.(orb.LineString))
r.ExtraMembers["grid_ids"] = gridids
}
if err := h.Storage.CreateRegularRoutes(routes); err != nil {
return err
}
return nil
}
// GetUserPlanning returns the planned routes for a user between 2 dates. It transforms regular routes to multiple indivual planned route schedules
func (h *CarpoolServiceHandler) GetUserPlanning(userid string, minDepartureDate time.Time, maxDepartureDate time.Time) (planned_schedules map[string][]internal.PlannedRouteSchedule, missing_planning bool, err error) {
log.Debug().
Str("user_id", userid).
Time("min_departure_date", minDepartureDate).
Time("max_departure_date", maxDepartureDate).
Msg("carpool service handler - GetUserPlanning")
results := map[string][]internal.PlannedRouteSchedule{}
current_date := minDepartureDate
for current_date.Before(maxDepartureDate) {
results[current_date.Format("2006-01-02")] = []internal.PlannedRouteSchedule{}
current_date = current_date.Add(24 * time.Hour)
}
routes, err := h.Storage.GetUserRegularRoutes(userid)
if err != nil {
log.Error().Err(err).Msg("error in storage - GetUserRegularRoutes")
return nil, false, err
}
if len(routes) == 0 {
return results, true, nil
}
all_schedules := []internal.PlannedRouteSchedule{}
for _, r := range routes {
rr := internal.RegularRoute(*r)
schedules, err := rr.PlannedRouteSchedules(minDepartureDate, maxDepartureDate)
if err != nil {
log.Error().Err(err).Msg("PlannedRouteSchedules error")
return nil, false, err
}
all_schedules = append(all_schedules, schedules...)
for _, s := range schedules {
log.Debug().
Str("route id", s.Route.ExtraMembers.MustString("id")).
Any("datetime", s.DepartureDate.Format(time.RFC3339)).
Msg("new schedule")
dateString := s.DepartureDate.Format("2006-01-02")
results[dateString] = append(results[dateString], s)
}
}
if len(all_schedules) > 0 {
err = h.Storage.StoreRouteSchedules(all_schedules)
if err != nil {
log.Error().Err(err).Msg("could not store route schedules")
return nil, false, err
}
}
return results, false, nil
}
// GetPlannedTrip returns a planned trip, given an ID. This should be called after getting the user planning from regular routes
func (h *CarpoolServiceHandler) GetPlannedTrip(id string) (*internal.PlannedRouteSchedule, error) {
planned_trip, err := h.Storage.GetRouteSchedule(id)
if err != nil {
log.Error().Str("planned trip id", id).Err(err).Msg("could not retrieve planned schedule")
return nil, err
}
return planned_trip, nil
}