Geopandas中Polygon对象无to_wkt属性报错求助
问题描述
我是geopandas新手,正参照教程在PySpark环境中处理自有shapefile。使用Jupyter(Python 3.7.6)执行代码时多次触发AttributeError: 'Polygon' object has no attribute 'to_wkt'错误,其他几何类型(如Point、Polygon Z)也出现相同错误。
执行代码
import os.path, json, io import matplotlib.pyplot as plt import matplotlib matplotlib.style.use('ggplot') matplotlib.rcParams['figure.figsize'] = (16, 20) from retrying import retry # for exponential back down when calling TurboOverdrive API import pyspark.sql.functions as func # resuse as func.coalace for example from pyspark.sql.types import StringType, IntegerType, FloatType, DoubleType,DecimalType from pyspark.sql import SparkSession import pandas as pd from geopandas import GeoDataFrame # Loading boundaries Data from shapely.geometry import Point, Polygon, shape # creating geospatial data from shapely import wkb, wkt # creating and parsing geospatial data from ast import literal_eval as make_tuple # used to decode data from java # Create SparkSession and attach Sparkcontext to it spark = SparkSession.builder.appName("pyspark-geopandas").getOrCreate() sc = spark.sparkContext # Load the boundaries data geo_df = GeoDataFrame.from_file('it_1km.shp') geo_df.head() geo_df.columns geo_df.plot(column='PUNTI', categorical=True, legend=True) plt.show() wkts = map(lambda g: g.to_wkt() , geo_df.geometry) #wkts[0] type(geo_df.geometry) geo_df.crs=('epsg:4326') geo_df.crs geo_df.geometry.area wkts = map(lambda g: g.to_wkt() , geo_df.geometry) type(geo_df.geometry) geo_df.crs=('epsg:4326') geo_df.crs geo_df.geometry.area geo_df['wkt'] = pd.Series( map(lambda geom: str(geom.to_wkt()), geo_df['geometry']), index=geo_df.index, dtype='string')
报错信息
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-14-f03fdc1f586f> in <module> 1 geo_df['wkt'] = pd.Series( 2 map(lambda geom: str(geom.to_wkt()), geo_df['geometry']), ----> 3 index=geo_df.index, dtype='string') /opt/conda/lib/python3.7/site-packages/pandas/core/series.py in __init__(self, data, index, dtype, name, copy, fastpath) 277 data = data.to_dense() 278 else: --> 279 data = com.maybe_iterable_to_list(data) 280 281 if index is None: /opt/conda/lib/python3.7/site-packages/pandas/core/common.py in maybe_iterable_to_list(obj) 278 """ 279 if isinstance(obj, abc.Iterable) and not isinstance(obj, abc.Sized): --> 280 return list(obj) 281 return obj 282 <ipython-input-14-f03fdc1f586f> in <lambda>(geom) 1 geo_df['wkt'] = pd.Series( ----> 2 map(lambda geom: str(geom.to_wkt()), geo_df['geometry']), 3 index=geo_df.index, dtype='string') AttributeError: 'Polygon' object has no attribute 'to_wkt'
解决方案
这个错误的核心原因是你使用的Shapely版本过低——to_wkt()方法是在Shapely 1.8.0版本才新增的,而你的环境里的Shapely版本低于这个阈值,所以Shapely的几何对象(Polygon、Point等)没有这个方法。
有两种可行的解决办法:
方法1:升级Shapely到1.8.0及以上版本
在终端执行以下命令升级:
pip install --upgrade shapely
升级完成后重启Jupyter内核,再运行代码即可正常调用geom.to_wkt()方法。
方法2:使用兼容旧版本的wkt.dumps()替代
如果因为环境限制无法升级Shapely,可以改用你已经导入的shapely.wkt模块里的dumps()函数来转换几何对象为WKT字符串,修改代码如下:
# 替换原来的代码行 geo_df['wkt'] = pd.Series( map(lambda geom: wkt.dumps(geom), geo_df['geometry']), index=geo_df.index, dtype='string')
或者更简洁的Geopandas内置方式:
geo_df['wkt'] = geo_df.geometry.apply(wkt.dumps)
这种方式不需要修改Shapely版本,兼容所有支持Geopandas的旧版Shapely。
内容的提问来源于stack exchange,提问作者Luigi
相关产品推荐
相关产品推荐

