Skip to content

Commit

Permalink
Merge pull request #1101 from gboeing/feature
Browse files Browse the repository at this point in the history
warning and optimization
  • Loading branch information
gboeing authored Dec 25, 2023
2 parents d61a218 + 3a2aac4 commit dde24f3
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 25 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Unreleased

- fix a bug arising from the save_graph_xml function (#1093)
- warn user if their query area is significantly larger than max query area size (#1101)
- refactor utils_geo module and deprecate quadrat_width and min_num function arguments (#1100)
- under-the-hood code clean-up (#1092 #1099)

Expand Down
42 changes: 18 additions & 24 deletions osmnx/_overpass.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,31 +202,25 @@ def _make_overpass_polygon_coord_strs(polygon):
Returns
-------
polygon_coord_strs : list
list of exterior coordinate strings for smaller sub-divided polygons
coord_strs : list
list of strings of exterior coordinates of polygon(s)
"""
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)

# 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
# first subdivide the polygon if its area exceeds max size
# this results in a multipolygon of 1+ constituent polygons
poly_proj, crs_proj = projection.project_geometry(polygon)
multi_poly_proj = utils_geo._consolidate_subdivide_geometry(poly_proj)
multi_poly, _ = projection.project_geometry(multi_poly_proj, crs=crs_proj, to_latlong=True)

# then extract each's exterior coords to the string format Overpass
# expects, rounding lats and lons to 6 decimals (ie, ~100 mm) so we
# can hash and cache URL strings consistently
coord_strs = []
for geom in multi_poly.geoms:
x, y = geom.exterior.xy
coord_list = [f'{xy[1]:.6f}{" "}{xy[0]:.6f}' for xy in zip(x, y)]
coord_strs.append(" ".join(coord_list))

return coord_strs


def _create_overpass_query(polygon_coord_str, tags):
Expand Down
11 changes: 11 additions & 0 deletions osmnx/utils_geo.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,17 @@ def _consolidate_subdivide_geometry(geometry):
):
geometry = geometry.convex_hull

# warn user if they passed a geometry with area much larger than max size
ratio = int(geometry.area / mqas)
warning_threshold = 10
if ratio > warning_threshold:
msg = (
f"This area is {ratio:,} times your configured Overpass max query "
"area size. It will automatically be divided up into multiple "
"sub-queries accordingly. This may take a long time."
)
warn(msg, stacklevel=2)

# if geometry area exceeds max size, subdivide it into smaller subpolygons
# that are no greater than settings.max_query_area_size in size
if geometry.area > mqas:
Expand Down
7 changes: 6 additions & 1 deletion tests/test_osmnx.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ def test_find_nearest():
ne2 = ox.distance.nearest_edges(G, X[0], Y[0], interpolate=50, return_dist=True)


def test_endpoints():
def test_api_endpoints():
"""Test different API endpoints."""
default_timeout = ox.settings.timeout
default_key = ox.settings.nominatim_key
Expand Down Expand Up @@ -563,6 +563,11 @@ def test_graph_save_load():

def test_graph_from_functions():
"""Test downloading graphs from Overpass."""
# test subdividing a large geometry (raises a UserWarning)
bbox = ox.utils_geo.bbox_from_point((0, 0), dist=1e5, project_utm=True)
poly = ox.utils_geo.bbox_to_poly(*bbox)
_ = ox.utils_geo._consolidate_subdivide_geometry(poly)

# graph from bounding box
_ = ox.utils_geo.bbox_from_point(location_point, project_utm=True, return_crs=True)
north, south, east, west = ox.utils_geo.bbox_from_point(location_point, dist=500)
Expand Down

0 comments on commit dde24f3

Please sign in to comment.