将多边形数组转换为多多边形

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

我有一组多边形。我需要将数组转换为多边形。

["POLYGON ((-93.8153401599999 31.6253224010001, -93.8154545089999 31.613245482, -93.8256952309999 31.6133096470001, -93.8239846819999 31.6142335050001, -93.822649241 31.614534889, -93.819589744 31.6141266810001, -93.8187199179999 31.6145615630001, -93.818796329 31.6166099970001, -93.8191396409999 31.616805696, -93.822160944 31.6185287610001, -93.8259606669999 31.6195415540001, -93.827173805 31.6202834370001, -93.826861 31.621054014, -93.826721397 31.6210996090001, -93.825838469 31.621387795, -93.823763302 31.620645804, -93.8224278609999 31.620880388, -93.8207344099999 31.6214468590001, -93.817712918 31.621645233, -93.8171636009999 31.6218779230001, -93.8170138 31.622175612, -93.816896795 31.622408104, -93.816843193 31.622514901, -93.8172703129999 31.623758464, -93.817027909 31.6250143240001, -93.816942408 31.624910524, -93.8153401599999 31.6253224010001))", "POLYGON ((-93.827875499 31.6135011530001, -93.8276549939999 31.6133218590001, -93.830593683 31.613340276, -93.827860513 31.616556659, -93.825911348 31.6159317660001, -93.825861447 31.615915767, -93.826296355 31.6149087000001, -93.8272805829999 31.614407122, -93.827341685 31.6143140250001, -93.827875499 31.6135011530001))"]

我正在使用以下代码使用 Apache Sedona 转换多边形

select FID,ST_Multi(ST_GeomFromText(collect_list(polygon))) polygon_list group by 1

我收到类似“org.apache.spark.sql.catalyst.util.GenericArrayData 无法转换为 org.apache.spark.unsafe.types.UTF8String”的错误。如何克服此问题?使用 Geopandas 或 shapely 可以实现同样的效果吗?

geospatial spatial geopandas shapely spatial-query
3个回答
2
投票

@Antoine B 给出的答案是一个非常好的尝试。但它不适用于其中有孔的多边形。还有另一种方法可以处理此类多边形,并且代码更容易理解。

from shapely.geometry import Polygon, MultiPolygon
from shapely import wkt
from shapely.wkt import loads

# List of strings representing polygons (each without hole)
poly_string = ["POLYGON ((-93.8153401599999 31.6253224010001, -93.8154545089999 31.613245482, -93.8256952309999 31.6133096470001, -93.8239846819999 31.6142335050001, -93.822649241 31.614534889, -93.819589744 31.6141266810001, -93.8187199179999 31.6145615630001, -93.818796329 31.6166099970001, -93.8191396409999 31.616805696, -93.822160944 31.6185287610001, -93.8259606669999 31.6195415540001, -93.827173805 31.6202834370001, -93.826861 31.621054014, -93.826721397 31.6210996090001, -93.825838469 31.621387795, -93.823763302 31.620645804, -93.8224278609999 31.620880388, -93.8207344099999 31.6214468590001, -93.817712918 31.621645233, -93.8171636009999 31.6218779230001, -93.8170138 31.622175612, -93.816896795 31.622408104, -93.816843193 31.622514901, -93.8172703129999 31.623758464, -93.817027909 31.6250143240001, -93.816942408 31.624910524, -93.8153401599999 31.6253224010001))", "POLYGON ((-93.827875499 31.6135011530001, -93.8276549939999 31.6133218590001, -93.830593683 31.613340276, -93.827860513 31.616556659, -93.825911348 31.6159317660001, -93.825861447 31.615915767, -93.826296355 31.6149087000001, -93.8272805829999 31.614407122, -93.827341685 31.6143140250001, -93.827875499 31.6135011530001))"]

# Create a list of polygons from the list of strings
all_pgons = [loads(pgon) for pgon in poly_string]

# Create the required multipolygon
multi_pgon = MultiPolygon(all_pgons)

这是一个多边形(字符串)列表,每个多边形都有一个洞。

# List of polygons with hole
poly_string = ['POLYGON ((1 2, 1 5, 4 4, 1 2), (1.2 3, 3 4, 1.3 4, 1.2 3))', 
               'POLYGON ((11 12, 11 15, 14 14, 11 12), (11.2 13, 13 14, 11.3 14, 11.2 13))']

上面的代码在这种情况下也能很好地工作。


1
投票

a

MultiPolygon
只是
Polygon
的列表,因此您需要重建列表中的每个
Polygon
,然后将其传递给
MultiPolygon

根据您提供的字符串格式,我让它像这样工作:

from shapely.geometry import Polygon, MultiPolygon

poly_string = ["POLYGON ((-93.8153401599999 31.6253224010001, -93.8154545089999 31.613245482, -93.8256952309999 31.6133096470001, -93.8239846819999 31.6142335050001, -93.822649241 31.614534889, -93.819589744 31.6141266810001, -93.8187199179999 31.6145615630001, -93.818796329 31.6166099970001, -93.8191396409999 31.616805696, -93.822160944 31.6185287610001, -93.8259606669999 31.6195415540001, -93.827173805 31.6202834370001, -93.826861 31.621054014, -93.826721397 31.6210996090001, -93.825838469 31.621387795, -93.823763302 31.620645804, -93.8224278609999 31.620880388, -93.8207344099999 31.6214468590001, -93.817712918 31.621645233, -93.8171636009999 31.6218779230001, -93.8170138 31.622175612, -93.816896795 31.622408104, -93.816843193 31.622514901, -93.8172703129999 31.623758464, -93.817027909 31.6250143240001, -93.816942408 31.624910524, -93.8153401599999 31.6253224010001))", "POLYGON ((-93.827875499 31.6135011530001, -93.8276549939999 31.6133218590001, -93.830593683 31.613340276, -93.827860513 31.616556659, -93.825911348 31.6159317660001, -93.825861447 31.615915767, -93.826296355 31.6149087000001, -93.8272805829999 31.614407122, -93.827341685 31.6143140250001, -93.827875499 31.6135011530001))"]

polygons = []
for poly in  poly_string:
    coordinates = []
    for s in poly.split('('):
        if len(s.split(')')) > 1:
            for c in s.split(')')[0].split(','):
                coordinates.append((float(c.lstrip().split(' ')[0]),
                                    float(c.lstrip().split(' ')[1]))) 
            polygons.append(Polygon(coordinates))

multipoly = MultiPolygon(polygons)

结果

MultiPolygon
看起来像这样 :


0
投票

我会尝试

select 
  FID, 
  ST_Multi(ST_Collect(ST_GeomFromText(polygon))) polygon_list 
group by 1
© www.soinside.com 2019 - 2024. All rights reserved.