From 3c49ad0296183b98d7027f0c76db27ddbe3b99d6 Mon Sep 17 00:00:00 2001 From: Martin Fleischmann Date: Mon, 29 Apr 2024 12:36:31 +0200 Subject: [PATCH 1/3] compat, warning cleanup, test lint --- momepy/dimension.py | 19 +++++-- momepy/elements.py | 26 ++++++---- momepy/functional/_elements.py | 2 +- momepy/functional/tests/test_elements.py | 5 +- momepy/intensity.py | 14 ++++- momepy/preprocessing.py | 21 ++++---- momepy/tests/test_dimension.py | 2 +- momepy/tests/test_distribution.py | 6 ++- momepy/tests/test_diversity.py | 6 ++- momepy/tests/test_elements.py | 66 +++++++++++++++++------- momepy/tests/test_graph.py | 8 ++- momepy/tests/test_intensity.py | 8 +-- momepy/tests/test_preprocess.py | 4 +- momepy/tests/test_shape.py | 2 +- momepy/tests/test_utils.py | 19 +++++-- momepy/tests/test_weights.py | 8 +-- momepy/utils.py | 4 +- momepy/weights.py | 4 +- pyproject.toml | 5 +- 19 files changed, 154 insertions(+), 75 deletions(-) diff --git a/momepy/dimension.py b/momepy/dimension.py index 59feddaa..5d462f72 100644 --- a/momepy/dimension.py +++ b/momepy/dimension.py @@ -5,14 +5,19 @@ import math +import geopandas as gpd import numpy as np import pandas as pd import scipy as sp import shapely +from packaging.version import Version from tqdm.auto import tqdm from .shape import _circle_radius +GPD_GE_10 = Version(gpd.__version__) >= Version("1.0dev") + + __all__ = [ "Area", "Perimeter", @@ -903,7 +908,9 @@ def __init__(self, gdf, spatial_weights=None, verbose=True): print("Calculating spatial weights...") if verbose else None from libpysal.weights import Queen - spatial_weights = Queen.from_dataframe(gdf, silence_warnings=True) + spatial_weights = Queen.from_dataframe( + gdf, silence_warnings=True, use_index=False + ) print("Spatial weights ready...") if verbose else None self.sw = spatial_weights @@ -921,7 +928,11 @@ def __init__(self, gdf, spatial_weights=None, verbose=True): to_join = components[components == comp].index joined = geom.iloc[to_join] # buffer to avoid multipolygons where buildings touch by corners only - dissolved = joined.buffer(0.01).unary_union + dissolved = ( + joined.buffer(0.01).union_all() + if GPD_GE_10 + else joined.buffer(0.01).unary_union + ) for b in to_join: walls[b] = dissolved.exterior.length @@ -986,7 +997,9 @@ def __init__(self, gdf, spatial_weights=None, mean=False, verbose=True): print("Calculating spatial weights...") if verbose else None from libpysal.weights import Queen - spatial_weights = Queen.from_dataframe(gdf, silence_warnings=True) + spatial_weights = Queen.from_dataframe( + gdf, silence_warnings=True, use_index=False + ) print("Spatial weights ready...") if verbose else None self.sw = spatial_weights diff --git a/momepy/elements.py b/momepy/elements.py index d36d584c..9698e6e5 100644 --- a/momepy/elements.py +++ b/momepy/elements.py @@ -26,6 +26,7 @@ ] GPD_GE_013 = Version(gpd.__version__) >= Version("0.13.0") +GPD_GE_10 = Version(gpd.__version__) >= Version("1.0dev") def buffered_limit(gdf, buffer=100): @@ -52,7 +53,9 @@ def buffered_limit(gdf, buffer=100): >>> type(limit) shapely.geometry.polygon.Polygon """ - return gdf.buffer(buffer).unary_union + return ( + gdf.buffer(buffer).union_all() if GPD_GE_10 else gdf.buffer(buffer).unary_union + ) class Tessellation: @@ -242,7 +245,7 @@ def __init__( ) else: if isinstance(limit, gpd.GeoSeries | gpd.GeoDataFrame): - limit = limit.unary_union + limit = limit.union_all() if GPD_GE_10 else limit.unary_union bounds = shapely.bounds(limit) centre_x = (bounds[0] + bounds[2]) / 2 @@ -624,7 +627,9 @@ def __init__(self, tessellation, edges, buildings, id_name, unique_id): how="difference", ) cut = cut.explode(ignore_index=True) - weights = libpysal.weights.Queen.from_dataframe(cut, silence_warnings=True) + weights = libpysal.weights.Queen.from_dataframe( + cut, silence_warnings=True, use_index=False + ) cut["component"] = weights.component_labels buildings_c = buildings.copy() buildings_c.geometry = buildings_c.representative_point() # make points @@ -986,7 +991,7 @@ def enclosures( """ if limit is not None: if isinstance(limit, BaseGeometry): - limit = gpd.GeoSeries([limit]) + limit = gpd.GeoSeries([limit], crs=primary_barriers.crs) if limit.geom_type.isin(["Polygon", "MultiPolygon"]).any(): limit_b = limit.boundary else: @@ -994,7 +999,7 @@ def enclosures( barriers = pd.concat([primary_barriers.geometry, limit_b.geometry]) else: barriers = primary_barriers - unioned = barriers.unary_union + unioned = barriers.union_all() if GPD_GE_10 else barriers.unary_union polygons = polygonize(unioned) enclosures = gpd.GeoSeries(list(polygons), crs=primary_barriers.crs) @@ -1034,11 +1039,12 @@ def enclosures( ) # keep only those within original polygon new += list(polygons[within]) - final_enclosures = ( - pd.concat( - [gpd.GeoSeries(enclosures).drop(unique), gpd.GeoSeries(new)] - ).reset_index(drop=True) - ).set_crs(primary_barriers.crs) + final_enclosures = pd.concat( + [ + gpd.GeoSeries(enclosures).drop(unique), + gpd.GeoSeries(new, crs=primary_barriers.crs), + ] + ).reset_index(drop=True) final_enclosures = gpd.GeoDataFrame( {enclosure_id: range(len(final_enclosures))}, geometry=final_enclosures diff --git a/momepy/functional/_elements.py b/momepy/functional/_elements.py index 618b3d43..7fe1c411 100644 --- a/momepy/functional/_elements.py +++ b/momepy/functional/_elements.py @@ -10,7 +10,7 @@ from packaging.version import Version GPD_GE_013 = Version(gpd.__version__) >= Version("0.13.0") -GPD_GE_10 = Version(gpd.__version__) >= Version("1.0.0") +GPD_GE_10 = Version(gpd.__version__) >= Version("1.0dev") __all__ = [ "morphological_tessellation", diff --git a/momepy/functional/tests/test_elements.py b/momepy/functional/tests/test_elements.py index f4e89b89..4480f1a0 100644 --- a/momepy/functional/tests/test_elements.py +++ b/momepy/functional/tests/test_elements.py @@ -21,7 +21,8 @@ def setup_method(self): self.df_streets = gpd.read_file(test_file_path, layer="streets") self.limit = mm.buffered_limit(self.df_buildings, 50) self.enclosures = mm.enclosures( - self.df_streets, gpd.GeoSeries([self.limit.exterior]) + self.df_streets, + gpd.GeoSeries([self.limit.exterior], crs=self.df_streets.crs), ) def test_morphological_tessellation(self): @@ -77,6 +78,7 @@ def test_morphological_tessellation_errors(self): affinity.rotate(df.geometry.iloc[0], 12), ], index=[144, 145, 146], + crs=df.crs, ), ] ) @@ -155,6 +157,7 @@ def test_verify_tessellation(self): Polygon([(x, y), (x, y + 1), (x + 1, y)]), ], index=[144], + crs=df.crs, ), ] ) diff --git a/momepy/intensity.py b/momepy/intensity.py index f3771244..5aad2548 100644 --- a/momepy/intensity.py +++ b/momepy/intensity.py @@ -5,10 +5,14 @@ import collections +import geopandas as gpd import numpy as np import pandas as pd +from packaging.version import Version from tqdm.auto import tqdm # progress bar +GPD_GE_10 = Version(gpd.__version__) >= Version("1.0dev") + __all__ = [ "AreaRatio", "Count", @@ -247,7 +251,9 @@ def __init__(self, gdf, spatial_weights=None, verbose=True): print("Calculating spatial weights...") if verbose else None from libpysal.weights import Queen - spatial_weights = Queen.from_dataframe(gdf, silence_warnings=True) + spatial_weights = Queen.from_dataframe( + gdf, silence_warnings=True, use_index=False + ) self.sw = spatial_weights # dict to store nr of courtyards for each uID @@ -264,7 +270,11 @@ def __init__(self, gdf, spatial_weights=None, verbose=True): to_join = components[components == comp].index joined = gdf.loc[to_join] # buffer to avoid multipolygons where buildings touch by corners only - dissolved = joined.geometry.buffer(0.01).unary_union + dissolved = ( + joined.buffer(0.01).union_all() + if GPD_GE_10 + else joined.buffer(0.01).unary_union + ) interiors = len(list(dissolved.interiors)) for b in to_join: courtyards[b] = interiors # fill dict with values diff --git a/momepy/preprocessing.py b/momepy/preprocessing.py index 4ae44a06..9c5e4924 100644 --- a/momepy/preprocessing.py +++ b/momepy/preprocessing.py @@ -88,7 +88,9 @@ def preprocess( print("Loop", loop + 1, f"out of {loops}.") if verbose else None blg.reset_index(inplace=True, drop=True) blg["mm_uid"] = range(len(blg)) - sw = libpysal.weights.contiguity.Rook.from_dataframe(blg, silence_warnings=True) + sw = libpysal.weights.contiguity.Rook.from_dataframe( + blg, silence_warnings=True, use_index=False + ) blg["neighbors"] = sw.neighbors.values() blg["n_count"] = blg.apply(lambda row: len(row.neighbors), axis=1) blg["circu"] = CircularCompactness(blg).series @@ -152,7 +154,7 @@ def preprocess( if not subset.empty: geoms.append(blg[blg["mm_uid"] == j].iloc[0].geometry) blg.drop(blg[blg["mm_uid"] == j].index[0], inplace=True) - new_geom = shapely.ops.unary_union(geoms) + new_geom = shapely.union_all(geoms) blg.loc[blg.loc[blg["mm_uid"] == key].index[0], blg.geometry.name] = ( new_geom ) @@ -238,13 +240,13 @@ def remove_false_nodes(gdf): # remove incorrect geometries and append fixed versions df = df.drop(merge) - final = gpd.GeoSeries(new).explode(ignore_index=True) + final = gpd.GeoSeries(new, crs=df.crs).explode(ignore_index=True) if isinstance(gdf, gpd.GeoDataFrame): return pd.concat( [ df, gpd.GeoDataFrame( - {df.geometry.name: final}, geometry=df.geometry.name + {df.geometry.name: final}, geometry=df.geometry.name, crs=df.crs ), ], ignore_index=True, @@ -757,7 +759,7 @@ def _selecting_rabs_from_poly( rab_adj.index.name = "index" # adding a hausdorff_distance threshold - rab_adj["hdist"] = 0 + rab_adj["hdist"] = 0.0 # TODO: (should be a way to vectorize) for i, group in rab_adj.groupby("index_right"): for g in group.itertuples(): @@ -1312,7 +1314,7 @@ def _get_rebuilt_edges( cols_drop = ["new_origin_pt", "new_destination_pt"] new_edges_gdf = new_edges_gdf.drop(columns=cols_drop) - new_edges_gdf = new_edges_gdf.set_geometry("new_geometry", drop=True) + new_edges_gdf = new_edges_gdf.set_geometry("new_geometry") new_edges_gdf.loc[:, "length"] = new_edges_gdf.length # Update the indices: @@ -1573,10 +1575,9 @@ def __init__( # Polygonize street network polygons = gpd.GeoSeries( shapely.polygonize( # polygonize - [gdf.unary_union] - ).geoms, # get parts of the collection from polygonize - crs=gdf.crs, - ).explode(ignore_index=True) # shouldn't be needed but doesn't hurt to ensure + [gdf.dissolve().geometry.item()] + ) + ).explode(ignore_index=True) # Store geometries as a GeoDataFrame self.polygons = gpd.GeoDataFrame(geometry=polygons) diff --git a/momepy/tests/test_dimension.py b/momepy/tests/test_dimension.py index 79837458..3e72fa51 100644 --- a/momepy/tests/test_dimension.py +++ b/momepy/tests/test_dimension.py @@ -219,7 +219,7 @@ def test_StreetProfile(self): # avoid infinity blg = gpd.GeoDataFrame( - dict(height=[2, 5]), + {"height": [2, 5]}, geometry=[ Point(0, 0).buffer(10, cap_style=3), Point(30, 0).buffer(10, cap_style=3), diff --git a/momepy/tests/test_distribution.py b/momepy/tests/test_distribution.py index 703ae087..79a27f40 100644 --- a/momepy/tests/test_distribution.py +++ b/momepy/tests/test_distribution.py @@ -2,8 +2,8 @@ import numpy as np import pytest import shapely -from packaging.version import Version from libpysal.weights import Queen +from packaging.version import Version import momepy as mm @@ -173,7 +173,9 @@ def test_NeighboringStreetOrientationDeviation(self): assert self.df_streets["dev"].mean() == pytest.approx(check) def test_BuildingAdjacency(self): - sw = Queen.from_dataframe(self.df_buildings, ids="uID", silence_warnings=True) + sw = Queen.from_dataframe( + self.df_buildings, ids="uID", silence_warnings=True, use_index=False + ) swh = mm.sw_high(k=3, gdf=self.df_tessellation, ids="uID") self.df_buildings["adj_sw"] = mm.BuildingAdjacency( self.df_buildings, diff --git a/momepy/tests/test_diversity.py b/momepy/tests/test_diversity.py index 1919d043..c6f5af39 100644 --- a/momepy/tests/test_diversity.py +++ b/momepy/tests/test_diversity.py @@ -114,7 +114,7 @@ def test_Gini(self): self.df_tessellation.area - self.df_tessellation.area.mean() ) with pytest.raises(ValueError): - mm.Gini(self.df_tessellation, "negative", self.sw, "uID").series + mm.Gini(self.df_tessellation, "negative", self.sw, "uID").series # noqa: B018 assert ( mm.Gini(self.df_tessellation, "area", self.sw_drop, "uID") .series.isna() @@ -220,7 +220,9 @@ def test_Percentile(self): _data = {"uID": [9999], "area": 1.0} _pgon = [Polygon(((0, 0), (0, 1), (1, 1), (1, 0)))] - _gdf = gpd.GeoDataFrame(_data, index=[9999], geometry=_pgon) + _gdf = gpd.GeoDataFrame( + _data, index=[9999], geometry=_pgon, crs=self.df_tessellation.crs + ) perc = mm.Percentiles( pd.concat([self.df_tessellation, _gdf]), diff --git a/momepy/tests/test_elements.py b/momepy/tests/test_elements.py index 3fcb09b9..7e9f5d71 100644 --- a/momepy/tests/test_elements.py +++ b/momepy/tests/test_elements.py @@ -15,6 +15,7 @@ GPD_GE_013 = Version(gpd.__version__) >= Version("0.13.0") + class TestElements: def setup_method(self): test_file_path = mm.datasets.get_path("bubenec") @@ -24,7 +25,8 @@ def setup_method(self): self.df_streets["nID"] = range(len(self.df_streets)) self.limit = mm.buffered_limit(self.df_buildings, 50) self.enclosures = mm.enclosures( - self.df_streets, gpd.GeoSeries([self.limit.exterior]) + self.df_streets, + gpd.GeoSeries([self.limit.exterior], crs=self.df_streets.crs), ) def test_Tessellation(self): @@ -89,17 +91,18 @@ def test_erroroneous_geom(self): affinity.rotate(df.geometry.iloc[0], 12), ], index=[144, 145, 146], + crs=df.crs, ), ] ) - with pytest.warns( - UserWarning, match="Tessellation does not fully match buildings." - ): - mm.Tessellation(df, "uID", self.limit) - - with pytest.warns( - UserWarning, match="Tessellation contains MultiPolygon elements." + with ( + pytest.warns( + UserWarning, match="Tessellation does not fully match buildings." + ), + pytest.warns( + UserWarning, match="Tessellation contains MultiPolygon elements." + ), ): tess = mm.Tessellation(df, "uID", self.limit) assert tess.collapsed == {145} @@ -148,10 +151,17 @@ def test_Blocks_inner(self): assert not blocks.buildings_id.isna().any() assert len(blocks.blocks) == 9 if GPD_GE_013: - assert len(blocks.blocks.sindex.query(blocks.blocks.geometry, "overlaps")[0]) == 0 + assert ( + len(blocks.blocks.sindex.query(blocks.blocks.geometry, "overlaps")[0]) + == 0 + ) else: assert ( - len(blocks.blocks.sindex.query_bulk(blocks.blocks.geometry, "overlaps")[0]) + len( + blocks.blocks.sindex.query_bulk(blocks.blocks.geometry, "overlaps")[ + 0 + ] + ) == 0 ) @@ -186,8 +196,10 @@ def test_get_node_id_ratio(self): nx = mm.gdf_to_nx(self.df_streets) nodes, edges = mm.nx_to_gdf(nx) - convex_hull = edges.unary_union.convex_hull - enclosures = mm.enclosures(edges, limit=gpd.GeoSeries([convex_hull])) + convex_hull = edges.dissolve().convex_hull.item() + enclosures = mm.enclosures( + edges, limit=gpd.GeoSeries([convex_hull], crs=edges.crs) + ) enclosed_tess = mm.Tessellation( self.df_buildings, unique_id="uID", enclosures=enclosures ).tessellation @@ -214,32 +226,46 @@ def test_enclosures(self): assert len(limited) == 20 assert isinstance(limited, gpd.GeoDataFrame) - limited2 = mm.enclosures(self.df_streets, gpd.GeoSeries([self.limit])) + limited2 = mm.enclosures( + self.df_streets, gpd.GeoSeries([self.limit], crs=self.df_streets.crs) + ) assert len(limited2) == 20 assert isinstance(limited2, gpd.GeoDataFrame) b = self.limit.bounds - additional_barrier = gpd.GeoSeries([LineString([(b[0], b[1]), (b[2], b[3])])]) + additional_barrier = gpd.GeoSeries( + [LineString([(b[0], b[1]), (b[2], b[3])])], crs=self.df_streets.crs + ) additional = mm.enclosures( - self.df_streets, gpd.GeoSeries([self.limit]), [additional_barrier] + self.df_streets, + gpd.GeoSeries([self.limit], crs=self.df_streets.crs), + [additional_barrier], ) assert len(additional) == 28 assert isinstance(additional, gpd.GeoDataFrame) with pytest.raises(TypeError, match="`additional_barriers` expects a list"): additional = mm.enclosures( - self.df_streets, gpd.GeoSeries([self.limit]), additional_barrier + self.df_streets, + gpd.GeoSeries([self.limit], crs=self.df_streets.crs), + additional_barrier, ) # test clip - limit = self.df_streets.unary_union.convex_hull.buffer(-100) - encl = mm.enclosures(self.df_streets, limit=gpd.GeoSeries([limit]), clip=True) + limit = self.df_streets.dissolve().convex_hull.buffer(-100).item() + encl = mm.enclosures( + self.df_streets, + limit=gpd.GeoSeries([limit], crs=self.df_streets.crs), + clip=True, + ) assert len(encl) == 18 def test_get_network_ratio(self): - convex_hull = self.df_streets.unary_union.convex_hull - enclosures = mm.enclosures(self.df_streets, limit=gpd.GeoSeries([convex_hull])) + convex_hull = self.df_streets.dissolve().convex_hull.item() + enclosures = mm.enclosures( + self.df_streets, limit=gpd.GeoSeries([convex_hull], crs=self.df_streets.crs) + ) enclosed_tess = mm.Tessellation( self.df_buildings, unique_id="uID", enclosures=enclosures ).tessellation diff --git a/momepy/tests/test_graph.py b/momepy/tests/test_graph.py index a1af42e6..4f992b53 100644 --- a/momepy/tests/test_graph.py +++ b/momepy/tests/test_graph.py @@ -1,7 +1,5 @@ import geopandas as gpd -import networkx as nx import pytest -from packaging.version import Version import momepy as mm @@ -149,9 +147,9 @@ def test_straightness_centrality(self): net2 = mm.straightness_centrality( self.network, normalized=False, name="nonnorm" ) - G = self.network.copy() - G.add_node(1) - net3 = mm.straightness_centrality(G) + g = self.network.copy() + g.add_node(1) + net3 = mm.straightness_centrality(g) check = 0.8574045143712158 nonnorm = 0.8574045143712158 assert ( diff --git a/momepy/tests/test_intensity.py b/momepy/tests/test_intensity.py index c1866941..f2b7429c 100644 --- a/momepy/tests/test_intensity.py +++ b/momepy/tests/test_intensity.py @@ -2,8 +2,8 @@ import numpy as np import pytest from libpysal.weights import Queen -from shapely.geometry import Point from pandas.testing import assert_series_equal +from shapely.geometry import Point import momepy as mm @@ -103,11 +103,13 @@ def test_Count(self): with pytest.raises( TypeError, match="Geometry type does not support weighting." ): - mm.Count(point_gdf, self.blocks, "nID", "bID", weighted=True).series + mm.Count(point_gdf, self.blocks, "nID", "bID", weighted=True).series # noqa: B018 def test_Courtyards(self): courtyards = mm.Courtyards(self.df_buildings).series - sw = Queen.from_dataframe(self.df_buildings, silence_warnings=True) + sw = Queen.from_dataframe( + self.df_buildings, silence_warnings=True, use_index=False + ) courtyards_wm = mm.Courtyards(self.df_buildings, sw).series check = 0.6805555555555556 assert courtyards.mean() == check diff --git a/momepy/tests/test_preprocess.py b/momepy/tests/test_preprocess.py index fd28a2df..cf9b78db 100644 --- a/momepy/tests/test_preprocess.py +++ b/momepy/tests/test_preprocess.py @@ -2,7 +2,6 @@ import numpy as np import pytest from geopandas.testing import assert_geodataframe_equal -from packaging.version import Version from shapely import affinity from shapely.geometry import LineString, MultiPoint, Point, Polygon from shapely.ops import polygonize @@ -21,7 +20,7 @@ def setup_method(self): self.df_streets_rabs = gpd.read_file(test_file_path2, layer="test_rabs") plgns = polygonize(self.df_streets_rabs.geometry) self.df_rab_polys = gpd.GeoDataFrame( - geometry=[g for g in plgns], crs=self.df_streets_rabs.crs + geometry=list(plgns), crs=self.df_streets_rabs.crs ) self.test_file_path3 = mm.datasets.get_path("nyc_graph", extension="graphml") @@ -196,6 +195,7 @@ def test_consolidate_intersections_unsupported(self): rebuild_edges_method="banana", ) + def test_FaceArtifacts(): pytest.importorskip("esda") osmnx = pytest.importorskip("osmnx") diff --git a/momepy/tests/test_shape.py b/momepy/tests/test_shape.py index 04cfcd85..874c0f0f 100644 --- a/momepy/tests/test_shape.py +++ b/momepy/tests/test_shape.py @@ -3,7 +3,7 @@ import geopandas as gpd import numpy as np import pytest -from shapely.geometry import MultiLineString, Point, Polygon, MultiPolygon +from shapely.geometry import MultiLineString, MultiPolygon, Point, Polygon import momepy as mm from momepy.shape import _circle_area diff --git a/momepy/tests/test_utils.py b/momepy/tests/test_utils.py index 701d2dc5..b9f63b2b 100644 --- a/momepy/tests/test_utils.py +++ b/momepy/tests/test_utils.py @@ -2,7 +2,6 @@ import networkx import numpy as np import pytest -from packaging.version import Version from shapely.geometry import LineString, Point import momepy as mm @@ -134,6 +133,7 @@ def test_gdf_to_nx_labels(self): "x": 1603585.6402153103, "y": 6464428.773867372, } + def test_nx_to_gdf(self): nx = mm.gdf_to_nx(self.df_streets) nodes, edges, W = mm.nx_to_gdf(nx, spatial_weights=True) @@ -162,14 +162,14 @@ def test_nx_to_gdf(self): # check graph without attributes G = networkx.MultiGraph() key = 0 - for index, row in self.df_streets.iterrows(): + for _index, row in self.df_streets.iterrows(): first = row.geometry.coords[0] last = row.geometry.coords[-1] data = [row[f] for f in list(self.df_streets.columns)] - attributes = dict(zip(list(self.df_streets.columns), data)) + attributes = dict(zip(list(self.df_streets.columns), data, strict=False)) G.add_edge(first, last, key=key, **attributes) - key += 1 + key += 1 # noqa: SIM113 with pytest.warns(UserWarning, match="Approach is not set"): nodes, edges = mm.nx_to_gdf(G) @@ -197,7 +197,16 @@ def test_nx_to_gdf_osmnx(self): def test_limit_range(self): assert list(mm.limit_range(np.arange(10), rng=(25, 75))) == [2, 3, 4, 5, 6, 7] - assert list(mm.limit_range(np.arange(10), rng=(10, 90))) == [1, 2, 3, 4, 5, 6, 7, 8] + assert list(mm.limit_range(np.arange(10), rng=(10, 90))) == [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + ] assert list(mm.limit_range(np.array([0, 1]), rng=(25, 75))) == [0, 1] assert list( mm.limit_range(np.array([0, 1, 2, 3, 4, np.nan]), rng=(25, 75)) diff --git a/momepy/tests/test_weights.py b/momepy/tests/test_weights.py index 9a5a37c3..1334477d 100644 --- a/momepy/tests/test_weights.py +++ b/momepy/tests/test_weights.py @@ -13,7 +13,9 @@ def setup_method(self): self.df_tessellation["area"] = mm.Area(self.df_tessellation).series def test_sw_high(self): - first_order = libpysal.weights.Queen.from_dataframe(self.df_tessellation) + first_order = libpysal.weights.Queen.from_dataframe( + self.df_tessellation, use_index=False + ) from_sw = mm.sw_high(2, gdf=None, weights=first_order) from_df = mm.sw_high(2, gdf=self.df_tessellation) rook = mm.sw_high(2, gdf=self.df_tessellation, contiguity="rook") @@ -41,10 +43,10 @@ def test_DistanceBand(self): db_ids = mm.DistanceBand(self.df_buildings, 100, ids="uID") for k in range(len(self.df_buildings)): - assert k in db.neighbors.keys() + assert k in db.neighbors.keys() # noqa: SIM118 assert sorted(lp.neighbors[k]) == sorted(db.neighbors[k]) for k in self.df_buildings.uID: - assert k in db_ids.neighbors.keys() + assert k in db_ids.neighbors.keys() # noqa: SIM118 assert sorted(lp_ids.neighbors[k]) == sorted(db_ids.neighbors[k]) db_cent_false = mm.DistanceBand(self.df_buildings, 100, centroid=False) diff --git a/momepy/utils.py b/momepy/utils.py index bb437718..9dcc9715 100644 --- a/momepy/utils.py +++ b/momepy/utils.py @@ -96,7 +96,9 @@ def _generate_dual(graph, gdf_network, fields, angles, multigraph, angle): graph.graph["approach"] = "dual" key = 0 - sw = libpysal.weights.Queen.from_dataframe(gdf_network, silence_warnings=True) + sw = libpysal.weights.Queen.from_dataframe( + gdf_network, silence_warnings=True, use_index=False + ) cent = gdf_network.geometry.centroid gdf_network["temp_x_coords"] = cent.x gdf_network["temp_y_coords"] = cent.y diff --git a/momepy/weights.py b/momepy/weights.py index 3a6dd553..a634a585 100644 --- a/momepy/weights.py +++ b/momepy/weights.py @@ -122,11 +122,11 @@ def sw_high(k, gdf=None, weights=None, ids=None, contiguity="queen", silent=True elif gdf is not None: if contiguity == "queen": first_order = libpysal.weights.Queen.from_dataframe( - gdf, ids=ids, silence_warnings=silent + gdf, ids=ids, silence_warnings=silent, use_index=False ) elif contiguity == "rook": first_order = libpysal.weights.Rook.from_dataframe( - gdf, ids=ids, silence_warnings=silent + gdf, ids=ids, silence_warnings=silent, use_index=False ) else: raise ValueError(f"{contiguity} is not supported. Use 'queen' or 'rook'.") diff --git a/pyproject.toml b/pyproject.toml index 50e871b4..47f39dac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,7 +65,10 @@ momepy = ["datasets/bubenec.gpkg", "datasets/tests.gpkg"] line-length = 88 lint.select = ["E", "F", "W", "I", "UP", "N", "B", "A", "C4", "SIM", "ARG"] lint.ignore = ["B006", "F403", "SIM108"] -exclude = ["momepy/tests/*", "docs/*", "benchmarks/*"] +exclude = ["docs/*", "benchmarks/*"] + +[tool.ruff.lint.per-file-ignores] +"momepy/tests/*" = ["N802", "N806"] [tool.coverage.run] source = ['momepy'] From d5297074f73bc51047c093047e5cf08f0edb145b Mon Sep 17 00:00:00 2001 From: Martin Fleischmann Date: Mon, 29 Apr 2024 13:00:31 +0200 Subject: [PATCH 2/3] osmnx 2.0 compat --- momepy/tests/test_preprocess.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/momepy/tests/test_preprocess.py b/momepy/tests/test_preprocess.py index cf9b78db..a72ac295 100644 --- a/momepy/tests/test_preprocess.py +++ b/momepy/tests/test_preprocess.py @@ -167,7 +167,7 @@ def test_roundabout_simplification_center_type_mean(self): @pytest.mark.parametrize("method", ["spider", "euclidean", "extend"]) def test_consolidate_intersections(self, method): ox = pytest.importorskip("osmnx") - graph = ox.get_undirected(ox.load_graphml(self.test_file_path3)) + graph = ox.convert.to_undirected(ox.load_graphml(self.test_file_path3)) tol = 30 graph_simplified = mm.consolidate_intersections( @@ -186,7 +186,7 @@ def test_consolidate_intersections(self, method): def test_consolidate_intersections_unsupported(self): ox = pytest.importorskip("osmnx") - graph = ox.get_undirected(ox.load_graphml(self.test_file_path3)) + graph = ox.convert.to_undirected(ox.load_graphml(self.test_file_path3)) with pytest.raises(ValueError, match="Simplification 'banana' not recognized"): mm.consolidate_intersections( graph, From 9d1d944192b9c3aa92c22c2223b568d9600e75ce Mon Sep 17 00:00:00 2001 From: Martin Fleischmann Date: Mon, 29 Apr 2024 13:06:47 +0200 Subject: [PATCH 3/3] two more --- momepy/coins.py | 2 +- momepy/tests/test_preprocess.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/momepy/coins.py b/momepy/coins.py index afaf59d4..c6161854 100644 --- a/momepy/coins.py +++ b/momepy/coins.py @@ -61,7 +61,7 @@ class COINS: ----- The LineStrings of the ``edge_gdf`` are not expected to overlap. If you are creating it using OSMnx, don't forget to cast the graph to undirected using - ``osmnx.get_undirected(G)`` prior converting it to a GeoDataFrame. + ``osmnx.convert.to_undirected(G)`` prior converting it to a GeoDataFrame. """ def __init__(self, edge_gdf, angle_threshold=0): diff --git a/momepy/tests/test_preprocess.py b/momepy/tests/test_preprocess.py index a72ac295..b1ca475a 100644 --- a/momepy/tests/test_preprocess.py +++ b/momepy/tests/test_preprocess.py @@ -214,7 +214,7 @@ def test_FaceArtifacts(): ) streets_graph = osmnx.projection.project_graph(streets_graph) gdf = osmnx.graph_to_gdfs( - osmnx.get_undirected(streets_graph), + osmnx.convert.to_undirected(streets_graph), nodes=False, edges=True, node_geometry=False,