Add tiles management

This commit is contained in:
2023-03-29 12:50:25 +02:00
parent 77c8576254
commit bbc682386a
18 changed files with 559 additions and 64 deletions

View File

@@ -2,17 +2,23 @@ package handler
import (
"git.coopgo.io/coopgo-platform/carpool-service/storage"
"git.coopgo.io/coopgo-platform/carpool-service/tiles"
"git.coopgo.io/coopgo-platform/routing-service"
"github.com/spf13/viper"
)
type CarpoolServiceHandler struct {
Config *viper.Viper
Storage storage.Storage
Tiles *tiles.TilesHandler
Routing routing.RoutingService
}
func NewCarpoolServiceHandler(cfg *viper.Viper, storage storage.Storage) (*CarpoolServiceHandler, error) {
func NewCarpoolServiceHandler(cfg *viper.Viper, storage storage.Storage, tilesHandler *tiles.TilesHandler, routing routing.RoutingService) (*CarpoolServiceHandler, error) {
return &CarpoolServiceHandler{
Config: cfg,
Storage: storage,
Tiles: tilesHandler,
Routing: routing,
}, nil
}

View File

@@ -4,9 +4,13 @@ import (
"errors"
"time"
"git.coopgo.io/coopgo-platform/carpool-service/helpers"
"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"
)
@@ -26,10 +30,23 @@ func (h *CarpoolServiceHandler) CreateRegularRoutes(routes []*geojson.FeatureCol
return errors.New("no polyline found in properties from feature collection")
}
lineString := geojson.NewFeature(polylines.Decode(&polyline, 5))
lineString.Properties["encoded_polyline"] = polyline
linestring := polylines.Decode(&polyline, 5)
simplified_linestring := simplify.DouglasPeucker(0.003).Simplify(linestring.Clone())
r.Append(lineString)
// 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
}
@@ -40,18 +57,18 @@ func (h *CarpoolServiceHandler) CreateRegularRoutes(routes []*geojson.FeatureCol
return nil
}
func (h *CarpoolServiceHandler) GetUserPlanning(userid string, minDepartureDate time.Time, maxDepartureDate time.Time) (map[string][]PlannedRouteSchedule, error) {
func (h *CarpoolServiceHandler) GetUserPlanning(userid string, minDepartureDate time.Time, maxDepartureDate time.Time) (map[string][]helpers.PlannedRouteSchedule, 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][]PlannedRouteSchedule{}
results := map[string][]helpers.PlannedRouteSchedule{}
current_date := minDepartureDate
for current_date.Before(maxDepartureDate) {
results[current_date.Format("2006-01-02")] = []PlannedRouteSchedule{}
results[current_date.Format("2006-01-02")] = []helpers.PlannedRouteSchedule{}
current_date = current_date.Add(24 * time.Hour)
}
@@ -62,7 +79,7 @@ func (h *CarpoolServiceHandler) GetUserPlanning(userid string, minDepartureDate
}
for _, r := range routes {
rr := RegularRoute(*r)
rr := helpers.RegularRoute(*r)
schedules, err := rr.PlannedJourneySchedules(minDepartureDate, maxDepartureDate)
if err != nil {
log.Error().Err(err)

View File

@@ -1,78 +0,0 @@
package handler
import (
"errors"
"strconv"
"strings"
"time"
"github.com/paulmach/orb/geojson"
"github.com/rs/zerolog/log"
)
type PlannedRouteSchedule struct {
Route RegularRoute
DepartureDate time.Time
}
type RegularRoute geojson.FeatureCollection
func (rr RegularRoute) PlannedJourneySchedules(mindate time.Time, maxdate time.Time) ([]PlannedRouteSchedule, error) {
log.Debug().
Str("regular_route.id", rr.ExtraMembers.MustString("id", "")).
Str("mindate", mindate.Format(time.RFC3339)).
Str("maxdate", maxdate.Format(time.RFC3339)).
Msg("carpool service handler - PlannedJourneySchedules")
results := []PlannedRouteSchedule{}
current_date := mindate
for current_date.Before(maxdate) {
day := strings.ToUpper(current_date.Format("Mon"))
time_of_day, err := rr.checkSchedules(day)
if err != nil {
log.Error().
Err(err).
Str("day", day).
Msg("schedules not found")
}
if time_of_day != "" {
splitted := strings.Split(time_of_day, ":")
h, _ := strconv.Atoi(splitted[0])
m, _ := strconv.Atoi(splitted[1])
t := time.Date(current_date.Year(), current_date.Month(), current_date.Day(), h, m, 0, 0, time.Local)
results = append(results, PlannedRouteSchedule{
Route: rr,
DepartureDate: t,
})
}
current_date = current_date.Add(24 * time.Hour)
}
return results, nil
}
func (rr RegularRoute) checkSchedules(day string) (timeOfDay string, err error) {
if properties, ok := rr.ExtraMembers["properties"]; ok {
if propertiesMap, ok := properties.(map[string]any); ok {
if schedules, ok := propertiesMap["schedules"]; ok {
if schedulesSlice, ok := schedules.([]any); ok {
for _, sched := range schedulesSlice {
if daySchedule, ok := sched.(map[string]any); ok {
if daySchedule["day"].(string) == day {
return daySchedule["time_of_day"].(string), nil
}
}
}
}
}
}
}
return "", errors.New("not found")
}
func (rr RegularRoute) FeatureCollection() *geojson.FeatureCollection {
fc := geojson.FeatureCollection(rr)
return &fc
}

View File

@@ -3,10 +3,116 @@ package handler
import (
"time"
"git.coopgo.io/coopgo-platform/carpool-service/interoperability/ocss"
"git.coopgo.io/coopgo-platform/routing-service"
"github.com/paulmach/orb"
"github.com/paulmach/orb/geojson"
"github.com/paulmach/orb/planar"
"github.com/rs/zerolog/log"
)
func (h *CarpoolServiceHandler) GetDriverJourneys(departure orb.Point, arrival orb.Point, minDate time.Time, maxDate time.Time) ([]ocss.DriverJourney, error) {
return nil, nil
type SearchResult struct {
ID string
Route *geojson.FeatureCollection
DepartureDate time.Time
Itinerary *routing.Route
}
func (h *CarpoolServiceHandler) GetDriverJourneys(departure orb.Point, arrival orb.Point, departureRadius *float64, arrivalRadius *float64, minDate time.Time, maxDate time.Time, count *int64) ([]SearchResult, error) {
log.Debug().
Any("departure", departure).
Any("arrival", arrival).
Any("dep radius", departureRadius).
Any("arr radius", arrivalRadius).
Str("mindate", minDate.Format(time.RFC3339)).
Str("maxdate", maxDate.Format(time.RFC3339)).
Any("count", count).
Msg("Carpool service handler - GetDriverJourneys")
if count == nil {
c := int64(10)
count = &c
}
if departureRadius == nil {
d := float64(1000)
departureRadius = &d
}
if arrivalRadius == nil {
a := float64(1000)
departureRadius = &a
}
tileset, err := h.Tiles.GetTiles("driver", minDate, departure, arrival)
if err != nil {
log.Error().
Str("date", minDate.Format(time.RFC3339)).
Any("departure", departure).
Any("arrival", arrival).
Err(err).
Msg("could not retrieve tiles")
return nil, err
}
log.Debug().Any("tileset", tileset).Msg("got tileset")
candidate_routes := tileset.GetTiledRoutes()
journeys := []SearchResult{}
counted := int64(0)
for _, r := range candidate_routes {
ls := r.Route.Features[2].Geometry
distanceFromDeparture, indexDeparture := planar.DistanceFromWithIndex(ls, departure)
distanceFromArrival, indexArrival := planar.DistanceFromWithIndex(ls, arrival)
if indexArrival >= indexDeparture && distanceFromDeparture <= *departureRadius && distanceFromArrival < *arrivalRadius {
routePoints := []orb.Point{r.Route.Features[0].Point(), departure, arrival, r.Route.Features[0].Point()}
itinerary, err := h.Routing.Route(routePoints)
if err != nil {
log.Error().Err(err).Msg("error getting route with viapoints")
continue
}
journeys = append(journeys, SearchResult{
ID: r.ID,
Route: r.Route,
DepartureDate: r.DepartureDate,
Itinerary: itinerary,
})
counted = counted + 1
if counted == *count {
break
}
}
}
return journeys, nil
}
// //distance to Linestring computes the distance from point to the given linestring anf returns this minimum distance and the segment number
// func distanceToLineSTring(point orb.Point, lineString orb.LineString) (distance float64, closest_segment_index int) {
// minDistance := math.Inf(1)
// closest := -1
// for i := 0; i < len(lineString)-1; i++ {
// segment1 := lineString[i]
// segment2 := lineString[i+1]
// dist := distanceToSegment(point, segment1, segment2)
// if dist < minDistance {
// minDistance = dist
// closest = i
// }
// }
// return minDistance, closest
// }
// //distanceToSegment computes the distance to the segment defined with a starting and a ending point
// func distanceToSegment(point orb.Point, start orb.Point, end orb.Point) float64 {
// len := (end.Lon()-start.Lon())*(end.Lon()-start.Lon()) + (end.Lat()-start.Lat())*(end.Lat()-start.Lat())
// s := ((start.Lat()-point.Lat())*(end.Lon()-start.Lon()) - (start.Lon()-point.Lon())*(end.Lat()-start.Lat())) / len
// distance := math.Abs(s) * math.Sqrt(len)
// return distance
// }