Refactor and improve

This commit is contained in:
Andras Schmelczer 2026-02-03 20:26:57 +00:00
parent 1f148b2185
commit 242acff987
22 changed files with 754 additions and 1053 deletions

View file

@ -1,13 +1,11 @@
mod consts;
mod data;
mod features;
mod filter;
mod grid_index;
mod og_middleware;
pub mod parsing;
mod routes;
mod state;
#[cfg(test)]
mod tests;
pub mod utils;
use std::path::PathBuf;
use std::sync::Arc;
@ -21,7 +19,7 @@ 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::{info, warn};
use tracing_subscriber::EnvFilter;
use state::AppState;
@ -78,12 +76,12 @@ async fn main() -> anyhow::Result<()> {
info!(
rows = property_data.lat.len(),
features = property_data.num_features,
enums = property_data.enum_features.len(),
enums = property_data.enum_values.len(),
"Property data loaded"
);
info!("Building spatial grid index (0.01° cells)");
let grid = grid_index::GridIndex::build(
let grid = utils::GridIndex::build(
&property_data.lat,
&property_data.lon,
consts::GRID_CELL_SIZE,
@ -107,7 +105,7 @@ async fn main() -> anyhow::Result<()> {
info!("Building POI spatial grid index");
let poi_grid =
grid_index::GridIndex::build(&poi_data.lat, &poi_data.lng, consts::GRID_CELL_SIZE);
utils::GridIndex::build(&poi_data.lat, &poi_data.lng, consts::GRID_CELL_SIZE);
let min_keys: Vec<String> = property_data
.feature_names
@ -119,64 +117,8 @@ async fn main() -> anyhow::Result<()> {
.iter()
.map(|name| format!("max_{}", name))
.collect();
let enum_min_keys: Vec<String> = property_data
.enum_features
.iter()
.map(|enum_feature| format!("min_{}", enum_feature.name))
.collect();
let enum_max_keys: Vec<String> = property_data
.enum_features
.iter()
.map(|enum_feature| format!("max_{}", enum_feature.name))
.collect();
// Precompute POI category groups
let poi_category_groups = {
let mut group_cats: std::collections::HashMap<String, std::collections::HashSet<String>> =
std::collections::HashMap::new();
let num_pois = poi_data.category.indices.len();
for row in 0..num_pois {
let category = poi_data.category.get(row).to_string();
let group = poi_data.group.get(row).to_string();
group_cats.entry(group).or_default().insert(category);
}
// Validate that data groups match the hardcoded order exactly
let expected: std::collections::HashSet<&str> =
consts::POI_GROUP_ORDER.iter().copied().collect();
let actual: std::collections::HashSet<&str> =
group_cats.keys().map(|key| key.as_str()).collect();
let missing_from_data: Vec<&&str> = expected.difference(&actual).collect();
let missing_from_order: Vec<&&str> = actual.difference(&expected).collect();
if !missing_from_data.is_empty() || !missing_from_order.is_empty() {
bail!(
"POI group mismatch!\n In POI_GROUP_ORDER but not in data: {:?}\n In data but not in POI_GROUP_ORDER: {:?}",
missing_from_data, missing_from_order
);
}
consts::POI_GROUP_ORDER
.iter()
.map(|group_name| group_name.to_string())
.collect::<Vec<_>>()
.into_iter()
.map(|name| {
let mut categories: Vec<String> = group_cats
.remove(&name)
.context("POI group validated but missing from map")?
.into_iter()
.collect();
categories.sort();
Ok(state::POICategoryGroup { name, categories })
})
.collect::<anyhow::Result<Vec<_>>>()?
};
// Precompute enum name → index map
let enum_name_to_idx: rustc_hash::FxHashMap<String, usize> = property_data
.enum_features
.iter()
.enumerate()
.map(|(index, enum_feature)| (enum_feature.name.clone(), index))
.collect();
let poi_category_groups = poi_data.category_groups()?;
// Read index.html at startup for crawler OG injection
let frontend_dist = cli.dist.unwrap_or_else(|| {
@ -200,7 +142,7 @@ async fn main() -> anyhow::Result<()> {
Some(html)
}
Err(err) => {
tracing::warn!("Could not read index.html: {}", err);
warn!("Could not read index.html: {}", err);
None
}
}
@ -217,6 +159,12 @@ async fn main() -> anyhow::Result<()> {
);
}
let features_response = routes::build_features_response(&property_data);
info!(
groups = features_response.groups.len(),
"Precomputed features response"
);
let state = Arc::new(AppState {
data: property_data,
grid,
@ -225,10 +173,8 @@ async fn main() -> anyhow::Result<()> {
poi_grid,
min_keys,
max_keys,
enum_min_keys,
enum_max_keys,
poi_category_groups,
enum_name_to_idx,
features_response,
og_sidecar_url: cli.og_sidecar_url,
public_url: cli.public_url,
index_html,