几何类型多边形与列类型多边形不匹配
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()
使用 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()