good stuff
This commit is contained in:
parent
ea8389ef40
commit
f4de0eeb9f
39 changed files with 5165 additions and 348 deletions
|
|
@ -38,11 +38,12 @@ struct Properties {
|
|||
pub struct PostcodeData {
|
||||
/// Postcode strings
|
||||
pub postcodes: Vec<String>,
|
||||
/// All polygon parts per postcode: polygons[i] = list of outer rings
|
||||
/// Single Polygon → 1 ring, MultiPolygon → N rings
|
||||
pub polygons: Vec<Vec<Vec<[f32; 2]>>>,
|
||||
/// Centroid (lat, lon) for lookups
|
||||
pub centroids: Vec<(f32, f32)>,
|
||||
/// Precomputed AABB per postcode: (south, west, north, east) as f32
|
||||
pub aabbs: Vec<(f32, f32, f32, f32)>,
|
||||
/// Precomputed GeoJSON geometry Value per postcode
|
||||
pub geometries: Vec<serde_json::Value>,
|
||||
/// Lookup from postcode string to index
|
||||
pub postcode_to_idx: FxHashMap<String, usize>,
|
||||
}
|
||||
|
|
@ -96,6 +97,7 @@ impl PostcodeData {
|
|||
let mut local_postcodes = Vec::new();
|
||||
let mut local_polygons = Vec::new();
|
||||
let mut local_centroids = Vec::new();
|
||||
let mut local_aabbs: Vec<(f32, f32, f32, f32)> = Vec::new();
|
||||
|
||||
for feature in collection.features {
|
||||
let postcode = feature.properties.postcodes;
|
||||
|
|
@ -140,20 +142,44 @@ impl PostcodeData {
|
|||
(sum_lat / count, sum_lon / count)
|
||||
};
|
||||
|
||||
// Compute AABB across all rings
|
||||
let (mut aabb_south, mut aabb_north) = (f32::INFINITY, f32::NEG_INFINITY);
|
||||
let (mut aabb_west, mut aabb_east) = (f32::INFINITY, f32::NEG_INFINITY);
|
||||
for ring in &rings {
|
||||
for &[lon, lat] in ring {
|
||||
if lat < aabb_south {
|
||||
aabb_south = lat;
|
||||
}
|
||||
if lat > aabb_north {
|
||||
aabb_north = lat;
|
||||
}
|
||||
if lon < aabb_west {
|
||||
aabb_west = lon;
|
||||
}
|
||||
if lon > aabb_east {
|
||||
aabb_east = lon;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
local_postcodes.push(postcode);
|
||||
local_polygons.push(rings);
|
||||
local_centroids.push(centroid);
|
||||
local_aabbs.push((aabb_south, aabb_west, aabb_north, aabb_east));
|
||||
}
|
||||
|
||||
Ok::<_, anyhow::Error>((local_postcodes, local_polygons, local_centroids))
|
||||
Ok::<_, anyhow::Error>((local_postcodes, local_polygons, local_centroids, local_aabbs))
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
let mut aabbs: Vec<(f32, f32, f32, f32)> = Vec::new();
|
||||
|
||||
// Flatten results
|
||||
for (local_postcodes, local_polygons, local_centroids) in file_results {
|
||||
for (local_postcodes, local_polygons, local_centroids, local_aabbs) in file_results {
|
||||
postcodes.extend(local_postcodes);
|
||||
polygons.extend(local_polygons);
|
||||
centroids.extend(local_centroids);
|
||||
aabbs.extend(local_aabbs);
|
||||
}
|
||||
|
||||
debug!(
|
||||
|
|
@ -167,12 +193,49 @@ impl PostcodeData {
|
|||
postcode_to_idx.insert(postcode.clone(), idx);
|
||||
}
|
||||
|
||||
// Precompute GeoJSON geometry for each postcode
|
||||
let geometries: Vec<serde_json::Value> = polygons
|
||||
.iter()
|
||||
.map(|rings| {
|
||||
if rings.len() == 1 {
|
||||
let coords: Vec<serde_json::Value> = rings[0]
|
||||
.iter()
|
||||
.map(|[lon, lat]| {
|
||||
serde_json::Value::Array(vec![
|
||||
serde_json::Value::from(*lon as f64),
|
||||
serde_json::Value::from(*lat as f64),
|
||||
])
|
||||
})
|
||||
.collect();
|
||||
serde_json::json!({"type": "Polygon", "coordinates": [coords]})
|
||||
} else {
|
||||
let polys: Vec<serde_json::Value> = rings
|
||||
.iter()
|
||||
.map(|ring| {
|
||||
let coords: Vec<serde_json::Value> = ring
|
||||
.iter()
|
||||
.map(|[lon, lat]| {
|
||||
serde_json::Value::Array(vec![
|
||||
serde_json::Value::from(*lon as f64),
|
||||
serde_json::Value::from(*lat as f64),
|
||||
])
|
||||
})
|
||||
.collect();
|
||||
serde_json::Value::Array(vec![serde_json::Value::Array(coords)])
|
||||
})
|
||||
.collect();
|
||||
serde_json::json!({"type": "MultiPolygon", "coordinates": polys})
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
info!(postcodes = postcodes.len(), "Postcode boundary data ready");
|
||||
|
||||
Ok(PostcodeData {
|
||||
postcodes,
|
||||
polygons,
|
||||
centroids,
|
||||
aabbs,
|
||||
geometries,
|
||||
postcode_to_idx,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue