You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

一周后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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 09:05:57