Refactor the server

This commit is contained in:
Andras Schmelczer 2026-01-31 20:25:54 +00:00
parent 3b9ad11d71
commit 01ec17ff04
15 changed files with 939 additions and 1226 deletions

View file

@ -1,7 +1,9 @@
mod consts;
mod data;
mod filter;
mod index;
mod routes;
mod state;
use std::path::PathBuf;
use std::sync::Arc;
@ -11,41 +13,55 @@ use axum::Router;
use tower_http::compression::CompressionLayer;
use tower_http::cors::{Any, CorsLayer};
use tower_http::services::ServeDir;
use tower_http::trace::TraceLayer;
use tracing::info;
use tracing_subscriber::EnvFilter;
use routes::AppState;
use state::AppState;
#[tokio::main]
async fn main() {
tracing_subscriber::fmt()
.with_env_filter(
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")),
)
.with_ansi(true)
.init();
let parquet_path = PathBuf::from(
std::env::args()
.nth(1)
.unwrap_or_else(|| "data_sources/processed/wide.parquet".to_string()),
);
if !parquet_path.exists() {
eprintln!("Error: {} not found.", parquet_path.display());
tracing::error!("Parquet file not found: {}", parquet_path.display());
std::process::exit(1);
}
// Load property data and build indices
info!("Loading property data from {}", parquet_path.display());
let property_data = data::PropertyData::load(&parquet_path);
info!(
rows = property_data.lat.len(),
features = property_data.num_features,
enums = property_data.enum_features.len(),
"Property data loaded"
);
info!("Building spatial grid index (0.01° cells)");
let grid = index::GridIndex::build(&property_data.lat, &property_data.lon, 0.01);
info!("Precomputing H3 cells for resolutions {}-{}", consts::H3_PRECOMPUTE_MIN, consts::H3_PRECOMPUTE_MAX);
let h3_cells = data::precompute_h3(&property_data.lat, &property_data.lon);
// Load POI data and build spatial index
// Derive POI path from the data parquet path (same directory)
let poi_path = parquet_path
.parent()
.and_then(|p| p.parent())
.map(|p| p.join("filtered_uk_pois.parquet"))
.unwrap_or_else(|| PathBuf::from("data_sources/filtered_uk_pois.parquet"));
let poi_path = PathBuf::from("/volumes/syncthing/Projects/property-map/data/filtered_uk_pois.parquet");
let poi_data = if poi_path.exists() {
data::POIData::load(&poi_path)
info!("Loading POI data from {}", poi_path.display());
let pd = data::POIData::load(&poi_path);
info!(pois = pd.lat.len(), "POI data loaded");
pd
} else {
eprintln!(
"Warning: {} not found. POI endpoints will be unavailable.",
poi_path.display()
);
tracing::warn!("POI file not found: {}. POI endpoints will be unavailable.", poi_path.display());
data::POIData {
id: Vec::new(),
name: Vec::new(),
@ -55,6 +71,8 @@ async fn main() {
emoji: Vec::new(),
}
};
info!("Building POI spatial grid index");
let poi_grid = index::GridIndex::build(&poi_data.lat, &poi_data.lng, 0.01);
let state = Arc::new(AppState {
@ -70,7 +88,6 @@ async fn main() {
.allow_methods(Any)
.allow_headers(Any);
// API routes
let state_features = state.clone();
let state_hexagons = state.clone();
let state_pois = state.clone();
@ -101,7 +118,6 @@ async fn main() {
}),
);
// Static file serving for frontend
let frontend_dist = PathBuf::from("frontend/dist");
let app = if frontend_dist.exists() {
api.fallback_service(ServeDir::new(frontend_dist))
@ -109,10 +125,13 @@ async fn main() {
api
};
let app = app.layer(cors).layer(CompressionLayer::new().gzip(true));
let app = app
.layer(cors)
.layer(CompressionLayer::new().gzip(true))
.layer(TraceLayer::new_for_http());
let addr = "0.0.0.0:8001";
eprintln!("Server listening on {}", addr);
info!("Server listening on {}", addr);
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
axum::serve(listener, app).await.unwrap();