@@ -30,6 +30,7 @@ def morphological_tessellation(
30
30
clip : str | shapely .Geometry | GeoSeries | GeoDataFrame | None = "bounding_box" ,
31
31
shrink : float = 0.4 ,
32
32
segment : float = 0.5 ,
33
+ simplify : bool = True ,
33
34
** kwargs ,
34
35
) -> GeoDataFrame :
35
36
"""Generate morphological tessellation.
@@ -70,6 +71,9 @@ def morphological_tessellation(
70
71
By default 0.4
71
72
segment : float, optional
72
73
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.
73
77
**kwargs
74
78
Additional keyword arguments pased to libpysal.cg.voronoi_frames, such as
75
79
``grid_size``.
@@ -98,13 +102,20 @@ def morphological_tessellation(
98
102
99
103
>>> momepy.morphological_tessellation(buildings).head()
100
104
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 ...
106
110
107
111
"""
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
+ )
108
119
109
120
if isinstance (geometry .index , MultiIndex ):
110
121
raise ValueError (
@@ -114,7 +125,7 @@ def morphological_tessellation(
114
125
if isinstance (clip , GeoSeries | GeoDataFrame ):
115
126
clip = clip .union_all () if GPD_GE_10 else clip .unary_union
116
127
117
- return voronoi_frames (
128
+ mt = voronoi_frames (
118
129
geometry ,
119
130
clip = clip ,
120
131
shrink = shrink ,
@@ -123,6 +134,11 @@ def morphological_tessellation(
123
134
as_gdf = True ,
124
135
** kwargs ,
125
136
)
137
+ if simplify :
138
+ mt .geometry = shapely .coverage_simplify (
139
+ mt .geometry , tolerance = segment / 2 , simplify_boundary = False
140
+ )
141
+ return mt
126
142
127
143
128
144
def enclosed_tessellation (
@@ -236,6 +252,8 @@ def enclosed_tessellation(
236
252
"""
237
253
238
254
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
239
257
raise ImportError (
240
258
"`simplify=True` requires shapely 2.1 or higher. "
241
259
"Update shapely or set `simplify` to False."
@@ -330,10 +348,9 @@ def _tess(ix, poly, blg, threshold, shrink, segment, enclosure_id, to_simplify,
330
348
** kwargs ,
331
349
)
332
350
if to_simplify :
333
- simpl_collection = shapely .coverage_simplify (
351
+ tess . geometry = shapely .coverage_simplify (
334
352
tess .geometry , tolerance = segment / 2 , simplify_boundary = False
335
353
)
336
- tess .geometry = gpd .GeoSeries (simpl_collection ).values
337
354
tess [enclosure_id ] = ix
338
355
return tess
339
356
@@ -619,24 +636,24 @@ def generate_blocks(
619
636
Generate tessellation:
620
637
621
638
>>> tessellation = momepy.morphological_tessellation(buildings)
622
- >>> tessellation
639
+ >>> tessellation.head()
623
640
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 ...
629
646
630
647
>>> blocks, tessellation_id = momepy.generate_blocks(
631
648
... tessellation, streets, buildings
632
649
... )
633
650
>>> blocks.head()
634
651
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 ...
640
657
641
658
``tessellation_id`` can be directly assigned to its
642
659
respective parental DataFrame directly.
0 commit comments