使用Cartopy遇struct.error: unpack需8字节缓冲区错误的解决咨询
问题:Cartopy地图程序shapefile.py报错struct.error: unpack requires a buffer of 8 bytes
运行基于Cartopy的地图程序时,在shapefile.py中触发struct.error: unpack requires a buffer of 8 bytes错误,按照开发者建议回退到Python3.8后问题依旧。
完整错误堆栈
(venv_with_python3.8) lnx@lnx-System-Product-Name:~/Desktop/globus$ python3 globus.py 2022-10-08 14:57:29,347 start /home/lnx/virtual_env/venv_with_python3.8/lib/python3.8/site-packages/shapely/geometry/base.py:250: ShapelyDeprecationWarning: Setting the 'coords' to mutate a Geometry in place is deprecated, and will not be possible any more in Shapely 2.0 super().__setattr__(name, value) 2022-10-08 14:57:32,114 reading the land polygons 2022-10-08 14:57:32,571 marking the ocean on axes 0 2022-10-08 14:57:47,094 marking the ocean on axes 1 2022-10-08 14:57:56,265 marking the ocean on axes 2 2022-10-08 14:58:11,742 marking the ocean on axes 3 2022-10-08 14:58:18,259 marking the ocean on axes 4 2022-10-08 14:58:24,119 marking the ocean on axes 5 2022-10-08 14:58:34,041 projecting the raster map on axes 0 2022-10-08 14:58:35,313 projecting the raster map on axes 1 2022-10-08 14:58:36,484 projecting the raster map on axes 2 2022-10-08 14:58:36,574 projecting the raster map on axes 3 2022-10-08 14:58:36,638 projecting the raster map on axes 4 2022-10-08 14:58:36,721 projecting the raster map on axes 5 2022-10-08 14:58:36,791 reading features Traceback (most recent call last): File "globus.py", line 495, in <module> main() File "globus.py", line 468, in main axes.add_features() File "globus.py", line 236, in add_features borders = reader.ReadBorders() File "/home/lnx/Desktop/globus/reader.py", line 310, in ReadBorders b.geometry for b in ReadRecords('shapes/ne_10m_admin_0_boundary_lines_land') File "/home/lnx/Desktop/globus/reader.py", line 209, in ReadRecords return list(shapereader.Reader(name).records()) File "/home/lnx/virtual_env/venv_with_python3.8/lib/python3.8/site-packages/cartopy/io/shapereader.py", line 167, in records for shape_record in self._reader.iterShapeRecords(): File "/home/lnx/virtual_env/venv_with_python3.8/lib/python3.8/site-packages/shapefile.py", line 1771, in iterShapeRecords for shape, record in izip(self.iterShapes(), self.iterRecords(fields=fields)): File "/home/lnx/virtual_env/venv_with_python3.8/lib/python3.8/site-packages/shapefile.py", line 1483, in iterShapes shape = self.__shape(oid=i, bbox=bbox) File "/home/lnx/virtual_env/venv_with_python3.8/lib/python3.8/site-packages/shapefile.py", line 1309, in __shape (recNum, recLength) = unpack(">2i", f.read(8)) struct.error: unpack requires a buffer of 8 bytes (venv_with_python3.8) lnx@lnx-System-Product-Name:~/Desktop/globus$
出错的shapefile.py代码片段
(recNum, recLength) = unpack(">2i", f.read(8)) # Determine the start of the next record next = f.tell() + (2 * recLength) shapeType = unpack("<i", f.read(4))[0] record.shapeType = shapeType # For Null shapes create an empty points list for consistency if shapeType == 0: record.points = [] # All shape types capable of having a bounding box elif shapeType in (3,5,8,13,15,18,23,25,28,31): record.bbox = _Array('d', unpack("<4d", f.read(32))) # if bbox specified and no overlap, skip this shape if bbox is not None and not bbox_overlap(bbox, record.bbox): # because we stop parsing this shape, skip to beginning of # next shape before we return f.seek(next) return None
修复方案
- 检查并重新下载shapefile文件:错误根源大概率是
ne_10m_admin_0_boundary_lines_land相关的shp/shx/dbf文件损坏或下载不完整,重新获取完整的文件包替换原文件。 - 降级shapefile库版本:当前使用的pyshp(即shapefile库)版本可能存在兼容性问题,执行以下命令安装稳定版本:
pip install pyshp==2.3.1 - 添加读取容错逻辑:如果不想更换库版本,可以修改shapefile.py第1309行附近代码,增加读取长度校验,避免因文件损坏导致崩溃:
data = f.read(8) if len(data) != 8: # 跳到文件末尾终止循环,或根据需求自定义处理逻辑 f.seek(os.path.getsize(f.name)) return None (recNum, recLength) = unpack(">2i", data) - 验证文件路径完整性:确保
shapes/ne_10m_admin_0_boundary_lines_land路径下的所有配套文件(.shp、.shx、.dbf、.prj等)都存在且版本匹配。
内容的提问来源于stack exchange,提问作者RemiDocs
相关产品推荐
相关产品推荐

