首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么上下文无法在自动缩放模式下获取一些瓷砖?

为什么上下文无法在自动缩放模式下获取一些瓷砖?
EN

Stack Overflow用户
提问于 2022-09-30 09:43:29
回答 1查看 48关注 0票数 1

我想使用contextily将OSM层添加到我用GeoPandas绘制的地图中。但是,在自动模式(默认)中使用zoom时,我遇到了某种随机错误。

MCVE

这是一个MCVE:

代码语言:javascript
复制
df = pd.DataFrame({"key": ["A"], "lon": [3.6], "lat": [43.4]})

point = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df.lon, df.lat), crs=4326).to_crs(crs="ESRI:102014")
circle = point.geometry.buffer(3000)

axe = point.plot(color="red")
circle.plot(alpha=0.35, color="red", ax=axe)
ctx.add_basemap(axe, zoom="auto", crs=point.crs)

不幸的是,由于瓷砖的URL不存在,所以失败了:

代码语言:javascript
复制
---------------------------------------------------------------------------
HTTPError                                 Traceback (most recent call last)
File ~/.local/lib/python3.10/site-packages/contextily/tile.py:396, in _retryer(tile_url, wait, max_retries)
    395     request = requests.get(tile_url, headers={"user-agent": USER_AGENT})
--> 396     request.raise_for_status()
    397 except requests.HTTPError:

File /usr/local/lib/python3.10/dist-packages/requests/models.py:1021, in Response.raise_for_status(self)
   1020 if http_error_msg:
-> 1021     raise HTTPError(http_error_msg, response=self)

HTTPError: 404 Client Error: Not Found for url: https://stamen-tiles-a.a.ssl.fastly.net/terrain/14/8353/5993.png

During handling of the above exception, another exception occurred:

HTTPError                                 Traceback (most recent call last)
Cell In [9], line 3
      1 axe = point.plot(color="red")
      2 circle.plot(alpha=0.35, color="red", ax=axe)
----> 3 ctx.add_basemap(axe, zoom="auto", crs=point.crs)

File ~/.local/lib/python3.10/site-packages/contextily/plotting.py:121, in add_basemap(ax, zoom, source, interpolation, attribution, attribution_size, reset_extent, crs, resampling, **extra_imshow_args)
    117     left, right, bottom, top = _reproj_bb(
    118         left, right, bottom, top, crs, {"init": "epsg:3857"}
    119     )
    120 # Download image
--> 121 image, extent = bounds2img(
    122     left, bottom, right, top, zoom=zoom, source=source, ll=False
    123 )
    124 # Warping
    125 if crs is not None:

File ~/.local/lib/python3.10/site-packages/contextily/tile.py:222, in bounds2img(w, s, e, n, zoom, source, ll, wait, max_retries)
    220 x, y, z = t.x, t.y, t.z
    221 tile_url = provider.build_url(x=x, y=y, z=z)
--> 222 image = _fetch_tile(tile_url, wait, max_retries)
    223 tiles.append(t)
    224 arrays.append(image)

File /usr/local/lib/python3.10/dist-packages/joblib/memory.py:594, in MemorizedFunc.__call__(self, *args, **kwargs)
    593 def __call__(self, *args, **kwargs):
--> 594     return self._cached_call(args, kwargs)[0]

File /usr/local/lib/python3.10/dist-packages/joblib/memory.py:537, in MemorizedFunc._cached_call(self, args, kwargs, shelving)
    534         must_call = True
    536 if must_call:
--> 537     out, metadata = self.call(*args, **kwargs)
    538     if self.mmap_mode is not None:
    539         # Memmap the output at the first call to be consistent with
    540         # later calls
    541         if self._verbose:

File /usr/local/lib/python3.10/dist-packages/joblib/memory.py:779, in MemorizedFunc.call(self, *args, **kwargs)
    777 if self._verbose > 0:
    778     print(format_call(self.func, args, kwargs))
--> 779 output = self.func(*args, **kwargs)
    780 self.store_backend.dump_item(
    781     [func_id, args_id], output, verbose=self._verbose)
    783 duration = time.time() - start_time

File ~/.local/lib/python3.10/site-packages/contextily/tile.py:252, in _fetch_tile(tile_url, wait, max_retries)
    250 @memory.cache
    251 def _fetch_tile(tile_url, wait, max_retries):
--> 252     request = _retryer(tile_url, wait, max_retries)
    253     with io.BytesIO(request.content) as image_stream:
    254         image = Image.open(image_stream).convert("RGBA")

File ~/.local/lib/python3.10/site-packages/contextily/tile.py:399, in _retryer(tile_url, wait, max_retries)
    397 except requests.HTTPError:
    398     if request.status_code == 404:
--> 399         raise requests.HTTPError(
    400             "Tile URL resulted in a 404 error. "
    401             "Double-check your tile url:\n{}".format(tile_url)
    402         )
    403     elif request.status_code == 104:
    404         if max_retries > 0:

HTTPError: Tile URL resulted in a 404 error. Double-check your tile url:
https://stamen-tiles-a.a.ssl.fastly.net/terrain/14/8353/5993.png

有趣的是,它似乎与瓷砖的细节水平有关。因为如果我选择了一个具有更复杂几何学的点,它就会起作用:

代码语言:javascript
复制
df = pd.DataFrame({"key": ["A"], "lon": [3.7], "lat": [43.8]})

或者,如果我将缩放缩小一个单位与原来的点:

代码语言:javascript
复制
ctx.add_basemap(axe, zoom=13, crs=point.crs)

它也能工作(zoom=14是使它崩溃的值)。

分析

它似乎有一些问题,一些瓷砖没有呈现或映射到一个预期的contextily生成,因此404。

问题似乎与瓷砖本身的详细程度有关,因为:

选择一个包含很多细节的瓷砖使work;

  • Reducing自动缩放,手动缩放也使有效,但分辨率较低。

问题

我没有足够的洞察力来区分它是否是contextily错误,或者它是否与瓷砖提供者有关。如何在防止404错误的同时仍然使用自动缩放模式?我能用提供程序的定义做些什么吗?为什么上下文不能在自动缩放模式下获取一些瓷砖?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-30 10:47:03

这不是contextily的问题。雄蕊地形(默认的瓷砖)没有一个均匀的覆盖,所以有些地方有很多缩放级别,而其他地方较少。你的观察也证明了这一点。因此,上下文自动计算预期的瓷砖,但不能知道这个地方没有提供它,因为其他一些地方有相同的缩放,所以tiles元数据表示允许级别14。如果使用不同的瓷砖,则相同的代码可以工作。

代码语言:javascript
复制
ctx.add_basemap(axe, zoom="auto", crs=point.crs, source=ctx.providers.OpenStreetMap.Mapnik)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73906822

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档