Skip to content

Commit

Permalink
Merge pull request #5 from Vector-Hector/dev
Browse files Browse the repository at this point in the history
Interface improvements
  • Loading branch information
Vector-Hector authored Dec 15, 2023
2 parents 73ea376 + 0f0e68f commit 226f862
Show file tree
Hide file tree
Showing 4 changed files with 287 additions and 6 deletions.
208 changes: 208 additions & 0 deletions fptf.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,211 @@ func GetTripFromTrip(r *RoutingData, round map[uint64]StopArrival, arrival StopA

return result, route.Stops[enterKey]
}

func (b *Bifrost) addSourceAndDestination(journey *fptf.Journey, sources []SourceLocation, dest *fptf.Location) {
b.addJourneyDestination(journey, dest)

origin := journey.GetOrigin().GetLocation()
if origin == nil {
return
}

originPoint := &GeoPoint{
Latitude: origin.Latitude,
Longitude: origin.Longitude,
}

minSourceDistance := uint32(0)
minSourceKey := -1

for i, source := range sources {
distance := b.DistanceMs(&GeoPoint{
Latitude: source.Location.Latitude,
Longitude: source.Location.Longitude,
}, originPoint, VehicleTypeWalking)

if minSourceKey == -1 || distance < minSourceDistance {
minSourceDistance = distance
minSourceKey = i
}
}

if minSourceKey == -1 {
return
}

b.addJourneyOrigin(journey, sources[minSourceKey].Location)
}

func (b *Bifrost) addJourneyOrigin(journey *fptf.Journey, origin *fptf.Location) {
firstTrip := journey.GetFirstTrip()
if firstTrip == nil {
return
}

journeyOrigin := journey.GetOrigin()
journeyOriginLoc := journey.GetOrigin().GetLocation()

if journeyOriginLoc == nil {
return
}

vehicleType := VehicleTypeWalking
willAddTrip := true

if firstTrip.Mode == fptf.ModeWalking {
vehicleType = VehicleTypeWalking
willAddTrip = false
} else if firstTrip.Mode == fptf.ModeBicycle {
vehicleType = VehicleTypeBicycle
willAddTrip = false
} else if firstTrip.Mode == fptf.ModeCar {
vehicleType = VehicleTypeCar
willAddTrip = false
}

dist := uint64(b.DistanceMs(&GeoPoint{
Latitude: origin.Latitude,
Longitude: origin.Longitude,
}, &GeoPoint{
Latitude: journeyOriginLoc.Latitude,
Longitude: journeyOriginLoc.Longitude,
}, vehicleType))

pad := b.TransferPaddingMs
if !willAddTrip {
pad = 0
}

dist += pad

journeyDep := journey.GetDeparture()
journeyDepDelay := journey.GetDepartureDelay()
if journeyDepDelay != nil {
journeyDep = journeyDep.Add(time.Duration(*journeyDepDelay) * time.Second)
}

newDep := journeyDep.Add(-time.Duration(dist) * time.Millisecond)
newArrAtOrigin := journeyDep.Add(-time.Duration(pad) * time.Millisecond)
newOrigin := &fptf.StopStation{
Station: &fptf.Station{
Name: "origin",
Location: &fptf.Location{
Latitude: origin.Latitude,
Longitude: origin.Longitude,
},
},
}

if !willAddTrip {
addTripOrigin(firstTrip, newOrigin, newDep, newArrAtOrigin)
return
}

// create new walk trip
walkTrip := &fptf.Trip{
Origin: newOrigin,
Destination: journeyOrigin,
Departure: fptf.TimeNullable{Time: newDep},
Arrival: fptf.TimeNullable{Time: newArrAtOrigin},
Stopovers: []*fptf.Stopover{{
StopStation: newOrigin,
Departure: fptf.TimeNullable{Time: newDep},
}, {
StopStation: journeyOrigin,
Arrival: fptf.TimeNullable{Time: newArrAtOrigin},
}},
Mode: fptf.ModeWalking,
}

journey.Trips = append([]*fptf.Trip{walkTrip}, journey.Trips...)
}

func addTripOrigin(trip *fptf.Trip, newOrigin *fptf.StopStation, newDep time.Time, newArrAtOrigin time.Time) {
trip.Origin = newOrigin
trip.Departure = fptf.TimeNullable{Time: newDep}
trip.Stopovers = append([]*fptf.Stopover{{
StopStation: newOrigin,
Departure: fptf.TimeNullable{Time: newDep},
}}, trip.Stopovers...)
trip.Stopovers[1].Arrival = fptf.TimeNullable{Time: newArrAtOrigin}
}

func (b *Bifrost) addJourneyDestination(journey *fptf.Journey, dest *fptf.Location) {
lastTrip := journey.GetLastTrip()
if lastTrip == nil {
return
}

journeyDest := journey.GetDestination()
journeyDestLoc := journey.GetDestination().GetLocation()

if journeyDestLoc == nil {
return
}

vehicleType := VehicleTypeWalking
if lastTrip.Mode == fptf.ModeBicycle {
vehicleType = VehicleTypeBicycle
} else if lastTrip.Mode == fptf.ModeCar {
vehicleType = VehicleTypeCar
}

dist := uint64(b.DistanceMs(&GeoPoint{
Latitude: dest.Latitude,
Longitude: dest.Longitude,
}, &GeoPoint{
Latitude: journeyDestLoc.Latitude,
Longitude: journeyDestLoc.Longitude,
}, vehicleType))

journeyArr := journey.GetArrival()
journeyArrDelay := journey.GetArrivalDelay()
if journeyArrDelay != nil {
journeyArr = journeyArr.Add(time.Duration(*journeyArrDelay) * time.Second)
}

newArr := journeyArr.Add(time.Duration(dist) * time.Millisecond)
newDest := &fptf.StopStation{
Station: &fptf.Station{
Name: "destination",
Location: &fptf.Location{
Latitude: dest.Latitude,
Longitude: dest.Longitude,
},
},
}

if lastTrip.Mode == fptf.ModeWalking || lastTrip.Mode == fptf.ModeBicycle || lastTrip.Mode == fptf.ModeCar {
addTripDestination(lastTrip, newDest, newArr, journeyArr)
return
}

// create new walk trip
walkTrip := &fptf.Trip{
Origin: journeyDest,
Destination: newDest,
Departure: fptf.TimeNullable{Time: journeyArr},
Arrival: fptf.TimeNullable{Time: newArr},
Stopovers: []*fptf.Stopover{{
StopStation: journeyDest,
Departure: fptf.TimeNullable{Time: journeyArr},
}, {
StopStation: newDest,
Arrival: fptf.TimeNullable{Time: newArr},
}},
Mode: fptf.ModeWalking,
}

journey.Trips = append(journey.Trips, walkTrip)
}

func addTripDestination(trip *fptf.Trip, newDest *fptf.StopStation, newArr time.Time, journeyArr time.Time) {
trip.Destination = newDest
trip.Arrival = fptf.TimeNullable{Time: newArr}
trip.Stopovers = append(trip.Stopovers, &fptf.Stopover{
StopStation: newDest,
Arrival: fptf.TimeNullable{Time: newArr},
})
trip.Stopovers[len(trip.Stopovers)-2].Departure = fptf.TimeNullable{Time: journeyArr}
}
8 changes: 8 additions & 0 deletions load.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"github.com/klauspost/compress/zstd"
"os"
"path/filepath"
"time"
)

Expand Down Expand Up @@ -104,6 +105,13 @@ func (b *Bifrost) AddBifrostData(fileName string) {
}

func (b *Bifrost) WriteBifrostData(fileName string) {
// create directory if not exists
directory := filepath.Dir(fileName)
err := os.MkdirAll(directory, os.ModePerm)
if err != nil {
panic(err)
}

f, err := os.Create(fileName)
if err != nil {
panic(err)
Expand Down
19 changes: 16 additions & 3 deletions raptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,22 @@ func (b *Bifrost) Route(rounds *Rounds, origins []SourceLocation, dest *fptf.Loc
return nil, err
}

var journey *fptf.Journey

if !isTransit {
return b.RouteOnlyTimeIndependent(rounds, originKeys, destKey, vehicleType, debug)
journey, err = b.RouteOnlyTimeIndependent(rounds, originKeys, destKey, vehicleType, debug)
} else {
journey, err = b.RouteTransit(rounds, originKeys, destKey, debug)
}

if err != nil {
return nil, err
}

return b.RouteTransit(rounds, originKeys, destKey, debug)
b.addSourceAndDestination(journey, origins, dest)

return journey, nil

}

func getVehicleType(modes []fptf.Mode) (VehicleType, bool) {
Expand Down Expand Up @@ -520,9 +531,11 @@ func (b *Bifrost) matchSourceLocations(origins []SourceLocation, vehicleToStart
for _, vertex := range vertices {
point := vertex.(*GeoPoint)

dist := b.DistanceMs(loc, point, vehicleToStart)

originKeys = append(originKeys, SourceKey{
StopKey: point.VertKey,
Departure: origin.Departure,
Departure: origin.Departure.Add(time.Duration(dist) * time.Millisecond),
})
}
}
Expand Down
58 changes: 55 additions & 3 deletions server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/Vector-Hector/bifrost"
"github.com/Vector-Hector/fptf"
"github.com/gin-gonic/gin"
"math"
"runtime/debug"
"strings"
"time"
Expand Down Expand Up @@ -67,17 +68,39 @@ func main() {
return
}

roundChan := make(chan *bifrost.Rounds, *numHandlerThreads)
const roundChanSize = 200

for i := 0; i < *numHandlerThreads; i++ {
roundChan := make(chan *bifrost.Rounds, roundChanSize)

for i := 0; i < roundChanSize; i++ {
roundChan <- b.NewRounds()
}

if *numHandlerThreads < 1 {
*numHandlerThreads = 1
}

if *numHandlerThreads > roundChanSize {
*numHandlerThreads = roundChanSize
}

threadChan := make(chan bool, *numHandlerThreads)

for i := 0; i < *numHandlerThreads; i++ {
threadChan <- true
}

fmt.Println("Startup took", time.Since(start))

engine := gin.Default()

engine.POST("/bifrost", func(c *gin.Context) {
<-threadChan

defer func() {
threadChan <- true
}()

handle(c, b, roundChan)
})

Expand All @@ -98,7 +121,7 @@ func handle(c *gin.Context, b *bifrost.Bifrost, roundChan chan *bifrost.Rounds)

debug.PrintStack()

c.String(500, "Internal server error")
c.String(500, "Internal server error: %v", r)
}
}()

Expand All @@ -108,6 +131,35 @@ func handle(c *gin.Context, b *bifrost.Bifrost, roundChan chan *bifrost.Rounds)
panic(err)
}

// validate request
if req.Origin == nil || math.Abs(req.Origin.Longitude) < 0.0001 || math.Abs(req.Origin.Latitude) < 0.0001 {
c.JSON(400, gin.H{
"error": "invalid origin",
})
return
}

if req.Destination == nil || math.Abs(req.Destination.Longitude) < 0.0001 || math.Abs(req.Destination.Latitude) < 0.0001 {
c.JSON(400, gin.H{
"error": "invalid destination",
})
return
}

if req.Departure.IsZero() {
c.JSON(400, gin.H{
"error": "invalid departure",
})
return
}

if len(req.Modes) == 0 {
c.JSON(400, gin.H{
"error": "invalid modes",
})
return
}

t := time.Now()

journey, err := b.Route(rounds, []bifrost.SourceLocation{{
Expand Down

0 comments on commit 226f862

Please sign in to comment.