一周后Cartopy加载Mapbox卫星地图出现新报错
Mapbox卫星地图在Cartopy中报错:形状不匹配问题
近期运行Cartopy加载Mapbox卫星地图的代码时出现报错,此前代码完全正常。报错核心信息:ValueError: could not broadcast input array from shape (512,512,3) into shape (766,512,3)
相关代码
import cartopy.io.img_tiles as cimgt import matplotlib.pyplot as plt mapbox = cimgt.MapboxTiles(access_token=token, map_id = 'satellite-v9') ax = plt.axes(projection=mapbox.crs) ax.set_extent(extent) ax.add_image(mapbox, 14) plt.show()
完整报错栈
Traceback (most recent call last): File "/<ENV>/lib/python3.10/site-packages/matplotlib/backend_bases.py", line 1226, in _on_timer ret = func(*args, **kwargs) File "/<ENV>/lib/python3.10/site-packages/matplotlib/backends/backend_macosx.py", line 68, in callback_func callback() File "/<ENV>/lib/python3.10/site-packages/matplotlib/backends/backend_macosx.py", line 88, in _draw_idle self.draw() File "/<ENV>/lib/python3.10/site-packages/matplotlib/backends/backend_macosx.py", line 50, in draw super().draw() File "/<ENV>/lib/python3.10/site-packages/matplotlib/backends/backend_agg.py", line 400, in draw self.figure.draw(self.renderer) File "/<ENV>/lib/python3.10/site-packages/matplotlib/artist.py", line 95, in draw_wrapper result = draw(artist, renderer, *args, **kwargs) File "/<ENV>/lib/python3.10/site-packages/matplotlib/artist.py", line 72, in draw_wrapper return draw(artist, renderer) File "/<ENV>/lib/python3.10/site-packages/matplotlib/figure.py", line 3140, in draw mimage._draw_list_compositing_images( File "/<ENV>/lib/python3.10/site-packages/matplotlib/image.py", line 131, in _draw_list_compositing_images a.draw(renderer) File "/<ENV>/lib/python3.10/site-packages/matplotlib/artist.py", line 72, in draw_wrapper return draw(artist, renderer) File "/<ENV>/lib/python3.10/site-packages/cartopy/mpl/geoaxes.py", line 528, in draw img, extent, origin = factory.image_for_domain( File "/<ENV>/lib/python3.10/site-packages/cartopy/io/img_tiles.py", line 98, in image_for_domain img, extent, origin = _merge_tiles(tiles) File "/<ENV>/lib/python3.10/site-packages/cartopy/io/img_tiles.py", line 669, in _merge_tiles img[img_slice] = tile_img ValueError: could not broadcast input array from shape (512,512,3) into shape (512,766,3)
问题原因
这个问题和同类Stamen地图报错根源一致,大概率是以下情况导致:
- Cartopy版本更新后,瓦片合并逻辑引入兼容问题,无法处理非标准尺寸的瓦片
- Mapbox服务端调整了
satellite-v9瓦片的输出规格,返回尺寸与Cartopy预期不符 - 本地缓存的瓦片文件损坏或异常
解决方案
1. 降级Cartopy到稳定版本
如果是近期更新了Cartopy,尝试回退到之前能正常运行的版本,例如:
pip install cartopy==0.22.0
2. 重写瓦片合并逻辑
自定义_merge_tiles函数,强制统一瓦片尺寸后再合并:
import cartopy.io.img_tiles as cimgt import matplotlib.pyplot as plt import numpy as np from cartopy.io.img_tiles import _merge_tiles as original_merge_tiles def fixed_merge_tiles(tiles): tile_imgs, tile_extents, origins = zip(*tiles) min_x = min(extent[0] for extent in tile_extents) max_x = max(extent[1] for extent in tile_extents) min_y = min(extent[2] for extent in tile_extents) max_y = max(extent[3] for extent in tile_extents) # 以第一个瓦片尺寸为标准 tile_h, tile_w = tile_imgs[0].shape[:2] # 计算所需瓦片行列数 x_tiles = int(np.ceil((max_x - min_x) / (tile_extents[0][1] - tile_extents[0][0]))) y_tiles = int(np.ceil((max_y - min_y) / (tile_extents[0][3] - tile_extents[0][2]))) total_h = y_tiles * tile_h total_w = x_tiles * tile_w # 创建空画布 img = np.zeros((total_h, total_w, 3), dtype=tile_imgs[0].dtype) for tile_img, tile_extent in zip(tile_imgs, tile_extents): # 计算瓦片在画布中的偏移位置 x_off = int((tile_extent[0] - min_x) / (max_x - min_x) * total_w) y_off = int((max_y - tile_extent[3]) / (max_y - min_y) * total_h) # 统一瓦片尺寸 if tile_img.shape[:2] != (tile_h, tile_w): tile_img = np.resize(tile_img, (tile_h, tile_w, 3)) # 写入画布 img[y_off:y_off+tile_h, x_off:x_off+tile_w] = tile_img return img, (min_x, max_x, min_y, max_y), origins[0] # 替换Cartopy原有的合并函数 cimgt._merge_tiles = fixed_merge_tiles # 原业务代码 mapbox = cimgt.MapboxTiles(access_token=token, map_id='satellite-v9') ax = plt.axes(projection=mapbox.crs) ax.set_extent(extent) ax.add_image(mapbox, 14) plt.show()
3. 清除Cartopy瓦片缓存
删除本地缓存的瓦片文件,避免加载异常缓存:
- Linux/macOS: 清除
~/.local/share/cartopy目录 - Windows: 清除
C:\Users\<你的用户名>\AppData\Local\cartopy目录
4. 检查Mapbox服务状态
登录Mapbox开发者后台,确认satellite-v9瓦片服务是否有API变更或维护通知,确保使用的token权限正常。
内容的提问来源于stack exchange,提问作者calquigs
相关产品推荐
相关产品推荐

