1use crate::wmts::grid::ExtentInt;
9
10pub struct GridIterator {
12 z: u8,
13 x: u32,
14 y: u32,
15 maxz: u8,
16 limits: Vec<ExtentInt>,
17 finished: bool,
18}
19
20impl GridIterator {
21 pub fn new(minz: u8, maxz: u8, limits: Vec<ExtentInt>) -> GridIterator {
22 if minz <= maxz && limits.len() > minz as usize {
23 let limit = &limits[minz as usize];
24 let maxz = std::cmp::min(maxz, limits.len() as u8 - 1);
25 GridIterator {
26 z: minz,
27 x: limit.minx,
28 y: limit.miny,
29 maxz,
30 limits,
31 finished: false,
32 }
33 } else {
34 GridIterator {
36 z: 0,
37 x: 0,
38 y: 0,
39 maxz: 0,
40 limits: Vec::new(),
41 finished: true,
42 }
43 }
44 }
45}
46
47impl Iterator for GridIterator {
48 type Item = (u8, u32, u32);
50
51 fn next(&mut self) -> Option<Self::Item> {
52 if self.finished {
53 return None;
54 }
55 let current = (self.z, self.x, self.y);
56 let limit = &self.limits[self.z as usize];
57 if self.y < limit.maxy - 1 {
58 self.y += 1;
59 } else if self.x < limit.maxx - 1 {
60 self.x += 1;
61 self.y = limit.miny;
62 } else if self.z < self.maxz {
63 self.z += 1;
64 let limit = &self.limits[self.z as usize];
65 self.x = limit.minx;
66 self.y = limit.miny;
67 } else {
68 self.finished = true;
69 }
70 Some(current)
71 }
72}
73
74#[test]
75fn test_mercator_iter() {
76 use crate::wmts::grid::Grid;
77 let grid = Grid::web_mercator();
78 let tile_limits = grid.tile_limits(grid.extent.clone(), 0);
79 let griditer = GridIterator::new(0, 2, tile_limits);
80 let cells = griditer.collect::<Vec<_>>();
81 assert_eq!(
82 cells,
83 vec![
84 (0, 0, 0),
85 (1, 0, 0),
86 (1, 0, 1),
87 (1, 1, 0),
88 (1, 1, 1),
89 (2, 0, 0),
90 (2, 0, 1),
91 (2, 0, 2),
92 (2, 0, 3),
93 (2, 1, 0),
94 (2, 1, 1),
95 (2, 1, 2),
96 (2, 1, 3),
97 (2, 2, 0),
98 (2, 2, 1),
99 (2, 2, 2),
100 (2, 2, 3),
101 (2, 3, 0),
102 (2, 3, 1),
103 (2, 3, 2),
104 (2, 3, 3)
105 ]
106 );
107
108 let tile_limits = grid.tile_limits(grid.extent.clone(), 0);
109 let griditer = GridIterator::new(1, 2, tile_limits);
110 let cells = griditer.collect::<Vec<_>>();
111 assert_eq!(
112 cells,
113 vec![
114 (1, 0, 0),
115 (1, 0, 1),
116 (1, 1, 0),
117 (1, 1, 1),
118 (2, 0, 0),
119 (2, 0, 1),
120 (2, 0, 2),
121 (2, 0, 3),
122 (2, 1, 0),
123 (2, 1, 1),
124 (2, 1, 2),
125 (2, 1, 3),
126 (2, 2, 0),
127 (2, 2, 1),
128 (2, 2, 2),
129 (2, 2, 3),
130 (2, 3, 0),
131 (2, 3, 1),
132 (2, 3, 2),
133 (2, 3, 3)
134 ]
135 );
136
137 let tile_limits = grid.tile_limits(grid.extent.clone(), 0);
138 let griditer = GridIterator::new(0, 0, tile_limits);
139 let cells = griditer.collect::<Vec<_>>();
140 assert_eq!(cells, vec![(0, 0, 0)]);
141}
142
143#[test]
144fn test_bad_params() {
145 use crate::wmts::grid::Grid;
146 let grid = Grid::web_mercator();
147
148 let griditer = GridIterator::new(0, 10, Vec::new());
150 let cells = griditer.collect::<Vec<_>>();
151 assert_eq!(cells, vec![]);
152
153 let tile_limits = grid.tile_limits(grid.extent.clone(), 0);
155 let griditer = GridIterator::new(3, 2, tile_limits);
156 let cells = griditer.collect::<Vec<_>>();
157 assert_eq!(cells, vec![]);
158
159 let griditer = GridIterator::new(
161 0,
162 2,
163 vec![
164 ExtentInt {
165 minx: 0,
166 miny: 0,
167 maxx: 1,
168 maxy: 1,
169 },
170 ExtentInt {
171 minx: 0,
172 miny: 0,
173 maxx: 2,
174 maxy: 2,
175 },
176 ],
177 );
178 let cells = griditer.collect::<Vec<_>>();
179 assert_eq!(
180 cells,
181 vec![(0, 0, 0), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)]
182 );
183
184 let griditer = GridIterator::new(
186 1,
187 2,
188 vec![ExtentInt {
189 minx: 0,
190 miny: 0,
191 maxx: 1,
192 maxy: 1,
193 }],
194 );
195 let cells = griditer.collect::<Vec<_>>();
196 assert_eq!(cells, vec![]);
197}