2023-03-27 18:54:56 +00:00
|
|
|
package handler
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"time"
|
|
|
|
|
2023-03-30 06:44:58 +00:00
|
|
|
"git.coopgo.io/coopgo-platform/carpool-service/internal"
|
2023-03-29 10:50:25 +00:00
|
|
|
"git.coopgo.io/coopgo-platform/carpool-service/tiles"
|
2023-03-27 18:54:56 +00:00
|
|
|
"git.coopgo.io/coopgo-platform/routing-service/encoding/polylines"
|
|
|
|
"github.com/google/uuid"
|
2023-03-29 10:50:25 +00:00
|
|
|
"github.com/paulmach/orb"
|
2023-03-27 18:54:56 +00:00
|
|
|
"github.com/paulmach/orb/geojson"
|
2023-03-29 10:50:25 +00:00
|
|
|
"github.com/paulmach/orb/simplify"
|
2023-03-27 18:54:56 +00:00
|
|
|
"github.com/rs/zerolog/log"
|
|
|
|
)
|
|
|
|
|
2023-05-07 23:29:59 +00:00
|
|
|
// CreateRegularRoutes creates and stores a regular route
|
2023-03-27 18:54:56 +00:00
|
|
|
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")
|
|
|
|
}
|
|
|
|
|
2023-03-29 10:50:25 +00:00
|
|
|
linestring := polylines.Decode(&polyline, 5)
|
|
|
|
simplified_linestring := simplify.DouglasPeucker(0.003).Simplify(linestring.Clone())
|
2023-03-27 18:54:56 +00:00
|
|
|
|
2023-03-29 10:50:25 +00:00
|
|
|
// 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
|
2023-03-27 18:54:56 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := h.Storage.CreateRegularRoutes(routes); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-05-07 23:29:59 +00:00
|
|
|
// GetUserPlanning returns the planned routes for a user between 2 dates. It transforms regular routes to multiple indivual planned route schedules
|
2023-09-26 14:42:46 +00:00
|
|
|
func (h *CarpoolServiceHandler) GetUserPlanning(userid string, minDepartureDate time.Time, maxDepartureDate time.Time) (planned_schedules map[string][]internal.PlannedRouteSchedule, missing_planning bool, err error) {
|
2023-03-27 18:54:56 +00:00
|
|
|
log.Debug().
|
|
|
|
Str("user_id", userid).
|
|
|
|
Time("min_departure_date", minDepartureDate).
|
|
|
|
Time("max_departure_date", maxDepartureDate).
|
|
|
|
Msg("carpool service handler - GetUserPlanning")
|
|
|
|
|
2023-03-30 06:44:58 +00:00
|
|
|
results := map[string][]internal.PlannedRouteSchedule{}
|
2023-03-27 18:54:56 +00:00
|
|
|
|
|
|
|
current_date := minDepartureDate
|
|
|
|
for current_date.Before(maxDepartureDate) {
|
2023-03-30 06:44:58 +00:00
|
|
|
results[current_date.Format("2006-01-02")] = []internal.PlannedRouteSchedule{}
|
2023-03-27 18:54:56 +00:00
|
|
|
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")
|
2023-09-26 14:42:46 +00:00
|
|
|
return nil, false, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(routes) == 0 {
|
|
|
|
return results, true, nil
|
2023-03-27 18:54:56 +00:00
|
|
|
}
|
|
|
|
|
2023-04-03 18:35:12 +00:00
|
|
|
all_schedules := []internal.PlannedRouteSchedule{}
|
|
|
|
|
2023-03-27 18:54:56 +00:00
|
|
|
for _, r := range routes {
|
2023-03-30 06:44:58 +00:00
|
|
|
rr := internal.RegularRoute(*r)
|
2023-05-07 23:29:59 +00:00
|
|
|
schedules, err := rr.PlannedRouteSchedules(minDepartureDate, maxDepartureDate)
|
2023-03-27 18:54:56 +00:00
|
|
|
if err != nil {
|
2023-05-07 23:29:59 +00:00
|
|
|
log.Error().Err(err).Msg("PlannedRouteSchedules error")
|
2023-09-26 14:42:46 +00:00
|
|
|
return nil, false, err
|
2023-03-27 18:54:56 +00:00
|
|
|
}
|
|
|
|
|
2023-04-03 18:35:12 +00:00
|
|
|
all_schedules = append(all_schedules, schedules...)
|
|
|
|
|
2023-03-27 18:54:56 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-03 18:35:12 +00:00
|
|
|
if len(all_schedules) > 0 {
|
|
|
|
err = h.Storage.StoreRouteSchedules(all_schedules)
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Err(err).Msg("could not store route schedules")
|
2023-09-26 14:42:46 +00:00
|
|
|
return nil, false, err
|
2023-04-03 18:35:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-26 14:42:46 +00:00
|
|
|
return results, false, nil
|
2023-03-27 18:54:56 +00:00
|
|
|
}
|
2023-04-05 18:57:27 +00:00
|
|
|
|
2023-05-07 23:29:59 +00:00
|
|
|
// GetPlannedTrip returns a planned trip, given an ID. This should be called after getting the user planning from regular routes
|
2023-04-05 18:57:27 +00:00
|
|
|
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
|
|
|
|
}
|