119 lines
3.4 KiB
Go
119 lines
3.4 KiB
Go
package handler
|
|
|
|
import (
|
|
"time"
|
|
|
|
"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"
|
|
)
|
|
|
|
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
|
|
// }
|