From 9bf7afcc42b5d8215f8f653d735b355c3408dd14 Mon Sep 17 00:00:00 2001 From: Geoff Boeing Date: Thu, 7 Dec 2023 09:05:58 -0800 Subject: [PATCH 01/10] update ver --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 006f44962..8ba7336dd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -30,7 +30,7 @@ repos: types_or: [markdown, yaml] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.6" + rev: "v0.1.7" hooks: - id: ruff args: [--fix] From 9b72135858f6e12521439982a313bf782c6662a0 Mon Sep 17 00:00:00 2001 From: Geoff Boeing Date: Thu, 7 Dec 2023 10:02:07 -0800 Subject: [PATCH 02/10] update lint rules --- pyproject.toml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 2c41bae9f..e52fedfd6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,17 +70,21 @@ extend-select = [ "A", # check python builtins being used as variables or parameters "ARG", # check unused function arguments "B", # check common design problems a la flake8-bugbear - "BLE", # check for blind exception catching + "BLE", # check blind exception catching "C4", # check proper comprehensions "C9", # check mccabe complexity "D", # check docstring conventions a la pydocstyle - "D417", # check missing arguments in docstrings (disabled by default for numpy convention) + "D417", # check missing args in docstrings (disabled by default for numpy convention) "DTZ", # check unsafe naive datetime use a la flake8-datetimez "E", # check code style conventions a la pycodestyle errors "EM", # check raw literals inside exception raising "ERA", # check commented-out code from python files a la eradicate "F", # check python source code for errors a la pyflakes + "FIX", # check temporary developer notes a la flake8-fixme + #"FURB", # check code improvements a la refurb (preview) + "G", # check logging string formatting a la flake8-logging-format "I", # check isort imports + #"LOG", # check logging module usage a la flake8-logging (preview) "PERF", # check performance anti-patterns a la perflint "PGH", # check pygrep hooks "PIE", # check misc lints a la flake8-pie @@ -88,7 +92,9 @@ extend-select = [ "PT", # check common pytest issues "PTH", # check pathlib usage "RET", # check return statements a la flake8-return - "T20", # check for print statements + "RSE", # check exception raise statements via flake8-raise + "SIM", # check code simplicity a la flake8-simplify + "T20", # check print statements "TRY", # check exception handling anti-patterns a la tryceratops "UP", # check outdated syntax a la pyupgrade "W", # check code style conventions a la pycodestyle warnings From d4f1c27dcedba26c83a09308fe2a94db08f1fdd4 Mon Sep 17 00:00:00 2001 From: Geoff Boeing Date: Thu, 7 Dec 2023 10:02:38 -0800 Subject: [PATCH 03/10] use cwd instead because it's more explicit --- docs/source/conf.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index e6e3aee08..703d96699 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -10,8 +10,9 @@ import sys from pathlib import Path -# go up two levels from /docs/source to the package root -sys.path.insert(0, str(Path().resolve().parent.parent)) +# go up two levels from current working dir (/docs/source) to package root +pkg_root_path = str(Path.cwd().parent.parent) +sys.path.insert(0, pkg_root_path) author = "Geoff Boeing" copyright = "2016-2023, Geoff Boeing" # noqa: A001 From a0e444f29fc915f3a4df1167a60bebb818dc718c Mon Sep 17 00:00:00 2001 From: Geoff Boeing Date: Thu, 7 Dec 2023 10:09:31 -0800 Subject: [PATCH 04/10] lint code --- osmnx/_overpass.py | 10 ++-------- osmnx/distance.py | 5 +---- osmnx/elevation.py | 1 + osmnx/folium.py | 12 +++--------- osmnx/geocoder.py | 5 +---- osmnx/io.py | 17 +++++------------ osmnx/osm_xml.py | 6 ++---- osmnx/plot.py | 19 +++++-------------- osmnx/simplification.py | 2 +- osmnx/speed.py | 5 +---- osmnx/stats.py | 2 +- osmnx/utils_graph.py | 2 +- tests/test_osmnx.py | 2 +- 13 files changed, 25 insertions(+), 63 deletions(-) diff --git a/osmnx/_overpass.py b/osmnx/_overpass.py index 8f353aeae..f413c4b49 100644 --- a/osmnx/_overpass.py +++ b/osmnx/_overpass.py @@ -183,10 +183,7 @@ def _make_overpass_settings(): ------- string """ - if settings.memory is None: - maxsize = "" - else: - maxsize = f"[maxsize:{settings.memory}]" + maxsize = "" if settings.memory is None else f"[maxsize:{settings.memory}]" return settings.overpass_settings.format(timeout=settings.timeout, maxsize=maxsize) @@ -301,10 +298,7 @@ def _download_overpass_network(polygon, network_type, custom_filter): """ # create a filter to exclude certain kinds of ways based on the requested # network_type, if provided, otherwise use custom_filter - if custom_filter is not None: - osm_filter = custom_filter - else: - osm_filter = _get_osm_filter(network_type) + osm_filter = custom_filter if custom_filter is not None else _get_osm_filter(network_type) # create overpass settings string overpass_settings = _make_overpass_settings() diff --git a/osmnx/distance.py b/osmnx/distance.py index a39098601..42a9da8f7 100644 --- a/osmnx/distance.py +++ b/osmnx/distance.py @@ -210,10 +210,7 @@ def add_edge_lengths(G, precision=None, edges=None): stacklevel=2, ) - if edges is None: - uvk = tuple(G.edges) - else: - uvk = edges + uvk = tuple(G.edges) if edges is None else edges # extract edge IDs and corresponding coordinates from their nodes x = G.nodes(data="x") diff --git a/osmnx/elevation.py b/osmnx/elevation.py index c2c014cb3..ddf6ab2d3 100644 --- a/osmnx/elevation.py +++ b/osmnx/elevation.py @@ -1,4 +1,5 @@ """Add node elevations from raster files or web APIs, and calculate edge grades.""" + import multiprocessing as mp import time from hashlib import sha1 diff --git a/osmnx/folium.py b/osmnx/folium.py index aaa4539cd..1103edc63 100644 --- a/osmnx/folium.py +++ b/osmnx/folium.py @@ -165,10 +165,7 @@ def _plot_folium(gdf, m, popup_attribute, tiles, zoom, fit_bounds, **kwargs): m = folium.Map(location=centroid, zoom_start=zoom, tiles=tiles) # identify the geometry and popup columns - if popup_attribute is None: - attrs = ["geometry"] - else: - attrs = ["geometry", popup_attribute] + attrs = ["geometry"] if popup_attribute is None else ["geometry", popup_attribute] # add each edge to the map for vals in gdf[attrs].values: @@ -207,11 +204,8 @@ def _make_folium_polyline(geom, popup_val=None, **kwargs): locations = [(lat, lon) for lon, lat in geom.coords] # create popup if popup_val is not None - if popup_val is None: - popup = None - else: - # folium doesn't interpret html, so can't do newlines without iframe - popup = folium.Popup(html=json.dumps(popup_val)) + # folium doesn't interpret html, so can't do newlines without iframe + popup = None if popup_val is None else folium.Popup(html=json.dumps(popup_val)) # create a folium polyline with attributes return folium.PolyLine(locations=locations, popup=popup, **kwargs) diff --git a/osmnx/geocoder.py b/osmnx/geocoder.py index 02d29ff1a..8f68fd554 100644 --- a/osmnx/geocoder.py +++ b/osmnx/geocoder.py @@ -173,10 +173,7 @@ def _geocode_query_to_gdf(query, which_result, by_osmid): gdf : geopandas.GeoDataFrame a GeoDataFrame with one row containing the result of geocoding """ - if which_result is None: - limit = 50 - else: - limit = which_result + limit = 50 if which_result is None else which_result results = _nominatim._download_nominatim_element(query, by_osmid=by_osmid, limit=limit) diff --git a/osmnx/io.py b/osmnx/io.py index 5d4325228..676d9de78 100644 --- a/osmnx/io.py +++ b/osmnx/io.py @@ -38,10 +38,7 @@ def save_graph_geopackage(G, filepath=None, encoding="utf-8", directed=False): None """ # default filepath if none was provided - if filepath is None: - filepath = Path(settings.data_folder) / "graph.gpkg" - else: - filepath = Path(filepath) + filepath = Path(settings.data_folder) / "graph.gpkg" if filepath is None else Path(filepath) # if save folder does not already exist, create it filepath.parent.mkdir(parents=True, exist_ok=True) @@ -94,10 +91,9 @@ def save_graph_shapefile(G, filepath=None, encoding="utf-8", directed=False): ) # default filepath if none was provided - if filepath is None: - filepath = Path(settings.data_folder) / "graph_shapefile" - else: - filepath = Path(filepath) + filepath = ( + Path(settings.data_folder) / "graph_shapefile" if filepath is None else Path(filepath) + ) # if save folder does not already exist, create it (shapefiles # get saved as set of files) @@ -141,10 +137,7 @@ def save_graphml(G, filepath=None, gephi=False, encoding="utf-8"): None """ # default filepath if none was provided - if filepath is None: - filepath = Path(settings.data_folder) / "graph.graphml" - else: - filepath = Path(filepath) + filepath = Path(settings.data_folder) / "graph.graphml" if filepath is None else Path(filepath) # if save folder does not already exist, create it filepath.parent.mkdir(parents=True, exist_ok=True) diff --git a/osmnx/osm_xml.py b/osmnx/osm_xml.py index 7a0b2e28e..884b1b1af 100644 --- a/osmnx/osm_xml.py +++ b/osmnx/osm_xml.py @@ -1,4 +1,5 @@ """Read/write .osm formatted XML files.""" + import bz2 import xml.sax from pathlib import Path @@ -232,10 +233,7 @@ def _save_graph_xml( None """ # default filepath if none was provided - if filepath is None: - filepath = Path(settings.data_folder) / "graph.osm" - else: - filepath = Path(filepath) + filepath = Path(settings.data_folder) / "graph.osm" if filepath is None else Path(filepath) # if save folder does not already exist, create it filepath.parent.mkdir(parents=True, exist_ok=True) diff --git a/osmnx/plot.py b/osmnx/plot.py index d32d78f5e..5280bfc8b 100644 --- a/osmnx/plot.py +++ b/osmnx/plot.py @@ -540,9 +540,7 @@ def plot_figure_ground( et_flat.append(et) # lookup corresponding width for each edge type in flat list - edge_widths = [ - street_widths[et] if et in street_widths else default_width for et in et_flat - ] + edge_widths = [street_widths.get(et, default_width) for et in et_flat] # node diameter should equal largest edge width to make joints # perfectly smooth. alternatively use min(?) to prevent @@ -748,14 +746,10 @@ def plot_orientation( # width: make bars fill the circumference without gaps or overlaps width = 2 * np.pi / num_bins - # radius: how long to make each bar + # radius: how long to make each bar. set bar length so either the bar area + # (ie, via sqrt) or the bar height is proportional to the bin's frequency bin_frequency = bin_counts / bin_counts.sum() - if area: - # set bar length so area is proportional to frequency - radius = np.sqrt(bin_frequency) - else: - # set bar length so height is proportional to frequency - radius = bin_frequency + radius = np.sqrt(bin_frequency) if area else bin_frequency # create ax (if necessary) then set N at top and go clockwise if ax is None: @@ -885,10 +879,7 @@ def _save_and_show(fig, ax, save=False, show=True, close=True, filepath=None, dp if save: # default filepath, if none provided - if filepath is None: - filepath = Path(settings.imgs_folder) / "image.png" - else: - filepath = Path(filepath) + filepath = Path(settings.imgs_folder) / "image.png" if filepath is None else Path(filepath) # if save folder does not already exist, create it filepath.parent.mkdir(parents=True, exist_ok=True) diff --git a/osmnx/simplification.py b/osmnx/simplification.py index e5e85d53e..f6479a0cd 100644 --- a/osmnx/simplification.py +++ b/osmnx/simplification.py @@ -134,7 +134,7 @@ def _build_path(G, endpoint, endpoint_successor, endpoints): # where a one-way street turns into a two-way here, but # duplicate incoming one-way edges are present msg = f"Unexpected simplify pattern handled near {successor}" - utils.log(msg, level=lg.WARN) + utils.log(msg, level=lg.WARNING) return path else: # pragma: no cover # if successor has >1 successors, then successor must have diff --git a/osmnx/speed.py b/osmnx/speed.py index 59f21987f..121537a09 100644 --- a/osmnx/speed.py +++ b/osmnx/speed.py @@ -89,10 +89,7 @@ def add_edge_speeds(G, hwy_speeds=None, fallback=None, precision=None, agg=np.me # if user provided hwy_speeds, use them as default values, otherwise # initialize an empty series to populate with values - if hwy_speeds is None: - hwy_speed_avg = pd.Series(dtype=float) - else: - hwy_speed_avg = pd.Series(hwy_speeds).dropna() + hwy_speed_avg = pd.Series(dtype=float) if hwy_speeds is None else pd.Series(hwy_speeds).dropna() # for each highway type that caller did not provide in hwy_speeds, impute # speed of type by taking the mean of the preexisting speed values of that diff --git a/osmnx/stats.py b/osmnx/stats.py index 7537cdb79..d70824dea 100644 --- a/osmnx/stats.py +++ b/osmnx/stats.py @@ -42,7 +42,7 @@ def streets_per_node(G): """ spn = dict(nx.get_node_attributes(G, "street_count")) if set(spn) != set(G.nodes): - utils.log("Graph nodes changed since `street_count`s were calculated", level=lg.WARN) + utils.log("Graph nodes changed since `street_count`s were calculated", level=lg.WARNING) return spn diff --git a/osmnx/utils_graph.py b/osmnx/utils_graph.py index 9fb446727..079b84442 100644 --- a/osmnx/utils_graph.py +++ b/osmnx/utils_graph.py @@ -482,7 +482,7 @@ def _is_same_geometry(ls1, ls2): geom1_r = [tuple(reversed(coords)) for coords in ls1.xy] # if second geometry matches first in either direction, return True - return geom2 in (geom1, geom1_r) + return geom2 in (geom1, geom1_r) # noqa: PLR6201 def _update_edge_keys(G): diff --git a/tests/test_osmnx.py b/tests/test_osmnx.py index db7555afc..73159e350 100755 --- a/tests/test_osmnx.py +++ b/tests/test_osmnx.py @@ -174,7 +174,7 @@ def test_osm_xml(): edge_key = (node_id, neighbor_id, 0) assert neighbor_id in G.nodes assert edge_key in G.edges - assert G.edges[edge_key]["name"] in ("8th Street", "Willow Street") + assert G.edges[edge_key]["name"] in {"8th Street", "Willow Street"} Path.unlink(Path(temp_filename)) From a86e56b59ecab8ab2a85bbc4c7d26238abfd5df2 Mon Sep 17 00:00:00 2001 From: Geoff Boeing Date: Thu, 7 Dec 2023 10:46:59 -0800 Subject: [PATCH 05/10] pandas lint fixes --- osmnx/elevation.py | 8 ++++---- osmnx/features.py | 2 +- osmnx/folium.py | 2 +- osmnx/osm_xml.py | 2 +- osmnx/plot.py | 4 ++-- osmnx/speed.py | 8 ++++---- osmnx/utils_graph.py | 2 +- tests/test_osmnx.py | 14 +++++++------- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/osmnx/elevation.py b/osmnx/elevation.py index ddf6ab2d3..00895f9a8 100644 --- a/osmnx/elevation.py +++ b/osmnx/elevation.py @@ -265,10 +265,10 @@ def add_node_elevations_google( raise InsufficientResponseError(err_msg) # add elevation as an attribute to the nodes - df = pd.DataFrame(node_points, columns=["node_points"]) - df["elevation"] = [result["elevation"] for result in results] - df["elevation"] = df["elevation"].round(precision) - nx.set_node_attributes(G, name="elevation", values=df["elevation"].to_dict()) + df_elev = pd.DataFrame(node_points, columns=["node_points"]) + df_elev["elevation"] = [result["elevation"] for result in results] + df_elev["elevation"] = df_elev["elevation"].round(precision) + nx.set_node_attributes(G, name="elevation", values=df_elev["elevation"].to_dict()) utils.log(f"Added elevation data from {domain!r} to all nodes.") return G diff --git a/osmnx/features.py b/osmnx/features.py index 2cb4b663a..a177aadd0 100644 --- a/osmnx/features.py +++ b/osmnx/features.py @@ -1031,7 +1031,7 @@ def _filter_gdf_by_polygon_and_tags(gdf, polygon, tags): gdf = gdf[polygon_filter & combined_tag_filter].copy() # remove columns of all nulls (created by discarded component features) - gdf.dropna(axis="columns", how="all", inplace=True) + gdf = gdf.dropna(axis="columns", how="all") # multi-index gdf by element_type and osmid then return idx_cols = ["element_type", "osmid"] diff --git a/osmnx/folium.py b/osmnx/folium.py index 1103edc63..1c00c840a 100644 --- a/osmnx/folium.py +++ b/osmnx/folium.py @@ -168,7 +168,7 @@ def _plot_folium(gdf, m, popup_attribute, tiles, zoom, fit_bounds, **kwargs): attrs = ["geometry"] if popup_attribute is None else ["geometry", popup_attribute] # add each edge to the map - for vals in gdf[attrs].values: + for vals in gdf[attrs].to_numpy(): params = dict(zip(["geom", "popup_val"], vals)) pl = _make_folium_polyline(**params, **kwargs) pl.add_to(m) diff --git a/osmnx/osm_xml.py b/osmnx/osm_xml.py index 884b1b1af..a867858b8 100644 --- a/osmnx/osm_xml.py +++ b/osmnx/osm_xml.py @@ -275,7 +275,7 @@ def _save_graph_xml( # misc. string replacements to meet OSM XML spec if "oneway" in gdf_edges.columns: # fill blank oneway tags with default (False) - gdf_edges.loc[pd.isnull(gdf_edges["oneway"]), "oneway"] = oneway + gdf_edges.loc[pd.isna(gdf_edges["oneway"]), "oneway"] = oneway gdf_edges.loc[:, "oneway"] = gdf_edges["oneway"].astype(str) gdf_edges.loc[:, "oneway"] = ( gdf_edges["oneway"].str.replace("False", "no").replace("True", "yes") diff --git a/osmnx/plot.py b/osmnx/plot.py index 5280bfc8b..c9ec5da36 100644 --- a/osmnx/plot.py +++ b/osmnx/plot.py @@ -834,14 +834,14 @@ def _get_colors_by_value(vals, num_bins, cmap, start, stop, na_color, equal_size normalizer = colors.Normalize(full_min, full_max) scalar_mapper = cm.ScalarMappable(normalizer, colormaps[cmap]) color_series = vals.map(scalar_mapper.to_rgba) - color_series.loc[pd.isnull(vals)] = na_color + color_series.loc[pd.isna(vals)] = na_color else: # otherwise, bin values then assign colors to bins cut_func = pd.qcut if equal_size else pd.cut bins = cut_func(vals, num_bins, labels=range(num_bins)) bin_colors = get_colors(num_bins, cmap, start, stop) - color_list = [bin_colors[b] if pd.notnull(b) else na_color for b in bins] + color_list = [bin_colors[b] if pd.notna(b) else na_color for b in bins] color_series = pd.Series(color_list, index=bins.index) return color_series diff --git a/osmnx/speed.py b/osmnx/speed.py index 121537a09..1fd2da881 100644 --- a/osmnx/speed.py +++ b/osmnx/speed.py @@ -111,7 +111,7 @@ def add_edge_speeds(G, hwy_speeds=None, fallback=None, precision=None, agg=np.me # all speeds will be null if edges had no preexisting maxspeed data and # caller did not pass in hwy_speeds or fallback arguments - if pd.isnull(speed_kph).all(): + if pd.isna(speed_kph).all(): msg = ( "this graph's edges have no preexisting `maxspeed` attribute " "values so you must pass `hwy_speeds` or `fallback` arguments." @@ -119,7 +119,7 @@ def add_edge_speeds(G, hwy_speeds=None, fallback=None, precision=None, agg=np.me raise ValueError(msg) # add speed kph attribute to graph edges - edges["speed_kph"] = speed_kph.round(precision).values + edges["speed_kph"] = speed_kph.round(precision).to_numpy() nx.set_edge_attributes(G, values=edges["speed_kph"], name="speed_kph") return G @@ -162,7 +162,7 @@ def add_edge_travel_times(G, precision=None): raise KeyError(msg) # verify edge length and speed_kph attributes contain no nulls - if pd.isnull(edges["length"]).any() or pd.isnull(edges["speed_kph"]).any(): # pragma: no cover + if pd.isna(edges["length"]).any() or pd.isna(edges["speed_kph"]).any(): # pragma: no cover msg = "edge `length` and `speed_kph` values must be non-null." raise ValueError(msg) @@ -174,7 +174,7 @@ def add_edge_travel_times(G, precision=None): travel_time = distance_km / speed_km_sec # add travel time attribute to graph edges - edges["travel_time"] = travel_time.round(precision).values + edges["travel_time"] = travel_time.round(precision).to_numpy() nx.set_edge_attributes(G, values=edges["travel_time"], name="travel_time") return G diff --git a/osmnx/utils_graph.py b/osmnx/utils_graph.py index 079b84442..126b096b5 100644 --- a/osmnx/utils_graph.py +++ b/osmnx/utils_graph.py @@ -172,7 +172,7 @@ def graph_from_gdfs(gdf_nodes, gdf_edges, graph_attrs=None): attr_names = gdf_edges.columns.to_list() for (u, v, k), attr_vals in zip(gdf_edges.index, gdf_edges.values): data_all = zip(attr_names, attr_vals) - data = {name: val for name, val in data_all if isinstance(val, list) or pd.notnull(val)} + data = {name: val for name, val in data_all if isinstance(val, list) or pd.notna(val)} G.add_edge(u, v, key=k, **data) # add any nodes with no incident edges, since they wouldn't be added above diff --git a/tests/test_osmnx.py b/tests/test_osmnx.py index 73159e350..e68d94768 100755 --- a/tests/test_osmnx.py +++ b/tests/test_osmnx.py @@ -192,8 +192,8 @@ def test_osm_xml(): ox.osm_xml.save_graph_xml([nodes, edges]) # test ordered nodes from way - df = pd.DataFrame({"u": [54, 2, 5, 3, 10, 19, 20], "v": [76, 3, 8, 10, 5, 20, 15]}) - ordered_nodes = ox.osm_xml._get_unique_nodes_ordered_from_way(df) + df_uv = pd.DataFrame({"u": [54, 2, 5, 3, 10, 19, 20], "v": [76, 3, 8, 10, 5, 20, 15]}) + ordered_nodes = ox.osm_xml._get_unique_nodes_ordered_from_way(df_uv) assert ordered_nodes == [2, 3, 10, 5, 8] # test roundabout handling @@ -236,11 +236,11 @@ def test_elevation(): # add node elevations from a single raster file (some nodes will be null) rasters = list(Path("tests/input_data").glob("elevation*.tif")) G = ox.elevation.add_node_elevations_raster(G, rasters[0], cpus=1) - assert pd.notnull(pd.Series(dict(G.nodes(data="elevation")))).any() + assert pd.notna(pd.Series(dict(G.nodes(data="elevation")))).any() # add node elevations from multiple raster files (no nodes should be null) G = ox.elevation.add_node_elevations_raster(G, rasters) - assert pd.notnull(pd.Series(dict(G.nodes(data="elevation")))).all() + assert pd.notna(pd.Series(dict(G.nodes(data="elevation")))).all() # add edge grades and their absolute values G = ox.add_edge_grades(G, add_absolute=True) @@ -377,8 +377,8 @@ def test_find_nearest(): G = ox.graph_from_point(location_point, dist=500, network_type="drive", simplify=False) Gp = ox.project_graph(G) points = ox.utils_geo.sample_points(ox.get_undirected(Gp), 5) - X = points.x.values - Y = points.y.values + X = points.x.to_numpy() + Y = points.y.to_numpy() # get nearest nodes nn0, dist0 = ox.distance.nearest_nodes(G, X[0], Y[0], return_dist=True) @@ -629,5 +629,5 @@ def test_features(): os.close(handle) for filename in ("tests/input_data/West-Oakland.osm.bz2", temp_filename): gdf = ox.geometries_from_xml(filename) - assert "Willow Street" in gdf["name"].values + assert "Willow Street" in gdf["name"].to_numpy() Path.unlink(Path(temp_filename)) From 4ce95893dc56fab48a7e66672c4d8629f520ce73 Mon Sep 17 00:00:00 2001 From: Geoff Boeing Date: Thu, 7 Dec 2023 11:21:24 -0800 Subject: [PATCH 06/10] pandas lint fixes --- osmnx/osm_xml.py | 4 ++-- osmnx/utils_graph.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osmnx/osm_xml.py b/osmnx/osm_xml.py index a867858b8..e7556fe32 100644 --- a/osmnx/osm_xml.py +++ b/osmnx/osm_xml.py @@ -253,7 +253,7 @@ def _save_graph_xml( ) # rename columns per osm specification - gdf_nodes.rename(columns={"x": "lon", "y": "lat"}, inplace=True) + gdf_nodes = gdf_nodes.rename(columns={"x": "lon", "y": "lat"}) gdf_nodes["lon"] = gdf_nodes["lon"].round(precision) gdf_nodes["lat"] = gdf_nodes["lat"].round(precision) gdf_nodes = gdf_nodes.reset_index().rename(columns={"osmid": "id"}) @@ -464,7 +464,7 @@ def _append_edges_xml_tree(root, gdf_edges, edge_attrs, edge_tags, edge_tag_aggs root : ElementTree.Element XML tree with edges appended """ - gdf_edges.reset_index(inplace=True) + gdf_edges = gdf_edges.reset_index() if merge_edges: for _, all_way_edges in gdf_edges.groupby("id"): first = all_way_edges.iloc[0].dropna().astype(str) diff --git a/osmnx/utils_graph.py b/osmnx/utils_graph.py index 126b096b5..414e59c47 100644 --- a/osmnx/utils_graph.py +++ b/osmnx/utils_graph.py @@ -54,7 +54,7 @@ def graph_to_gdfs(G, nodes=True, edges=True, node_geometry=True, fill_edge_geome else: gdf_nodes = gpd.GeoDataFrame(data, index=nodes) - gdf_nodes.index.rename("osmid", inplace=True) + gdf_nodes.index = gdf_nodes.index.rename("osmid") utils.log("Created nodes GeoDataFrame from graph") if edges: @@ -91,7 +91,7 @@ def _make_geom(u, v, data, x=x_lookup, y=y_lookup): gdf_edges["u"] = u gdf_edges["v"] = v gdf_edges["key"] = k - gdf_edges.set_index(["u", "v", "key"], inplace=True) + gdf_edges = gdf_edges.set_index(["u", "v", "key"]) utils.log("Created edges GeoDataFrame from graph") From 99953439feb42ae5029ad7bb0dcd814de455a463 Mon Sep 17 00:00:00 2001 From: Geoff Boeing Date: Thu, 7 Dec 2023 11:29:47 -0800 Subject: [PATCH 07/10] pandas lint fixes --- osmnx/osm_xml.py | 2 +- pyproject.toml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/osmnx/osm_xml.py b/osmnx/osm_xml.py index e7556fe32..41ea86d58 100644 --- a/osmnx/osm_xml.py +++ b/osmnx/osm_xml.py @@ -516,7 +516,7 @@ def _get_unique_nodes_ordered_from_way(df_way_edges): design schema. """ G = nx.MultiDiGraph() - df_way_edges.reset_index(inplace=True) + df_way_edges.reset_index(inplace=True) # noqa: PD002 all_nodes = list(df_way_edges["u"].values) + list(df_way_edges["v"].values) G.add_nodes_from(all_nodes) diff --git a/pyproject.toml b/pyproject.toml index e52fedfd6..7bcfcd081 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -85,6 +85,7 @@ extend-select = [ "G", # check logging string formatting a la flake8-logging-format "I", # check isort imports #"LOG", # check logging module usage a la flake8-logging (preview) + "PD", # check pandas linting a la pandas-vet "PERF", # check performance anti-patterns a la perflint "PGH", # check pygrep hooks "PIE", # check misc lints a la flake8-pie @@ -94,7 +95,7 @@ extend-select = [ "RET", # check return statements a la flake8-return "RSE", # check exception raise statements via flake8-raise "SIM", # check code simplicity a la flake8-simplify - "T20", # check print statements + "T20", # check for any print statements "TRY", # check exception handling anti-patterns a la tryceratops "UP", # check outdated syntax a la pyupgrade "W", # check code style conventions a la pycodestyle warnings From 7eaeb284068e9b64636c43f90257cc287d0933ba Mon Sep 17 00:00:00 2001 From: Geoff Boeing Date: Thu, 7 Dec 2023 11:45:15 -0800 Subject: [PATCH 08/10] replace pandas .values with .to_numpy() --- osmnx/distance.py | 2 +- osmnx/elevation.py | 2 +- osmnx/osm_xml.py | 4 ++-- osmnx/utils_graph.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osmnx/distance.py b/osmnx/distance.py index 42a9da8f7..325897807 100644 --- a/osmnx/distance.py +++ b/osmnx/distance.py @@ -378,7 +378,7 @@ def nearest_edges(G, X, Y, interpolate=None, return_dist=False): # interpolate points along edges to index with k-d tree or ball tree uvk_xy = [] - for uvk, geom in zip(geoms.index, geoms.values): + for uvk, geom in zip(geoms.index, geoms.to_numpy()): uvk_xy.extend((uvk, xy) for xy in utils_geo.interpolate_points(geom, interpolate)) labels, xy = zip(*uvk_xy) vertices = pd.DataFrame(xy, index=labels, columns=["x", "y"]) diff --git a/osmnx/elevation.py b/osmnx/elevation.py index 00895f9a8..13c318887 100644 --- a/osmnx/elevation.py +++ b/osmnx/elevation.py @@ -95,7 +95,7 @@ def _query_raster(nodes, filepath, band): """ # must open raster file here: cannot pickle it to pass in multiprocessing with rasterio.open(filepath) as raster: - values = np.array(tuple(raster.sample(nodes.values, band)), dtype=float).squeeze() + values = np.array(tuple(raster.sample(nodes.to_numpy(), band)), dtype=float).squeeze() values[values == raster.nodata] = np.nan return zip(nodes.index, values) diff --git a/osmnx/osm_xml.py b/osmnx/osm_xml.py index 41ea86d58..0e626df24 100644 --- a/osmnx/osm_xml.py +++ b/osmnx/osm_xml.py @@ -517,10 +517,10 @@ def _get_unique_nodes_ordered_from_way(df_way_edges): """ G = nx.MultiDiGraph() df_way_edges.reset_index(inplace=True) # noqa: PD002 - all_nodes = list(df_way_edges["u"].values) + list(df_way_edges["v"].values) + all_nodes = list(df_way_edges["u"].to_numpy()) + list(df_way_edges["v"].to_numpy()) G.add_nodes_from(all_nodes) - G.add_edges_from(df_way_edges[["u", "v"]].values) + G.add_edges_from(df_way_edges[["u", "v"]].to_numpy()) # copy nodes into new graph H = utils_graph.get_largest_component(G, strongly=False) diff --git a/osmnx/utils_graph.py b/osmnx/utils_graph.py index 414e59c47..df60642d7 100644 --- a/osmnx/utils_graph.py +++ b/osmnx/utils_graph.py @@ -170,7 +170,7 @@ def graph_from_gdfs(gdf_nodes, gdf_edges, graph_attrs=None): # add edges and their attributes to graph, but filter out null attribute # values so that edges only get attributes with non-null values attr_names = gdf_edges.columns.to_list() - for (u, v, k), attr_vals in zip(gdf_edges.index, gdf_edges.values): + for (u, v, k), attr_vals in zip(gdf_edges.index, gdf_edges.to_numpy()): data_all = zip(attr_names, attr_vals) data = {name: val for name, val in data_all if isinstance(val, list) or pd.notna(val)} G.add_edge(u, v, key=k, **data) From 2aee4385d4308782e8a0855fdcef22b925b26556 Mon Sep 17 00:00:00 2001 From: Geoff Boeing Date: Thu, 7 Dec 2023 11:46:57 -0800 Subject: [PATCH 09/10] prune before packing --- tests/git_repack.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/git_repack.sh b/tests/git_repack.sh index 8b626eab0..f7979dfde 100644 --- a/tests/git_repack.sh +++ b/tests/git_repack.sh @@ -1,2 +1,6 @@ #!/bin/bash +git remote prune origin git repack -a -d -f --depth=250 --window=250 +git prune-packed +git reflog expire --expire=1.month.ago +git gc --aggressive From a5c6ad4db459e2f11bcdb0e82c23ef587b70262d Mon Sep 17 00:00:00 2001 From: Geoff Boeing Date: Thu, 7 Dec 2023 11:47:04 -0800 Subject: [PATCH 10/10] update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 227754307..ffc7b0885 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +- under-the-hood code clean-up (#1092) + ## 1.8.0 (2023-11-30) - formally support Python 3.12 (#1082)