vibes
This commit is contained in:
parent
39ef5c6646
commit
c995f12f8b
78 changed files with 4830 additions and 1619 deletions
|
|
@ -40,7 +40,13 @@ pub struct ActualListingsResponse {
|
|||
pub truncated: bool,
|
||||
}
|
||||
|
||||
const KEEP_UNKNOWN_LISTING_FILTER_FEATURES: &[&str] = &["Total floor area (sqm)"];
|
||||
const KEEP_UNKNOWN_LISTING_FILTER_FEATURES: &[&str] = &[
|
||||
"Total floor area (sqm)",
|
||||
"Leasehold/Freehold",
|
||||
"Number of bedrooms & living rooms",
|
||||
"Property type",
|
||||
];
|
||||
const LISTING_BOUNDS_EPSILON_DEGREES: f64 = 0.00001;
|
||||
|
||||
pub async fn get_actual_listings(
|
||||
State(shared): State<Arc<SharedState>>,
|
||||
|
|
@ -98,14 +104,29 @@ pub async fn get_actual_listings(
|
|||
};
|
||||
|
||||
let row_indices = actual_listings.grid.query(south, west, north, east);
|
||||
let total_in_bounds = row_indices.len();
|
||||
|
||||
// Build (row, sort_key) pairs so we can sort by index without
|
||||
// materializing the full ActualListing for every matching row.
|
||||
let mut matching_rows: Vec<usize> = row_indices
|
||||
let total_grid_candidates = row_indices.len();
|
||||
let candidate_rows: Vec<usize> = row_indices
|
||||
.iter()
|
||||
.filter_map(|&row_idx| {
|
||||
let row = row_idx as usize;
|
||||
row_is_within_bounds(
|
||||
actual_listings.lat[row],
|
||||
actual_listings.lon[row],
|
||||
south,
|
||||
west,
|
||||
north,
|
||||
east,
|
||||
)
|
||||
.then_some(row)
|
||||
})
|
||||
.collect();
|
||||
let total_in_bounds = candidate_rows.len();
|
||||
|
||||
// Build (row, sort_key) pairs so we can sort by index without
|
||||
// materializing the full ActualListing for every matching row.
|
||||
let mut matching_rows: Vec<usize> = candidate_rows
|
||||
.into_iter()
|
||||
.filter(|&row| {
|
||||
if has_listing_filters
|
||||
&& !row_passes_listing_filters(
|
||||
row,
|
||||
|
|
@ -116,7 +137,7 @@ pub async fn get_actual_listings(
|
|||
&keep_unknown_listing_filter_idxs,
|
||||
)
|
||||
{
|
||||
return None;
|
||||
return false;
|
||||
}
|
||||
if has_poi_filters
|
||||
&& !row_passes_listing_poi_filters(
|
||||
|
|
@ -126,7 +147,7 @@ pub async fn get_actual_listings(
|
|||
poi_num_features,
|
||||
)
|
||||
{
|
||||
return None;
|
||||
return false;
|
||||
}
|
||||
if has_travel_filters
|
||||
&& !row_passes_travel_filters(
|
||||
|
|
@ -135,9 +156,9 @@ pub async fn get_actual_listings(
|
|||
&travel_data,
|
||||
)
|
||||
{
|
||||
return None;
|
||||
return false;
|
||||
}
|
||||
Some(row)
|
||||
true
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
|
@ -162,6 +183,7 @@ pub async fn get_actual_listings(
|
|||
results = listings.len(),
|
||||
total = total_matching,
|
||||
total_in_bounds,
|
||||
total_grid_candidates,
|
||||
offset,
|
||||
listing_filtered = has_listing_filters,
|
||||
poi_filtered = has_poi_filters,
|
||||
|
|
@ -214,10 +236,23 @@ fn row_passes_listing_filters(
|
|||
}
|
||||
}) && enum_filters.iter().all(|filter| {
|
||||
let raw = feature_data[base + filter.feat_idx];
|
||||
raw != NAN_U16 && filter.allowed.contains(&raw)
|
||||
if raw == NAN_U16 {
|
||||
keep_unknown_filter_idxs.contains(&filter.feat_idx)
|
||||
} else {
|
||||
filter.allowed.contains(&raw)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn row_is_within_bounds(lat: f32, lon: f32, south: f64, west: f64, north: f64, east: f64) -> bool {
|
||||
let lat = lat as f64;
|
||||
let lon = lon as f64;
|
||||
lat >= south - LISTING_BOUNDS_EPSILON_DEGREES
|
||||
&& lat <= north + LISTING_BOUNDS_EPSILON_DEGREES
|
||||
&& lon >= west - LISTING_BOUNDS_EPSILON_DEGREES
|
||||
&& lon <= east + LISTING_BOUNDS_EPSILON_DEGREES
|
||||
}
|
||||
|
||||
fn row_passes_listing_poi_filters(
|
||||
row: usize,
|
||||
filters: &[ParsedPoiFilter],
|
||||
|
|
@ -245,6 +280,20 @@ fn row_passes_listing_poi_filters(
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn listing_bounds_check_keeps_only_exact_viewport_rows() {
|
||||
assert!(row_is_within_bounds(51.5, -0.1, 51.4, -0.2, 51.6, 0.0));
|
||||
|
||||
// Bounds are inclusive so edge points are retained.
|
||||
assert!(row_is_within_bounds(51.4, -0.2, 51.4, -0.2, 51.6, 0.0));
|
||||
assert!(row_is_within_bounds(51.6, 0.0, 51.4, -0.2, 51.6, 0.0));
|
||||
|
||||
assert!(!row_is_within_bounds(51.399, -0.1, 51.4, -0.2, 51.6, 0.0));
|
||||
assert!(!row_is_within_bounds(51.601, -0.1, 51.4, -0.2, 51.6, 0.0));
|
||||
assert!(!row_is_within_bounds(51.5, -0.201, 51.4, -0.2, 51.6, 0.0));
|
||||
assert!(!row_is_within_bounds(51.5, 0.001, 51.4, -0.2, 51.6, 0.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn listing_floor_area_filter_keeps_unknown_values() {
|
||||
let floor_area_filter = ParsedFilter {
|
||||
|
|
@ -290,6 +339,48 @@ mod tests {
|
|||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn listing_enum_filter_keeps_allowlisted_unknown_values() {
|
||||
let enum_filter = ParsedEnumFilter {
|
||||
feat_idx: 0,
|
||||
allowed: [1u16].into_iter().collect(),
|
||||
};
|
||||
let keep_unknown_filter_idxs: FxHashSet<usize> = [0usize].into_iter().collect();
|
||||
|
||||
assert!(row_passes_listing_filters(
|
||||
0,
|
||||
&[],
|
||||
&[enum_filter],
|
||||
&[NAN_U16],
|
||||
1,
|
||||
&keep_unknown_filter_idxs
|
||||
));
|
||||
|
||||
assert!(!row_passes_listing_filters(
|
||||
0,
|
||||
&[],
|
||||
&[ParsedEnumFilter {
|
||||
feat_idx: 0,
|
||||
allowed: [1u16].into_iter().collect(),
|
||||
}],
|
||||
&[2],
|
||||
1,
|
||||
&keep_unknown_filter_idxs
|
||||
));
|
||||
|
||||
assert!(row_passes_listing_filters(
|
||||
0,
|
||||
&[],
|
||||
&[ParsedEnumFilter {
|
||||
feat_idx: 0,
|
||||
allowed: [1u16].into_iter().collect(),
|
||||
}],
|
||||
&[1],
|
||||
1,
|
||||
&keep_unknown_filter_idxs
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn listing_poi_filter_uses_listing_metric_matrix() {
|
||||
let filter = ParsedPoiFilter {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue