Skip to content

Commit

Permalink
multiindex additions
Browse files Browse the repository at this point in the history
  • Loading branch information
u3ks committed Jun 20, 2024
1 parent efbb4d5 commit 29c3ef5
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 63 deletions.
32 changes: 31 additions & 1 deletion momepy/functional/_elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from libpysal.cg import voronoi_frames
from libpysal.graph import Graph
from packaging.version import Version
from pandas import Series
from pandas import MultiIndex, Series

GPD_GE_013 = Version(gpd.__version__) >= Version("0.13.0")
GPD_GE_10 = Version(gpd.__version__) >= Version("1.0dev")
Expand Down Expand Up @@ -103,6 +103,10 @@ def morphological_tessellation(
4 POLYGON ((1603084.231 6464104.386, 1603083.773...
"""

if isinstance(geometry.index, MultiIndex):
raise ValueError("MultiIndex is not supported for tessellation.")

if isinstance(clip, GeoSeries | GeoDataFrame):
clip = clip.union_all() if GPD_GE_10 else clip.unary_union

Expand Down Expand Up @@ -218,6 +222,9 @@ def enclosed_tessellation(
126 POLYGON ((1603528.593 6464221.033, 1603527.796... 0
"""

if isinstance(geometry.index, MultiIndex):
raise ValueError("MultiIndex is not supported for tessellation.")

# convert to GeoDataFrame and add position (we will need it later)
enclosures = enclosures.geometry.to_frame()
enclosures["position"] = range(len(enclosures))
Expand Down Expand Up @@ -354,6 +361,12 @@ def verify_tessellation(tessellation, geometry):
>>> excluded, multipolygons = momepy.verify_tessellation(tessellation, buildings)
"""

if isinstance(geometry.index, MultiIndex) or isinstance(
tessellation.index, MultiIndex
):
raise ValueError("MultiIndex is not supported for tessellation.")

# check against input layer
ids_original = geometry.index
ids_generated = tessellation.index
Expand Down Expand Up @@ -516,6 +529,17 @@ def get_nearest_node(
143 22.0
Length: 144, dtype: float64
"""

if (
isinstance(buildings.index, MultiIndex)
or isinstance(nearest_edge.index, MultiIndex)
or isinstance(nodes.index, MultiIndex)
or isinstance(edges.index, MultiIndex)
):
raise ValueError(
"MultiIndex is not supported for calculating the nearest node."
)

# treat possibly missing edge index
a = np.empty(len(buildings))
na_mask = np.isnan(nearest_edge)
Expand Down Expand Up @@ -600,6 +624,12 @@ def generate_blocks(
>>> tessellation["block_id"] = tessellation_id
"""

if (
isinstance(buildings.index, MultiIndex)
or isinstance(tessellation.index, MultiIndex)
or isinstance(edges.index, MultiIndex)
):
raise ValueError("MultiIndex is not supported for generating blocks.")
id_name: str = "bID"

# slice the tessellations by the street network
Expand Down
8 changes: 6 additions & 2 deletions momepy/functional/_shape.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from geopandas import GeoDataFrame, GeoSeries
from numpy.typing import NDArray
from packaging.version import Version
from pandas import DataFrame, Series
from pandas import DataFrame, MultiIndex, Series

from momepy.functional import _dimension

Expand Down Expand Up @@ -724,6 +724,10 @@ def centroid_corner_distance(
"momepy.centroid_corner_distance requires geopandas 0.13 or later. "
)

result_index = geometry.index
if isinstance(geometry.index, MultiIndex):
geometry = geometry.reset_index(drop=True)

def _ccd(points: DataFrame, eps: float) -> Series:
centroid = points.values[0, 2:]
pts = points.values[:-1, :2]
Expand All @@ -738,7 +742,7 @@ def _ccd(points: DataFrame, eps: float) -> Series:
coords = geometry.exterior.get_coordinates(index_parts=False)
coords[["cent_x", "cent_y"]] = geometry.centroid.get_coordinates(index_parts=False)
ccd = coords.groupby(level=0).apply(_ccd, eps=eps)
ccd.index = geometry.index
ccd.index = result_index
return ccd


Expand Down
28 changes: 28 additions & 0 deletions momepy/functional/tests/test_elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,34 @@ def test_blocks_inner(self):
else:
assert len(blocks.sindex.query_bulk(blocks.geometry, "overlaps")[0]) == 0

def test_multi_index(self):
buildings = self.df_buildings.set_index(["uID", "uID"])
with pytest.raises(
ValueError, match="MultiIndex is not supported for tessellation."
):
mm.morphological_tessellation(buildings)
with pytest.raises(
ValueError, match="MultiIndex is not supported for tessellation."
):
mm.enclosed_tessellation(buildings, self.enclosures)
with pytest.raises(
ValueError, match="MultiIndex is not supported for tessellation."
):
mm.verify_tessellation(buildings, self.enclosures)

with pytest.raises(
ValueError,
match="MultiIndex is not supported for calculating the nearest node.",
):
mm.get_nearest_node(
buildings, self.enclosures, self.enclosures, self.enclosures
)

with pytest.raises(
ValueError, match="MultiIndex is not supported for generating blocks."
):
mm.generate_blocks(buildings, self.enclosures, self.enclosures)


class TestElementsEquivalence:
def setup_method(self):
Expand Down
60 changes: 0 additions & 60 deletions momepy/functional/tests/test_multi_index.py

This file was deleted.

0 comments on commit 29c3ef5

Please sign in to comment.