mirror of
https://github.com/maplibre/martin.git
synced 2024-12-18 20:31:54 +03:00
Fix bbox to xyz roundtrip computation (#1059)
Add `tile-grid` as a dependency to use its webmercator tile math. --------- Co-authored-by: sharkAndshark <zhangyijunmetro@hotmail.com>
This commit is contained in:
parent
ce89a44a05
commit
886358e93f
83
Cargo.lock
generated
83
Cargo.lock
generated
@ -45,7 +45,7 @@ dependencies = [
|
||||
"actix-service",
|
||||
"actix-utils",
|
||||
"ahash",
|
||||
"base64",
|
||||
"base64 0.21.5",
|
||||
"bitflags 2.4.1",
|
||||
"brotli",
|
||||
"bytes",
|
||||
@ -429,6 +429,12 @@ dependencies = [
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.5"
|
||||
@ -582,8 +588,10 @@ checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
@ -1881,7 +1889,7 @@ dependencies = [
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_with",
|
||||
"serde_with 3.4.0",
|
||||
"serde_yaml",
|
||||
"spreet",
|
||||
"subst",
|
||||
@ -1896,6 +1904,7 @@ name = "martin-tile-utils"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"approx",
|
||||
"tile-grid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1916,7 +1925,7 @@ dependencies = [
|
||||
"rstest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_with",
|
||||
"serde_with 3.4.0",
|
||||
"serde_yaml",
|
||||
"size_format",
|
||||
"sqlite-hashes",
|
||||
@ -2412,7 +2421,7 @@ version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49b6c5ef183cd3ab4ba005f1ca64c21e8bd97ce4699cfea9e8d9a2c4958ca520"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"base64 0.21.5",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"fallible-iterator 0.2.0",
|
||||
@ -2883,7 +2892,7 @@ version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"base64 0.21.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3022,6 +3031,17 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_tuple"
|
||||
version = "0.5.0"
|
||||
@ -3055,23 +3075,51 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_with"
|
||||
version = "2.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe"
|
||||
dependencies = [
|
||||
"base64 0.13.1",
|
||||
"chrono",
|
||||
"hex",
|
||||
"indexmap 1.9.3",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_with_macros 2.3.3",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_with"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"base64 0.21.5",
|
||||
"chrono",
|
||||
"hex",
|
||||
"indexmap 1.9.3",
|
||||
"indexmap 2.1.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_with_macros",
|
||||
"serde_with_macros 3.4.0",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_with_macros"
|
||||
version = "2.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_with_macros"
|
||||
version = "3.4.0"
|
||||
@ -3373,7 +3421,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4"
|
||||
dependencies = [
|
||||
"atoi",
|
||||
"base64",
|
||||
"base64 0.21.5",
|
||||
"bitflags 2.4.1",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
@ -3415,7 +3463,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24"
|
||||
dependencies = [
|
||||
"atoi",
|
||||
"base64",
|
||||
"base64 0.21.5",
|
||||
"bitflags 2.4.1",
|
||||
"byteorder",
|
||||
"crc",
|
||||
@ -3617,6 +3665,21 @@ dependencies = [
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tile-grid"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b57cef548fda6f42e870ed9106b6c15af81f34e4b7f679d8620b3be21d02039"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"serde_with 2.3.3",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tilejson"
|
||||
version = "0.4.1"
|
||||
@ -3992,7 +4055,7 @@ version = "0.36.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c51daa774fe9ee5efcf7b4fec13019b8119cda764d9a8b5b06df02bb1445c656"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"base64 0.21.5",
|
||||
"log",
|
||||
"pico-args",
|
||||
"usvg-parser",
|
||||
|
@ -73,6 +73,7 @@ sqlite-hashes = { version = "0.5", default-features = false, features = ["md5",
|
||||
sqlx = { version = "0.7", features = ["sqlite", "runtime-tokio"] }
|
||||
subst = { version = "0.3", features = ["yaml"] }
|
||||
thiserror = "1"
|
||||
tile-grid = "0.5"
|
||||
tilejson = "0.4"
|
||||
tokio = { version = "1", features = ["macros"] }
|
||||
tokio-postgres-rustls = "0.10"
|
||||
|
@ -17,6 +17,7 @@ repository.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
tile-grid.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
approx.workspace = true
|
||||
|
@ -6,10 +6,18 @@
|
||||
use std::f64::consts::PI;
|
||||
use std::fmt::Display;
|
||||
|
||||
use tile_grid::{tms, Tms, Xyz};
|
||||
|
||||
pub const EARTH_CIRCUMFERENCE: f64 = 40_075_016.685_578_5;
|
||||
pub const EARTH_RADIUS: f64 = EARTH_CIRCUMFERENCE / 2.0 / PI;
|
||||
|
||||
pub const MAX_ZOOM: u8 = 30;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
fn web_merc() -> &'static Tms {
|
||||
static TMS: OnceLock<Tms> = OnceLock::new();
|
||||
TMS.get_or_init(|| tms().lookup("WebMercatorQuad").unwrap())
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum Format {
|
||||
@ -190,27 +198,22 @@ impl Display for TileInfo {
|
||||
#[must_use]
|
||||
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
|
||||
pub fn tile_index(lon: f64, lat: f64, zoom: u8) -> (u32, u32) {
|
||||
let n = f64::from(1_u32 << zoom);
|
||||
let x = ((lon + 180.0) / 360.0 * n).floor() as u32;
|
||||
let y = ((1.0 - (lat.to_radians().tan() + 1.0 / lat.to_radians().cos()).ln() / PI) / 2.0 * n)
|
||||
.floor() as u32;
|
||||
let max_value = (1_u32 << zoom) - 1;
|
||||
(x.min(max_value), y.min(max_value))
|
||||
assert!(zoom <= MAX_ZOOM, "zoom {zoom} must be <= {MAX_ZOOM}");
|
||||
let tile = web_merc().tile(lon, lat, zoom).unwrap();
|
||||
let max_value = (1_u64 << zoom) - 1;
|
||||
(tile.x.min(max_value) as u32, tile.y.min(max_value) as u32)
|
||||
}
|
||||
|
||||
/// Convert min/max XYZ tile coordinates to a bounding box values.
|
||||
/// The result is `[min_lng, min_lat, max_lng, max_lat]`
|
||||
#[must_use]
|
||||
pub fn xyz_to_bbox(zoom: u8, min_x: i32, min_y: i32, max_x: i32, max_y: i32) -> [f64; 4] {
|
||||
let tile_size = EARTH_CIRCUMFERENCE / f64::from(1_u32 << zoom);
|
||||
let (min_lng, min_lat) = webmercator_to_wgs84(
|
||||
-0.5 * EARTH_CIRCUMFERENCE + f64::from(min_x) * tile_size,
|
||||
-0.5 * EARTH_CIRCUMFERENCE + f64::from(min_y) * tile_size,
|
||||
);
|
||||
let (max_lng, max_lat) = webmercator_to_wgs84(
|
||||
-0.5 * EARTH_CIRCUMFERENCE + f64::from(max_x + 1) * tile_size,
|
||||
-0.5 * EARTH_CIRCUMFERENCE + f64::from(max_y + 1) * tile_size,
|
||||
);
|
||||
pub fn xyz_to_bbox(zoom: u8, min_x: u32, min_y: u32, max_x: u32, max_y: u32) -> [f64; 4] {
|
||||
assert!(zoom <= MAX_ZOOM, "zoom {zoom} must be <= {MAX_ZOOM}");
|
||||
let left_top_bounds = web_merc().xy_bounds(&Xyz::new(u64::from(min_x), u64::from(min_y), zoom));
|
||||
let right_bottom_bounds =
|
||||
web_merc().xy_bounds(&Xyz::new(u64::from(max_x), u64::from(max_y), zoom));
|
||||
let (min_lng, min_lat) = webmercator_to_wgs84(left_top_bounds.left, right_bottom_bounds.bottom);
|
||||
let (max_lng, max_lat) = webmercator_to_wgs84(right_bottom_bounds.right, left_top_bounds.top);
|
||||
|
||||
[min_lng, min_lat, max_lng, max_lat]
|
||||
}
|
||||
@ -228,6 +231,7 @@ pub fn bbox_to_xyz(left: f64, bottom: f64, right: f64, top: f64, zoom: u8) -> (u
|
||||
#[must_use]
|
||||
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
|
||||
pub fn get_zoom_precision(zoom: u8) -> usize {
|
||||
assert!(zoom < MAX_ZOOM, "zoom {zoom} must be <= {MAX_ZOOM}");
|
||||
let lng_delta = webmercator_to_wgs84(EARTH_CIRCUMFERENCE / f64::from(1_u32 << zoom), 0.0).0;
|
||||
let log = lng_delta.log10() - 0.5;
|
||||
if log > 0.0 {
|
||||
@ -246,6 +250,8 @@ pub fn webmercator_to_wgs84(x: f64, y: f64) -> (f64, f64) {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#![allow(clippy::unreadable_literal)]
|
||||
|
||||
use std::fs::read;
|
||||
|
||||
use approx::assert_relative_eq;
|
||||
@ -293,7 +299,59 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::unreadable_literal)]
|
||||
fn test_xyz_to_bbox() {
|
||||
// you could easily get test cases from maptiler: https://www.maptiler.com/google-maps-coordinates-tile-bounds-projection/#4/-118.82/71.02
|
||||
let bbox = xyz_to_bbox(0, 0, 0, 0, 0);
|
||||
assert_relative_eq!(bbox[0], -179.99999999999955, epsilon = f64::EPSILON * 2.0);
|
||||
assert_relative_eq!(bbox[1], -85.0511287798066, epsilon = f64::EPSILON * 2.0);
|
||||
assert_relative_eq!(bbox[2], 179.99999999999986, epsilon = f64::EPSILON * 2.0);
|
||||
assert_relative_eq!(bbox[3], 85.05112877980655, epsilon = f64::EPSILON * 2.0);
|
||||
|
||||
let xyz = bbox_to_xyz(bbox[0], bbox[1], bbox[2], bbox[3], 0);
|
||||
assert_eq!(xyz, (0, 0, 0, 0));
|
||||
|
||||
let bbox = xyz_to_bbox(1, 0, 0, 0, 0);
|
||||
assert_relative_eq!(bbox[0], -179.99999999999955, epsilon = f64::EPSILON * 2.0);
|
||||
assert_relative_eq!(bbox[1], 2.007891127734306e-13, epsilon = f64::EPSILON * 2.0);
|
||||
assert_relative_eq!(
|
||||
bbox[2],
|
||||
-2.007891127734306e-13,
|
||||
epsilon = f64::EPSILON * 2.0
|
||||
);
|
||||
assert_relative_eq!(bbox[3], 85.05112877980655, epsilon = f64::EPSILON * 2.0);
|
||||
|
||||
let xyz = bbox_to_xyz(bbox[0], bbox[1], bbox[2], bbox[3], 1);
|
||||
assert!(xyz.0 == 0 || xyz.0 == 1);
|
||||
assert!(xyz.1 == 0);
|
||||
assert!(xyz.2 == 0 || xyz.2 == 1);
|
||||
assert!(xyz.3 == 0 || xyz.3 == 1);
|
||||
|
||||
let bbox = xyz_to_bbox(5, 1, 1, 2, 2);
|
||||
assert_relative_eq!(bbox[0], -168.74999999999955, epsilon = f64::EPSILON * 2.0);
|
||||
assert_relative_eq!(bbox[1], 81.09321385260832, epsilon = f64::EPSILON * 2.0);
|
||||
assert_relative_eq!(bbox[2], -146.2499999999996, epsilon = f64::EPSILON * 2.0);
|
||||
assert_relative_eq!(bbox[3], 83.979259498862, epsilon = f64::EPSILON * 2.0);
|
||||
|
||||
let xyz = bbox_to_xyz(bbox[0], bbox[1], bbox[2], bbox[3], 5);
|
||||
assert!(xyz.0 == 1 || xyz.0 == 2);
|
||||
assert!(xyz.1 == 0 || xyz.1 == 1);
|
||||
assert!(xyz.2 == 2 || xyz.2 == 3);
|
||||
assert!(xyz.3 == 2 || xyz.3 == 3);
|
||||
|
||||
let bbox = xyz_to_bbox(5, 1, 3, 2, 5);
|
||||
assert_relative_eq!(bbox[0], -168.74999999999955, epsilon = f64::EPSILON * 2.0);
|
||||
assert_relative_eq!(bbox[1], 74.01954331150218, epsilon = f64::EPSILON * 2.0);
|
||||
assert_relative_eq!(bbox[2], -146.2499999999996, epsilon = f64::EPSILON * 2.0);
|
||||
assert_relative_eq!(bbox[3], 81.09321385260832, epsilon = f64::EPSILON * 2.0);
|
||||
|
||||
let xyz = bbox_to_xyz(bbox[0], bbox[1], bbox[2], bbox[3], 5);
|
||||
assert!(xyz.0 == 1 || xyz.0 == 2);
|
||||
assert!(xyz.1 == 2 || xyz.1 == 3);
|
||||
assert!(xyz.2 == 2 || xyz.2 == 3);
|
||||
assert!(xyz.3 == 5 || xyz.3 == 6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn meter_to_lng_lat() {
|
||||
let (lng, lat) = webmercator_to_wgs84(-20037508.34, -20037508.34);
|
||||
assert_relative_eq!(lng, -179.9999999749437, epsilon = f64::EPSILON * 2.0);
|
||||
|
@ -14,7 +14,7 @@ use size_format::SizeFormatterBinary;
|
||||
use sqlx::{query, SqliteExecutor};
|
||||
use tilejson::Bounds;
|
||||
|
||||
use crate::{MbtResult, MbtType, Mbtiles};
|
||||
use crate::{invert_y_value, MbtResult, MbtType, Mbtiles};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize)]
|
||||
pub struct ZoomInfo {
|
||||
@ -154,10 +154,10 @@ impl Mbtiles {
|
||||
avg_tile_size: r.average.unwrap_or(0.0),
|
||||
bbox: xyz_to_bbox(
|
||||
zoom,
|
||||
r.min_tile_x.unwrap(),
|
||||
r.min_tile_y.unwrap(),
|
||||
r.max_tile_x.unwrap(),
|
||||
r.max_tile_y.unwrap(),
|
||||
r.min_tile_x.unwrap() as u32,
|
||||
invert_y_value(zoom, r.max_tile_y.unwrap() as u32),
|
||||
r.max_tile_x.unwrap() as u32,
|
||||
invert_y_value(zoom, r.min_tile_y.unwrap() as u32),
|
||||
)
|
||||
.into(),
|
||||
}
|
||||
@ -239,10 +239,10 @@ mod tests {
|
||||
max_tile_size: 1107
|
||||
avg_tile_size: 96.2295918367347
|
||||
bbox:
|
||||
- -180
|
||||
- -85.0511287798066
|
||||
- 180
|
||||
- 85.0511287798066
|
||||
- -179.99999999999955
|
||||
- -85.05112877980659
|
||||
- 180.00000000000028
|
||||
- 85.05112877980655
|
||||
min_zoom: 0
|
||||
max_zoom: 6
|
||||
zoom_info:
|
||||
@ -252,70 +252,70 @@ mod tests {
|
||||
max_tile_size: 1107
|
||||
avg_tile_size: 1107
|
||||
bbox:
|
||||
- -180
|
||||
- -85.0511287798066
|
||||
- 180
|
||||
- 85.0511287798066
|
||||
- -179.99999999999955
|
||||
- -85.05112877980659
|
||||
- 179.99999999999986
|
||||
- 85.05112877980655
|
||||
- zoom: 1
|
||||
tile_count: 4
|
||||
min_tile_size: 160
|
||||
max_tile_size: 650
|
||||
avg_tile_size: 366.5
|
||||
bbox:
|
||||
- -180
|
||||
- -85.0511287798066
|
||||
- 180
|
||||
- 85.0511287798066
|
||||
- -179.99999999999955
|
||||
- -85.05112877980652
|
||||
- 179.99999999999915
|
||||
- 85.05112877980655
|
||||
- zoom: 2
|
||||
tile_count: 7
|
||||
min_tile_size: 137
|
||||
max_tile_size: 495
|
||||
avg_tile_size: 239.57142857142858
|
||||
bbox:
|
||||
- -180
|
||||
- -66.51326044311186
|
||||
- 180
|
||||
- 66.51326044311186
|
||||
- -179.99999999999955
|
||||
- -66.51326044311165
|
||||
- 179.99999999999915
|
||||
- 66.51326044311182
|
||||
- zoom: 3
|
||||
tile_count: 17
|
||||
min_tile_size: 67
|
||||
max_tile_size: 246
|
||||
avg_tile_size: 134
|
||||
bbox:
|
||||
- -135
|
||||
- -40.97989806962013
|
||||
- 180
|
||||
- 66.51326044311186
|
||||
- -134.99999999999957
|
||||
- -40.979898069620376
|
||||
- 180.00000000000028
|
||||
- 66.51326044311169
|
||||
- zoom: 4
|
||||
tile_count: 38
|
||||
min_tile_size: 64
|
||||
max_tile_size: 175
|
||||
avg_tile_size: 86
|
||||
bbox:
|
||||
- -135
|
||||
- -40.97989806962013
|
||||
- 180
|
||||
- 66.51326044311186
|
||||
- -134.99999999999963
|
||||
- -40.979898069620106
|
||||
- 179.99999999999966
|
||||
- 66.51326044311175
|
||||
- zoom: 5
|
||||
tile_count: 57
|
||||
min_tile_size: 64
|
||||
max_tile_size: 107
|
||||
avg_tile_size: 72.7719298245614
|
||||
bbox:
|
||||
- -123.75000000000001
|
||||
- -40.97989806962013
|
||||
- 180
|
||||
- 61.60639637138628
|
||||
- -123.74999999999966
|
||||
- -40.979898069620106
|
||||
- 179.99999999999966
|
||||
- 61.606396371386154
|
||||
- zoom: 6
|
||||
tile_count: 72
|
||||
min_tile_size: 64
|
||||
max_tile_size: 97
|
||||
avg_tile_size: 68.29166666666667
|
||||
bbox:
|
||||
- -123.75000000000001
|
||||
- -40.97989806962013
|
||||
- 180
|
||||
- 61.60639637138628
|
||||
- -123.74999999999957
|
||||
- -40.979898069620305
|
||||
- 180.00000000000009
|
||||
- 61.606396371386104
|
||||
"###);
|
||||
|
||||
Ok(())
|
||||
|
@ -7,7 +7,7 @@ Page size: 512B
|
||||
1 | 4 | 474B | 983B | 609B | -180,-85,180,85
|
||||
2 | 5 | 150B | 865B | 451B | -90,-67,180,67
|
||||
3 | 8 | 57B | 839B | 264B | -45,-41,180,67
|
||||
4 | 13 | 57B | 751B | 216B | -23,-22,158,56
|
||||
4 | 13 | 57B | 751B | 216B | -22,-22,157,56
|
||||
5 | 27 | 57B | 666B | 167B | -11,-11,146,49
|
||||
6 | 69 | 57B | 636B | 127B | -6,-6,146,45
|
||||
all | 127 | 57B | 983B | 187B | -180,-85,180,85
|
||||
|
@ -4,10 +4,10 @@ Page size: 512B
|
||||
|
||||
Zoom | Count | Smallest | Largest | Average | Bounding Box
|
||||
0 | 1 | 643B | 643B | 643B | -180,-85,180,85
|
||||
1 | 2 | 150B | 172B | 161B | -180,-85,0,85
|
||||
1 | 2 | 150B | 172B | 161B | -180,-85,-0,85
|
||||
2 | 4 | 291B | 690B | 414B | -90,-67,90,67
|
||||
3 | 7 | 75B | 727B | 263B | -45,-41,90,67
|
||||
4 | 13 | 75B | 684B | 225B | -23,-22,158,56
|
||||
4 | 13 | 75B | 684B | 225B | -22,-22,157,56
|
||||
5 | 27 | 75B | 659B | 195B | -11,-11,146,49
|
||||
6 | 69 | 75B | 633B | 155B | -6,-6,146,45
|
||||
all | 123 | 75B | 727B | 190B | -180,-85,180,85
|
||||
|
Loading…
Reference in New Issue
Block a user