Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MAINT: compatibility, warning cleanup, test lint #574

Merged
merged 3 commits into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion momepy/coins.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
19 changes: 16 additions & 3 deletions momepy/dimension.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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

Expand All @@ -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

Expand Down Expand Up @@ -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

Expand Down
26 changes: 16 additions & 10 deletions momepy/elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -52,7 +53,9 @@
>>> 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:
Expand Down Expand Up @@ -242,7 +245,7 @@
)
else:
if isinstance(limit, gpd.GeoSeries | gpd.GeoDataFrame):
limit = limit.unary_union
limit = limit.union_all() if GPD_GE_10 else limit.unary_union

Check warning on line 248 in momepy/elements.py

View check run for this annotation

Codecov / codecov/patch

momepy/elements.py#L248

Added line #L248 was not covered by tests

bounds = shapely.bounds(limit)
centre_x = (bounds[0] + bounds[2]) / 2
Expand Down Expand Up @@ -624,7 +627,9 @@
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
Expand Down Expand Up @@ -986,15 +991,15 @@
"""
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:
limit_b = limit
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)

Expand Down Expand Up @@ -1034,11 +1039,12 @@
) # 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
Expand Down
2 changes: 1 addition & 1 deletion momepy/functional/_elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
5 changes: 4 additions & 1 deletion momepy/functional/tests/test_elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -77,6 +78,7 @@ def test_morphological_tessellation_errors(self):
affinity.rotate(df.geometry.iloc[0], 12),
],
index=[144, 145, 146],
crs=df.crs,
),
]
)
Expand Down Expand Up @@ -155,6 +157,7 @@ def test_verify_tessellation(self):
Polygon([(x, y), (x, y + 1), (x + 1, y)]),
],
index=[144],
crs=df.crs,
),
]
)
Expand Down
14 changes: 12 additions & 2 deletions momepy/intensity.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
21 changes: 11 additions & 10 deletions momepy/preprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
)
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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():
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion momepy/tests/test_dimension.py
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
6 changes: 4 additions & 2 deletions momepy/tests/test_distribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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,
Expand Down
6 changes: 4 additions & 2 deletions momepy/tests/test_diversity.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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]),
Expand Down
Loading