This commit is contained in:
2025-11-25 18:18:03 +01:00
parent f5f5f10338
commit 410fc79056
6 changed files with 464 additions and 11 deletions

View File

@@ -59,6 +59,36 @@ pub async fn initialize_schema(session: &Session) -> Result<(), Box<dyn std::err
)
.await?;
session
.query(
"CREATE TABLE IF NOT EXISTS map_data.landuse (
zoom int,
tile_x int,
tile_y int,
id bigint,
tags map<text, text>,
points blob,
PRIMARY KEY ((zoom, tile_x, tile_y), id)
)",
&[],
)
.await?;
session
.query(
"CREATE TABLE IF NOT EXISTS map_data.water (
zoom int,
tile_x int,
tile_y int,
id bigint,
tags map<text, text>,
points blob,
PRIMARY KEY ((zoom, tile_x, tile_y), id)
)",
&[],
)
.await?;
println!("Schema initialized.");
Ok(())
}

View File

@@ -22,6 +22,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt::init();
println!("Connecting to ScyllaDB...");
println!("Starting backend with landuse support...");
let uri = std::env::var("SCYLLA_URI").unwrap_or_else(|_| "127.0.0.1:9042".to_string());
let session = SessionBuilder::new()
@@ -45,6 +46,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.route("/api/tiles/:z/:x/:y", get(get_tile))
.route("/api/tiles/:z/:x/:y/ways", get(get_tile_ways))
.route("/api/tiles/:z/:x/:y/buildings", get(get_tile_buildings))
.route("/api/tiles/:z/:x/:y/landuse", get(get_tile_landuse))
.route("/api/tiles/:z/:x/:y/water", get(get_tile_water))
.nest_service("/", ServeDir::new("static"))
.layer(CorsLayer::permissive())
.with_state(state);
@@ -144,3 +147,55 @@ async fn get_tile_buildings(
Json(buildings)
}
async fn get_tile_landuse(
Path((z, x, y)): Path<(i32, i32, i32)>,
State(state): State<Arc<AppState>>,
) -> Json<Vec<MapWay>> {
let query = "SELECT id, tags, points FROM map_data.landuse WHERE zoom = ? AND tile_x = ? AND tile_y = ?";
let rows = state.scylla_session.query(query, (z, x, y)).await.unwrap().rows.unwrap_or_default();
let mut landuse = Vec::new();
for row in rows {
let (id, tags, points_blob) = row.into_typed::<(i64, std::collections::HashMap<String, String>, Vec<u8>)>().unwrap();
let mut points = Vec::new();
for chunk in points_blob.chunks(16) {
if chunk.len() == 16 {
let lat = f64::from_be_bytes(chunk[0..8].try_into().unwrap());
let lon = f64::from_be_bytes(chunk[8..16].try_into().unwrap());
points.push(vec![lat, lon]);
}
}
landuse.push(MapWay { id, tags, points });
}
Json(landuse)
}
async fn get_tile_water(
Path((z, x, y)): Path<(i32, i32, i32)>,
State(state): State<Arc<AppState>>,
) -> Json<Vec<MapWay>> {
let query = "SELECT id, tags, points FROM map_data.water WHERE zoom = ? AND tile_x = ? AND tile_y = ?";
let rows = state.scylla_session.query(query, (z, x, y)).await.unwrap().rows.unwrap_or_default();
let mut water = Vec::new();
for row in rows {
let (id, tags, points_blob) = row.into_typed::<(i64, std::collections::HashMap<String, String>, Vec<u8>)>().unwrap();
let mut points = Vec::new();
for chunk in points_blob.chunks(16) {
if chunk.len() == 16 {
let lat = f64::from_be_bytes(chunk[0..8].try_into().unwrap());
let lon = f64::from_be_bytes(chunk[8..16].try_into().unwrap());
points.push(vec![lat, lon]);
}
}
water.push(MapWay { id, tags, points });
}
Json(water)
}