Files
cloud-services/pkg/utils/quadkey/quadkey_test.go

461 lines
11 KiB
Go

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)
}
})
}
}