Initial cloud-services repo - gateway service + pkg modules
This commit is contained in:
460
pkg/utils/quadkey/quadkey_test.go
Normal file
460
pkg/utils/quadkey/quadkey_test.go
Normal file
@@ -0,0 +1,460 @@
|
||||
package quadkey_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"fiskerinc.com/modules/utils/quadkey"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestLatLongToQuadkey(t *testing.T) {
|
||||
|
||||
tests := map[string]struct {
|
||||
lat float64
|
||||
long float64
|
||||
expectedQuadkeyStr string
|
||||
expectedQuadkeyInt uint64
|
||||
}{
|
||||
"lapalma": {
|
||||
lat: 33.86219399999999,
|
||||
long: -118.029596,
|
||||
expectedQuadkeyStr: "02301320022100032301331202320110",
|
||||
expectedQuadkeyInt: 3204356230721449492,
|
||||
},
|
||||
|
||||
"london": {
|
||||
lat: 51.507822,
|
||||
long: -0.162069,
|
||||
expectedQuadkeyStr: "03131313113000100311131122203023",
|
||||
expectedQuadkeyInt: 3996764367461132491,
|
||||
},
|
||||
|
||||
"null": {
|
||||
lat: 0.0,
|
||||
long: 0.0,
|
||||
expectedQuadkeyStr: "30000000000000000000000000000000",
|
||||
expectedQuadkeyInt: 0xC000000000000000,
|
||||
},
|
||||
|
||||
"invalid": {
|
||||
lat: -2000.0,
|
||||
long: -2000.0,
|
||||
expectedQuadkeyStr: "22222222222222222222222222222222",
|
||||
expectedQuadkeyInt: 0xAAAAAAAAAAAAAAAA,
|
||||
},
|
||||
}
|
||||
|
||||
for tname, tt := range tests {
|
||||
t.Run(tname, func(t *testing.T) {
|
||||
|
||||
qkey := quadkey.LatLongToQuadKey(tt.lat, tt.long)
|
||||
qkeyStr := quadkey.QuadkeyStr(qkey)
|
||||
|
||||
assert.Equal(t, tt.expectedQuadkeyInt, qkey)
|
||||
assert.Equal(t, tt.expectedQuadkeyStr, qkeyStr)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestQuadkeySearchBuckets(t *testing.T) {
|
||||
|
||||
tests := map[string]struct {
|
||||
lat float64
|
||||
long float64
|
||||
radius float64
|
||||
coarseness float64
|
||||
|
||||
expectedKeys map[uint64]bool
|
||||
expectedBuckets map[uint64]quadkey.QuadkeyBucket
|
||||
absentKeys map[uint64]bool //set of keys that should not show up
|
||||
}{
|
||||
|
||||
"invalid": {
|
||||
lat: -2000.0,
|
||||
long: -2000.0,
|
||||
radius: 100.0, //100m
|
||||
coarseness: 600000.0, // 600km
|
||||
expectedKeys: map[uint64]bool{}, //an invalid quad is generated, and fails every intersect check
|
||||
},
|
||||
|
||||
"null": {
|
||||
lat: 0.0,
|
||||
long: 0.0,
|
||||
radius: 100.0, //100m
|
||||
coarseness: 600000.0, // 600km
|
||||
expectedKeys: map[uint64]bool{
|
||||
0x3FF0000000000000: true, //033333
|
||||
0xC000000000000000: true, //300000
|
||||
0x6AA0000000000000: true, //122222
|
||||
0x9550000000000000: true, //211111
|
||||
},
|
||||
},
|
||||
|
||||
"london": {
|
||||
lat: 51.507822,
|
||||
long: -0.162069,
|
||||
radius: 8, //8 meters radius
|
||||
coarseness: 8,
|
||||
|
||||
expectedKeys: map[uint64]bool{
|
||||
0x37775C0435400000: true, //0313131311300010031110
|
||||
0x37775C0435500000: true, //0313131311300010031111
|
||||
0x37775C0460000000: true, //0313131311300010120000
|
||||
0x37775C0435600000: true, //0313131311300010031112
|
||||
0x37775C0435700000: true, //0313131311300010031113
|
||||
0x37775C0460200000: true, //0313131311300010120002
|
||||
0x37775C0435C00000: true, //0313131311300010031130
|
||||
0x37775C0435D00000: true, //0313131311300010031131
|
||||
0x37775C0460800000: true, //0313131311300010120020
|
||||
},
|
||||
absentKeys: map[uint64]bool{
|
||||
0x2C782903B1D00000: true,
|
||||
0x2C782903B1DC8000: true,
|
||||
0x2C782903B4000000: true,
|
||||
0x2C782903B4080000: true,
|
||||
0x2C782903B00C0000: true,
|
||||
0x2C782903B4800000: true,
|
||||
0x2C78290000000000: true,
|
||||
},
|
||||
},
|
||||
|
||||
//lapalma test cases use quadkeys from visually inspecting mapbox maps
|
||||
"lapalma": {
|
||||
lat: 33.86219399999999,
|
||||
long: -118.029596,
|
||||
radius: 8, //8 meters radius
|
||||
coarseness: 4, //looking for buckets with width of 4 meters
|
||||
|
||||
expectedKeys: map[uint64]bool{
|
||||
0x2C782903B1D80000: true,
|
||||
0x2C782903B1DC0000: true,
|
||||
0x2C782903B4A00000: true,
|
||||
0x2C782903B4A80000: true,
|
||||
0x2C782903B1EC0000: true,
|
||||
0x2C782903B1F00000: true,
|
||||
0x2C782903B1F40000: true,
|
||||
0x2C782903B3540000: true,
|
||||
0x2C782903B6000000: true,
|
||||
0x2C782903B1CC0000: true,
|
||||
0x2C782903B1E40000: true,
|
||||
0x2C782903B1FC0000: true,
|
||||
0x2C782903B3440000: true,
|
||||
0x2C782903B4880000: true,
|
||||
0x2C782903B1F80000: true,
|
||||
0x2C782903B3500000: true,
|
||||
},
|
||||
absentKeys: map[uint64]bool{
|
||||
0x2C782903B1D00000: true,
|
||||
0x2C782903B1DC8000: true,
|
||||
0x2C782903B4000000: true,
|
||||
0x2C782903B4080000: true,
|
||||
0x2C782903B00C0000: true,
|
||||
0x2C782903B4800000: true,
|
||||
0x2C78290000000000: true,
|
||||
},
|
||||
},
|
||||
|
||||
"lapalma_2": {
|
||||
lat: 33.86219399999999,
|
||||
long: -118.029596,
|
||||
radius: 8,
|
||||
coarseness: 8,
|
||||
|
||||
expectedKeys: map[uint64]bool{
|
||||
0x2C782903B1C00000: true,
|
||||
0x2C782903B1D00000: true,
|
||||
0x2C782903B4800000: true,
|
||||
|
||||
0x2C782903B1E00000: true,
|
||||
0x2C782903B1F00000: true,
|
||||
0x2C782903B4A00000: true,
|
||||
|
||||
0x2C782903B3400000: true,
|
||||
0x2C782903B3500000: true,
|
||||
0x2C782903B6000000: true,
|
||||
},
|
||||
absentKeys: map[uint64]bool{
|
||||
0x2C782903B3440000: true,
|
||||
0x2C782903B4880000: true,
|
||||
0x2C782903B1F80000: true,
|
||||
0x2C78290000000000: true,
|
||||
0x2C782903B3000000: true,
|
||||
},
|
||||
},
|
||||
|
||||
"lapalma_3": {
|
||||
lat: 33.86219399999999,
|
||||
long: -118.029596,
|
||||
radius: 8,
|
||||
coarseness: 32,
|
||||
|
||||
expectedKeys: map[uint64]bool{
|
||||
0x2C782903B1000000: true,
|
||||
0x2C782903B4000000: true,
|
||||
0x2C782903B3000000: true,
|
||||
0x2C782903B6000000: true,
|
||||
},
|
||||
absentKeys: map[uint64]bool{
|
||||
0x2C782903B3400000: true,
|
||||
0x2C782903B3500000: true,
|
||||
0x2C782903B0000000: true,
|
||||
0x2C78290000000000: true,
|
||||
},
|
||||
},
|
||||
|
||||
"lapalma_4": {
|
||||
lat: 33.86219399999999,
|
||||
long: -118.029596,
|
||||
radius: 8,
|
||||
coarseness: 128, //looking for 128m width nodes
|
||||
|
||||
expectedKeys: map[uint64]bool{
|
||||
0x2C782903B0000000: true, //corresponds to 023013200221000323, ~127m width node
|
||||
},
|
||||
absentKeys: map[uint64]bool{
|
||||
0x2C78000000000000: true,
|
||||
0x2C782903B4000000: true,
|
||||
0x2C782903B3000000: true,
|
||||
0x2C78290000000000: true,
|
||||
},
|
||||
},
|
||||
|
||||
"lapalma_5": {
|
||||
lat: 33.86219399999999,
|
||||
long: -118.029596,
|
||||
radius: 8,
|
||||
coarseness: 100000, //looking for 100km width nodes
|
||||
|
||||
expectedKeys: map[uint64]bool{
|
||||
0x2C78000000000000: true, //corresponds to 02301320, ~130km width node
|
||||
},
|
||||
absentKeys: map[uint64]bool{
|
||||
0x2C782903B0000000: true,
|
||||
0x2C782903B1F00000: true,
|
||||
0x2C782903B4A00000: true,
|
||||
0x2C78290000000000: true,
|
||||
},
|
||||
|
||||
expectedBuckets: map[uint64]quadkey.QuadkeyBucket{
|
||||
0x2C78000000000000: {
|
||||
0x2C78000000000000,
|
||||
7,
|
||||
0x2C78000000000000,
|
||||
0x2C78FFFFFFFFFFFF,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for tname, tt := range tests {
|
||||
t.Run(tname, func(t *testing.T) {
|
||||
buckets := quadkey.QuadkeySearchBuckets(tt.lat, tt.long, tt.radius, tt.coarseness)
|
||||
|
||||
assert.Equal(t, len(tt.expectedKeys), len(buckets))
|
||||
for key := range buckets {
|
||||
assert.Contains(t, tt.expectedKeys, key)
|
||||
}
|
||||
|
||||
for key, bucket := range tt.expectedBuckets {
|
||||
assert.Contains(t, buckets, key)
|
||||
|
||||
actualBucket, ok := buckets[key]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
assert.Equal(t, bucket.Quadkey, actualBucket.Quadkey)
|
||||
assert.Equal(t, bucket.Depth, actualBucket.Depth)
|
||||
assert.Equal(t, bucket.Start, actualBucket.Start)
|
||||
assert.Equal(t, bucket.End, actualBucket.End)
|
||||
}
|
||||
|
||||
for key := range tt.absentKeys {
|
||||
assert.NotContains(t, buckets, key)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestQuadkeyGridBuckets(t *testing.T) {
|
||||
|
||||
tests := map[string]struct {
|
||||
lat float64
|
||||
long float64
|
||||
radius float64
|
||||
coarseness float64
|
||||
|
||||
expectedKeys map[uint64]bool
|
||||
absentKeys map[uint64]bool //set of keys that should not show up
|
||||
}{
|
||||
|
||||
"invalid": {
|
||||
lat: -2000.0,
|
||||
long: -2000.0,
|
||||
radius: 100.0, //100m
|
||||
coarseness: 600000.0, // 600km
|
||||
expectedKeys: map[uint64]bool{
|
||||
0x0000000000000000: true, //clamped lat long. 90, -180
|
||||
0xAAA0000000000000: true, //clamped lat long -90, -180
|
||||
0xFFF0000000000000: true, //clamped lat long, -90, +180
|
||||
0x5550000000000000: true, //clamped lat long, +90, +180
|
||||
},
|
||||
},
|
||||
"null": {
|
||||
lat: 0.0,
|
||||
long: 0.0,
|
||||
radius: 100.0, //1km
|
||||
coarseness: 600000.0, // 600km
|
||||
expectedKeys: map[uint64]bool{
|
||||
0x3FF0000000000000: true, //033333
|
||||
0xC000000000000000: true, //300000
|
||||
0x6AA0000000000000: true, //122222
|
||||
0x9550000000000000: true, //211111
|
||||
},
|
||||
},
|
||||
"london": {
|
||||
lat: 51.507822,
|
||||
long: -0.162069,
|
||||
radius: 8, //8 meters radius
|
||||
coarseness: 8,
|
||||
|
||||
expectedKeys: map[uint64]bool{
|
||||
0x37775C0435400000: true, //0313131311300010031110
|
||||
0x37775C0435500000: true, //0313131311300010031111
|
||||
0x37775C0460000000: true, //0313131311300010120000
|
||||
0x37775C0435600000: true, //0313131311300010031112
|
||||
0x37775C0435700000: true, //0313131311300010031113
|
||||
0x37775C0460200000: true, //0313131311300010120002
|
||||
0x37775C0435C00000: true, //0313131311300010031130
|
||||
0x37775C0435D00000: true, //0313131311300010031131
|
||||
0x37775C0460800000: true, //0313131311300010120020
|
||||
},
|
||||
absentKeys: map[uint64]bool{
|
||||
0x2C782903B1D00000: true,
|
||||
0x2C782903B1DC8000: true,
|
||||
0x2C782903B4000000: true,
|
||||
0x2C782903B4080000: true,
|
||||
0x2C782903B00C0000: true,
|
||||
0x2C782903B4800000: true,
|
||||
0x2C78290000000000: true,
|
||||
},
|
||||
},
|
||||
//lapalma test cases use quadkeys from visually inspecting mapbox maps
|
||||
"lapalma": {
|
||||
lat: 33.86219399999999,
|
||||
long: -118.029596,
|
||||
radius: 8,
|
||||
coarseness: 4,
|
||||
|
||||
expectedKeys: map[uint64]bool{
|
||||
0x2C782903B1D80000: true,
|
||||
0x2C782903B1DC0000: true,
|
||||
0x2C782903B4A00000: true,
|
||||
0x2C782903B4A80000: true,
|
||||
0x2C782903B1EC0000: true,
|
||||
0x2C782903B1F00000: true,
|
||||
0x2C782903B1F40000: true,
|
||||
0x2C782903B3540000: true,
|
||||
0x2C782903B6000000: true,
|
||||
0x2C782903B1CC0000: true,
|
||||
0x2C782903B1E40000: true,
|
||||
0x2C782903B1FC0000: true,
|
||||
0x2C782903B3440000: true,
|
||||
0x2C782903B4880000: true,
|
||||
0x2C782903B1F80000: true,
|
||||
0x2C782903B3500000: true,
|
||||
},
|
||||
|
||||
absentKeys: map[uint64]bool{
|
||||
0x2C782903B3400000: true,
|
||||
0x2C782903B1000000: true,
|
||||
0x2C782903B0000000: true,
|
||||
0x2C78290000000000: true,
|
||||
},
|
||||
},
|
||||
|
||||
"lapalma_2": {
|
||||
lat: 33.86219399999999,
|
||||
long: -118.029596,
|
||||
radius: 8,
|
||||
coarseness: 8,
|
||||
|
||||
expectedKeys: map[uint64]bool{
|
||||
0x2C782903B1C00000: true,
|
||||
0x2C782903B1D00000: true,
|
||||
0x2C782903B4800000: true,
|
||||
|
||||
0x2C782903B1E00000: true,
|
||||
0x2C782903B1F00000: true,
|
||||
0x2C782903B4A00000: true,
|
||||
|
||||
0x2C782903B3400000: true,
|
||||
0x2C782903B3500000: true,
|
||||
0x2C782903B6000000: true,
|
||||
},
|
||||
absentKeys: map[uint64]bool{
|
||||
0x2C782903B1000000: true,
|
||||
0x2C782903B0000000: true,
|
||||
0x2C78290000000000: true,
|
||||
0x2c782903B4000000: true,
|
||||
},
|
||||
},
|
||||
|
||||
"lapalma_3": {
|
||||
lat: 33.86219399999999,
|
||||
long: -118.029596,
|
||||
radius: 8,
|
||||
coarseness: 32,
|
||||
|
||||
expectedKeys: map[uint64]bool{
|
||||
0x2C782903B1000000: true,
|
||||
0x2c782903B3000000: true,
|
||||
0x2c782903B4000000: true,
|
||||
0x2c782903B6000000: true,
|
||||
},
|
||||
absentKeys: map[uint64]bool{
|
||||
0x2C782903B1F00000: true,
|
||||
0x2C782903B4A00000: true,
|
||||
0x2C782903B0000000: true,
|
||||
0x2C78290000000000: true,
|
||||
},
|
||||
},
|
||||
|
||||
"lapalma_4": {
|
||||
lat: 33.86219399999999,
|
||||
long: -118.029596,
|
||||
radius: 8,
|
||||
coarseness: 128,
|
||||
|
||||
expectedKeys: map[uint64]bool{
|
||||
0x2C782903B0000000: true,
|
||||
},
|
||||
absentKeys: map[uint64]bool{
|
||||
0x2C782903B1000000: true,
|
||||
0x2C782903B1D00000: true,
|
||||
0x2C782903B4800000: true,
|
||||
0x2C782903B1CC0000: true,
|
||||
0x2C782903B1E40000: true,
|
||||
0x2C78290000000000: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for tname, tt := range tests {
|
||||
t.Run(tname, func(t *testing.T) {
|
||||
fmt.Println(tname)
|
||||
|
||||
buckets := quadkey.QuadkeyGridBuckets(tt.lat, tt.long, tt.radius, tt.coarseness)
|
||||
|
||||
assert.Equal(t, len(tt.expectedKeys), len(buckets))
|
||||
for key := range buckets {
|
||||
assert.Contains(t, tt.expectedKeys, key)
|
||||
}
|
||||
|
||||
for key := range tt.absentKeys {
|
||||
assert.NotContains(t, buckets, key)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user