@@ -30,6 +30,7 @@ def morphological_tessellation(
3030 clip : str | shapely .Geometry | GeoSeries | GeoDataFrame | None = "bounding_box" ,
3131 shrink : float = 0.4 ,
3232 segment : float = 0.5 ,
33+ simplify : bool = True ,
3334 ** kwargs ,
3435) -> GeoDataFrame :
3536 """Generate morphological tessellation.
@@ -70,6 +71,9 @@ def morphological_tessellation(
7071 By default 0.4
7172 segment : float, optional
7273 The maximum distance between points after discretization. By default 0.5
74+ simplify: bool, optional
75+ Whether to attempt to simplify the resulting tesselation boundaries with
76+ ``shapely.coverage_simplify``. By default True.
7377 **kwargs
7478 Additional keyword arguments pased to libpysal.cg.voronoi_frames, such as
7579 ``grid_size``.
@@ -98,13 +102,20 @@ def morphological_tessellation(
98102
99103 >>> momepy.morphological_tessellation(buildings).head()
100104 geometry
101- 0 POLYGON ((1603577.153 6464348.291, 1603576.946 ...
102- 1 POLYGON ((1603166.356 6464326.62, 1603166.425 ...
103- 2 POLYGON ((1603006.941 6464167.63, 1603009.97 6...
104- 3 POLYGON ((1602995.269 6464132.007, 1603001.768 ...
105- 4 POLYGON ((1603084.231 6464104.386, 1603083.773 ...
105+ 0 POLYGON ((1603536.56 6464392.264, 1603541.262 ...
106+ 1 POLYGON ((1603167.679 6464323.194, 1603167.552 ...
107+ 2 POLYGON ((1603078.787 6464172.1, 1603077.665 6...
108+ 3 POLYGON ((1603070.306 6464154.611, 1603070.081 ...
109+ 4 POLYGON ((1603083.134 6464103.971, 1603077.387 ...
106110
107111 """
112+ if simplify and not SHPLY_GE_210 :
113+ # TODO: remove the keyword and do simplification by default once it is
114+ # safe to pin shapely 2.1
115+ raise ImportError (
116+ "`simplify=True` requires shapely 2.1 or higher. "
117+ "Update shapely or set `simplify` to False."
118+ )
108119
109120 if isinstance (geometry .index , MultiIndex ):
110121 raise ValueError (
@@ -114,7 +125,7 @@ def morphological_tessellation(
114125 if isinstance (clip , GeoSeries | GeoDataFrame ):
115126 clip = clip .union_all () if GPD_GE_10 else clip .unary_union
116127
117- return voronoi_frames (
128+ mt = voronoi_frames (
118129 geometry ,
119130 clip = clip ,
120131 shrink = shrink ,
@@ -123,6 +134,11 @@ def morphological_tessellation(
123134 as_gdf = True ,
124135 ** kwargs ,
125136 )
137+ if simplify :
138+ mt .geometry = shapely .coverage_simplify (
139+ mt .geometry , tolerance = segment / 2 , simplify_boundary = False
140+ )
141+ return mt
126142
127143
128144def enclosed_tessellation (
@@ -236,6 +252,8 @@ def enclosed_tessellation(
236252 """
237253
238254 if simplify and not SHPLY_GE_210 :
255+ # TODO: remove the keyword and do simplification by default once it is
256+ # safe to pin shapely 2.1
239257 raise ImportError (
240258 "`simplify=True` requires shapely 2.1 or higher. "
241259 "Update shapely or set `simplify` to False."
@@ -330,10 +348,9 @@ def _tess(ix, poly, blg, threshold, shrink, segment, enclosure_id, to_simplify,
330348 ** kwargs ,
331349 )
332350 if to_simplify :
333- simpl_collection = shapely .coverage_simplify (
351+ tess . geometry = shapely .coverage_simplify (
334352 tess .geometry , tolerance = segment / 2 , simplify_boundary = False
335353 )
336- tess .geometry = gpd .GeoSeries (simpl_collection ).values
337354 tess [enclosure_id ] = ix
338355 return tess
339356
@@ -619,24 +636,24 @@ def generate_blocks(
619636 Generate tessellation:
620637
621638 >>> tessellation = momepy.morphological_tessellation(buildings)
622- >>> tessellation
639+ >>> tessellation.head()
623640 geometry
624- 0 POLYGON ((1603577.153 6464348.291, 1603576.946 ...
625- 1 POLYGON ((1603166.356 6464326.62, 1603166.425 ...
626- 2 POLYGON ((1603006.941 6464167.63, 1603009.97 6...
627- 3 POLYGON ((1602995.269 6464132.007, 1603001.768 ...
628- 4 POLYGON ((1603084.231 6464104.386, 1603083.773 ...
641+ 0 POLYGON ((1603536.56 6464392.264, 1603541.262 ...
642+ 1 POLYGON ((1603167.679 6464323.194, 1603167.552 ...
643+ 2 POLYGON ((1603078.787 6464172.1, 1603077.665 6...
644+ 3 POLYGON ((1603070.306 6464154.611, 1603070.081 ...
645+ 4 POLYGON ((1603083.134 6464103.971, 1603077.387 ...
629646
630647 >>> blocks, tessellation_id = momepy.generate_blocks(
631648 ... tessellation, streets, buildings
632649 ... )
633650 >>> blocks.head()
634651 geometry
635- 0 POLYGON ((1603500.079 6464214.019, 1603499.565 ...
636- 1 POLYGON ((1603431.893 6464278.302, 1603431.553 ...
637- 2 POLYGON ((1603321.257 6464125.859, 1603320.938 ...
638- 3 POLYGON ((1603137.411 6464124.658, 1603137.116 ...
639- 4 POLYGON ((1603179.384 6463961.584, 1603179.357 ...
652+ 0 POLYGON ((1603421.741 6464282.377, 1603415.23 ...
653+ 1 POLYGON ((1603485.548 6464217.177, 1603483.228 ...
654+ 2 POLYGON ((1603314.034 6464117.593, 1603295.424 ...
655+ 3 POLYGON ((1602992.334 6464131.13, 1602992.334 ...
656+ 4 POLYGON ((1602992.334 6463992.499, 1602992.334 ...
640657
641658 ``tessellation_id`` can be directly assigned to its
642659 respective parental DataFrame directly.
0 commit comments