diff --git a/README.md b/README.md index b8c1fa7..90ad1f9 100644 --- a/README.md +++ b/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 diff --git a/go.mod b/go.mod index f5dd542..282441c 100644 --- a/go.mod +++ b/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 ) diff --git a/go.sum b/go.sum index 1f59b6b..1047a23 100644 --- a/go.sum +++ b/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= diff --git a/handler/handler.go b/handler/handler.go index 59ed61f..cb65967 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -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 } diff --git a/handler/management.go b/handler/management.go index e802406..3d3d6b8 100644 --- a/handler/management.go +++ b/handler/management.go @@ -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) diff --git a/handler/search.go b/handler/search.go index 734ed39..2b81e95 100644 --- a/handler/search.go +++ b/handler/search.go @@ -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 +// } diff --git a/helpers/journeys.go b/helpers/journeys.go new file mode 100644 index 0000000..353eba7 --- /dev/null +++ b/helpers/journeys.go @@ -0,0 +1,8 @@ +package helpers + +import "time" + +type PlannedJourney struct { + Route RegularRoute + DepartureDate time.Time +} diff --git a/handler/routes_helpers.go b/helpers/regular_routes.go similarity index 99% rename from handler/routes_helpers.go rename to helpers/regular_routes.go index 410ae4e..97baf34 100644 --- a/handler/routes_helpers.go +++ b/helpers/regular_routes.go @@ -1,4 +1,4 @@ -package handler +package helpers import ( "errors" diff --git a/main.go b/main.go index 7b2b501..28f43b1 100644 --- a/main.go +++ b/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 } diff --git a/servers/ocss-api/ocss-api.go b/servers/ocss-api/ocss-api.go index 702c1ce..a3826da 100644 --- a/servers/ocss-api/ocss-api.go +++ b/servers/ocss-api/ocss-api.go @@ -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, diff --git a/servers/ocss-api/search.go b/servers/ocss-api/search.go index e687e27..1f946e8 100644 --- a/servers/ocss-api/search.go +++ b/servers/ocss-api/search.go @@ -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) { diff --git a/storage/mongodb.go b/storage/mongodb.go index 6bec0d5..c12a6ee 100644 --- a/storage/mongodb.go +++ b/storage/mongodb.go @@ -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") diff --git a/storage/storage.go b/storage/storage.go index 6d5aeab..717ae0e 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -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) { diff --git a/tiles/grid.go b/tiles/grid.go new file mode 100644 index 0000000..77b6ee4 --- /dev/null +++ b/tiles/grid.go @@ -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 +} diff --git a/tiles/routes.go b/tiles/routes.go new file mode 100644 index 0000000..c3e5ab4 --- /dev/null +++ b/tiles/routes.go @@ -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 +} diff --git a/tiles/tiles-handler.go b/tiles/tiles-handler.go new file mode 100644 index 0000000..c38c975 --- /dev/null +++ b/tiles/tiles-handler.go @@ -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 +} diff --git a/tiles/tiles.go b/tiles/tiles.go index d681df9..0a38f33 100644 --- a/tiles/tiles.go +++ b/tiles/tiles.go @@ -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 } diff --git a/tiles/tilesets.go b/tiles/tilesets.go new file mode 100644 index 0000000..8f54726 --- /dev/null +++ b/tiles/tilesets.go @@ -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 +}