From bf6453b9639aed814f0b93cd841f5066b19aec6d Mon Sep 17 00:00:00 2001 From: Arnaud Delcasse Date: Thu, 30 Mar 2023 00:45:18 +0200 Subject: [PATCH] make distance stuff greate again --- Dockerfile | 28 ++++++++ geoutils/distance.go | 54 +++++++++++++++ go.mod | 6 +- go.sum | 8 +++ handler/search.go | 119 +++++++++++++++++++++++++++++--- interoperability/ocss/server.go | 113 ++++++++++++++++++++++++++---- servers/ocss-api/book.go | 4 +- servers/ocss-api/search.go | 78 +++++++++++++++++++-- storage/mongodb.go | 20 ++++-- tiles/grid.go | 11 ++- tiles/tiles-handler.go | 9 ++- tiles/tiles.go | 6 ++ 12 files changed, 414 insertions(+), 42 deletions(-) create mode 100644 Dockerfile create mode 100644 geoutils/distance.go diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..79dce19 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,28 @@ +FROM golang:alpine as builder + +ARG ACCESS_TOKEN_USR="nothing" +ARG ACCESS_TOKEN_PWD="nothing" + +RUN apk add --no-cache ca-certificates tzdata git + +WORKDIR / + +# Create a netrc file using the credentials specified using --build-arg +RUN printf "machine git.coopgo.io\n\ + login ${ACCESS_TOKEN_USR}\n\ + password ${ACCESS_TOKEN_PWD}\n"\ + >> ~/.netrc +RUN chmod 600 ~/.netrc + +COPY . . + +RUN go mod download && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /server + +FROM scratch +COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ +COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo +COPY --from=builder /server / + +EXPOSE 8080 +EXPOSE 80 +ENTRYPOINT ["/server"] diff --git a/geoutils/distance.go b/geoutils/distance.go new file mode 100644 index 0000000..97d949b --- /dev/null +++ b/geoutils/distance.go @@ -0,0 +1,54 @@ +package geoutils + +import ( + "math" + + "github.com/paulmach/orb" + "github.com/paulmach/orb/geo" + "github.com/rs/zerolog/log" +) + +func DistanceFromLineString(point orb.Point, lineString orb.LineString) (distance float64, closestIndex int) { + minDistance := math.Inf(1) + closest := -1 + + for i := 0; i < len(lineString)-1; i++ { + a := lineString[i] + b := lineString[i+1] + pointOnSegment := projectToSegment(point, a, b) + dist := geo.Distance(point, pointOnSegment) + if dist < minDistance { + minDistance = dist + closest = i + } + } + + log.Debug(). + Float64("min distance", minDistance). + Int("index", closest). + Any("point", point). + Any("linestring", lineString). + Msg("minimum distance to polyline") + return minDistance, closest +} + +func projectToSegment(point, a, b orb.Point) orb.Point { + x := a[0] + y := a[1] + dx := b[0] - x + dy := b[1] - y + + if dx != 0 || dy != 0 { + t := ((point[0]-x)*dx + (point[1]-y)*dy) / (dx*dx + dy*dy) + + if t > 1 { + x = b[0] + y = b[1] + } else if t > 0 { + x += dx * t + y += dy * t + } + } + + return orb.Point{x, y} +} diff --git a/go.mod b/go.mod index 1ee8178..839a014 100644 --- a/go.mod +++ b/go.mod @@ -2,9 +2,9 @@ module git.coopgo.io/coopgo-platform/carpool-service go 1.18 -// replace git.coopgo.io/coopgo-platform/routing-service => ../../coopgo-platform/routing-service/ +replace git.coopgo.io/coopgo-platform/routing-service => ../../coopgo-platform/routing-service/ -// replace git.coopgo.io/coopgo-platform/carpool-service/interoperability/ocss => ./interoperability/ocss/ +replace git.coopgo.io/coopgo-platform/carpool-service/interoperability/ocss => ./interoperability/ocss/ require ( github.com/google/uuid v1.3.0 @@ -18,7 +18,7 @@ require ( require ( git.coopgo.io/coopgo-platform/carpool-service/interoperability/ocss v0.0.0-20230329105025-bbc682386a58 // indirect - git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230329105109-a2dc346ed5b5 // indirect + git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230329165521-1442647132b9 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.1 // indirect diff --git a/go.sum b/go.sum index bf1034e..631555a 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,14 @@ git.coopgo.io/coopgo-platform/carpool-service/interoperability/ocss v0.0.0-20230 git.coopgo.io/coopgo-platform/carpool-service/interoperability/ocss v0.0.0-20230329105025-bbc682386a58/go.mod h1:sT9fl92Nb4K7rWsEeddGRbJKVi+84dnorDunIbnDYWk= git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230329105109-a2dc346ed5b5 h1:7lhbgBk4oXTIK6T109IymgpoC2J4tHaU2O/rj/Y8M4s= git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230329105109-a2dc346ed5b5/go.mod h1:qKf4kan3/vJXVywIBHa4omSlxIOMYyR11xZrrE5v9D0= +git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230329161053-d4ad6d1f4e33 h1:zm7lc0m0po6Tq/mjkJv7udnUEXZ+Z0swVO/anirbKmY= +git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230329161053-d4ad6d1f4e33/go.mod h1:qKf4kan3/vJXVywIBHa4omSlxIOMYyR11xZrrE5v9D0= +git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230329161338-761449b82889 h1:Ti1gDoERrCwXzVS1SVYskwkwu3qbPAVmh0MGB6igtPA= +git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230329161338-761449b82889/go.mod h1:qKf4kan3/vJXVywIBHa4omSlxIOMYyR11xZrrE5v9D0= +git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230329163129-d535e945ffe9 h1:Xz7r+xWvddSrhR+lmUOSI4x8WCovqQslj5bVA+ZFiyg= +git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230329163129-d535e945ffe9/go.mod h1:qKf4kan3/vJXVywIBHa4omSlxIOMYyR11xZrrE5v9D0= +git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230329165521-1442647132b9 h1:GPvpqJasCouzXZbDH3GyfKV++TmjPydCpj4LDZXZmeA= +git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230329165521-1442647132b9/go.mod h1:qKf4kan3/vJXVywIBHa4omSlxIOMYyR11xZrrE5v9D0= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= diff --git a/handler/search.go b/handler/search.go index 2b81e95..622a829 100644 --- a/handler/search.go +++ b/handler/search.go @@ -3,10 +3,11 @@ package handler import ( "time" + "git.coopgo.io/coopgo-platform/carpool-service/geoutils" "git.coopgo.io/coopgo-platform/routing-service" + "git.coopgo.io/coopgo-platform/routing-service/encoding/polylines" "github.com/paulmach/orb" "github.com/paulmach/orb/geojson" - "github.com/paulmach/orb/planar" "github.com/rs/zerolog/log" ) @@ -34,14 +35,14 @@ func (h *CarpoolServiceHandler) GetDriverJourneys(departure orb.Point, arrival o count = &c } - if departureRadius == nil { - d := float64(1000) - departureRadius = &d + drad := float64(1000) + if departureRadius != nil { + drad = *departureRadius * 1000 } - if arrivalRadius == nil { - a := float64(1000) - departureRadius = &a + arad := float64(1000) + if arrivalRadius != nil { + arad = *arrivalRadius * 1000 } tileset, err := h.Tiles.GetTiles("driver", minDate, departure, arrival) @@ -64,12 +65,108 @@ func (h *CarpoolServiceHandler) GetDriverJourneys(departure orb.Point, arrival o counted := int64(0) for _, r := range candidate_routes { - ls := r.Route.Features[2].Geometry + ls := r.Route.Features[2].Geometry.(orb.LineString) - distanceFromDeparture, indexDeparture := planar.DistanceFromWithIndex(ls, departure) - distanceFromArrival, indexArrival := planar.DistanceFromWithIndex(ls, arrival) + // distanceFromDeparture, indexDeparture := planar.DistanceFromWithIndex(ls, departure) + // distanceFromArrival, indexArrival := planar.DistanceFromWithIndex(ls, arrival) + distanceFromDeparture, indexDeparture := geoutils.DistanceFromLineString(departure, ls) + distanceFromArrival, indexArrival := geoutils.DistanceFromLineString(arrival, ls) - if indexArrival >= indexDeparture && distanceFromDeparture <= *departureRadius && distanceFromArrival < *arrivalRadius { + if indexArrival >= indexDeparture && distanceFromDeparture <= drad && distanceFromArrival < arad { + //routePoints := []orb.Point{r.Route.Features[0].Point(), departure, arrival, r.Route.Features[1].Point()} + routePoints := []orb.Point{departure, arrival} + log.Debug().Any("route points", routePoints).Msg("calculate multipoint route") + 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 +} + +func (h *CarpoolServiceHandler) GetPassengerJourneys(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") + + routePoints := []orb.Point{departure, arrival} + itinerary, err := h.Routing.Route(routePoints) + if err != nil { + log.Error().Err(err).Msg("error getting route with viapoints") + return nil, err + } + + if count == nil { + c := int64(10) + count = &c + } + + drad := float64(1000) + if departureRadius != nil { + drad = *departureRadius * 1000 + } + + arad := float64(1000) + if arrivalRadius != nil { + arad = *arrivalRadius * 1000 + } + + decodedPolyline := polylines.Decode(&itinerary.Summary.Polyline, 5) + + points := []orb.Point{departure, arrival} + + for _, p := range decodedPolyline { + points = append(points, p) + } + + tileset, err := h.Tiles.GetTiles("passenger", minDate, points...) + 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 := decodedPolyline + + // distanceFromDeparture, indexDeparture := planar.DistanceFromWithIndex(ls, r.Route.Features[0].Point()) + // distanceFromArrival, indexArrival := planar.DistanceFromWithIndex(ls, r.Route.Features[1].Point()) + distanceFromDeparture, indexDeparture := geoutils.DistanceFromLineString(r.Route.Features[0].Point(), ls) + distanceFromArrival, indexArrival := geoutils.DistanceFromLineString(r.Route.Features[1].Point(), ls) + + if indexArrival >= indexDeparture && distanceFromDeparture <= drad && distanceFromArrival < arad { routePoints := []orb.Point{r.Route.Features[0].Point(), departure, arrival, r.Route.Features[0].Point()} itinerary, err := h.Routing.Route(routePoints) if err != nil { diff --git a/interoperability/ocss/server.go b/interoperability/ocss/server.go index 5ad703a..9d1afde 100644 --- a/interoperability/ocss/server.go +++ b/interoperability/ocss/server.go @@ -10,6 +10,7 @@ import ( "time" "github.com/gorilla/schema" + "github.com/rs/zerolog/log" "golang.org/x/crypto/bcrypt" ) @@ -24,8 +25,8 @@ type Handler interface { //Booking by API PostBookings(ctx context.Context, booking Booking) (*Booking, error) - PatchBooking(ctx context.Context, bookingId string, status BookingStatus, message *string) error - GetBooking(ctx context.Context, bookingId string) (*Booking, error) + PatchBookings(ctx context.Context, bookingId string, status BookingStatus, message *string) error + GetBookings(ctx context.Context, bookingId string) (*Booking, error) // Webhooks PostBookingEvents(ctx context.Context, event CarpoolBookingEvent) error @@ -93,6 +94,12 @@ type GetPassengerRegularTripsRequest struct { Count *int64 `schema:"count"` } +type PatchBookingsRequest struct { + BookingId string `json:"bookingId"` + Status string `json:"status"` + Message string `json:message"` +} + type Server struct { Handler Handler AuthorizedOperators []AuthorizedOperator @@ -131,7 +138,7 @@ func (s Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { apiKey := r.Header.Get("X-Api-Key") operator, err := s.FindApiKey(apiKey) if err != nil { - fmt.Println(err) + log.Error().Err(err).Msg("unauthorized") w.WriteHeader(http.StatusUnauthorized) return } @@ -153,6 +160,18 @@ func (s Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { case r.Method == "GET" && n == 1 && p[0] == "passenger_regular_trips": s.getPassengerRegularTrips(w, r.WithContext(ctx)) return + case r.Method == "POST" && n == 1 && p[0] == "bookings": + s.postBookings(w, r.WithContext(ctx)) + return + case r.Method == "PATCH" && n == 2 && p[0] == "bookings": + s.patchBookings(w, p[1], r.WithContext(ctx)) + return + case r.Method == "GET" && n == 2 && p[0] == "bookings": + s.getBookings(w, p[1], r.WithContext(ctx)) + return + // case r.Method == "GET" && n == 1 && p[0] == "status": + // s.getStatus(w, r.WithContext(ctx)) + // return default: w.WriteHeader(http.StatusNotFound) } @@ -164,7 +183,7 @@ func (s *Server) getDriverJourneys(w http.ResponseWriter, r *http.Request) { var decoder = schema.NewDecoder() if err := decoder.Decode(&request, r.URL.Query()); err != nil { - fmt.Println(err) + log.Error().Err(err).Msg("could not parse the request") badRequest(w, fmt.Errorf("could not parse the request : %s", err)) return } @@ -190,7 +209,7 @@ func (s *Server) getDriverJourneys(w http.ResponseWriter, r *http.Request) { request.Count) if err != nil { - fmt.Println(err) + log.Error().Err(err).Msg("GetDriverJourneys failed") jsonError(w, err, http.StatusInternalServerError) return } @@ -204,7 +223,7 @@ func (s *Server) getPassengerJourneys(w http.ResponseWriter, r *http.Request) { var decoder = schema.NewDecoder() if err := decoder.Decode(&request, r.URL.Query()); err != nil { - fmt.Println(err) + log.Error().Err(err).Msg("could not parse the request") badRequest(w, fmt.Errorf("could not parse the request : %s", err)) return } @@ -230,7 +249,7 @@ func (s *Server) getPassengerJourneys(w http.ResponseWriter, r *http.Request) { request.Count) if err != nil { - fmt.Println(err) + log.Error().Err(err).Msg("GetPassengerJourneys failed") jsonError(w, err, http.StatusInternalServerError) return } @@ -244,7 +263,7 @@ func (s *Server) getDriverRegularTrips(w http.ResponseWriter, r *http.Request) { var decoder = schema.NewDecoder() if err := decoder.Decode(&request, r.URL.Query()); err != nil { - fmt.Println(err) + log.Error().Err(err).Msg("could not parse the request") badRequest(w, fmt.Errorf("could not parse the request : %s", err)) return } @@ -284,7 +303,7 @@ func (s *Server) getDriverRegularTrips(w http.ResponseWriter, r *http.Request) { request.Count) if err != nil { - fmt.Println(err) + log.Error().Err(err).Msg("GetDriverRegularTrips failed") jsonError(w, err, http.StatusInternalServerError) return } @@ -298,7 +317,7 @@ func (s *Server) getPassengerRegularTrips(w http.ResponseWriter, r *http.Request var decoder = schema.NewDecoder() if err := decoder.Decode(&request, r.URL.Query()); err != nil { - fmt.Println(err) + log.Error().Err(err).Msg("could not parse the request") badRequest(w, fmt.Errorf("could not parse the request : %s", err)) return } @@ -338,7 +357,7 @@ func (s *Server) getPassengerRegularTrips(w http.ResponseWriter, r *http.Request request.Count) if err != nil { - fmt.Println(err) + log.Error().Err(err).Msg("GetPassengerRegularTrips failed") jsonError(w, err, http.StatusInternalServerError) return } @@ -346,11 +365,81 @@ func (s *Server) getPassengerRegularTrips(w http.ResponseWriter, r *http.Request jsonResponse(w, passengerTrips, http.StatusOK) } +func (s *Server) postBookings(w http.ResponseWriter, r *http.Request) { + var request Booking + + var decoder = json.NewDecoder(r.Body) + + if err := decoder.Decode(&request); err != nil { + log.Error().Err(err).Msg("PostBookings - could not parse the request ") + badRequest(w, fmt.Errorf("could not parse the request : %s", err)) + return + } + + response, err := s.Handler.PostBookings( + r.Context(), + request, + ) + if err != nil { + log.Error().Err(err).Msg("error in PostBookings") + jsonError(w, err, http.StatusInternalServerError) + return + } + + jsonResponse(w, response, http.StatusOK) +} + +func (s *Server) patchBookings(w http.ResponseWriter, bookingId string, r *http.Request) { + var request PatchBookingsRequest + + var decoder = json.NewDecoder(r.Body) + if err := decoder.Decode(&request); err != nil { + log.Error().Err(err).Msg("PatchBookings - could not parse the request ") + badRequest(w, fmt.Errorf("could not parse the request : %s", err)) + return + } + + err := s.Handler.PatchBookings( + r.Context(), + bookingId, + BookingConfirmed, + &request.Message, + ) + + if err != nil { + log.Error().Err(err).Msg("error in PatchBookings") + jsonError(w, err, http.StatusInternalServerError) + return + } + + jsonResponse(w, map[string]any{}, http.StatusOK) + +} + +func (s *Server) getBookings(w http.ResponseWriter, bookingId string, r *http.Request) { + + booking, err := s.Handler.GetBookings( + r.Context(), + bookingId, + ) + + if err != nil { + log.Error().Err(err).Msg("error in PatchBookings") + jsonError(w, err, http.StatusInternalServerError) + return + } + + jsonResponse(w, booking, http.StatusOK) + +} + func jsonResponse(w http.ResponseWriter, response any, statuscode int) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(statuscode) err := json.NewEncoder(w).Encode(response) - fmt.Println(err) + if err != nil { + log.Error().Err(err).Msg("json error encoding issue") + } } func jsonError(w http.ResponseWriter, err error, statuscode int) { diff --git a/servers/ocss-api/book.go b/servers/ocss-api/book.go index 1fd2f74..98b4913 100644 --- a/servers/ocss-api/book.go +++ b/servers/ocss-api/book.go @@ -10,9 +10,9 @@ import ( func (s *OCSSApiService) PostBookings(ctx context.Context, booking ocss.Booking) (*ocss.Booking, error) { return nil, errors.New("method not implmeented - PostBookings") } -func (s *OCSSApiService) PatchBooking(ctx context.Context, bookingId string, status ocss.BookingStatus, message *string) error { +func (s *OCSSApiService) PatchBookings(ctx context.Context, bookingId string, status ocss.BookingStatus, message *string) error { return errors.New("method not implmeented - PatchBooking") } -func (s *OCSSApiService) GetBooking(ctx context.Context, bookingId string) (*ocss.Booking, error) { +func (s *OCSSApiService) GetBookings(ctx context.Context, bookingId string) (*ocss.Booking, error) { return nil, errors.New("method not implmeented - GetBooking") } diff --git a/servers/ocss-api/search.go b/servers/ocss-api/search.go index 1f946e8..2b8ab6e 100644 --- a/servers/ocss-api/search.go +++ b/servers/ocss-api/search.go @@ -2,11 +2,11 @@ package ocssapi import ( "context" - "errors" "time" "git.coopgo.io/coopgo-platform/carpool-service/interoperability/ocss" "github.com/paulmach/orb" + "github.com/rs/zerolog/log" ) func (s *OCSSApiService) GetDriverJourneys(ctx context.Context, departureLat float64, departureLng float64, arrivalLat float64, arrivalLng float64, departureDate time.Time, timeDelta *time.Duration, departureRadius *float64, arrivalRadius *float64, count *int64) ([]ocss.DriverJourney, error) { @@ -29,8 +29,9 @@ func (s *OCSSApiService) GetDriverJourneys(ctx context.Context, departureLat flo results := []ocss.DriverJourney{} for _, j := range journeys { - usermap := j.Route.ExtraMembers["user"].(map[string]any) - journeyId := j.Route.ExtraMembers.MustString("journey_id") + properties := j.Route.ExtraMembers["properties"].(map[string]any) + usermap := properties["user"].(map[string]any) + journeyId := j.ID driverDepartureLat := j.Route.Features[0].Point().Lat() driverDepartureLng := j.Route.Features[0].Point().Lon() driverArrivalLat := j.Route.Features[1].Point().Lat() @@ -48,7 +49,7 @@ func (s *OCSSApiService) GetDriverJourneys(ctx context.Context, departureLat flo DriverTrip: ocss.DriverTrip{ Driver: ocss.User{ ID: usermap["id"].(string), - Operator: usermap["opeator"].(string), + Operator: usermap["operator"].(string), Alias: usermap["alias"].(string), }, Trip: ocss.Trip{ @@ -82,7 +83,74 @@ func (s *OCSSApiService) GetDriverJourneys(ctx context.Context, departureLat flo } func (s *OCSSApiService) GetPassengerJourneys(ctx context.Context, departureLat float64, departureLng float64, arrivalLat float64, arrivalLng float64, departureDate time.Time, timeDelta *time.Duration, departureRadius *float64, arrivalRadius *float64, count *int64) ([]ocss.PassengerJourney, error) { - return nil, errors.New("method not implmeented - GetPassengerJourneys") + departure := orb.Point{departureLng, departureLat} + arrival := orb.Point{arrivalLng, arrivalLat} + + td := 900 * time.Second + if timeDelta != nil { + td = *timeDelta + } + + minDate := departureDate.Add(-td * time.Second) + maxDate := departureDate.Add(td * time.Second) + + journeys, err := s.Handler.GetPassengerJourneys(departure, arrival, departureRadius, arrivalRadius, minDate, maxDate, count) + if err != nil { + return nil, err + } + + results := []ocss.PassengerJourney{} + + for _, j := range journeys { + properties := j.Route.ExtraMembers["properties"].(map[string]any) + usermap := properties["user"].(map[string]any) + journeyId := j.ID + passengerDepartureLat := j.Route.Features[0].Point().Lat() + passengerDepartureLng := j.Route.Features[0].Point().Lon() + passengerArrivalLat := j.Route.Features[1].Point().Lat() + passengerArrivalLng := j.Route.Features[1].Point().Lon() + passengerDepartureDate := ocss.JSONTime(j.DepartureDate) + driverDepartureDate := ocss.JSONTime(j.DepartureDate.Add(-j.Itinerary.Legs[0].Duration)) + duration := time.Duration(0) + var distance *int64 + log.Debug().Any("itinerary", j.Itinerary).Msg("debug itinerary") + if len(j.Itinerary.Legs) > 2 { + duration = j.Itinerary.Legs[1].Duration / time.Second + dist := int64(j.Itinerary.Legs[1].Distance) + distance = &dist + } + + results = append(results, ocss.PassengerJourney{ + PassengerTrip: ocss.PassengerTrip{ + Passenger: ocss.User{ + ID: usermap["id"].(string), + Operator: usermap["operator"].(string), + Alias: usermap["alias"].(string), + }, + Trip: ocss.Trip{ + Operator: "ridygo.fr", + PassengerPickupLat: passengerDepartureLat, + PassengerPickupLng: passengerDepartureLng, + PassengerDropLat: passengerArrivalLat, + PassengerDropLng: passengerArrivalLng, + DriverDepartureLat: &departureLat, + DriverDepartureLng: &departureLng, + DriverArrivalLat: &arrivalLat, + DriverArrivalLng: &arrivalLng, + Duration: duration, + Distance: distance, + }, + }, + JourneySchedule: ocss.JourneySchedule{ + ID: &journeyId, + PassengerPickupDate: passengerDepartureDate, + DriverDepartureDate: &driverDepartureDate, + Type: ocss.Planned, + }, + }) + } + + return results, nil } func (s *OCSSApiService) GetDriverRegularTrips(ctx context.Context, departureLat float64, departureLng float64, arrivalLat float64, arrivalLng float64, departureTimeOfDay string, departureWeekDays *[]string, timeDelta *time.Duration, departureRadius *float64, arrivalRadius *float64, minDepartureDate *time.Time, maxDepartureDate *time.Time, count *int64) ([]ocss.DriverTrip, error) { diff --git a/storage/mongodb.go b/storage/mongodb.go index c12a6ee..e4bc6c7 100644 --- a/storage/mongodb.go +++ b/storage/mongodb.go @@ -116,14 +116,20 @@ func (s MongoDBStorage) GetUserRegularRoutes(userid string) ([]*geojson.FeatureC } func (s MongoDBStorage) GetDriverRegularRoutesForTile(day string, gridId int64) ([]*geojson.FeatureCollection, error) { + log.Debug(). + Str("day", day). + Int64("grid id", gridId). + Msg("GetDriverRegularRoutesForTile") + findOptions := options.Find() collection := s.Client.Database(s.DbName).Collection(s.Collections["regular_routes"]) cur, err := collection.Find(context.TODO(), bson.M{ - "properties.schedule.day": day, - "grid_ids": gridId, - "properties.is_driver": true, + "properties.schedules.day": day, + "grid_ids": gridId, + "properties.is_driver": true, }, findOptions) if err != nil { + log.Error().Err(err).Msg("GetDriverRegularRoutesForTile - mongodb issue") return nil, err } @@ -132,12 +138,14 @@ func (s MongoDBStorage) GetDriverRegularRoutesForTile(day string, gridId int64) var elem bson.M if err := cur.Decode(&elem); err != nil { + log.Error().Err(err).Msg("GetDriverRegularRoutesForTile - decode error") return nil, err } bsonBytes, _ := bson.Marshal(elem) fc := geojson.NewFeatureCollection() err := fc.UnmarshalBSON(bsonBytes) if err != nil { + log.Error().Err(err).Msg("GetDriverRegularRoutesForTile - unmarshalling error") return nil, err } fc.ExtraMembers["id"] = fc.ExtraMembers.MustString("_id") @@ -162,9 +170,9 @@ func (s MongoDBStorage) GetPassengerRegularRoutesForTile(day string, gridId int6 findOptions := options.Find() collection := s.Client.Database(s.DbName).Collection(s.Collections["regular_routes"]) cur, err := collection.Find(context.TODO(), bson.M{ - "properties.schedule.day": day, - "grid_ids": gridId, - "properties.is_passenger": true, + "properties.schedules.day": day, + "grid_ids": gridId, + "properties.is_passenger": true, }, findOptions) if err != nil { return nil, err diff --git a/tiles/grid.go b/tiles/grid.go index 77b6ee4..b319da8 100644 --- a/tiles/grid.go +++ b/tiles/grid.go @@ -1,6 +1,9 @@ package tiles -import "github.com/paulmach/orb" +import ( + "github.com/paulmach/orb" + "github.com/rs/zerolog/log" +) // GridId defines the position of a tile // It follows the Valhalla way of handling tiles : https://github.com/Telenav/open-source-spec/blob/master/valhalla/doc/valhalla-tiles-basic.md @@ -10,13 +13,17 @@ const tilesize float64 = 1.0 // PointGridId returns the id on the grid for a given point func PointGridId(point orb.Point) GridId { + log.Debug().Any("Point", point).Msg("PointGridId") width := int64(360 / tilesize) - return GridId(int64((point.Lat()+90)/tilesize)*width + int64((point.Lon()+180)/tilesize)) + gridid := GridId(int64((point.Lat()+90)/tilesize)*width + int64((point.Lon()+180)/tilesize)) + log.Debug().Any("value", gridid).Msg("") + return gridid } // LineStringGridIds returns the list of ids on the grid the linestring goes through. // In some really specific cases on tile edges, this could be unaccurate if the polyline was too much simplified func LineStringGridIds(linestring orb.LineString) []GridId { + log.Debug().Any("Linestring", linestring).Msg("LineStringGridIds") results := []GridId{} gidmap := map[int64]bool{} diff --git a/tiles/tiles-handler.go b/tiles/tiles-handler.go index c38c975..2646cb5 100644 --- a/tiles/tiles-handler.go +++ b/tiles/tiles-handler.go @@ -5,6 +5,7 @@ import ( "git.coopgo.io/coopgo-platform/carpool-service/storage" "github.com/paulmach/orb" + "github.com/rs/zerolog/log" "github.com/spf13/viper" ) @@ -24,6 +25,13 @@ func NewTilesHandler(cfg *viper.Viper, persistantStorage storage.Storage) (*Tile // GetTiles retrieves tiles func (h *TilesHandler) GetTiles(driverOrPassenger string, date time.Time, points ...orb.Point) (*Tileset, error) { + dateString := date.Format("2006-01-02") + + log.Debug(). + Any("points", points). + Str("date", dateString). + Msg("Get Tiles") + result := Tileset{} grid_ids := []GridId{} @@ -36,7 +44,6 @@ func (h *TilesHandler) GetTiles(driverOrPassenger string, date time.Time, points grid_ids = []GridId{PointGridId(points[0])} } - dateString := date.Format("2006-01-02") for _, gid := range grid_ids { tile, err := h.GetTile(driverOrPassenger, date, gid) if err != nil { diff --git a/tiles/tiles.go b/tiles/tiles.go index 0a38f33..be89d23 100644 --- a/tiles/tiles.go +++ b/tiles/tiles.go @@ -29,6 +29,12 @@ func (tile *Tile) ID() string { // GetTile retrieves a tile from persistant storage or cache func (h *TilesHandler) GetTile(driverOrPassenger string, date time.Time, gridid GridId) (*Tile, error) { + log.Debug(). + Str("driver_or_passenger", driverOrPassenger). + Str("date", date.Format("2006-01-02")). + Any("grid_id", gridid). + Msg("GetTile") + routes := []*geojson.FeatureCollection{} day := strings.ToUpper(date.Format("Mon")) dateString := date.Format("2006-01-02")