Add pocketbase and other changes

This commit is contained in:
Andras Schmelczer 2026-02-07 19:20:22 +00:00
parent a9717d570d
commit 229150b641
14 changed files with 1178 additions and 91 deletions

View file

@ -22,6 +22,10 @@ pub struct FeatureConfig {
pub source: &'static str,
}
/// Features whose histogram bins should be exactly 1 unit wide (one per integer).
/// p1/p99 are snapped to integer boundaries before binning.
pub const INTEGER_BIN_FEATURES: &[&str] = &["Number of bedrooms & living rooms"];
pub struct FeatureGroup {
pub name: &'static str,
pub features: &'static [FeatureConfig],
@ -107,6 +111,17 @@ pub static FEATURE_GROUPS: &[FeatureGroup] = &[
detail: "Total number of habitable rooms (bedrooms plus living rooms) as recorded in the Energy Performance Certificate. Kitchens and bathrooms are typically excluded unless they are large enough to count as habitable rooms.",
source: "epc",
},
FeatureConfig {
name: "Transaction year",
bounds: Bounds::Fixed {
min: 1995.0,
max: 2026.0,
},
step: 1.0,
description: "Year of the most recent sale from the Land Registry",
detail: "The year (and fractional month) of the most recent recorded sale for this property from HM Land Registry Price Paid data. Used to show price history trends in the area chart.",
source: "price-paid",
},
FeatureConfig {
name: "Construction age",
bounds: Bounds::Fixed {
@ -593,23 +608,77 @@ pub static FEATURE_GROUPS: &[FeatureGroup] = &[
pub static ENUM_FEATURE_GROUPS: &[EnumFeatureGroup] = &[
EnumFeatureGroup {
name: "Property",
features: &[
EnumFeatureConfig {
name: "Leashold/Freehold",
order: Some(&["Freehold", "Leasehold"]),
description: "Whether the property is leasehold or freehold",
detail: "From HM Land Registry Price Paid data. Freehold means you own the building and the land it stands on. Leasehold means you own the building but not the land — you have a lease from the freeholder for a set number of years.",
source: "price-paid",
},
EnumFeatureConfig {
name: "Property type",
order: Some(&["Detached", "Semi-Detached", "Terraced", "Flat"]),
description: "Type of property: detached, semi-detached, terraced, or flat",
detail: "From HM Land Registry Price Paid data. The broad property type classification: Detached, Semi-Detached, Terraced, or Flat/Maisonette.",
source: "price-paid",
},
],
name: "Property",
features: &[
EnumFeatureConfig {
name: "Leashold/Freehold",
order: Some(&["Freehold", "Leasehold"]),
description: "Whether the property is leasehold or freehold",
detail: "From HM Land Registry Price Paid data. Freehold means you own the building and the land it stands on. Leasehold means you own the building but not the land — you have a lease from the freeholder for a set number of years.",
source: "price-paid",
},
EnumFeatureConfig {
name: "Property type",
order: Some(&["Detached", "Semi-Detached", "Terraced", "Flat"]),
description: "Type of property: detached, semi-detached, terraced, or flat",
detail: "From HM Land Registry Price Paid data. The broad property type classification: Detached, Semi-Detached, Terraced, or Flat/Maisonette.",
source: "price-paid",
},
],
},
EnumFeatureGroup {
name: "Environment",
features: &[
EnumFeatureConfig {
name: "Environmental risk",
order: Some(&["Low", "Moderate", "Significant"]),
description: "Highest ground stability risk across all six hazard types",
detail: "Overall ground stability risk for the area, taken as the maximum across all six GeoSure hazard categories (collapsible deposits, compressible ground, landslides, running sand, shrink-swell, and soluble rocks). From Ordnance Survey GeoSure data on a 5km hex grid.",
source: "geosure",
},
EnumFeatureConfig {
name: "Collapsible deposits risk",
order: Some(&["Low", "Moderate", "Significant"]),
description: "Risk of ground collapse from natural underground cavities",
detail: "From OS GeoSure. Indicates the likelihood of ground collapse due to natural cavities formed by dissolution of soluble rocks or the collapse of old mines and natural pipes. Rated on a 5km hex grid across Great Britain.",
source: "geosure",
},
EnumFeatureConfig {
name: "Compressible ground risk",
order: Some(&["Low", "Moderate", "Significant"]),
description: "Risk of ground compression causing subsidence",
detail: "From OS GeoSure. Indicates the potential for ground to compress under loading, which can cause gradual settlement or subsidence of buildings and infrastructure. Typically associated with soft clay, silt, or peat deposits.",
source: "geosure",
},
EnumFeatureConfig {
name: "Landslide risk",
order: Some(&["Low", "Moderate", "Significant"]),
description: "Risk of landslide or slope instability",
detail: "From OS GeoSure. Indicates the susceptibility of the ground to landslides and slope instability. Based on slope angle, geology, and historical landslide records.",
source: "geosure",
},
EnumFeatureConfig {
name: "Running sand risk",
order: Some(&["Low", "Moderate", "Significant"]),
description: "Risk of sand becoming fluid when saturated",
detail: "From OS GeoSure. Indicates the potential for fine-grained sand to behave like a fluid when saturated with water, which can affect excavations and foundations.",
source: "geosure",
},
EnumFeatureConfig {
name: "Shrink-swell risk",
order: Some(&["Low", "Moderate", "Significant"]),
description: "Risk of clay shrinking and swelling with moisture changes",
detail: "From OS GeoSure. Indicates the potential for clay-rich soils to shrink when dry and swell when wet, causing ground movement that can damage buildings and infrastructure. One of the most common causes of subsidence in the UK.",
source: "geosure",
},
EnumFeatureConfig {
name: "Soluble rocks risk",
order: Some(&["Low", "Moderate", "Significant"]),
description: "Risk of sinkholes from dissolution of soluble rocks",
detail: "From OS GeoSure. Indicates the potential for soluble rocks (limestone, chalk, gypsum) to dissolve, creating underground voids that can lead to sinkholes and ground subsidence.",
source: "geosure",
},
],
},
];
@ -638,6 +707,11 @@ pub fn order_for(name: &str) -> Option<&'static [&'static str]> {
.and_then(|feature| feature.order)
}
/// Whether this feature should use integer-width histogram bins.
pub fn has_integer_bins(name: &str) -> bool {
INTEGER_BIN_FEATURES.contains(&name)
}
/// Look up the Bounds config for a numeric feature by name.
pub fn bounds_for(name: &str) -> Option<&'static Bounds> {
FEATURE_GROUPS
@ -651,12 +725,14 @@ pub fn bounds_for(name: &str) -> Option<&'static Bounds> {
/// The server will panic at startup if the data contains groups not in this list or vice versa.
pub const POI_GROUP_ORDER: &[&str] = &[
"Public Transport",
"Amenity",
"Building",
"Craft",
"Healthcare",
"Leisure",
"Office",
"Shop",
"Tourism",
"Education",
"Health",
"Emergency Services",
"Other",
"Groceries",
"Local Businesses",
"Culture",
"Services",
"Shops",
];