Add tiles management
This commit is contained in:
parent
77c8576254
commit
bbc682386a
10
README.md
10
README.md
|
@ -14,9 +14,15 @@ Trips and journeys are managed through the provided gRPC service and stored in t
|
|||
|
||||
### Tiles architecture and cache
|
||||
|
||||
To reduce dependencies on the chosen database, we decided to manage geographical calculations directly in out code instead of relying completely on MongoDB geographical features.
|
||||
To reduce dependencies on the chosen database, we decided to manage geographical calculations directly in our code instead of relying completely on MongoDB geographical features.
|
||||
|
||||
For opti
|
||||
We use a tiles system to retrieve relevant journeys easily. Each tile is defined by :
|
||||
|
||||
- driver or passenger status of the journey
|
||||
- date of the journey
|
||||
- Tile ID in the tiles grid. The tiles grid is inspired by Valhalla https://github.com/Telenav/open-source-spec/blob/master/valhalla/doc/valhalla-tiles-basic.md. We use a level 0 grid
|
||||
|
||||
Journeys are stored in each relevant tile (where a departure, destination or part of the polyline enters the tile)
|
||||
|
||||
### Search
|
||||
|
||||
|
|
29
go.mod
29
go.mod
|
@ -3,16 +3,27 @@ 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/carpool-service/interoperability/ocss => ./interoperability/ocss/
|
||||
|
||||
require git.coopgo.io/coopgo-platform/routing-service v0.0.0
|
||||
require git.coopgo.io/coopgo-platform/carpool-service/interoperability/ocss v0.0.0
|
||||
|
||||
require (
|
||||
git.coopgo.io/coopgo-platform/carpool-service/interoperability/ocss v0.0.0
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/paulmach/orb v0.9.0
|
||||
github.com/rs/zerolog v1.29.0
|
||||
github.com/spf13/viper v1.15.0
|
||||
go.mongodb.org/mongo-driver v1.11.3
|
||||
google.golang.org/grpc v1.53.0
|
||||
google.golang.org/protobuf v1.30.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golang/snappy v0.0.1 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/gorilla/schema v1.2.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.13.6 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
|
@ -20,30 +31,24 @@ require (
|
|||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
|
||||
github.com/paulmach/orb v0.9.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/rs/zerolog v1.29.0 // indirect
|
||||
github.com/spf13/afero v1.9.3 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.15.0 // indirect
|
||||
github.com/subosito/gotenv v1.4.2 // indirect
|
||||
github.com/twpayne/go-polyline v1.1.1 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.1 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.3 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
|
||||
go.mongodb.org/mongo-driver v1.11.3 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
|
||||
golang.org/x/net v0.5.0 // indirect
|
||||
golang.org/x/crypto v0.7.0 // indirect
|
||||
golang.org/x/net v0.8.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.4.0 // indirect
|
||||
golang.org/x/text v0.6.0 // indirect
|
||||
golang.org/x/sys v0.6.0 // indirect
|
||||
golang.org/x/text v0.8.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect
|
||||
google.golang.org/grpc v1.53.0 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
33
go.sum
33
go.sum
|
@ -48,6 +48,7 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht
|
|||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
|
@ -56,6 +57,7 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
|||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
|
@ -105,6 +107,7 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
|
@ -125,6 +128,8 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
|||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
||||
github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc=
|
||||
github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
|
@ -139,8 +144,10 @@ github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQ
|
|||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||
|
@ -159,9 +166,11 @@ github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha
|
|||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w=
|
||||
github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
|
||||
|
@ -187,9 +196,11 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
|
||||
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/twpayne/go-polyline v1.1.1 h1:/tSF1BR7rN4HWj4XKqvRUNrCiYVMCvywxTFVofvDV0w=
|
||||
github.com/twpayne/go-polyline v1.1.1/go.mod h1:ybd9IWWivW/rlXPXuuckeKUyF3yrIim+iqA7kSl4NFY=
|
||||
|
@ -221,8 +232,9 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
|
@ -288,8 +300,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v
|
|||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
|
||||
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -350,10 +362,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -363,10 +373,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
|
||||
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
|
||||
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
@ -518,11 +526,10 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
|
|||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
// }
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package helpers
|
||||
|
||||
import "time"
|
||||
|
||||
type PlannedJourney struct {
|
||||
Route RegularRoute
|
||||
DepartureDate time.Time
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package handler
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"errors"
|
29
main.go
29
main.go
|
@ -8,6 +8,8 @@ import (
|
|||
grpcserver "git.coopgo.io/coopgo-platform/carpool-service/servers/grpc/server"
|
||||
ocssapi "git.coopgo.io/coopgo-platform/carpool-service/servers/ocss-api"
|
||||
"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/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
@ -21,10 +23,12 @@ func main() {
|
|||
}
|
||||
|
||||
var (
|
||||
service_name = cfg.GetString("name")
|
||||
grpc_enable = cfg.GetBool("services.grpc.enable")
|
||||
ocss_enable = cfg.GetBool("services.ocss_api.enable")
|
||||
dev_env = cfg.GetBool("dev_env")
|
||||
service_name = cfg.GetString("name")
|
||||
grpc_enable = cfg.GetBool("services.grpc.enable")
|
||||
ocss_enable = cfg.GetBool("services.ocss_api.enable")
|
||||
dev_env = cfg.GetBool("dev_env")
|
||||
routing_service_type = cfg.GetString("routing.type")
|
||||
valhalla_base_url = cfg.GetString("routing.valhalla.base_url")
|
||||
)
|
||||
|
||||
if dev_env {
|
||||
|
@ -36,11 +40,24 @@ func main() {
|
|||
storage, err := storage.NewStorage(cfg)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("could not initiate storage")
|
||||
return
|
||||
}
|
||||
|
||||
handler, err := handler.NewCarpoolServiceHandler(cfg, storage)
|
||||
routing, err := routing.NewRoutingService(routing_service_type, valhalla_base_url)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("could not initiate incentives handler")
|
||||
log.Fatal().Err(err).Msg("Could not initiate the routing service")
|
||||
return
|
||||
}
|
||||
|
||||
tilesHandler, err := tiles.NewTilesHandler(cfg, storage)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("could not initialize tiles handler")
|
||||
return
|
||||
}
|
||||
|
||||
handler, err := handler.NewCarpoolServiceHandler(cfg, storage, tilesHandler, routing)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("could not initiate carpoool service handler")
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -37,10 +37,15 @@ func Run(done chan error, cfg *viper.Viper, handler *handler.CarpoolServiceHandl
|
|||
return
|
||||
}
|
||||
|
||||
err = http.ListenAndServe(address, ocss.NewServer(service))
|
||||
server := ocss.NewServer(service)
|
||||
server.AddOperator("mobilaude_preprod", "wxvSwUpTTZ5wiAxrHpPfDsijz88w6tMW")
|
||||
server.AuthorizedOperators = append(server.AuthorizedOperators, ocss.AuthorizedOperator{
|
||||
Operator: "mobilaude",
|
||||
ApiKey: "$2y$10$TJuDZDu.mqy5dDKGMSfxSO5f6pz/36XVrAyQ1CXJd63ccjRlX7gpC",
|
||||
})
|
||||
|
||||
srv := &http.Server{
|
||||
Handler: ocss.NewServer(service),
|
||||
Handler: server,
|
||||
Addr: address,
|
||||
WriteTimeout: 15 * time.Second,
|
||||
ReadTimeout: 15 * time.Second,
|
||||
|
|
|
@ -21,12 +21,64 @@ func (s *OCSSApiService) GetDriverJourneys(ctx context.Context, departureLat flo
|
|||
minDate := departureDate.Add(-td * time.Second)
|
||||
maxDate := departureDate.Add(td * time.Second)
|
||||
|
||||
result, err := s.Handler.GetDriverJourneys(departure, arrival, minDate, maxDate)
|
||||
journeys, err := s.Handler.GetDriverJourneys(departure, arrival, departureRadius, arrivalRadius, minDate, maxDate, count)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
results := []ocss.DriverJourney{}
|
||||
|
||||
for _, j := range journeys {
|
||||
usermap := j.Route.ExtraMembers["user"].(map[string]any)
|
||||
journeyId := j.Route.ExtraMembers.MustString("journey_id")
|
||||
driverDepartureLat := j.Route.Features[0].Point().Lat()
|
||||
driverDepartureLng := j.Route.Features[0].Point().Lon()
|
||||
driverArrivalLat := j.Route.Features[1].Point().Lat()
|
||||
driverArrivalLng := j.Route.Features[1].Point().Lon()
|
||||
driverDepartureDate := ocss.JSONTime(j.DepartureDate)
|
||||
duration := time.Duration(0)
|
||||
var distance *int64
|
||||
if len(j.Itinerary.Legs) > 2 {
|
||||
duration = j.Itinerary.Legs[1].Duration
|
||||
dist := int64(j.Itinerary.Legs[1].Distance)
|
||||
distance = &dist
|
||||
}
|
||||
|
||||
results = append(results, ocss.DriverJourney{
|
||||
DriverTrip: ocss.DriverTrip{
|
||||
Driver: ocss.User{
|
||||
ID: usermap["id"].(string),
|
||||
Operator: usermap["opeator"].(string),
|
||||
Alias: usermap["alias"].(string),
|
||||
},
|
||||
Trip: ocss.Trip{
|
||||
Operator: "ridygo.fr",
|
||||
PassengerPickupLat: departureLat,
|
||||
PassengerPickupLng: departureLng,
|
||||
PassengerDropLat: arrivalLat,
|
||||
PassengerDropLng: arrivalLng,
|
||||
DriverDepartureLat: &driverDepartureLat,
|
||||
DriverDepartureLng: &driverDepartureLng,
|
||||
DriverArrivalLat: &driverArrivalLat,
|
||||
DriverArrivalLng: &driverArrivalLng,
|
||||
Duration: duration,
|
||||
Distance: distance,
|
||||
},
|
||||
},
|
||||
JourneySchedule: ocss.JourneySchedule{
|
||||
ID: &journeyId,
|
||||
PassengerPickupDate: ocss.JSONTime(j.DepartureDate.Add(j.Itinerary.Legs[0].Duration)),
|
||||
DriverDepartureDate: &driverDepartureDate,
|
||||
Type: ocss.Planned,
|
||||
},
|
||||
// Price: &ocss.Price{
|
||||
// Amount: ,
|
||||
// Currency: "EUR",
|
||||
// },
|
||||
})
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -115,6 +115,92 @@ func (s MongoDBStorage) GetUserRegularRoutes(userid string) ([]*geojson.FeatureC
|
|||
return results, nil
|
||||
}
|
||||
|
||||
func (s MongoDBStorage) GetDriverRegularRoutesForTile(day string, gridId int64) ([]*geojson.FeatureCollection, error) {
|
||||
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,
|
||||
}, findOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
results := []*geojson.FeatureCollection{}
|
||||
for cur.Next(context.TODO()) {
|
||||
var elem bson.M
|
||||
|
||||
if err := cur.Decode(&elem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bsonBytes, _ := bson.Marshal(elem)
|
||||
fc := geojson.NewFeatureCollection()
|
||||
err := fc.UnmarshalBSON(bsonBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fc.ExtraMembers["id"] = fc.ExtraMembers.MustString("_id")
|
||||
delete(fc.ExtraMembers, "_id")
|
||||
|
||||
for k, v := range fc.ExtraMembers {
|
||||
if val, ok := v.(primitive.D); ok {
|
||||
em := map[string]any{}
|
||||
jsonbytes, _ := bson.MarshalExtJSON(val, true, true)
|
||||
json.Unmarshal(jsonbytes, &em)
|
||||
fc.ExtraMembers[k] = em
|
||||
}
|
||||
}
|
||||
|
||||
results = append(results, fc)
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (s MongoDBStorage) GetPassengerRegularRoutesForTile(day string, gridId int64) ([]*geojson.FeatureCollection, error) {
|
||||
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,
|
||||
}, findOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
results := []*geojson.FeatureCollection{}
|
||||
for cur.Next(context.TODO()) {
|
||||
var elem bson.M
|
||||
|
||||
if err := cur.Decode(&elem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bsonBytes, _ := bson.Marshal(elem)
|
||||
fc := geojson.NewFeatureCollection()
|
||||
err := fc.UnmarshalBSON(bsonBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fc.ExtraMembers["id"] = fc.ExtraMembers.MustString("_id")
|
||||
delete(fc.ExtraMembers, "_id")
|
||||
|
||||
for k, v := range fc.ExtraMembers {
|
||||
if val, ok := v.(primitive.D); ok {
|
||||
em := map[string]any{}
|
||||
jsonbytes, _ := bson.MarshalExtJSON(val, true, true)
|
||||
json.Unmarshal(jsonbytes, &em)
|
||||
fc.ExtraMembers[k] = em
|
||||
}
|
||||
}
|
||||
|
||||
results = append(results, fc)
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// func (s MongoDBStorage) CreatePassengerRegularTrips(trips []*geojson.FeatureCollection) error {
|
||||
|
||||
// log.Debug().Msg("Storage - CreatePassengerRegularTrips")
|
||||
|
|
|
@ -10,6 +10,8 @@ import (
|
|||
type Storage interface {
|
||||
CreateRegularRoutes([]*geojson.FeatureCollection) error
|
||||
GetUserRegularRoutes(userid string) ([]*geojson.FeatureCollection, error)
|
||||
GetDriverRegularRoutesForTile(day string, gridId int64) ([]*geojson.FeatureCollection, error)
|
||||
GetPassengerRegularRoutesForTile(day string, gridId int64) ([]*geojson.FeatureCollection, error)
|
||||
}
|
||||
|
||||
func NewStorage(cfg *viper.Viper) (Storage, error) {
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package tiles
|
||||
|
||||
import "github.com/paulmach/orb"
|
||||
|
||||
// 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
|
||||
type GridId uint64
|
||||
|
||||
const tilesize float64 = 1.0
|
||||
|
||||
// PointGridId returns the id on the grid for a given point
|
||||
func PointGridId(point orb.Point) GridId {
|
||||
width := int64(360 / tilesize)
|
||||
return GridId(int64((point.Lat()+90)/tilesize)*width + int64((point.Lon()+180)/tilesize))
|
||||
}
|
||||
|
||||
// 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 {
|
||||
results := []GridId{}
|
||||
|
||||
gidmap := map[int64]bool{}
|
||||
|
||||
for _, p := range linestring {
|
||||
gid := PointGridId(p)
|
||||
if _, ok := gidmap[int64(gid)]; !ok {
|
||||
gidmap[int64(gid)] = true
|
||||
results = append(results, gid)
|
||||
}
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package tiles
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/paulmach/orb/geojson"
|
||||
)
|
||||
|
||||
type TiledRouteType int
|
||||
|
||||
const (
|
||||
TiledRouteRegular TiledRouteType = iota
|
||||
TiledRoutePunctual
|
||||
)
|
||||
|
||||
type TiledRoute struct {
|
||||
ID string
|
||||
Type TiledRouteType
|
||||
Route *geojson.FeatureCollection
|
||||
DepartureDate time.Time
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package tiles
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"git.coopgo.io/coopgo-platform/carpool-service/storage"
|
||||
"github.com/paulmach/orb"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type TilesHandler struct {
|
||||
Config *viper.Viper
|
||||
PersistentStorage storage.Storage
|
||||
|
||||
CachedTileset map[string]Tileset
|
||||
}
|
||||
|
||||
func NewTilesHandler(cfg *viper.Viper, persistantStorage storage.Storage) (*TilesHandler, error) {
|
||||
return &TilesHandler{
|
||||
Config: cfg,
|
||||
PersistentStorage: persistantStorage,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetTiles retrieves tiles
|
||||
func (h *TilesHandler) GetTiles(driverOrPassenger string, date time.Time, points ...orb.Point) (*Tileset, error) {
|
||||
result := Tileset{}
|
||||
|
||||
grid_ids := []GridId{}
|
||||
|
||||
nb_points := len(points)
|
||||
|
||||
if nb_points > 1 {
|
||||
grid_ids = LineStringGridIds(orb.LineString(points))
|
||||
} else if nb_points == 1 {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
result[dateString] = tile
|
||||
}
|
||||
|
||||
return &result, nil
|
||||
}
|
|
@ -2,26 +2,83 @@ package tiles
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/paulmach/orb"
|
||||
"git.coopgo.io/coopgo-platform/carpool-service/helpers"
|
||||
"github.com/google/uuid"
|
||||
"github.com/paulmach/orb/geojson"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type IndexedTilesets struct {
|
||||
Tileset map[string]*Tile // Key is "date:geo" (example : "2023-01-01:fr-south-west")
|
||||
ByDate map[string]Tileset // Key is the date in the form "YYYY-MM-DD"
|
||||
ByGeo map[string]Tileset // Key is the Geo tiles id (could be any string as defined in the configuration)
|
||||
}
|
||||
|
||||
type Tileset []*Tile
|
||||
|
||||
// Tiles are defined as :
|
||||
// - "driver" or "passenger" string depending on the status of the journeys included in the tiles
|
||||
// - a date formatted as "2006-01-02"
|
||||
// - Bounds of the tile
|
||||
type Tile struct {
|
||||
Date string
|
||||
GeoId string
|
||||
Bounds orb.Bound
|
||||
Journeys []*geojson.FeatureCollection
|
||||
DriverOrPassenger string
|
||||
Date string // Date formatted as "2006-01-02"
|
||||
GridId GridId
|
||||
|
||||
TiledRoutes []TiledRoute
|
||||
}
|
||||
|
||||
func (t Tile) Id() string {
|
||||
return fmt.Sprintf("%s:%s", t.Date, t.GeoId)
|
||||
func (tile *Tile) ID() string {
|
||||
return fmt.Sprintf("%s/%s/%d", tile.DriverOrPassenger, tile.Date, tile.GridId)
|
||||
}
|
||||
|
||||
// GetTile retrieves a tile from persistant storage or cache
|
||||
func (h *TilesHandler) GetTile(driverOrPassenger string, date time.Time, gridid GridId) (*Tile, error) {
|
||||
routes := []*geojson.FeatureCollection{}
|
||||
day := strings.ToUpper(date.Format("Mon"))
|
||||
dateString := date.Format("2006-01-02")
|
||||
|
||||
if driverOrPassenger == "driver" {
|
||||
regroutes, err := h.PersistentStorage.GetDriverRegularRoutesForTile(day, int64(gridid))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
routes = regroutes
|
||||
} else if driverOrPassenger == "passenger" {
|
||||
regroutes, err := h.PersistentStorage.GetPassengerRegularRoutesForTile(day, int64(gridid))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
routes = regroutes
|
||||
}
|
||||
|
||||
date0h, _ := time.Parse("2006-01-02", dateString)
|
||||
date24h := date0h.Add(24 * time.Hour)
|
||||
|
||||
result := []TiledRoute{}
|
||||
|
||||
for _, r := range routes {
|
||||
|
||||
rr := helpers.RegularRoute(*r)
|
||||
schedules, err := rr.PlannedJourneySchedules(date0h, date24h)
|
||||
if err != nil {
|
||||
log.Error().Err(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(schedules) > 0 {
|
||||
tiledRoute := TiledRoute{
|
||||
ID: uuid.NewString(),
|
||||
Route: r,
|
||||
Type: TiledRouteRegular,
|
||||
DepartureDate: schedules[0].DepartureDate,
|
||||
}
|
||||
|
||||
result = append(result, tiledRoute)
|
||||
}
|
||||
}
|
||||
|
||||
return &Tile{
|
||||
DriverOrPassenger: driverOrPassenger,
|
||||
Date: dateString,
|
||||
GridId: gridid,
|
||||
TiledRoutes: result,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package tiles
|
||||
|
||||
// Tileset stores tiles by TileID
|
||||
type Tileset map[string]*Tile
|
||||
|
||||
func (tileset Tileset) GetTiledRoutes() []TiledRoute {
|
||||
idmap := map[string]bool{}
|
||||
result := []TiledRoute{}
|
||||
for _, tile := range tileset {
|
||||
for _, tr := range tile.TiledRoutes {
|
||||
if _, ok := idmap[tr.Route.ExtraMembers.MustString("id")]; !ok {
|
||||
idmap[tr.Route.ExtraMembers.MustString("id")] = true
|
||||
result = append(result, tr)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
Loading…
Reference in New Issue