Refactor and improve
This commit is contained in:
parent
1f148b2185
commit
242acff987
22 changed files with 754 additions and 1053 deletions
|
|
@ -9,15 +9,12 @@ use serde::{Deserialize, Serialize};
|
|||
use tracing::{info, warn};
|
||||
|
||||
use crate::consts::{
|
||||
DEFAULT_PROPERTIES_LIMIT, ENUM_NULL, H3_PRECOMPUTE_MAX, H3_REQUEST_MAX, H3_REQUEST_MIN,
|
||||
DEFAULT_PROPERTIES_LIMIT, H3_PRECOMPUTE_MAX, H3_REQUEST_MAX, H3_REQUEST_MIN,
|
||||
MAX_PROPERTIES_LIMIT,
|
||||
};
|
||||
use crate::data::EnumFeatureData;
|
||||
use crate::filter::{parse_filters, row_passes_filters};
|
||||
use crate::parsing::{h3_cell_bounds, parse_filters, row_passes_filters};
|
||||
use crate::state::AppState;
|
||||
|
||||
use super::parse::h3_cell_bounds;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct HexagonPropertiesParams {
|
||||
pub h3: String,
|
||||
|
|
@ -66,21 +63,25 @@ fn non_empty_string(text: &str) -> Option<String> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Look up an enum feature value by trying multiple possible column names.
|
||||
/// Uses the unified feature model: enum values stored as f32 indices in feature_data.
|
||||
fn lookup_enum_value(
|
||||
enum_features: &[EnumFeatureData],
|
||||
enum_data: &[u8],
|
||||
num_enums: usize,
|
||||
enum_idx: &FxHashMap<String, usize>,
|
||||
feature_names: &[String],
|
||||
feature_data: &[f32],
|
||||
num_features: usize,
|
||||
enum_values: &FxHashMap<usize, Vec<String>>,
|
||||
row: usize,
|
||||
names: &[&str],
|
||||
) -> Option<String> {
|
||||
for name in names {
|
||||
if let Some(&feature_index) = enum_idx.get(*name) {
|
||||
let enum_feature = &enum_features[feature_index];
|
||||
let data_index = enum_data[row * num_enums + feature_index];
|
||||
if data_index != ENUM_NULL {
|
||||
if let Some(value) = enum_feature.values.get(data_index as usize) {
|
||||
return Some(value.clone());
|
||||
if let Some(feat_idx) = feature_names.iter().position(|feat_name| feat_name == *name) {
|
||||
if let Some(values) = enum_values.get(&feat_idx) {
|
||||
let value = feature_data[row * num_features + feat_idx];
|
||||
if value.is_finite() {
|
||||
let idx = value as usize;
|
||||
if let Some(str_value) = values.get(idx) {
|
||||
return Some(str_value.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -120,7 +121,7 @@ pub async fn get_hexagon_properties(
|
|||
let (parsed_filters, parsed_enum_filters) = parse_filters(
|
||||
params.filters.as_deref(),
|
||||
&state.data.feature_names,
|
||||
&state.data.enum_features,
|
||||
&state.data.enum_values,
|
||||
);
|
||||
let num_filters = parsed_filters.len() + parsed_enum_filters.len();
|
||||
|
||||
|
|
@ -131,10 +132,9 @@ pub async fn get_hexagon_properties(
|
|||
.map_err(|err| format!("Invalid H3 resolution {}: {}", resolution, err))?;
|
||||
let need_parent = resolution < H3_PRECOMPUTE_MAX;
|
||||
let num_features = state.data.num_features;
|
||||
let num_enums = state.data.num_enums;
|
||||
let feature_data = &state.data.feature_data;
|
||||
let enum_data_flat = &state.data.enum_data;
|
||||
let enum_features = &state.data.enum_features;
|
||||
let feature_names = &state.data.feature_names;
|
||||
let enum_values = &state.data.enum_values;
|
||||
|
||||
let (min_lat, min_lon, max_lat, max_lon) = h3_cell_bounds(cell, 0.001);
|
||||
|
||||
|
|
@ -162,8 +162,6 @@ pub async fn get_hexagon_properties(
|
|||
&parsed_enum_filters,
|
||||
feature_data,
|
||||
num_features,
|
||||
enum_data_flat,
|
||||
num_enums,
|
||||
)
|
||||
{
|
||||
matching_rows.push(row);
|
||||
|
|
@ -185,7 +183,11 @@ pub async fn get_hexagon_properties(
|
|||
.map(|&row| {
|
||||
let mut features = FxHashMap::default();
|
||||
let base = row * num_features;
|
||||
for (feat_idx, feat_name) in state.data.feature_names.iter().enumerate() {
|
||||
for (feat_idx, feat_name) in feature_names.iter().enumerate() {
|
||||
// Skip enum features in the generic features map
|
||||
if enum_values.contains_key(&feat_idx) {
|
||||
continue;
|
||||
}
|
||||
let value = feature_data[base + feat_idx];
|
||||
if value.is_finite() {
|
||||
features.insert(feat_name.clone(), value);
|
||||
|
|
@ -197,42 +199,42 @@ pub async fn get_hexagon_properties(
|
|||
postcode: non_empty_string(state.data.postcode(row)),
|
||||
is_construction_date_approximate: Some(state.data.is_approx_build_date(row)),
|
||||
property_type: lookup_enum_value(
|
||||
enum_features,
|
||||
enum_data_flat,
|
||||
num_enums,
|
||||
&state.enum_name_to_idx,
|
||||
feature_names,
|
||||
feature_data,
|
||||
num_features,
|
||||
enum_values,
|
||||
row,
|
||||
&["Property type", "epc_property_type", "pp_property_type"],
|
||||
),
|
||||
built_form: lookup_enum_value(
|
||||
enum_features,
|
||||
enum_data_flat,
|
||||
num_enums,
|
||||
&state.enum_name_to_idx,
|
||||
feature_names,
|
||||
feature_data,
|
||||
num_features,
|
||||
enum_values,
|
||||
row,
|
||||
&["Property type/built form", "built_form"],
|
||||
),
|
||||
duration: lookup_enum_value(
|
||||
enum_features,
|
||||
enum_data_flat,
|
||||
num_enums,
|
||||
&state.enum_name_to_idx,
|
||||
feature_names,
|
||||
feature_data,
|
||||
num_features,
|
||||
enum_values,
|
||||
row,
|
||||
&["Leashold/Freehold", "duration"],
|
||||
),
|
||||
current_energy_rating: lookup_enum_value(
|
||||
enum_features,
|
||||
enum_data_flat,
|
||||
num_enums,
|
||||
&state.enum_name_to_idx,
|
||||
feature_names,
|
||||
feature_data,
|
||||
num_features,
|
||||
enum_values,
|
||||
row,
|
||||
&["Current energy rating", "current_energy_rating"],
|
||||
),
|
||||
potential_energy_rating: lookup_enum_value(
|
||||
enum_features,
|
||||
enum_data_flat,
|
||||
num_enums,
|
||||
&state.enum_name_to_idx,
|
||||
feature_names,
|
||||
feature_data,
|
||||
num_features,
|
||||
enum_values,
|
||||
row,
|
||||
&["Potential energy rating", "potential_energy_rating"],
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue