update to zoom zone
This commit is contained in:
@@ -4,6 +4,49 @@ use scylla::{Session, SessionBuilder};
|
||||
use std::collections::HashMap;
|
||||
use tokio::task::JoinSet;
|
||||
|
||||
|
||||
const ZOOM_LEVELS: [u32; 4] = [6, 9, 12, 14];
|
||||
|
||||
fn should_include(tags: &HashMap<String, String>, zoom: u32) -> bool {
|
||||
if zoom >= 14 { return true; }
|
||||
|
||||
let highway = tags.get("highway").map(|s| s.as_str());
|
||||
let place = tags.get("place").map(|s| s.as_str());
|
||||
let natural = tags.get("natural").map(|s| s.as_str());
|
||||
let railway = tags.get("railway").map(|s| s.as_str());
|
||||
let waterway = tags.get("waterway").map(|s| s.as_str());
|
||||
|
||||
match zoom {
|
||||
6 => {
|
||||
matches!(highway, Some("motorway" | "trunk" | "primary" | "secondary")) ||
|
||||
matches!(place, Some("city")) ||
|
||||
matches!(natural, Some("water" | "wood" | "scrub" | "heath" | "wetland")) ||
|
||||
matches!(tags.get("landuse").map(|s| s.as_str()), Some("forest" | "meadow" | "grass" | "recreation_ground" | "farmland")) ||
|
||||
tags.contains_key("leisure") || // Parks, nature reserves, golf courses
|
||||
matches!(waterway, Some("river" | "riverbank"))
|
||||
},
|
||||
9 => {
|
||||
matches!(highway, Some("motorway" | "trunk" | "primary" | "secondary")) ||
|
||||
matches!(place, Some("city" | "town")) ||
|
||||
matches!(railway, Some("rail")) ||
|
||||
matches!(natural, Some("water" | "wood" | "scrub" | "heath" | "wetland")) ||
|
||||
tags.contains_key("landuse") ||
|
||||
tags.contains_key("leisure") ||
|
||||
matches!(waterway, Some("river" | "riverbank"))
|
||||
},
|
||||
12 => {
|
||||
matches!(highway, Some("motorway" | "trunk" | "primary" | "secondary" | "tertiary")) ||
|
||||
matches!(place, Some("city" | "town" | "village")) ||
|
||||
matches!(railway, Some("rail")) ||
|
||||
tags.contains_key("landuse") ||
|
||||
tags.contains_key("leisure") ||
|
||||
matches!(natural, Some("water" | "wood" | "scrub" | "wetland" | "heath")) ||
|
||||
matches!(waterway, Some("river" | "riverbank" | "stream"))
|
||||
},
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
// Connect to ScyllaDB
|
||||
@@ -46,8 +89,8 @@ async fn main() -> Result<()> {
|
||||
// Channel for backpressure
|
||||
// Producer (reader) -> Consumer (writer)
|
||||
enum DbTask {
|
||||
Node { id: i64, lat: f64, lon: f64, tags: HashMap<String, String>, x: i32, y: i32 },
|
||||
Way { table: &'static str, id: i64, tags: HashMap<String, String>, points: Vec<u8>, x: i32, y: i32 },
|
||||
Node { zoom: i32, id: i64, lat: f64, lon: f64, tags: HashMap<String, String>, x: i32, y: i32 },
|
||||
Way { zoom: i32, table: &'static str, id: i64, tags: HashMap<String, String>, points: Vec<u8>, x: i32, y: i32 },
|
||||
}
|
||||
|
||||
let (tx, mut rx) = tokio::sync::mpsc::channel::<DbTask>(10_000);
|
||||
@@ -72,20 +115,20 @@ async fn main() -> Result<()> {
|
||||
}
|
||||
|
||||
match task {
|
||||
DbTask::Node { id, lat, lon, tags, x, y } => {
|
||||
DbTask::Node { zoom, id, lat, lon, tags, x, y } => {
|
||||
join_set.spawn(async move {
|
||||
let _ = session.query(
|
||||
"INSERT INTO map_data.nodes (zoom, tile_x, tile_y, id, lat, lon, tags) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
||||
(10, x, y, id, lat, lon, tags),
|
||||
(zoom, x, y, id, lat, lon, tags),
|
||||
).await;
|
||||
});
|
||||
}
|
||||
DbTask::Way { table, id, tags, points, x, y } => {
|
||||
DbTask::Way { zoom, table, id, tags, points, x, y } => {
|
||||
let query = format!("INSERT INTO map_data.{} (zoom, tile_x, tile_y, id, tags, points) VALUES (?, ?, ?, ?, ?, ?)", table);
|
||||
join_set.spawn(async move {
|
||||
let _ = session.query(
|
||||
query,
|
||||
(10, x, y, id, tags, points),
|
||||
(zoom, x, y, id, tags, points),
|
||||
).await;
|
||||
});
|
||||
}
|
||||
@@ -123,10 +166,14 @@ async fn main() -> Result<()> {
|
||||
let lat = node.lat();
|
||||
let lon = node.lon();
|
||||
let tags: HashMap<String, String> = node.tags().map(|(k, v)| (k.to_string(), v.to_string())).collect();
|
||||
let (x, y) = lat_lon_to_tile(lat, lon, 10);
|
||||
|
||||
let task = DbTask::Node { id, lat, lon, tags, x, y };
|
||||
let _ = tx.blocking_send(task);
|
||||
|
||||
for &zoom in &ZOOM_LEVELS {
|
||||
if should_include(&tags, zoom) {
|
||||
let (x, y) = lat_lon_to_tile(lat, lon, zoom);
|
||||
let task = DbTask::Node { zoom: zoom as i32, id, lat, lon, tags: tags.clone(), x, y };
|
||||
let _ = tx.blocking_send(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Element::DenseNode(node) => {
|
||||
@@ -144,10 +191,14 @@ async fn main() -> Result<()> {
|
||||
let lat = node.lat();
|
||||
let lon = node.lon();
|
||||
let tags: HashMap<String, String> = node.tags().map(|(k, v)| (k.to_string(), v.to_string())).collect();
|
||||
let (x, y) = lat_lon_to_tile(lat, lon, 10);
|
||||
|
||||
let task = DbTask::Node { id, lat, lon, tags, x, y };
|
||||
let _ = tx.blocking_send(task);
|
||||
|
||||
for &zoom in &ZOOM_LEVELS {
|
||||
if should_include(&tags, zoom) {
|
||||
let (x, y) = lat_lon_to_tile(lat, lon, zoom);
|
||||
let task = DbTask::Node { zoom: zoom as i32, id, lat, lon, tags: tags.clone(), x, y };
|
||||
let _ = tx.blocking_send(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Element::Way(way) => {
|
||||
@@ -157,12 +208,12 @@ async fn main() -> Result<()> {
|
||||
// Filter for highways/roads OR buildings OR landuse OR water OR railways
|
||||
let is_highway = tags.contains_key("highway");
|
||||
let is_building = tags.contains_key("building");
|
||||
let is_water = tags.get("natural").map(|v| v == "water").unwrap_or(false) ||
|
||||
tags.get("waterway").map(|v| v == "riverbank").unwrap_or(false) ||
|
||||
tags.get("landuse").map(|v| v == "basin").unwrap_or(false);
|
||||
let is_landuse = tags.get("leisure").map(|v| v == "park" || v == "garden").unwrap_or(false) ||
|
||||
tags.get("landuse").map(|v| v == "grass" || v == "forest" || v == "meadow").unwrap_or(false) ||
|
||||
tags.get("natural").map(|v| v == "wood" || v == "scrub").unwrap_or(false);
|
||||
let is_water = tags.get("natural").map(|v| v == "water" || v == "wetland").unwrap_or(false) ||
|
||||
tags.get("waterway").map(|v| v == "riverbank" || v == "stream" || v == "river").unwrap_or(false) ||
|
||||
tags.get("landuse").map(|v| v == "basin" || v == "reservoir").unwrap_or(false);
|
||||
let is_landuse = tags.contains_key("leisure") ||
|
||||
tags.contains_key("landuse") ||
|
||||
tags.get("natural").map(|v| v == "wood" || v == "scrub" || v == "heath" || v == "wetland").unwrap_or(false);
|
||||
let is_railway = tags.contains_key("railway");
|
||||
|
||||
if is_highway || is_building || is_water || is_landuse || is_railway {
|
||||
@@ -183,7 +234,6 @@ async fn main() -> Result<()> {
|
||||
|
||||
// Insert into the tile of the first point
|
||||
let (first_lat, first_lon) = points[0];
|
||||
let (x, y) = lat_lon_to_tile(first_lat, first_lon, 10);
|
||||
|
||||
// Serialize points to blob (f64, f64) pairs
|
||||
let mut blob = Vec::with_capacity(points.len() * 16);
|
||||
@@ -192,29 +242,36 @@ async fn main() -> Result<()> {
|
||||
blob.extend_from_slice(&lon.to_be_bytes());
|
||||
}
|
||||
|
||||
if is_highway {
|
||||
let task = DbTask::Way { table: "ways", id, tags: tags.clone(), points: blob.clone(), x, y };
|
||||
let _ = tx.blocking_send(task);
|
||||
}
|
||||
for &zoom in &ZOOM_LEVELS {
|
||||
if !should_include(&tags, zoom) { continue; }
|
||||
|
||||
let (x, y) = lat_lon_to_tile(first_lat, first_lon, zoom);
|
||||
let zoom_i32 = zoom as i32;
|
||||
|
||||
if is_building {
|
||||
let task = DbTask::Way { table: "buildings", id, tags: tags.clone(), points: blob.clone(), x, y };
|
||||
let _ = tx.blocking_send(task);
|
||||
}
|
||||
if is_highway {
|
||||
let task = DbTask::Way { zoom: zoom_i32, table: "ways", id, tags: tags.clone(), points: blob.clone(), x, y };
|
||||
let _ = tx.blocking_send(task);
|
||||
}
|
||||
|
||||
if is_water {
|
||||
let task = DbTask::Way { table: "water", id, tags: tags.clone(), points: blob.clone(), x, y };
|
||||
let _ = tx.blocking_send(task);
|
||||
}
|
||||
if is_building {
|
||||
let task = DbTask::Way { zoom: zoom_i32, table: "buildings", id, tags: tags.clone(), points: blob.clone(), x, y };
|
||||
let _ = tx.blocking_send(task);
|
||||
}
|
||||
|
||||
if is_landuse {
|
||||
let task = DbTask::Way { table: "landuse", id, tags: tags.clone(), points: blob.clone(), x, y };
|
||||
let _ = tx.blocking_send(task);
|
||||
}
|
||||
if is_water {
|
||||
let task = DbTask::Way { zoom: zoom_i32, table: "water", id, tags: tags.clone(), points: blob.clone(), x, y };
|
||||
let _ = tx.blocking_send(task);
|
||||
}
|
||||
|
||||
if is_railway {
|
||||
let task = DbTask::Way { table: "railways", id, tags: tags.clone(), points: blob.clone(), x, y };
|
||||
let _ = tx.blocking_send(task);
|
||||
if is_landuse {
|
||||
let task = DbTask::Way { zoom: zoom_i32, table: "landuse", id, tags: tags.clone(), points: blob.clone(), x, y };
|
||||
let _ = tx.blocking_send(task);
|
||||
}
|
||||
|
||||
if is_railway {
|
||||
let task = DbTask::Way { zoom: zoom_i32, table: "railways", id, tags: tags.clone(), points: blob.clone(), x, y };
|
||||
let _ = tx.blocking_send(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user