|
|
@@ -147,6 +147,7 @@ impl MapView {
|
|
147
|
147
|
}
|
|
148
|
148
|
|
|
149
|
149
|
//TODO Put this in a new module with other "sphere things"
|
|
|
150
|
+ //TODO Return the transformation matrix that is used here to avoid redundant calculation.
|
|
150
|
151
|
/// Returns a `Vec` of all tiles that are visible in the current viewport.
|
|
151
|
152
|
pub fn visible_globe_tiles(&self) -> Vec<TileCoord> {
|
|
152
|
153
|
let uzoom = self.tile_zoom();
|
|
|
@@ -166,26 +167,86 @@ impl MapView {
|
|
166
|
167
|
|
|
167
|
168
|
let center_tile = self.center.on_tile_at_zoom(uzoom).globe_norm();
|
|
168
|
169
|
|
|
|
170
|
+ let transform = self.globe_transformation_matrix();
|
|
|
171
|
+
|
|
|
172
|
+ let add_tile_if_visible = |tc: TileCoord, vec: &mut Vec<TileCoord>| -> bool {
|
|
|
173
|
+ let nearest = tc.nearest_inside_point(self.center).to_latlon_rad().to_sphere_point3();
|
|
|
174
|
+ let screen_coord = transform.transform_point(nearest);
|
|
|
175
|
+
|
|
|
176
|
+ let visible = screen_coord.x >= -1.0 && screen_coord.x <= 1.0 &&
|
|
|
177
|
+ screen_coord.y >= -1.0 && screen_coord.y <= 1.0;
|
|
|
178
|
+
|
|
|
179
|
+ if visible {
|
|
|
180
|
+ vec.push(tc);
|
|
|
181
|
+ true
|
|
|
182
|
+ } else {
|
|
|
183
|
+ false
|
|
|
184
|
+ }
|
|
|
185
|
+ };
|
|
169
|
186
|
|
|
170
|
187
|
let mut tiles = vec![];
|
|
171
|
|
- tiles.push(center_tile);
|
|
172
|
188
|
|
|
173
|
|
- // Check rings of tiles with the same Chebyshev distance to the center_tile
|
|
174
|
189
|
{
|
|
175
|
190
|
let zoom_level_tiles = TileCoord::get_zoom_level_tiles(uzoom);
|
|
176
|
|
- let max_full_rings = (zoom_level_tiles - 1) / 2;
|
|
177
|
191
|
|
|
178
|
|
- for radius in 1..3.min(max_full_rings + 1) {
|
|
179
|
|
- let (rx1, rx2) = (center_tile.x - radius, center_tile.x + radius);
|
|
180
|
|
- let (ry1, ry2) = (center_tile.y - radius, center_tile.y + radius);
|
|
|
192
|
+ for dx in 0..(zoom_level_tiles / 2) {
|
|
|
193
|
+ let v = add_tile_if_visible(TileCoord::new(uzoom, center_tile.x + dx, center_tile.y), &mut tiles);
|
|
|
194
|
+ if !v {
|
|
|
195
|
+ break;
|
|
|
196
|
+ }
|
|
|
197
|
+ }
|
|
|
198
|
+ for dx in 1..(1 + zoom_level_tiles / 2) {
|
|
|
199
|
+ let v = add_tile_if_visible(TileCoord::new(uzoom, center_tile.x - dx, center_tile.y), &mut tiles);
|
|
|
200
|
+ if !v {
|
|
|
201
|
+ break;
|
|
|
202
|
+ }
|
|
|
203
|
+ }
|
|
|
204
|
+
|
|
|
205
|
+ // move south
|
|
|
206
|
+ for y in (center_tile.y + 1)..zoom_level_tiles {
|
|
|
207
|
+ let mut visible = false;
|
|
181
|
208
|
|
|
182
|
|
- for x in rx1..rx2+1 {
|
|
183
|
|
- tiles.push(TileCoord::new(uzoom, x, ry1).globe_norm());
|
|
184
|
|
- tiles.push(TileCoord::new(uzoom, x, ry2).globe_norm());
|
|
|
209
|
+ for dx in 0..(zoom_level_tiles / 2) {
|
|
|
210
|
+ let v = add_tile_if_visible(TileCoord::new(uzoom, center_tile.x + dx, y), &mut tiles);
|
|
|
211
|
+ visible = visible || v;
|
|
|
212
|
+ if !v {
|
|
|
213
|
+ break;
|
|
|
214
|
+ }
|
|
185
|
215
|
}
|
|
186
|
|
- for y in ry1+1..ry2 {
|
|
187
|
|
- tiles.push(TileCoord::new(uzoom, rx1, y).globe_norm());
|
|
188
|
|
- tiles.push(TileCoord::new(uzoom, rx2, y).globe_norm());
|
|
|
216
|
+ for dx in 1..(1 + zoom_level_tiles / 2) {
|
|
|
217
|
+ let v = add_tile_if_visible(TileCoord::new(uzoom, center_tile.x - dx, y), &mut tiles);
|
|
|
218
|
+ visible = visible || v;
|
|
|
219
|
+ if !v {
|
|
|
220
|
+ break;
|
|
|
221
|
+ }
|
|
|
222
|
+ }
|
|
|
223
|
+
|
|
|
224
|
+ if !visible {
|
|
|
225
|
+ break;
|
|
|
226
|
+ }
|
|
|
227
|
+ }
|
|
|
228
|
+
|
|
|
229
|
+ // move north
|
|
|
230
|
+ for y in (0..center_tile.y).rev() {
|
|
|
231
|
+ let mut visible = false;
|
|
|
232
|
+
|
|
|
233
|
+ for dx in 0..(zoom_level_tiles / 2) {
|
|
|
234
|
+ let v = add_tile_if_visible(TileCoord::new(uzoom, center_tile.x + dx, y), &mut tiles);
|
|
|
235
|
+ visible = visible || v;
|
|
|
236
|
+ if !v {
|
|
|
237
|
+ break;
|
|
|
238
|
+ }
|
|
|
239
|
+ }
|
|
|
240
|
+ for dx in 1..(1 + zoom_level_tiles / 2) {
|
|
|
241
|
+ let v = add_tile_if_visible(TileCoord::new(uzoom, center_tile.x - dx, y), &mut tiles);
|
|
|
242
|
+ visible = visible || v;
|
|
|
243
|
+ if !v {
|
|
|
244
|
+ break;
|
|
|
245
|
+ }
|
|
|
246
|
+ }
|
|
|
247
|
+
|
|
|
248
|
+ if !visible {
|
|
|
249
|
+ break;
|
|
189
|
250
|
}
|
|
190
|
251
|
}
|
|
191
|
252
|
}
|