我正在尝试使用python,sqlalchemy和psycopg2驱动程序,从shapefile到geodataframe,再到安装了this question的postgis的postgres数据库。
我将几何转换为WKB十六进制字符串,并使用df.to_sql()
成功导入了标准数据框。
运行alter table
查询时出现错误:
sqlalchemy.exc.DataError: (psycopg2.errors.InvalidParameterValue) Geometry type (MultiPolygon) does not match column type (Polygon)
答案 0 :(得分:2)
重写@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
答案 1 :(得分:1)
这是因为shapefile将指示对于所得地理数据框的给定行可以是Polygon或Multipolygon的几何类型。
当转换为已知二进制十六进制字符串时,将包含此信息,并且在将文本转换为几何时会产生类型问题。
mhweber's gist中的爆炸功能可通过将多边形折成其componenet部分来解决此问题。
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
我添加了一个副作用,以打印发现的多多边形数量。
奇怪的是,您应该研究这些,以确保爆炸功能不会破坏所需的关系。
答案 2 :(得分:1)
对于仍然回到这篇文章的人:The explode method 是(现在相当长的一段时间)GeoPandas api 的一部分:
gpd.GeoDataFrame.explode()