将边/边重新组织成适当的多边形

问题描述 投票:0回答:1

如何将结果 (

list_
) 重新组织成适当的多边形。

我们有几个多边形

import geopandas as gpd
import matplotlib.pyplot as plt

polys = gpd.GeoSeries([Polygon([(0,0), (2,0), (2, 1.5), (2,2), (0,2)]),
                     Polygon([(0,2), (2,2), (2,4), (0,4)]),
                     Polygon([(2,0), (5,0), (5,1.5), (2,1.5)]),
                     Polygon([(3,3), (5,3), (5,5), (3,5)])])

fp = gpd.GeoDataFrame({'geometry': polys, 'name': ['a', 'b', 'c', 'd'],
                      'grnd': [25, 25, 25, 25],
                      'rf': [29, 35, 26, 31]})

fig, ax = plt.subplots(figsize=(5, 5))
fp.plot(ax=ax, alpha=0.3, cmap='tab10', edgecolor='k',)
fp.apply(lambda x: ax.annotate(text=x['name'], xy=x.geometry.centroid.coords[0], ha='center'), axis=1)
plt.show()

我们想要在边的任一侧收获一些属性(

grnd
name
rf
)。

# Create series of all the line segments
lines = fp.geometry.apply(lambda x: list(map(
    LineString, 
    zip(x.boundary.coords[:-1], x.boundary.coords[1:]))
)).explode()

result = {line : list(fp.loc[
          (fp.geometry.touches(line)) # line touches the polygon
          & (fp.geometry.intersection(line).length > 0), # And the intersection is more than just a point 
          'rf'].values)
          for line in lines}
result
{<LINESTRING (0 0, 2 0)>: [29],
 <LINESTRING (2 0, 2 1.5)>: [29, 26],
 <LINESTRING (2 1.5, 2 2)>: [29],
 <LINESTRING (2 2, 0 2)>: [29, 35],
 <LINESTRING (0 2, 0 0)>: [29],
 <LINESTRING (0 2, 2 2)>: [29, 35],
 <LINESTRING (2 2, 2 4)>: [35],
 <LINESTRING (2 4, 0 4)>: [35],
 <LINESTRING (0 4, 0 2)>: [35],
 <LINESTRING (2 0, 5 0)>: [26],
 <LINESTRING (5 0, 5 1.5)>: [26],
 <LINESTRING (5 1.5, 2 1.5)>: [26],
 <LINESTRING (2 1.5, 2 0)>: [29, 26],
 <LINESTRING (3 3, 5 3)>: [31],
 <LINESTRING (5 3, 5 5)>: [31],
 <LINESTRING (5 5, 3 5)>: [31],
 <LINESTRING (3 5, 3 3)>: [31]}

可以确定每个多边形的边/边数:

s = fp.geometry.apply(lambda x: len(x.exterior.coords)) - 1
s
0    5
1    4
2    4
3    4
Name: geometry, dtype: int64

我可以组合(不重复)并对属性进行排序,但不知道如何将边/边分组到它们的多边形中。

list_ = []
for k, v in result.items():
    l = [l.tolist() for l in result[k]]
    if len(l) > 1:
        list_.append(sorted(set(l)))
    else:
        list_.append(l)
print(list_)

[[29], [26, 29], [29], [29, 35], [29], [29, 35], [35], [35], [35], [26], [26], [26], [26, 29], [31], [31], [31], [31]]

如何将

list_
分组到他们的多边形中;列表(从每条边向上一层)在哪里是多边形?有点像..

[[[29], [26, 29], [29], [29, 35], [29]], 
[[29, 35], [35], [35], [35]],
[[26], [26], [26], [26, 29]], 
[[31], [31], [31], [31]]]
python list dictionary polygon
1个回答
0
投票

在创建 '具有公共边的边'

dict

的原始函数中重新排序
with warnings.catch_warnings():
    warnings.simplefilter('ignore')
    result = {poly_name: {
        'sides': list(poly_sides),
        'edges': [list(fp.loc[
            (fp.geometry.touches(line)) # line touches the polygons
            & (fp.geometry.intersection(line).length > 0), # And the intersection is more than just a point 
            'rf'].values.tolist())
                  for line in poly_sides]}
              for poly_name, poly_sides in lines.groupby(fp.name)}
result['a']
{'a': {'sides': [<LINESTRING (0 0, 2 0)>,
   <LINESTRING (2 0, 2 1.5)>,
   <LINESTRING (2 1.5, 2 2)>,
   <LINESTRING (2 2, 0 2)>,
   <LINESTRING (0 2, 0 0)>],
  'edges': [[29], [29, 26], [29], [29, 35], [29]]},
 'b': {'sides': [<LINESTRING (0 2, 2 2)>,
   <LINESTRING (2 2, 2 4)>,
   <LINESTRING (2 4, 0 4)>,
   <LINESTRING (0 4, 0 2)>],
  'edges': [[29, 35], [35], [35], [35]]},
 'c': {'sides': [<LINESTRING (2 0, 5 0)>,
   <LINESTRING (5 0, 5 1.5)>,
   <LINESTRING (5 1.5, 2 1.5)>,
   <LINESTRING (2 1.5, 2 0)>],
  'edges': [[26], [26], [26], [29, 26]]},
 'd': {'sides': [<LINESTRING (3 3, 5 3)>,
   <LINESTRING (5 3, 5 5)>,
   <LINESTRING (5 5, 3 5)>,
   <LINESTRING (3 5, 3 3)>],
  'edges': [[31], [31], [31], [31]]}}
© www.soinside.com 2019 - 2024. All rights reserved.