mirror of
https://github.com/maplibre/maplibre-rs.git
synced 2025-12-08 19:05:57 +00:00
Struct for zoom level (#118)
* add struct for zoom level * fix linter errors * fix build errors * fixed for PR comments * Simplify stencil_reference_value, the z does not need to be taken into account Co-authored-by: Maximilian Ammann <max@maxammann.org>
This commit is contained in:
parent
e59dacdb45
commit
05dbdac924
@ -1,4 +1,4 @@
|
|||||||
use crate::coords::{Zoom, TILE_SIZE};
|
use crate::coords::{Zoom, ZoomLevel, TILE_SIZE};
|
||||||
use crate::io::shared_thread_state::SharedThreadState;
|
use crate::io::shared_thread_state::SharedThreadState;
|
||||||
use crate::io::tile_cache::TileCache;
|
use crate::io::tile_cache::TileCache;
|
||||||
use crate::io::TessellateMessage;
|
use crate::io::TessellateMessage;
|
||||||
@ -43,7 +43,7 @@ impl ViewState {
|
|||||||
self.camera.calc_view_proj(&self.perspective)
|
self.camera.calc_view_proj(&self.perspective)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn visible_level(&self) -> u8 {
|
pub fn visible_level(&self) -> ZoomLevel {
|
||||||
self.zoom.level()
|
self.zoom.level()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -33,12 +33,12 @@ const fn create_zoom_bounds<const DIM: usize>() -> [u32; DIM] {
|
|||||||
///
|
///
|
||||||
/// TODO: We can optimize the quadkey and store the keys on 2 bits instead of 8
|
/// TODO: We can optimize the quadkey and store the keys on 2 bits instead of 8
|
||||||
#[derive(Ord, PartialOrd, Eq, PartialEq, Clone, Copy)]
|
#[derive(Ord, PartialOrd, Eq, PartialEq, Clone, Copy)]
|
||||||
pub struct Quadkey([u8; MAX_ZOOM]);
|
pub struct Quadkey([ZoomLevel; MAX_ZOOM]);
|
||||||
|
|
||||||
impl Quadkey {
|
impl Quadkey {
|
||||||
pub fn new(quad_encoded: &[u8]) -> Self {
|
pub fn new(quad_encoded: &[ZoomLevel]) -> Self {
|
||||||
let mut key = [0u8; MAX_ZOOM];
|
let mut key = [ZoomLevel::default(); MAX_ZOOM];
|
||||||
key[0] = quad_encoded.len() as u8;
|
key[0] = (quad_encoded.len() as u8).into();
|
||||||
for (i, part) in quad_encoded.iter().enumerate() {
|
for (i, part) in quad_encoded.iter().enumerate() {
|
||||||
key[i + 1] = *part;
|
key[i + 1] = *part;
|
||||||
}
|
}
|
||||||
@ -48,7 +48,9 @@ impl Quadkey {
|
|||||||
|
|
||||||
impl fmt::Debug for Quadkey {
|
impl fmt::Debug for Quadkey {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let len = self.0[0] as usize;
|
let key = self.0;
|
||||||
|
let ZoomLevel(level) = key[0];
|
||||||
|
let len = level as usize;
|
||||||
for part in &self.0[0..len] {
|
for part in &self.0[0..len] {
|
||||||
write!(f, "{:?}", part)?;
|
write!(f, "{:?}", part)?;
|
||||||
}
|
}
|
||||||
@ -56,6 +58,57 @@ impl fmt::Debug for Quadkey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Ord, PartialOrd, Eq, PartialEq, Hash, Copy, Clone, Debug)]
|
||||||
|
pub struct ZoomLevel(u8);
|
||||||
|
|
||||||
|
impl ZoomLevel {
|
||||||
|
pub fn is_root(self) -> bool {
|
||||||
|
return self.0 == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ZoomLevel {
|
||||||
|
fn default() -> Self {
|
||||||
|
ZoomLevel(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::Add<u8> for ZoomLevel {
|
||||||
|
type Output = ZoomLevel;
|
||||||
|
|
||||||
|
fn add(self, rhs: u8) -> Self::Output {
|
||||||
|
let zoom_level = self.0.checked_add(rhs).unwrap();
|
||||||
|
ZoomLevel(zoom_level)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::Sub<u8> for ZoomLevel {
|
||||||
|
type Output = ZoomLevel;
|
||||||
|
|
||||||
|
fn sub(self, rhs: u8) -> Self::Output {
|
||||||
|
let zoom_level = self.0.checked_sub(rhs).unwrap();
|
||||||
|
ZoomLevel(zoom_level)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ZoomLevel {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "{}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u8> for ZoomLevel {
|
||||||
|
fn from(zoom_level: u8) -> Self {
|
||||||
|
ZoomLevel(zoom_level)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<u8> for ZoomLevel {
|
||||||
|
fn into(self) -> u8 {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// `Zoom` is an exponential scale that defines the zoom of the camera on the map.
|
/// `Zoom` is an exponential scale that defines the zoom of the camera on the map.
|
||||||
/// We can derive the `ZoomLevel` from `Zoom` by using the `[crate::coords::ZOOM_BOUNDS]`.
|
/// We can derive the `ZoomLevel` from `Zoom` by using the `[crate::coords::ZOOM_BOUNDS]`.
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
@ -67,6 +120,12 @@ impl Zoom {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Zoom {
|
||||||
|
pub fn from(zoom_level: ZoomLevel) -> Self {
|
||||||
|
Zoom(zoom_level.0 as f64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for Zoom {
|
impl Default for Zoom {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Zoom(0.0)
|
Zoom(0.0)
|
||||||
@ -97,19 +156,19 @@ impl std::ops::Sub for Zoom {
|
|||||||
|
|
||||||
impl Zoom {
|
impl Zoom {
|
||||||
pub fn scale_to_tile(&self, coords: &WorldTileCoords) -> f64 {
|
pub fn scale_to_tile(&self, coords: &WorldTileCoords) -> f64 {
|
||||||
2.0_f64.powf(coords.z as f64 - self.0)
|
2.0_f64.powf(coords.z.0 as f64 - self.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scale_to_zoom_level(&self, z: u8) -> f64 {
|
pub fn scale_to_zoom_level(&self, z: ZoomLevel) -> f64 {
|
||||||
2.0_f64.powf(z as f64 - self.0)
|
2.0_f64.powf(z.0 as f64 - self.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scale_delta(&self, zoom: &Zoom) -> f64 {
|
pub fn scale_delta(&self, zoom: &Zoom) -> f64 {
|
||||||
2.0_f64.powf(zoom.0 - self.0)
|
2.0_f64.powf(zoom.0 - self.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn level(&self) -> u8 {
|
pub fn level(&self) -> ZoomLevel {
|
||||||
self.0.floor() as u8
|
ZoomLevel::from(self.0.floor() as u8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +203,7 @@ pub struct InnerCoords {
|
|||||||
pub struct TileCoords {
|
pub struct TileCoords {
|
||||||
pub x: u32,
|
pub x: u32,
|
||||||
pub y: u32,
|
pub y: u32,
|
||||||
pub z: u8,
|
pub z: ZoomLevel,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TileCoords {
|
impl TileCoords {
|
||||||
@ -158,7 +217,7 @@ impl TileCoords {
|
|||||||
pub fn into_world_tile(self, scheme: TileAddressingScheme) -> Option<WorldTileCoords> {
|
pub fn into_world_tile(self, scheme: TileAddressingScheme) -> Option<WorldTileCoords> {
|
||||||
// FIXME: MAX_ZOOM is 32, which means max bound is 2^32, which wouldn't fit in u32 or i32
|
// FIXME: MAX_ZOOM is 32, which means max bound is 2^32, which wouldn't fit in u32 or i32
|
||||||
// Note that unlike WorldTileCoords, values are signed (no idea why)
|
// Note that unlike WorldTileCoords, values are signed (no idea why)
|
||||||
let bounds = ZOOM_BOUNDS[self.z as usize] as i32;
|
let bounds = ZOOM_BOUNDS[self.z.0 as usize] as i32;
|
||||||
let x = self.x as i32;
|
let x = self.x as i32;
|
||||||
let y = self.y as i32;
|
let y = self.y as i32;
|
||||||
|
|
||||||
@ -182,7 +241,7 @@ impl From<(u32, u32, u8)> for TileCoords {
|
|||||||
TileCoords {
|
TileCoords {
|
||||||
x: tuple.0,
|
x: tuple.0,
|
||||||
y: tuple.1,
|
y: tuple.1,
|
||||||
z: tuple.2,
|
z: ZoomLevel::from(tuple.2),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -198,7 +257,7 @@ impl From<(u32, u32, u8)> for TileCoords {
|
|||||||
pub struct WorldTileCoords {
|
pub struct WorldTileCoords {
|
||||||
pub x: i32,
|
pub x: i32,
|
||||||
pub y: i32,
|
pub y: i32,
|
||||||
pub z: u8,
|
pub z: ZoomLevel,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorldTileCoords {
|
impl WorldTileCoords {
|
||||||
@ -211,7 +270,7 @@ impl WorldTileCoords {
|
|||||||
/// `x=5,y=5` at zoom level `z=0`.
|
/// `x=5,y=5` at zoom level `z=0`.
|
||||||
pub fn into_tile(self, scheme: TileAddressingScheme) -> Option<TileCoords> {
|
pub fn into_tile(self, scheme: TileAddressingScheme) -> Option<TileCoords> {
|
||||||
// FIXME: MAX_ZOOM is 32, which means max bound is 2^32, which wouldn't fit in u32 or i32
|
// FIXME: MAX_ZOOM is 32, which means max bound is 2^32, which wouldn't fit in u32 or i32
|
||||||
let bounds = ZOOM_BOUNDS[self.z as usize];
|
let bounds = ZOOM_BOUNDS[self.z.0 as usize];
|
||||||
let x = self.x as u32;
|
let x = self.x as u32;
|
||||||
let y = self.y as u32;
|
let y = self.y as u32;
|
||||||
|
|
||||||
@ -239,7 +298,7 @@ impl WorldTileCoords {
|
|||||||
If tile.z > zoom:
|
If tile.z > zoom:
|
||||||
=> scale < 512
|
=> scale < 512
|
||||||
*/
|
*/
|
||||||
let tile_scale = TILE_SIZE * Zoom::new(self.z as f64).scale_delta(&zoom);
|
let tile_scale = TILE_SIZE * Zoom::from(self.z).scale_delta(&zoom);
|
||||||
|
|
||||||
let translate = Matrix4::from_translation(Vector3::new(
|
let translate = Matrix4::from_translation(Vector3::new(
|
||||||
self.x as f64 * tile_scale,
|
self.x as f64 * tile_scale,
|
||||||
@ -264,7 +323,7 @@ impl WorldTileCoords {
|
|||||||
|
|
||||||
/// Adopted from [tilebelt](https://github.com/mapbox/tilebelt)
|
/// Adopted from [tilebelt](https://github.com/mapbox/tilebelt)
|
||||||
pub fn build_quad_key(&self) -> Option<Quadkey> {
|
pub fn build_quad_key(&self) -> Option<Quadkey> {
|
||||||
let bounds = ZOOM_BOUNDS[self.z as usize];
|
let bounds = ZOOM_BOUNDS[self.z.0 as usize];
|
||||||
let x = self.x as u32;
|
let x = self.x as u32;
|
||||||
let y = self.y as u32;
|
let y = self.y as u32;
|
||||||
|
|
||||||
@ -272,11 +331,11 @@ impl WorldTileCoords {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut key = [0u8; MAX_ZOOM];
|
let mut key = [ZoomLevel::default(); MAX_ZOOM];
|
||||||
|
|
||||||
key[0] = self.z;
|
key[0] = self.z;
|
||||||
|
|
||||||
for z in 1..self.z + 1 {
|
for z in 1..self.z.0 + 1 {
|
||||||
let mut b = 0;
|
let mut b = 0;
|
||||||
let mask: i32 = 1 << (z - 1);
|
let mask: i32 = 1 << (z - 1);
|
||||||
if (self.x & mask) != 0 {
|
if (self.x & mask) != 0 {
|
||||||
@ -285,7 +344,7 @@ impl WorldTileCoords {
|
|||||||
if (self.y & mask) != 0 {
|
if (self.y & mask) != 0 {
|
||||||
b += 2u8;
|
b += 2u8;
|
||||||
}
|
}
|
||||||
key[z as usize] = b;
|
key[z as usize] = ZoomLevel::from(b);
|
||||||
}
|
}
|
||||||
Some(Quadkey(key))
|
Some(Quadkey(key))
|
||||||
}
|
}
|
||||||
@ -318,7 +377,7 @@ impl WorldTileCoords {
|
|||||||
|
|
||||||
/// Get the tile which is one zoom level lower and contains this one
|
/// Get the tile which is one zoom level lower and contains this one
|
||||||
pub fn get_parent(&self) -> Option<WorldTileCoords> {
|
pub fn get_parent(&self) -> Option<WorldTileCoords> {
|
||||||
if self.z == 0 {
|
if self.z.is_root() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,8 +389,8 @@ impl WorldTileCoords {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<(i32, i32, u8)> for WorldTileCoords {
|
impl From<(i32, i32, ZoomLevel)> for WorldTileCoords {
|
||||||
fn from(tuple: (i32, i32, u8)) -> Self {
|
fn from(tuple: (i32, i32, ZoomLevel)) -> Self {
|
||||||
WorldTileCoords {
|
WorldTileCoords {
|
||||||
x: tuple.0,
|
x: tuple.0,
|
||||||
y: tuple.1,
|
y: tuple.1,
|
||||||
@ -402,7 +461,7 @@ impl WorldCoords {
|
|||||||
Self { x, y }
|
Self { x, y }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_world_tile(self, z: u8, zoom: Zoom) -> WorldTileCoords {
|
pub fn into_world_tile(self, z: ZoomLevel, zoom: Zoom) -> WorldTileCoords {
|
||||||
let tile_scale = zoom.scale_to_zoom_level(z) / TILE_SIZE; // TODO: Deduplicate
|
let tile_scale = zoom.scale_to_zoom_level(z) / TILE_SIZE; // TODO: Deduplicate
|
||||||
let x = self.x * tile_scale;
|
let x = self.x * tile_scale;
|
||||||
let y = self.y * tile_scale;
|
let y = self.y * tile_scale;
|
||||||
@ -447,12 +506,12 @@ impl From<Point3<f64>> for WorldCoords {
|
|||||||
pub struct ViewRegion {
|
pub struct ViewRegion {
|
||||||
min_tile: WorldTileCoords,
|
min_tile: WorldTileCoords,
|
||||||
max_tile: WorldTileCoords,
|
max_tile: WorldTileCoords,
|
||||||
z: u8,
|
z: ZoomLevel,
|
||||||
padding: i32,
|
padding: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ViewRegion {
|
impl ViewRegion {
|
||||||
pub fn new(view_region: Aabb2<f64>, padding: i32, zoom: Zoom, z: u8) -> Self {
|
pub fn new(view_region: Aabb2<f64>, padding: i32, zoom: Zoom, z: ZoomLevel) -> Self {
|
||||||
let min_world: WorldCoords = WorldCoords::at_ground(view_region.min.x, view_region.min.y);
|
let min_world: WorldCoords = WorldCoords::at_ground(view_region.min.x, view_region.min.y);
|
||||||
let min_world_tile: WorldTileCoords = min_world.into_world_tile(z, zoom);
|
let min_world_tile: WorldTileCoords = min_world.into_world_tile(z, zoom);
|
||||||
let max_world: WorldCoords = WorldCoords::at_ground(view_region.max.x, view_region.max.y);
|
let max_world: WorldCoords = WorldCoords::at_ground(view_region.max.x, view_region.max.y);
|
||||||
@ -466,7 +525,7 @@ impl ViewRegion {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn zoom_level(&self) -> u8 {
|
pub fn zoom_level(&self) -> ZoomLevel {
|
||||||
self.z
|
self.z
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,7 +540,7 @@ impl ViewRegion {
|
|||||||
pub fn iter(&self) -> impl Iterator<Item = WorldTileCoords> + '_ {
|
pub fn iter(&self) -> impl Iterator<Item = WorldTileCoords> + '_ {
|
||||||
(self.min_tile.x - self.padding..self.max_tile.x + 1 + self.padding).flat_map(move |x| {
|
(self.min_tile.x - self.padding..self.max_tile.x + 1 + self.padding).flat_map(move |x| {
|
||||||
(self.min_tile.y - self.padding..self.max_tile.y + 1 + self.padding).map(move |y| {
|
(self.min_tile.y - self.padding..self.max_tile.y + 1 + self.padding).map(move |y| {
|
||||||
let tile_coord: WorldTileCoords = (x, y, self.z as u8).into();
|
let tile_coord: WorldTileCoords = (x, y, self.z).into();
|
||||||
tile_coord
|
tile_coord
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -489,7 +548,7 @@ impl ViewRegion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for TileCoords {
|
impl fmt::Display for TileCoords {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"T(x={x},y={y},z={z})",
|
"T(x={x},y={y},z={z})",
|
||||||
@ -524,14 +583,14 @@ mod tests {
|
|||||||
use crate::style::source::TileAddressingScheme;
|
use crate::style::source::TileAddressingScheme;
|
||||||
|
|
||||||
use crate::coords::{
|
use crate::coords::{
|
||||||
Quadkey, TileCoords, ViewRegion, WorldCoords, WorldTileCoords, Zoom, EXTENT,
|
Quadkey, TileCoords, ViewRegion, WorldCoords, WorldTileCoords, Zoom, ZoomLevel, EXTENT,
|
||||||
};
|
};
|
||||||
use crate::util::math::Aabb2;
|
use crate::util::math::Aabb2;
|
||||||
|
|
||||||
const TOP_LEFT: Vector4<f64> = Vector4::new(0.0, 0.0, 0.0, 1.0);
|
const TOP_LEFT: Vector4<f64> = Vector4::new(0.0, 0.0, 0.0, 1.0);
|
||||||
const BOTTOM_RIGHT: Vector4<f64> = Vector4::new(EXTENT, EXTENT, 0.0, 1.0);
|
const BOTTOM_RIGHT: Vector4<f64> = Vector4::new(EXTENT, EXTENT, 0.0, 1.0);
|
||||||
|
|
||||||
fn to_from_world(tile: (i32, i32, u8), zoom: Zoom) {
|
fn to_from_world(tile: (i32, i32, ZoomLevel), zoom: Zoom) {
|
||||||
let tile = WorldTileCoords::from(tile);
|
let tile = WorldTileCoords::from(tile);
|
||||||
let p1 = tile.transform_for_zoom(zoom) * TOP_LEFT;
|
let p1 = tile.transform_for_zoom(zoom) * TOP_LEFT;
|
||||||
let p2 = tile.transform_for_zoom(zoom) * BOTTOM_RIGHT;
|
let p2 = tile.transform_for_zoom(zoom) * BOTTOM_RIGHT;
|
||||||
@ -545,40 +604,56 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn world_coords_tests() {
|
fn world_coords_tests() {
|
||||||
to_from_world((1, 0, 1), Zoom::new(1.0));
|
to_from_world((1, 0, ZoomLevel::from(1)), Zoom::new(1.0));
|
||||||
to_from_world((67, 42, 7), Zoom::new(7.0));
|
to_from_world((67, 42, ZoomLevel::from(7)), Zoom::new(7.0));
|
||||||
to_from_world((17421, 11360, 15), Zoom::new(15.0));
|
to_from_world((17421, 11360, ZoomLevel::from(15)), Zoom::new(15.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_quad_key() {
|
fn test_quad_key() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
TileCoords { x: 0, y: 0, z: 1 }
|
TileCoords {
|
||||||
.into_world_tile(TileAddressingScheme::TMS)
|
x: 0,
|
||||||
.unwrap()
|
y: 0,
|
||||||
.build_quad_key(),
|
z: ZoomLevel::from(1)
|
||||||
Some(Quadkey::new(&[2]))
|
}
|
||||||
|
.into_world_tile(TileAddressingScheme::TMS)
|
||||||
|
.unwrap()
|
||||||
|
.build_quad_key(),
|
||||||
|
Some(Quadkey::new(&[ZoomLevel::from(2)]))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
TileCoords { x: 0, y: 1, z: 1 }
|
TileCoords {
|
||||||
.into_world_tile(TileAddressingScheme::TMS)
|
x: 0,
|
||||||
.unwrap()
|
y: 1,
|
||||||
.build_quad_key(),
|
z: ZoomLevel::from(1)
|
||||||
Some(Quadkey::new(&[0]))
|
}
|
||||||
|
.into_world_tile(TileAddressingScheme::TMS)
|
||||||
|
.unwrap()
|
||||||
|
.build_quad_key(),
|
||||||
|
Some(Quadkey::new(&[ZoomLevel::from(0)]))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
TileCoords { x: 1, y: 1, z: 1 }
|
TileCoords {
|
||||||
.into_world_tile(TileAddressingScheme::TMS)
|
x: 1,
|
||||||
.unwrap()
|
y: 1,
|
||||||
.build_quad_key(),
|
z: ZoomLevel::from(1)
|
||||||
Some(Quadkey::new(&[1]))
|
}
|
||||||
|
.into_world_tile(TileAddressingScheme::TMS)
|
||||||
|
.unwrap()
|
||||||
|
.build_quad_key(),
|
||||||
|
Some(Quadkey::new(&[ZoomLevel::from(1)]))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
TileCoords { x: 1, y: 0, z: 1 }
|
TileCoords {
|
||||||
.into_world_tile(TileAddressingScheme::TMS)
|
x: 1,
|
||||||
.unwrap()
|
y: 0,
|
||||||
.build_quad_key(),
|
z: ZoomLevel::from(1)
|
||||||
Some(Quadkey::new(&[3]))
|
}
|
||||||
|
.into_world_tile(TileAddressingScheme::TMS)
|
||||||
|
.unwrap()
|
||||||
|
.build_quad_key(),
|
||||||
|
Some(Quadkey::new(&[ZoomLevel::from(3)]))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,7 +663,7 @@ mod tests {
|
|||||||
Aabb2::new(Point2::new(0.0, 0.0), Point2::new(2000.0, 2000.0)),
|
Aabb2::new(Point2::new(0.0, 0.0), Point2::new(2000.0, 2000.0)),
|
||||||
1,
|
1,
|
||||||
Zoom::default(),
|
Zoom::default(),
|
||||||
0,
|
ZoomLevel::default(),
|
||||||
)
|
)
|
||||||
.iter()
|
.iter()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -11,7 +11,9 @@ use geozero::geo_types::GeoWriter;
|
|||||||
use geozero::{ColumnValue, FeatureProcessor, GeomProcessor, PropertyProcessor};
|
use geozero::{ColumnValue, FeatureProcessor, GeomProcessor, PropertyProcessor};
|
||||||
use rstar::{Envelope, PointDistance, RTree, RTreeObject, AABB};
|
use rstar::{Envelope, PointDistance, RTree, RTreeObject, AABB};
|
||||||
|
|
||||||
use crate::coords::{InnerCoords, Quadkey, WorldCoords, WorldTileCoords, Zoom, EXTENT, TILE_SIZE};
|
use crate::coords::{
|
||||||
|
InnerCoords, Quadkey, WorldCoords, WorldTileCoords, Zoom, ZoomLevel, EXTENT, TILE_SIZE,
|
||||||
|
};
|
||||||
use crate::util::math::bounds_from_points;
|
use crate::util::math::bounds_from_points;
|
||||||
|
|
||||||
/// A quad tree storing the currently loaded tiles.
|
/// A quad tree storing the currently loaded tiles.
|
||||||
@ -35,7 +37,7 @@ impl GeometryIndex {
|
|||||||
pub fn query_point(
|
pub fn query_point(
|
||||||
&self,
|
&self,
|
||||||
world_coords: &WorldCoords,
|
world_coords: &WorldCoords,
|
||||||
z: u8,
|
z: ZoomLevel,
|
||||||
zoom: Zoom,
|
zoom: Zoom,
|
||||||
) -> Option<Vec<&IndexedGeometry<f64>>> {
|
) -> Option<Vec<&IndexedGeometry<f64>>> {
|
||||||
let world_tile_coords = world_coords.into_world_tile(z, zoom);
|
let world_tile_coords = world_coords.into_world_tile(z, zoom);
|
||||||
@ -44,7 +46,7 @@ impl GeometryIndex {
|
|||||||
.build_quad_key()
|
.build_quad_key()
|
||||||
.and_then(|key| self.index.get(&key))
|
.and_then(|key| self.index.get(&key))
|
||||||
{
|
{
|
||||||
let scale = zoom.scale_delta(&Zoom::new(z as f64)); // FIXME: can be wrong, if tiles of different z are visible
|
let scale = zoom.scale_delta(&Zoom::from(z)); // FIXME: can be wrong, if tiles of different z are visible
|
||||||
|
|
||||||
let delta_x = world_coords.x / TILE_SIZE * scale - world_tile_coords.x as f64;
|
let delta_x = world_coords.x / TILE_SIZE * scale - world_tile_coords.x as f64;
|
||||||
let delta_y = world_coords.y / TILE_SIZE * scale - world_tile_coords.y as f64;
|
let delta_y = world_coords.y / TILE_SIZE * scale - world_tile_coords.y as f64;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
//! Shared thread state.
|
//! Shared thread state.
|
||||||
|
|
||||||
use crate::coords::{WorldCoords, WorldTileCoords, Zoom};
|
use crate::coords::{WorldCoords, WorldTileCoords, Zoom, ZoomLevel};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::io::geometry_index::{GeometryIndex, IndexProcessor, IndexedGeometry, TileIndex};
|
use crate::io::geometry_index::{GeometryIndex, IndexProcessor, IndexedGeometry, TileIndex};
|
||||||
use crate::io::tile_request_state::TileRequestState;
|
use crate::io::tile_request_state::TileRequestState;
|
||||||
@ -150,7 +150,7 @@ impl SharedThreadState {
|
|||||||
pub fn query_point(
|
pub fn query_point(
|
||||||
&self,
|
&self,
|
||||||
world_coords: &WorldCoords,
|
world_coords: &WorldCoords,
|
||||||
z: u8,
|
z: ZoomLevel,
|
||||||
zoom: Zoom,
|
zoom: Zoom,
|
||||||
) -> Option<Vec<IndexedGeometry<f64>>> {
|
) -> Option<Vec<IndexedGeometry<f64>>> {
|
||||||
if let Ok(geometry_index) = self.geometry_index.lock() {
|
if let Ok(geometry_index) = self.geometry_index.lock() {
|
||||||
|
|||||||
@ -167,13 +167,12 @@ impl<Q: Queue<B>, B> TileViewPattern<Q, B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn stencil_reference_value(&self, world_coords: &WorldTileCoords) -> u8 {
|
pub fn stencil_reference_value(&self, world_coords: &WorldTileCoords) -> u8 {
|
||||||
world_coords.z * 5
|
match (world_coords.x, world_coords.y) {
|
||||||
+ match (world_coords.x, world_coords.y) {
|
(x, y) if x % 2 == 0 && y % 2 == 0 => 2,
|
||||||
(x, y) if x % 2 == 0 && y % 2 == 0 => 2,
|
(x, y) if x % 2 == 0 && y % 2 != 0 => 1,
|
||||||
(x, y) if x % 2 == 0 && y % 2 != 0 => 1,
|
(x, y) if x % 2 != 0 && y % 2 == 0 => 4,
|
||||||
(x, y) if x % 2 != 0 && y % 2 == 0 => 4,
|
(x, y) if x % 2 != 0 && y % 2 != 0 => 3,
|
||||||
(x, y) if x % 2 != 0 && y % 2 != 0 => 3,
|
_ => unreachable!(),
|
||||||
_ => unreachable!(),
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user