Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions maptile/tile.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,34 @@ func (t Tile) Children() Tiles {
}
}

// ChildrenInZoomRange returns all the children tiles of tile from ranges [zoomStart, zoomEnd], both ends inclusive.
func ChildrenInZoomRange(tile Tile, zoomStart, zoomEnd Zoom) Tiles {
if !(zoomStart <= zoomEnd) {
panic("zoomStart must be <= zoomEnd")
}
if !(tile.Z <= zoomStart) {
panic("tile.Z is must be <= zoomStart")
}

zDeltaStart := zoomStart - tile.Z
zDeltaEnd := zoomEnd - tile.Z

res := make([]Tile, 0)

for d := zDeltaStart; d <= zDeltaEnd; d++ {
xStart := tile.X << d
yStart := tile.Y << d
dim := uint32(1 << d)
for x := xStart; x < xStart+dim; x++ {
for y := yStart; y < yStart+dim; y++ {
res = append(res, New(x, y, tile.Z+d))
}
}
}

return res
}

// Siblings returns the 4 tiles that share this tile's parent.
func (t Tile) Siblings() Tiles {
return t.Parent().Children()
Expand Down
93 changes: 93 additions & 0 deletions maptile/tile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package maptile
import (
"fmt"
"math"
"reflect"
"testing"

"github.com/paulmach/orb"
Expand Down Expand Up @@ -160,6 +161,98 @@ func TestContains(t *testing.T) {
}
}

func TestChildrenTilesSubRange(t *testing.T) {
type args struct {
tile Tile
zoomStart Zoom
zoomEnd Zoom
}
tests := []struct {
name string
args args
want Tiles
}{
{
name: "self zoom",
args: args{
tile: New(0, 0, 0),
zoomStart: 0,
zoomEnd: 0,
},
want: Tiles{New(0, 0, 0)},
},
{
name: "1 level zooming including zoom 0",
args: args{
tile: New(0, 0, 0),
zoomStart: 0,
zoomEnd: 1,
},
want: Tiles{New(0, 0, 0), New(0, 0, 1), New(0, 1, 1), New(1, 0, 1), New(1, 1, 1)},
},
{
name: "1 level zooming excluding zoom 0",
args: args{
tile: New(0, 0, 0),
zoomStart: 1,
zoomEnd: 1,
},
want: Tiles{New(0, 0, 1), New(0, 1, 1), New(1, 0, 1), New(1, 1, 1)},
},
{
name: "2 level zooming",
args: args{
tile: New(0, 0, 0),
zoomStart: 2,
zoomEnd: 2,
},
want: Tiles{
New(0, 0, 2),
New(0, 1, 2),
New(0, 2, 2),
New(0, 3, 2),
New(1, 0, 2),
New(1, 1, 2),
New(1, 2, 2),
New(1, 3, 2),
New(2, 0, 2),
New(2, 1, 2),
New(2, 2, 2),
New(2, 3, 2),
New(3, 0, 2),
New(3, 1, 2),
New(3, 2, 2),
New(3, 3, 2),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if !reflect.DeepEqual(tt.want, ChildrenInZoomRange(tt.args.tile, tt.args.zoomStart, tt.args.zoomEnd)) {
t.Errorf("tiles not equal")
}
})
}
}

func TestChildrenTilesSubRangeInvalidParams_ZoomStart_Larger_Than_ZoomEnd(t *testing.T) {
// No need to check whether `recover()` is nil. Just turn off the panic.
defer func() { _ = recover() }()
tile := New(0, 0, 0)
ChildrenInZoomRange(tile, 10, 8)
// Never reaches here if `ChildrenInZoomRange` panics.
t.Errorf("did not panic")
}

func TestChildrenTilesSubRangeInvalidParams_TileZ_Larger_Than_ZoomStart(t *testing.T) {
// No need to check whether `recover()` is nil. Just turn off the panic.
defer func() { _ = recover() }()
tile := New(0, 0, 10)
ChildrenInZoomRange(tile, 9, 12)
// Never reaches here if `ChildrenInZoomRange` panics.
t.Errorf("did not panic")
}

func TestRange(t *testing.T) {
tile := New(4, 4, 5)
min, max := tile.Range(3)
Expand Down