Skip to content

Commit

Permalink
Merge pull request #1100 from gboeing/fix
Browse files Browse the repository at this point in the history
refactor utils_geo module
  • Loading branch information
gboeing authored Dec 25, 2023
2 parents 48611d2 + 657dd73 commit 2ba8aa7
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 118 deletions.
12 changes: 6 additions & 6 deletions osmnx/_errors.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
"""Define custom errors and exceptions."""


class ResponseStatusCodeError(ValueError):
"""Exception for an unhandled server response status code."""


class CacheOnlyInterruptError(InterruptedError):
"""Exception for settings.cache_only_mode=True interruption."""


class GraphSimplificationError(ValueError):
"""Exception for a problem with graph simplification."""


class InsufficientResponseError(ValueError):
"""Exception for empty or too few results in server response."""


class GraphSimplificationError(ValueError):
"""Exception for a problem with graph simplification."""
class ResponseStatusCodeError(ValueError):
"""Exception for an unhandled server response status code."""
22 changes: 20 additions & 2 deletions osmnx/_overpass.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def _make_overpass_polygon_coord_strs(polygon):
Project to utm, divide polygon up into sub-polygons if area exceeds a
max size (in meters), project back to lat-lon, then get a list of
polygon(s) exterior coordinates
polygon(s) exterior coordinates. Ignore interior ("holes") coordinates.
Parameters
----------
Expand All @@ -208,7 +208,25 @@ def _make_overpass_polygon_coord_strs(polygon):
geometry_proj, crs_proj = projection.project_geometry(polygon)
gpcs = utils_geo._consolidate_subdivide_geometry(geometry_proj)
geometry, _ = projection.project_geometry(gpcs, crs=crs_proj, to_latlong=True)
return utils_geo._get_polygons_coordinates(geometry)

# extract geometry's exterior coords
polygons_coords = []
for polygon in geometry.geoms:
x, y = polygon.exterior.xy
polygons_coords.append(list(zip(x, y)))

# convert exterior coords to the string format the API expects
polygon_coord_strs = []
for coords in polygons_coords:
s = ""
separator = " "
for coord in list(coords):
# round floating point lats and longs to 6 decimals (ie, ~100 mm)
# so we can hash and cache strings consistently
s = f"{s}{separator}{coord[1]:.6f}{separator}{coord[0]:.6f}"
polygon_coord_strs.append(s.strip(separator))

return polygon_coord_strs


def _create_overpass_query(polygon_coord_str, tags):
Expand Down
16 changes: 8 additions & 8 deletions osmnx/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,8 @@ def plot_graph_route(
if ax is None:
# plot the graph but not the route, and override any user show/close
# args for now: we'll do that later
override = {"show", "save", "close"}
kwargs = {k: v for k, v in pg_kwargs.items() if k not in override}
overrides = {"show", "save", "close"}
kwargs = {k: v for k, v in pg_kwargs.items() if k not in overrides}
fig, ax = plot_graph(G, show=False, save=False, close=False, **kwargs)
else:
fig = ax.figure
Expand Down Expand Up @@ -375,8 +375,8 @@ def plot_graph_routes(G, routes, route_colors="r", route_linewidths=4, **pgr_kwa
raise ValueError(msg)

# plot the graph and the first route
override = {"route", "route_color", "route_linewidth", "show", "save", "close"}
kwargs = {k: v for k, v in pgr_kwargs.items() if k not in override}
overrides = {"route", "route_color", "route_linewidth", "show", "save", "close"}
kwargs = {k: v for k, v in pgr_kwargs.items() if k not in overrides}
fig, ax = plot_graph_route(
G,
route=routes[0],
Expand All @@ -389,8 +389,8 @@ def plot_graph_routes(G, routes, route_colors="r", route_linewidths=4, **pgr_kwa
)

# plot the subsequent routes on top of existing ax
override.update({"ax"})
kwargs = {k: v for k, v in pgr_kwargs.items() if k not in override}
overrides.update({"ax"})
kwargs = {k: v for k, v in pgr_kwargs.items() if k not in overrides}
r_rc_rlw = zip(routes[1:], route_colors[1:], route_linewidths[1:])
for route, route_color, route_linewidth in r_rc_rlw:
fig, ax = plot_graph_route(
Expand Down Expand Up @@ -559,8 +559,8 @@ def plot_figure_ground(
bbox = utils_geo.bbox_from_point(point, dist, project_utm=False)

# plot the figure
override = {"bbox", "node_size", "node_color", "edge_linewidth"}
kwargs = {k: v for k, v in pg_kwargs.items() if k not in override}
overrides = {"bbox", "node_size", "node_color", "edge_linewidth"}
kwargs = {k: v for k, v in pg_kwargs.items() if k not in overrides}
fig, ax = plot_graph(
G=Gu,
bbox=bbox,
Expand Down
38 changes: 19 additions & 19 deletions osmnx/truncate.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Truncate graph by distance, bounding box, or polygon."""

from warnings import warn

import networkx as nx

from . import utils
Expand All @@ -22,11 +24,10 @@ def truncate_graph_dist(G, source_node, max_dist=1000, weight="length", retain_a
the node in the graph from which to measure network distances to other
nodes
max_dist : int
remove every node in the graph greater than this distance from the
remove every node in the graph that is greater than this distance from
source_node (along the network)
weight : string
how to weight the graph when measuring distance (default 'length' is
how many meters long the edge is)
graph edge attribute to use to measure distance
retain_all : bool
if True, return the entire graph even if it is not connected.
otherwise, retain only the largest weakly connected component.
Expand Down Expand Up @@ -65,8 +66,8 @@ def truncate_graph_bbox(
west,
truncate_by_edge=False,
retain_all=False,
quadrat_width=0.05,
min_num=3,
quadrat_width=None,
min_num=None,
):
"""
Remove every node in graph that falls outside a bounding box.
Expand All @@ -90,13 +91,9 @@ def truncate_graph_bbox(
if True, return the entire graph even if it is not connected.
otherwise, retain only the largest weakly connected component.
quadrat_width : float
passed on to intersect_index_quadrats: the linear length (in degrees) of
the quadrats with which to cut up the geometry (default = 0.05, approx
4km at NYC's latitude)
deprecated, do not use
min_num : int
passed on to intersect_index_quadrats: the minimum number of linear
quadrat lines (e.g., min_num=3 would produce a quadrat grid of 4
squares)
deprecated, do not use
Returns
-------
Expand All @@ -119,7 +116,7 @@ def truncate_graph_bbox(


def truncate_graph_polygon(
G, polygon, retain_all=False, truncate_by_edge=False, quadrat_width=0.05, min_num=3
G, polygon, retain_all=False, truncate_by_edge=False, quadrat_width=None, min_num=None
):
"""
Remove every node in graph that falls outside a (Multi)Polygon.
Expand All @@ -137,24 +134,27 @@ def truncate_graph_polygon(
if True, retain nodes outside boundary polygon if at least one of
node's neighbors is within the polygon
quadrat_width : float
passed on to intersect_index_quadrats: the linear length (in degrees)
of the quadrats with which to cut up the geometry (default = 0.05,
approx 4km at NYC's latitude)
deprecated, do not use
min_num : int
passed on to intersect_index_quadrats: the minimum number of linear
quadrat lines (e.g., min_num=3 would produce a quadrat grid of 4
squares)
deprecated, do not use
Returns
-------
G : networkx.MultiDiGraph
the truncated graph
"""
if quadrat_width is not None or min_num is not None:
warn(
"the `quadrat_width` and `min_num` parameters are deprecated and "
"will be removed in a future release",
stacklevel=2,
)

utils.log("Identifying all nodes that lie outside the polygon...")

# first identify all nodes whose point geometries lie within the polygon
gs_nodes = utils_graph.graph_to_gdfs(G, edges=False)[["geometry"]]
to_keep = utils_geo._intersect_index_quadrats(gs_nodes, polygon, quadrat_width, min_num)
to_keep = utils_geo._intersect_index_quadrats(gs_nodes, polygon)

if not to_keep:
# no graph nodes within the polygon: can't create a graph from that
Expand Down
Loading

0 comments on commit 2ba8aa7

Please sign in to comment.