Closed otepencelik closed 1 week ago
Thanks for using OSMnx and suggesting this.
I think I disagree with this proposal on theoretical grounds. A graph (or the network itself) is a set of nodes which may (or may not) be linked to each other by a set of edges. The edges themselves are either ordered pairs (for a directed graph) or unordered tuples (for an undirected graph) of nodes. That is, the nodes have primacy as the object of the model and the edges exist in reference to the nodes.
That said, I think that:
if an edge of the graph crosses the bounding box but none of its nodes are inside the bounding box, the edge is not included in the resulting graph
is therefore the correct behavior. If the bounding box represents the spatial bounds of the model, and if an edge is a pair of nodes, then at least one node must exist within those bounds.
if we are trying to query OSM with a location from a vehicle going over a long bridge, the bridge edge should be included in the resulting graph as it is the nearest edge to the query point, but often it won't end up in the graph since the distance between the nodes are too long. This also happens for some highways that contain long edges.
OSMnx does accommodate this. All of the graph
module's graph_from_whatever
functions offer a truncate_by_edge
parameter. If False, then both endpoint nodes must be within the query bounds for an edge to be retained in the model. But if True, then just one node must be. This is useful when modeling a highway or bridge with just one endpoint in the query area, as that long edge will be retained even if its other endpoint falls outside the area.
I understand the design philosophy, but ultimately it deprecates the usefulness of OSMNX (which is awesome, don't get me wrong). Ultimately, the benefits listed in the overview of the documentation are hindered by it. You cannot model a street network if roads that pass through a corner with nodes outside of the bounding box are not rendered.
If I want to generate a map of a city highways/railroads or whatever passing through the bounding box, with two nodes outside of the bounding box, are not visible. So OSMNX cannot be used for generating accurate maps as it stands now.
Thank you so much for your prompt response and this amazing library @gboeing. I fully agree with @GCRVL. I would also like to point out that I was not questioning the current design and proposing a change to it, I was just trying to suggest this as an optional feature for specific use cases that might benefit from it, just like the truncate_by_edge
parameter.
I now realize that my suggestion of truncate_by_nearest_edge
only addresses my specific use case, and a more generic solution that checks for the intersection of each edge with the bounding box polygon would be able to address all kinds of similar issues as well, as mentioned by @GCRVL.
You cannot model a street network if roads that pass through a corner with nodes outside of the bounding box are not rendered.
@GCRVL Yes, you can, but it may take a few extra lines of code to generate the model you want. Could you provide an example code snippet to reproduce this limitation? I suspect it's feasible.
So OSMNX cannot be used for generating accurate maps as it stands now.
@GCRVL Just as a side note, generating maps is not the primary goal of OSMnx. Rather, it aims to generate accurate graph models (in the spirit of spatial graph theory mentioned above), and also allows you to visualize those graphs.
I now realize that my suggestion of truncate_by_nearest_edge only addresses my specific use case, and a more generic solution that checks for the intersection of each edge with the bounding box polygon would be able to address all kinds of similar issues as well
@otepencelik Yes, OSMnx currently lets you do this in a few lines of code. This is what I meant when I told @GCRVL in the previous comment: "Yes, you can, but it may take a few extra lines of code to generate the model you want." For example, you can get a buffered graph then retain only the nodes of edges that intersect the desired study area:
import osmnx as ox
# get a graph the usual way
place = "Piedmont, CA, USA"
G0 = ox.graph.graph_from_place(place, network_type="drive")
len(G0) # 352
# OR loosen the study area constraint via truncate_by_edge
G1 = ox.graph.graph_from_place(place, network_type="drive", truncate_by_edge=True)
len(G1) # 394
# OR retain all nodes with at least 1 incident edge intersecting study area
geom = ox.geocoder.geocode_to_gdf(place)["geometry"].iloc[0]
geom_proj, crs_proj = ox.projection.project_geometry(geom)
geom_buff, _ = ox.projection.project_geometry(geom_proj.buffer(500), crs=crs_proj, to_latlong=True)
G2 = ox.graph.graph_from_polygon(geom_buff, network_type="drive")
edges = ox.convert.graph_to_gdfs(G2, nodes=False)
nodes_keep = edges[edges.intersects(geom)].reset_index()[["u", "v"]].stack().unique()
G2.remove_nodes_from(set(G2.nodes) - set(nodes_keep))
len(G2) # 395
With #1214 you can do this even more simply:
import osmnx as ox
# retain all nodes with at least 1 incident edge intersecting study area
geom = ox.geocoder.geocode_to_gdf("Piedmont, CA, USA").iloc[0]["geometry"]
G = ox.graph.graph_from_polygon(ox.utils_geo.buffer_geometry(geom, 500), network_type="drive")
edges = ox.convert.graph_to_gdfs(G, nodes=False)
keep = edges[edges.intersects(geom)].reset_index()[["u", "v"]].stack().unique()
G.remove_nodes_from(set(G.nodes) - set(keep))
Resolved by #1214 (and the example code above).
Contributing guidelines
Documentation
Existing issues
What problem does your feature proposal solve?
When generating a graph from a gps coordinate, if an edge of the graph crosses the bounding box but none of its nodes are inside the bounding box, the edge is not included in the resulting graph. This could turn out to be useful in some scenarios. For example, if we are trying to query OSM with a location from a vehicle going over a long bridge, the bridge edge should be included in the resulting graph as it is the nearest edge to the query point, but often it won't end up in the graph since the distance between the nodes are too long. This also happens for some highways that contain long edges.
What is your proposed solution?
I don't have an implemented solution but I think that this could be a useful feature.
What alternatives have you considered?
The alternative is using a big enough bounding box which is computationally expensive.
Additional context
The context is provided in the proposal.