Skip to content

Commit

Permalink
BUG/ENH: support custom enclosure index is in tessellation and GeoDat…
Browse files Browse the repository at this point in the history
…aFrame as enclosure input (#582)

* BUG: ensure custom enclosure index is supported in tessellation

* support both series and datarame as enclosures input

* tests

* typing
  • Loading branch information
martinfleis committed May 20, 2024
1 parent 452a449 commit ee49502
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
17 changes: 11 additions & 6 deletions momepy/functional/_elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def morphological_tessellation(

def enclosed_tessellation(
geometry: GeoSeries | GeoDataFrame,
enclosures: GeoSeries,
enclosures: GeoSeries | GeoDataFrame,
shrink: float = 0.4,
segment: float = 0.5,
threshold: float = 0.05,
Expand Down Expand Up @@ -129,7 +129,7 @@ def enclosed_tessellation(
----------
geometry : GeoSeries | GeoDataFrame
A GeoDataFrame or GeoSeries containing buildings to tessellate the space around.
enclosures : GeoSeries
enclosures : GeoSeries | GeoDataFrame
The enclosures geometry, which can be generated using :func:`momepy.enclosures`.
shrink : float, optional
The distance for negative buffer to generate space between adjacent polygons).
Expand Down Expand Up @@ -161,7 +161,7 @@ def enclosed_tessellation(
"""

# convert to GeoDataFrame and add position (we will need it later)
enclosures = enclosures.to_frame()
enclosures = enclosures.geometry.to_frame()
enclosures["position"] = range(len(enclosures))

# preserve index name if exists
Expand Down Expand Up @@ -206,17 +206,22 @@ def enclosed_tessellation(
unchanged_in_new = new_df.loc[[-1]]
new_df = new_df.drop(-1)
clean_blocks = pd.concat(
[enclosures.drop(altered).drop(columns="position"), unchanged_in_new]
[
enclosures.drop(enclosures.index[altered]).drop(columns="position"),
unchanged_in_new,
]
)
else:
clean_blocks = enclosures.drop(altered).drop(columns="position")
clean_blocks = enclosures.drop(enclosures.index[altered]).drop(
columns="position"
)

# assign negative index to enclosures with no buildings
clean_blocks.index = range(-len(clean_blocks), 0, 1)

# get building index for enclosures with single building
singles = enclosures.iloc[single]
singles.index = singles.position.loc[single].apply(
singles.index = singles.position.loc[singles.index].apply(
lambda ix: geometry.iloc[res[inp == ix]].index[0]
)
# combine results
Expand Down
17 changes: 17 additions & 0 deletions momepy/functional/tests/test_elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,23 @@ def test_enclosed_tessellation(self):
threshold_elimination.sort_values("geometry").reset_index(drop=True),
)

tessellation_df = mm.enclosed_tessellation(
self.df_buildings,
self.enclosures,
)
assert_geodataframe_equal(tessellation, tessellation_df)

custom_index = self.enclosures
custom_index.index = (custom_index.index + 100).astype(str)
tessellation_custom_index = mm.enclosed_tessellation(
self.df_buildings,
custom_index,
)
assert (tessellation_custom_index.geom_type == "Polygon").all()
assert tessellation_custom_index.crs == self.df_buildings.crs
assert (self.df_buildings.index.isin(tessellation_custom_index.index)).all()
assert tessellation_custom_index.enclosure_index.isin(custom_index.index).all()

def test_verify_tessellation(self):
df = self.df_buildings
b = df.total_bounds
Expand Down

0 comments on commit ee49502

Please sign in to comment.