Skip to content

Commit ebd7887

Browse files
authored
Merge pull request #133 from peitili/master
Add ChildrenInZoomRange method
2 parents 83d306c + 9bf953a commit ebd7887

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed

maptile/tile.go

+28
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,34 @@ func (t Tile) Children() Tiles {
226226
}
227227
}
228228

229+
// ChildrenInZoomRange returns all the children tiles of tile from ranges [zoomStart, zoomEnd], both ends inclusive.
230+
func ChildrenInZoomRange(tile Tile, zoomStart, zoomEnd Zoom) Tiles {
231+
if !(zoomStart <= zoomEnd) {
232+
panic("zoomStart must be <= zoomEnd")
233+
}
234+
if !(tile.Z <= zoomStart) {
235+
panic("tile.Z is must be <= zoomStart")
236+
}
237+
238+
zDeltaStart := zoomStart - tile.Z
239+
zDeltaEnd := zoomEnd - tile.Z
240+
241+
res := make([]Tile, 0)
242+
243+
for d := zDeltaStart; d <= zDeltaEnd; d++ {
244+
xStart := tile.X << d
245+
yStart := tile.Y << d
246+
dim := uint32(1 << d)
247+
for x := xStart; x < xStart+dim; x++ {
248+
for y := yStart; y < yStart+dim; y++ {
249+
res = append(res, New(x, y, tile.Z+d))
250+
}
251+
}
252+
}
253+
254+
return res
255+
}
256+
229257
// Siblings returns the 4 tiles that share this tile's parent.
230258
func (t Tile) Siblings() Tiles {
231259
return t.Parent().Children()

maptile/tile_test.go

+93
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package maptile
33
import (
44
"fmt"
55
"math"
6+
"reflect"
67
"testing"
78

89
"github.com/paulmach/orb"
@@ -160,6 +161,98 @@ func TestContains(t *testing.T) {
160161
}
161162
}
162163

164+
func TestChildrenTilesSubRange(t *testing.T) {
165+
type args struct {
166+
tile Tile
167+
zoomStart Zoom
168+
zoomEnd Zoom
169+
}
170+
tests := []struct {
171+
name string
172+
args args
173+
want Tiles
174+
}{
175+
{
176+
name: "self zoom",
177+
args: args{
178+
tile: New(0, 0, 0),
179+
zoomStart: 0,
180+
zoomEnd: 0,
181+
},
182+
want: Tiles{New(0, 0, 0)},
183+
},
184+
{
185+
name: "1 level zooming including zoom 0",
186+
args: args{
187+
tile: New(0, 0, 0),
188+
zoomStart: 0,
189+
zoomEnd: 1,
190+
},
191+
want: Tiles{New(0, 0, 0), New(0, 0, 1), New(0, 1, 1), New(1, 0, 1), New(1, 1, 1)},
192+
},
193+
{
194+
name: "1 level zooming excluding zoom 0",
195+
args: args{
196+
tile: New(0, 0, 0),
197+
zoomStart: 1,
198+
zoomEnd: 1,
199+
},
200+
want: Tiles{New(0, 0, 1), New(0, 1, 1), New(1, 0, 1), New(1, 1, 1)},
201+
},
202+
{
203+
name: "2 level zooming",
204+
args: args{
205+
tile: New(0, 0, 0),
206+
zoomStart: 2,
207+
zoomEnd: 2,
208+
},
209+
want: Tiles{
210+
New(0, 0, 2),
211+
New(0, 1, 2),
212+
New(0, 2, 2),
213+
New(0, 3, 2),
214+
New(1, 0, 2),
215+
New(1, 1, 2),
216+
New(1, 2, 2),
217+
New(1, 3, 2),
218+
New(2, 0, 2),
219+
New(2, 1, 2),
220+
New(2, 2, 2),
221+
New(2, 3, 2),
222+
New(3, 0, 2),
223+
New(3, 1, 2),
224+
New(3, 2, 2),
225+
New(3, 3, 2),
226+
},
227+
},
228+
}
229+
for _, tt := range tests {
230+
t.Run(tt.name, func(t *testing.T) {
231+
if !reflect.DeepEqual(tt.want, ChildrenInZoomRange(tt.args.tile, tt.args.zoomStart, tt.args.zoomEnd)) {
232+
t.Errorf("tiles not equal")
233+
}
234+
})
235+
}
236+
}
237+
238+
func TestChildrenTilesSubRangeInvalidParams_ZoomStart_Larger_Than_ZoomEnd(t *testing.T) {
239+
// No need to check whether `recover()` is nil. Just turn off the panic.
240+
defer func() { _ = recover() }()
241+
tile := New(0, 0, 0)
242+
ChildrenInZoomRange(tile, 10, 8)
243+
// Never reaches here if `ChildrenInZoomRange` panics.
244+
t.Errorf("did not panic")
245+
}
246+
247+
func TestChildrenTilesSubRangeInvalidParams_TileZ_Larger_Than_ZoomStart(t *testing.T) {
248+
// No need to check whether `recover()` is nil. Just turn off the panic.
249+
defer func() { _ = recover() }()
250+
tile := New(0, 0, 10)
251+
ChildrenInZoomRange(tile, 9, 12)
252+
// Never reaches here if `ChildrenInZoomRange` panics.
253+
t.Errorf("did not panic")
254+
}
255+
163256
func TestRange(t *testing.T) {
164257
tile := New(4, 4, 5)
165258
min, max := tile.Range(3)

0 commit comments

Comments
 (0)