update
This commit is contained in:
3
.env
3
.env
@@ -16,4 +16,5 @@ CLIENT_PORT=8080
|
|||||||
|
|
||||||
SERVICE_LOG_LEVEL=debug
|
SERVICE_LOG_LEVEL=debug
|
||||||
|
|
||||||
OSM_PBF_PATH=europe-latest.osm.pbf
|
HOST_PBF_PATH=./oberbayern-251125.osm.pbf
|
||||||
|
HOST_CACHE_DIR=./cache
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -4,4 +4,5 @@ scylla_data/
|
|||||||
pkg/
|
pkg/
|
||||||
node_modules/
|
node_modules/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.pbf
|
*.pbf
|
||||||
|
docker-compose-remote.yml
|
||||||
7
Cargo.lock
generated
7
Cargo.lock
generated
@@ -576,6 +576,12 @@ dependencies = [
|
|||||||
"libloading 0.8.9",
|
"libloading 0.8.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dotenv"
|
||||||
|
version = "0.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "earcutr"
|
name = "earcutr"
|
||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
@@ -1292,6 +1298,7 @@ name = "importer"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"dotenv",
|
||||||
"memmap2 0.9.9",
|
"memmap2 0.9.9",
|
||||||
"osmpbf",
|
"osmpbf",
|
||||||
"scylla",
|
"scylla",
|
||||||
|
|||||||
@@ -4,10 +4,6 @@ services:
|
|||||||
scylla:
|
scylla:
|
||||||
image: scylladb/scylla:latest
|
image: scylladb/scylla:latest
|
||||||
container_name: scylla
|
container_name: scylla
|
||||||
ports:
|
|
||||||
- "9042:9042"
|
|
||||||
- "9160:9160"
|
|
||||||
- "10000:10000"
|
|
||||||
command: --smp 1 --memory 2G --overprovisioned 1 --api-address 0.0.0.0 --max-memory-for-unlimited-query-soft-limit 1073741824 --tombstone-warn-threshold 10000000
|
command: --smp 1 --memory 2G --overprovisioned 1 --api-address 0.0.0.0 --max-memory-for-unlimited-query-soft-limit 1073741824 --tombstone-warn-threshold 10000000
|
||||||
volumes:
|
volumes:
|
||||||
- scylla_data:/var/lib/scylla
|
- scylla_data:/var/lib/scylla
|
||||||
@@ -29,8 +25,8 @@ services:
|
|||||||
target: importer
|
target: importer
|
||||||
container_name: map-importer
|
container_name: map-importer
|
||||||
volumes:
|
volumes:
|
||||||
- ./oberbayern-251125.osm.pbf:/app/data.osm.pbf
|
- ${HOST_PBF_PATH:-./europe-latest.osm.pbf}:/app/data.osm.pbf
|
||||||
- importer_cache:/cache
|
- ${HOST_CACHE_DIR:-./cache}:/cache
|
||||||
environment:
|
environment:
|
||||||
- SCYLLA_URI=scylla:9042
|
- SCYLLA_URI=scylla:9042
|
||||||
- OSM_PBF_PATH=/app/data.osm.pbf
|
- OSM_PBF_PATH=/app/data.osm.pbf
|
||||||
@@ -42,4 +38,3 @@ services:
|
|||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
scylla_data:
|
scylla_data:
|
||||||
importer_cache:
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ web-sys = { version = "0.3", features = [
|
|||||||
"RequestInit",
|
"RequestInit",
|
||||||
"RequestMode",
|
"RequestMode",
|
||||||
"Response",
|
"Response",
|
||||||
|
"HtmlInputElement",
|
||||||
] }
|
] }
|
||||||
wgpu = { version = "0.19", default-features = false, features = ["webgl", "wgsl"] }
|
wgpu = { version = "0.19", default-features = false, features = ["webgl", "wgsl"] }
|
||||||
winit = { version = "0.29", default-features = false, features = ["rwh_06"] }
|
winit = { version = "0.29", default-features = false, features = ["rwh_06"] }
|
||||||
|
|||||||
@@ -363,24 +363,70 @@ pub async fn run() {
|
|||||||
user_location: None,
|
user_location: None,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// Zoom constants
|
||||||
|
const MIN_ZOOM: f32 = 20.0;
|
||||||
|
const MAX_ZOOM: f32 = 50000.0;
|
||||||
|
|
||||||
|
// Helper to convert slider (0-100) to zoom (logarithmic)
|
||||||
|
let slider_to_zoom = |val: f64| -> f32 {
|
||||||
|
let t = val / 100.0;
|
||||||
|
let log_min = MIN_ZOOM.ln();
|
||||||
|
let log_max = MAX_ZOOM.ln();
|
||||||
|
let log_zoom = log_min + (log_max - log_min) * t as f32;
|
||||||
|
log_zoom.exp()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper to convert zoom to slider (0-100)
|
||||||
|
let zoom_to_slider = |zoom: f32| -> f64 {
|
||||||
|
let log_min = MIN_ZOOM.ln();
|
||||||
|
let log_max = MAX_ZOOM.ln();
|
||||||
|
let log_zoom = zoom.ln();
|
||||||
|
let t = (log_zoom - log_min) / (log_max - log_min);
|
||||||
|
(t * 100.0) as f64
|
||||||
|
};
|
||||||
|
|
||||||
let window_doc = web_sys::window().unwrap().document().unwrap();
|
let window_doc = web_sys::window().unwrap().document().unwrap();
|
||||||
|
|
||||||
|
// Slider
|
||||||
|
let camera_clone = camera.clone();
|
||||||
|
let window_clone = window.clone();
|
||||||
|
let slider = window_doc.get_element_by_id("zoom-slider")
|
||||||
|
.and_then(|e| e.dyn_into::<web_sys::HtmlInputElement>().ok());
|
||||||
|
|
||||||
|
if let Some(slider) = slider {
|
||||||
|
let closure = wasm_bindgen::closure::Closure::<dyn FnMut(web_sys::Event)>::new(move |event: web_sys::Event| {
|
||||||
|
let target = event.target().unwrap();
|
||||||
|
let input = target.dyn_into::<web_sys::HtmlInputElement>().unwrap();
|
||||||
|
let val = input.value().parse::<f64>().unwrap_or(50.0);
|
||||||
|
|
||||||
|
let new_zoom = slider_to_zoom(val);
|
||||||
|
let mut cam = camera_clone.lock().unwrap();
|
||||||
|
cam.zoom = new_zoom;
|
||||||
|
window_clone.request_redraw();
|
||||||
|
});
|
||||||
|
slider.add_event_listener_with_callback("input", closure.as_ref().unchecked_ref()).unwrap();
|
||||||
|
closure.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zoom In Button
|
||||||
let camera_clone = camera.clone();
|
let camera_clone = camera.clone();
|
||||||
let window_clone = window.clone();
|
let window_clone = window.clone();
|
||||||
|
|
||||||
let btn_zoom_in = window_doc.get_element_by_id("btn-zoom-in")
|
let btn_zoom_in = window_doc.get_element_by_id("btn-zoom-in")
|
||||||
.and_then(|e| e.dyn_into::<web_sys::HtmlButtonElement>().ok());
|
.and_then(|e| e.dyn_into::<web_sys::HtmlButtonElement>().ok());
|
||||||
|
|
||||||
if let Some(btn) = btn_zoom_in {
|
if let Some(btn) = btn_zoom_in {
|
||||||
let closure = wasm_bindgen::closure::Closure::<dyn FnMut()>::new(move || {
|
let closure = wasm_bindgen::closure::Closure::<dyn FnMut()>::new(move || {
|
||||||
let mut cam = camera_clone.lock().unwrap();
|
let mut cam = camera_clone.lock().unwrap();
|
||||||
cam.zoom *= 1.5;
|
let current_slider = zoom_to_slider(cam.zoom);
|
||||||
cam.zoom = cam.zoom.max(20.0).min(50000.0);
|
let new_slider = (current_slider + 5.0).min(100.0); // +5% step
|
||||||
|
cam.zoom = slider_to_zoom(new_slider);
|
||||||
window_clone.request_redraw();
|
window_clone.request_redraw();
|
||||||
});
|
});
|
||||||
btn.set_onclick(Some(closure.as_ref().unchecked_ref()));
|
btn.set_onclick(Some(closure.as_ref().unchecked_ref()));
|
||||||
closure.forget();
|
closure.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Zoom Out Button
|
||||||
let camera_clone = camera.clone();
|
let camera_clone = camera.clone();
|
||||||
let window_clone = window.clone();
|
let window_clone = window.clone();
|
||||||
let btn_zoom_out = window_doc.get_element_by_id("btn-zoom-out")
|
let btn_zoom_out = window_doc.get_element_by_id("btn-zoom-out")
|
||||||
@@ -389,8 +435,9 @@ pub async fn run() {
|
|||||||
if let Some(btn) = btn_zoom_out {
|
if let Some(btn) = btn_zoom_out {
|
||||||
let closure = wasm_bindgen::closure::Closure::<dyn FnMut()>::new(move || {
|
let closure = wasm_bindgen::closure::Closure::<dyn FnMut()>::new(move || {
|
||||||
let mut cam = camera_clone.lock().unwrap();
|
let mut cam = camera_clone.lock().unwrap();
|
||||||
cam.zoom /= 1.5;
|
let current_slider = zoom_to_slider(cam.zoom);
|
||||||
cam.zoom = cam.zoom.max(20.0).min(50000.0);
|
let new_slider = (current_slider - 5.0).max(0.0); // -5% step
|
||||||
|
cam.zoom = slider_to_zoom(new_slider);
|
||||||
window_clone.request_redraw();
|
window_clone.request_redraw();
|
||||||
});
|
});
|
||||||
btn.set_onclick(Some(closure.as_ref().unchecked_ref()));
|
btn.set_onclick(Some(closure.as_ref().unchecked_ref()));
|
||||||
@@ -538,6 +585,23 @@ pub async fn run() {
|
|||||||
if let Some(el) = window_doc.get_element_by_id("debug-zoom") {
|
if let Some(el) = window_doc.get_element_by_id("debug-zoom") {
|
||||||
el.set_inner_html(&format!("{:.1}", cam.zoom));
|
el.set_inner_html(&format!("{:.1}", cam.zoom));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sync slider
|
||||||
|
if let Some(slider) = window_doc.get_element_by_id("zoom-slider").and_then(|e| e.dyn_into::<web_sys::HtmlInputElement>().ok()) {
|
||||||
|
let min_zoom: f32 = 20.0;
|
||||||
|
let max_zoom: f32 = 50000.0;
|
||||||
|
let log_min = min_zoom.ln();
|
||||||
|
let log_max = max_zoom.ln();
|
||||||
|
let log_zoom = cam.zoom.ln();
|
||||||
|
let t = (log_zoom - log_min) / (log_max - log_min);
|
||||||
|
let val = (t * 100.0) as f64;
|
||||||
|
|
||||||
|
// Only update if not dragging (optional, but good for UX? actually input event handles drag)
|
||||||
|
// But if we update while dragging it might fight.
|
||||||
|
// However, for scroll wheel we need this.
|
||||||
|
// Let's just update it. The browser handles the active state.
|
||||||
|
slider.set_value(&val.to_string());
|
||||||
|
}
|
||||||
if let Some(el) = window_doc.get_element_by_id("debug-pos") {
|
if let Some(el) = window_doc.get_element_by_id("debug-pos") {
|
||||||
el.set_inner_html(&format!("{:.4}, {:.4}", cam.y, cam.x)); // Lat, Lon approx
|
el.set_inner_html(&format!("{:.4}, {:.4}", cam.y, cam.x)); // Lat, Lon approx
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,3 +9,4 @@ scylla = "0.12"
|
|||||||
tokio = { version = "1.0", features = ["full"] }
|
tokio = { version = "1.0", features = ["full"] }
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
memmap2 = "0.9"
|
memmap2 = "0.9"
|
||||||
|
dotenv = "0.15"
|
||||||
|
|||||||
@@ -124,6 +124,9 @@ fn should_include(tags: &HashMap<String, String>, zoom: u32) -> bool {
|
|||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
|
// Load .env file if present
|
||||||
|
dotenv::dotenv().ok();
|
||||||
|
|
||||||
// Connect to ScyllaDB
|
// Connect to ScyllaDB
|
||||||
let uri = std::env::var("SCYLLA_URI").unwrap_or_else(|_| "127.0.0.1:9042".to_string());
|
let uri = std::env::var("SCYLLA_URI").unwrap_or_else(|_| "127.0.0.1:9042".to_string());
|
||||||
println!("Connecting to ScyllaDB at {}...", uri);
|
println!("Connecting to ScyllaDB at {}...", uri);
|
||||||
@@ -160,7 +163,9 @@ async fn main() -> Result<()> {
|
|||||||
let insert_railways = session.prepare("INSERT INTO map_data.railways (zoom, tile_x, tile_y, id, tags, points) VALUES (?, ?, ?, ?, ?, ?)").await?;
|
let insert_railways = session.prepare("INSERT INTO map_data.railways (zoom, tile_x, tile_y, id, tags, points) VALUES (?, ?, ?, ?, ?, ?)").await?;
|
||||||
println!("Statements prepared.");
|
println!("Statements prepared.");
|
||||||
|
|
||||||
let path = std::env::var("OSM_PBF_PATH").unwrap_or_else(|_| "europe-latest.osm.pbf".to_string());
|
let path = std::env::var("OSM_PBF_PATH")
|
||||||
|
.or_else(|_| std::env::var("HOST_PBF_PATH"))
|
||||||
|
.unwrap_or_else(|_| "europe-latest.osm.pbf".to_string());
|
||||||
println!("Reading {}...", path);
|
println!("Reading {}...", path);
|
||||||
let reader = ElementReader::from_path(path)?;
|
let reader = ElementReader::from_path(path)?;
|
||||||
|
|
||||||
|
|||||||
10
run.sh
10
run.sh
@@ -1 +1,9 @@
|
|||||||
docker compose --profile import up --build importer
|
#!/bin/bash
|
||||||
|
# Load .env variables
|
||||||
|
if [ -f .env ]; then
|
||||||
|
export $(cat .env | grep -v '#' | awk '/=/ {print $1}')
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Using PBF file: ${HOST_PBF_PATH:-./europe-latest.osm.pbf}"
|
||||||
|
docker compose --profile import up --build importer
|
||||||
|
docker compose build --no-cache
|
||||||
Reference in New Issue
Block a user