几何类型多边形与列类型多边形不匹配

Geomtery type Multipolygon does not Match Column Type Polygon

使用 python、sqlalchemy 和 psycopg2 驱动程序,我正在尝试从 shapefile 到地理数据框,再到安装了 postgis 的 postgres 数据库

我将几何图形转换为 WKB 十六进制字符串,并使用 df.to_sql() 成功导入了标准数据框。

在 运行 alter table 查询时我收到错误:

sqlalchemy.exc.DataError: (psycopg2.errors.InvalidParameterValue) Geometry type (MultiPolygon) does not match column type (Polygon)

这是因为 shapefile 将指示几何类型,对于生成的地理数据框的给定行,该几何类型可以是多边形或多边形。

转换为 Well-Known-Binary 十六进制字符串时包含此信息,并在将文本转换为几何图形时产生类型问题。

mhweber's gist 的 explode 函数将通过将多边形分解成它们的组成部分来解决这个问题。

import geopandas as gpd
from shapely.geometry.polygon import Polygon
from shapely.geometry.multipolygon import MultiPolygon

def explode(indata):
    count_mp = 0
    indf = gpd.GeoDataFrame.from_file(indata)
    outdf = gpd.GeoDataFrame(columns=indf.columns)
    for idx, row in indf.iterrows():
        if type(row.geometry) == Polygon:
            outdf = outdf.append(row,ignore_index=True)
        if type(row.geometry) == MultiPolygon:
            count_mp = count_mp + 1
            multdf = gpd.GeoDataFrame(columns=indf.columns)
            recs = len(row.geometry)
            multdf = multdf.append([row]*recs,ignore_index=True)
            for geom in range(recs):
                multdf.loc[geom,'geometry'] = row.geometry[geom]
            outdf = outdf.append(multdf,ignore_index=True)
    print("There were ", count_mp, "Multipolygons found and exploded")
    return outdf

我添加了一个副作用来打印找到的多边形数量。

很有可能您应该调查这些以确保 explode 函数不会破坏您需要的关系。

重写了@Hugh_Kelley 的函数以提高速度。

def _explode(indf):
    count_mp = 0
    outdf = gpd.GeoDataFrame(columns=indf.columns)
    outdf = indf[indf.geometry.type == 'Polygon']
    indf = indf[indf.geometry.type != 'Polygon']
    for idx, row in indf.iterrows():
        if type(row.geometry) == MultiPolygon:
            count_mp = count_mp + 1
            multdf = gpd.GeoDataFrame(columns=indf.columns)
            recs = len(row.geometry)
            multdf = multdf.append([row]*recs,ignore_index=True)
            for geom in range(recs):
                multdf.loc[geom,'geometry'] = row.geometry[geom]
            outdf = outdf.append(multdf,ignore_index=True)
        else:
            print(row)
    print("There were ", count_mp, "Multipolygons found and exploded")
    return outdf

对于仍然回到这里的人们 post:The explode method 是(现在相当长的一段时间)GeoPandas 的一部分 api:

gpd.GeoDataFrame.explode()