Skip to content

Commit

Permalink
Continue with u32 for simplicity, may revisit
Browse files Browse the repository at this point in the history
  • Loading branch information
nyurik committed Dec 15, 2023
1 parent 0525085 commit bda8e7d
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 40 deletions.
83 changes: 73 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +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.2"
tile-grid = "0.5"
tilejson = "0.4"
tokio = { version = "1", features = ["macros"] }
tokio-postgres-rustls = "0.10"
Expand Down
1 change: 1 addition & 0 deletions martin-tile-utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ rust-version.workspace = true

[dependencies]
tile-grid.workspace = true

[dev-dependencies]
approx.workspace = true
33 changes: 16 additions & 17 deletions martin-tile-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

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;
Expand All @@ -13,7 +14,7 @@ pub const EARTH_RADIUS: f64 = EARTH_CIRCUMFERENCE / 2.0 / PI;
pub const MAX_ZOOM: u8 = 30;
use std::sync::OnceLock;

fn gridset() -> &'static Tms {
fn web_merc() -> &'static Tms {
static TMS: OnceLock<Tms> = OnceLock::new();
TMS.get_or_init(|| tms().lookup("WebMercatorQuad").unwrap())
}
Expand Down Expand Up @@ -196,24 +197,21 @@ impl Display for TileInfo {
/// Convert longitude and latitude to a tile (x,y) coordinates for a given zoom
#[must_use]
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
pub fn tile_index(lon: f64, lat: f64, zoom: u8) -> (u64, u64) {
let tile = gridset().tile(lon, lat, zoom).unwrap();
pub fn tile_index(lon: f64, lat: f64, zoom: u8) -> (u32, u32) {
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), tile.y.min(max_value))
(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_tile_col: u64,
min_tile_row: u64,
max_tile_col: u64,
max_tile_row: u64,
) -> [f64; 4] {
let left_top_bounds = gridset().xy_bounds(&Xyz::new(min_tile_col, min_tile_row, zoom));
let right_bottom_bounds = gridset().xy_bounds(&Xyz::new(max_tile_col, max_tile_row, zoom));
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);

Expand All @@ -223,16 +221,17 @@ pub fn xyz_to_bbox(
/// Convert bounding box to a tile box `(min_x, min_y, max_x, max_y)` for a given zoom
#[must_use]
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
pub fn bbox_to_xyz(left: f64, bottom: f64, right: f64, top: f64, zoom: u8) -> (u64, u64, u64, u64) {
let (min_tile_x, min_tile_y) = tile_index(left, top, zoom);
let (max_tile_x, max_tile_y) = tile_index(right, bottom, zoom);
(min_tile_x, min_tile_y, max_tile_x, max_tile_y)
pub fn bbox_to_xyz(left: f64, bottom: f64, right: f64, top: f64, zoom: u8) -> (u32, u32, u32, u32) {
let (min_x, min_y) = tile_index(left, top, zoom);
let (max_x, max_y) = tile_index(right, bottom, zoom);
(min_x, min_y, max_x, max_y)
}

/// Compute precision of a zoom level, i.e. how many decimal digits of the longitude and latitude are relevant
#[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 {
Expand Down
9 changes: 1 addition & 8 deletions martin/src/bin/martin-cp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ async fn start(copy_args: CopierArgs) -> MartinCpResult<()> {
run_tile_copy(copy_args.copy, sources).await
}

#[allow(clippy::cast_possible_truncation)]
fn compute_tile_ranges(args: &CopyArgs) -> Vec<TileRect> {
let mut ranges = Vec::new();
let mut zooms_vec = Vec::new();
Expand All @@ -173,13 +172,7 @@ fn compute_tile_ranges(args: &CopyArgs) -> Vec<TileRect> {
bbox_to_xyz(bbox.left, bbox.bottom, bbox.right, bbox.top, *zoom);
append_rect(
&mut ranges,
TileRect::new(
*zoom,
min_x as u32,
min_y as u32,
max_x as u32,
max_y as u32,
),
TileRect::new(*zoom, min_x, min_y, max_x, max_y),
);
}
}
Expand Down
8 changes: 4 additions & 4 deletions mbtiles/src/summary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() as u64,
u64::from(invert_y_value(zoom, r.max_tile_y.unwrap() as u32)),
r.max_tile_x.unwrap() as u64,
u64::from(invert_y_value(zoom, r.min_tile_y.unwrap() as u32)),
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(),
}
Expand Down

0 comments on commit bda8e7d

Please sign in to comment.