Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some OSM POIs and start a POI density metric #212

Merged
merged 5 commits into from
Mar 8, 2025
Merged

Conversation

dabreegster
Copy link
Collaborator

Towards #203 and #157.

  1. Move the 3 existing POI layers from Scotland-wide GJ files just for display into per study area context data
  2. Add two more categories, filled out as we parse the OSM data
  3. Start a prioritization metric for POI density

The density scale likely needs tuning like stats19, though Edinburgh looks OK:
image

The raw POIs:
image

Copy link
Collaborator Author

@dabreegster dabreegster left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right before merging, I'll update the Cloudflare context data files

}

#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub enum POIKind {
Copy link
Collaborator Author

@dabreegster dabreegster Mar 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll work with Cici to refine these categories. We may want more. Maybe GPs and hospitals should be combined. The only purpose of distinguishing is for the layer, not the metric.

@@ -481,3 +496,23 @@ fn nodes_to_edges(graph: &Graph, nodes: Vec<utils::osm2graph::IntersectionID>) -
}
edges
}

fn get_poi(tags: &Tags, point: Coord) -> Option<POI> {
if tags.is_any("shop", vec!["convenience", "grocery", "supermarket"]) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These seem to cover most, but there might be niche things like fruit stands tagged differently. We can validate with local knowledge and iterate.

});
}

if tags.is_any("amenity", vec!["community_centre", "library"]) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm taking the liberty of lumping libraries into this category too, but may change after discussing with Cici

@@ -84,8 +92,7 @@ struct PopulationZoneInput {
impl PopulationZoneInput {
fn read_all_from_file() -> Result<Vec<Self>> {
let population_zones = geojson::de::deserialize_feature_collection_str_to_vec(
&std::fs::read_to_string("tmp/population.geojson")
.expect("missing population.geojson - see get_reference_layers.sh"),
&fs_err::read_to_string("tmp/population.geojson")?,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This crate generates nice error messages with the filename that's missing

pois.push(POI {
kind,
point: poi.geometry,
name: poi.name,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: We used to show the number of pupils per school. Removed here because I'm not sure it actually matters. We could form a description string instead of name if it is important.

@@ -33,6 +33,9 @@ export let areaColorScale = commonQuintileColorScale.toReversed();
export let stats19Limits = [0, 1.0, 10.0, 50.0, 100.0, 1000.0];
export let stats19ColorScale = commonQuintileColorScale.toReversed();

export let poiLimits = [0, 1.0, 10.0, 50.0, 100.0, 1000.0];
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blindly copying stats19. It seems reasonable enough to start.

@dabreegster dabreegster requested a review from michaelkirk March 8, 2025 13:16
@dabreegster
Copy link
Collaborator Author

I'm on battery so won't re-run benchmarks till later. I don't expect checking for more points-in-polygon should be that much of a problem.

Copy link
Contributor

@michaelkirk michaelkirk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You got farther with this than I was expecting, great!

I pushed up a commit to your branch that I think is uncontroversial. LMK if you'd prefer I don't do that in the future - it was expedient.

&tags,
// TODO If a POI is tagged on the building itself, ideally we'd use its centroid. But
// an arbitrary point on the boundary is good enough.
node_mapping[node_ids.into_iter().next().unwrap()],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
node_mapping[node_ids.into_iter().next().unwrap()],
node_mapping[node_ids[0]],

We could explode with less flourish.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hah, oops

{#if $backend}
{#if $currentProjectKey.startsWith("ltn_cnt/")}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was pre-existing (my bad!), so don't feel like you need to address it in this PR, but I think we should consolidate on using the appFocus == 'cnt' check as it's a little more explicit.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -324,6 +332,9 @@
{:else if selectedPrioritization == "stats19"}
<b>Pedestrian and cyclist collisions:</b>
{(props.number_stats19_collisions / props.area_km2).toFixed(1)} / km²
{:else if selectedPrioritization == "pois"}
<b>Points of interest:</b>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "Point of interest / POI" is a good enough name for an internal label / variable name, but I wonder if it's confusing for external people actually using the application.

For some reason I associate POI with historical placards that you'd find on a tourist map, for things like "On this spot in 1922, such and such happened". That could be my own weird bias though.

I don't immediately have a better suggestion. Maybe "amenities"? Maybe you've got something, or maybe sustrans has some advice, or maybe it's fine as is.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Land use density" was also mentioned... will bring up in the next meeting.

GP: "#beaed4",
Hospital: "#fdc086",
Grocery: "#386cb0",
CommunityCenter: "#ffff99",
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think using the existing linear-legend is fine for now, because it's expedient. But it strikes me as a little off to have different types of places "on a spectrum", and it's simply not enough space to fit all our POI text in a single row:

Screenshot 2025-03-08 at 13 22 10

To me, something like this makes more sense for categorical data:
Screenshot 2025-03-08 at 12 59 46

(not necessarily the icons, though that'd be cute, I primarily mean the multiline layout:

colored dot: School, colored dot: GP, colored dot: Hospital
colored dot: Grocery, colored dot: Community Center

I'm totally fine to merge this as-is for now, but I think addressing this will be necessary in the nearish term.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, I actually meant to comment on running out of space. I'll add a TODO in the issue.

@dabreegster
Copy link
Collaborator Author

Thanks for the review, and totally fine to push commits to the branch -- thanks for the better errors.

I'll upload the new files and merge

@dabreegster dabreegster merged commit 95daa8f into main Mar 8, 2025
1 check passed
@dabreegster dabreegster deleted the osm_pois branch March 8, 2025 22:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants