Изменить фоновую карту для контекстного

У меня есть такой код:

import pandas as pd
import numpy as np
from geopandas import GeoDataFrame
import geopandas
from shapely.geometry import LineString, Point
import matplotlib.pyplot as plt
import contextily

''' Do Something'''

df = start_stop_df.drop('track', axis=1)
crs = {'init': 'epsg:4326'}
gdf = GeoDataFrame(df, crs=crs, geometry=geometry)

ax = gdf.plot()
contextily.add_basemap(ax)
ax.set_axis_off()
plt.show()

По сути, это создает фоновую карту Сингапура. Однако, когда я запускаю его, я получаю следующую ошибку: HTTPError: Tile URL resulted in a 404 error. Double-check your tile url:http://tile.stamen.com/terrain/29/268436843/268435436.png Тем не менее, он по-прежнему создает это изображение: < img src = "https://i.stack.imgur.com/p9YSD.png" alt = "Вывод кода">

Как я могу изменить URL-адрес плитки? Я все еще хотел бы иметь карту Сингапура в качестве базового слоя.

РЕДАКТИРОВАТЬ:
Также пытался включить этот аргумент в add_basemap:
url ='https://www.openstreetmap.org/#map=12/1.3332/103.7987'
Что привело к этой ошибке:
OSError: cannot identify image file <_io.BytesIO object at 0x000001CC3CC4BC50>


person SingaporePythonProgrammer    schedule 12.06.2019    source источник


Ответы (3)


Сначала убедитесь, что ваш GeoDataframe находится в проекции Web Mercator (epsg=3857). После того, как ваш Geodataframe правильно привязан к местности, вы можете добиться этого с помощью перепроецирования Geopandas:

df = df.to_crs(epsg=3857)

Как только вы это сделаете, вы легко сможете выбрать любой из поддерживаемых стилей карты. Полный список можно найти в модуле contextily.sources на момент написания:

### Tile provider sources ###

ST_TONER = 'http://tile.stamen.com/toner/tileZ/tileX/tileY.png'
ST_TONER_HYBRID = 'http://tile.stamen.com/toner-hybrid/tileZ/tileX/tileY.png'
ST_TONER_LABELS = 'http://tile.stamen.com/toner-labels/tileZ/tileX/tileY.png'
ST_TONER_LINES = 'http://tile.stamen.com/toner-lines/tileZ/tileX/tileY.png'
ST_TONER_BACKGROUND = 'http://tile.stamen.com/toner-background/tileZ/tileX/tileY.png'
ST_TONER_LITE = 'http://tile.stamen.com/toner-lite/tileZ/tileX/tileY.png'

ST_TERRAIN = 'http://tile.stamen.com/terrain/tileZ/tileX/tileY.png'
ST_TERRAIN_LABELS = 'http://tile.stamen.com/terrain-labels/tileZ/tileX/tileY.png'
ST_TERRAIN_LINES = 'http://tile.stamen.com/terrain-lines/tileZ/tileX/tileY.png'
ST_TERRAIN_BACKGROUND = 'http://tile.stamen.com/terrain-background/tileZ/tileX/tileY.png'

ST_WATERCOLOR = 'http://tile.stamen.com/watercolor/tileZ/tileX/tileY.png'

# OpenStreetMap as an alternative
OSM_A = 'http://a.tile.openstreetmap.org/tileZ/tileX/tileY.png'
OSM_B = 'http://b.tile.openstreetmap.org/tileZ/tileX/tileY.png'
OSM_C = 'http://c.tile.openstreetmap.org/tileZ/tileX/tileY.png'

Имейте в виду, что вам не следует добавлять фактические номера плиток x, y, z в URL вашей плитки (как вы это делали в своем примере «ИЗМЕНИТЬ»). ctx позаботится обо всем этом.

Вы можете найти рабочий пример для копирования и вставки и дополнительную информацию в документах GeoPandas.

import contextily as ctx

# Dataframe you want to plot
gdf = GeoDataFrame(df, crs= {"init": "epsg:4326"}) # Create a georeferenced dataframe  
gdf = gdf.to_crs(epsg=3857) # reproject it in Web mercator
ax = gdf.plot()

# choose any of the supported maps from ctx.sources
ctx.add_basemap(ax, url=ctx.sources.ST_TERRAIN)
ax.set_axis_off()
plt.show()
person Marjan Moderc    schedule 13.06.2019
comment
У меня такая же проблема, и я последовал вашему примеру, но, похоже, это не решает проблему. Я преобразовал gdf через .to_crs(epsg=3857) из epsg = 4326, но все равно получаю HTTPError: Tile URL resulted in a 404 error. Double-check your tile url: http://tile.stamen.com/terrain-background/23/4194302/4194300.png - person JHuw; 16.10.2019
comment
Я не уверен, что вы можете получить уровень масштабирования до 23 ... Обычно он достигает только 20. (maps.stamen.com/toner/#20/37.80802/-122.32054). Может, тебе стоит немного уменьшить масштаб карты. - person Marjan Moderc; 16.10.2019
comment
У меня проблема с системой координат, исправить не удалось. (так что я вижу только Океан) Тем не менее, чтобы просто избежать ошибок из-за уровня масштабирования, как описано выше, я кодирую: contexttily.add_basemap (ax, zoom = 18) - person ChrCury78; 25.01.2020
comment
У меня также был HTTPError: Tile URL resulted in a 404 error. Double-check your tile url: https://stamen-tiles-a.a.ssl.fastly.net/terrain/14/8383/5485.png, но я обнаружил, что это проблема с некоторыми поставщиками листов карты Stamen (github.com/stamen/maps.stamen.com/issues/107). Как только я перешел на другого поставщика карт, например ctx.add_basemap(ax, alpha=0.8, source=ctx.providers.OpenStreetMap.Mapnik), проблема, похоже, решена. - person Sander Vanden Hautte; 31.05.2021

crs по умолчанию Contextily - epsg: 3857. Однако ваш фрейм данных находится в другом CRS. Используйте следующее, см. Руководство здесь:

ctx.add_basemap(ax, crs='epsg:4326', source=ctx.providers.Stamen.TonerLite)

Пожалуйста, обратитесь к этой ссылке для использования различных источников, таких как Stamen.Toner, Stamen.Terrain и т. Д. (Stamen.Terrain используется как дефолт).

Кроме того, вы можете преобразовать ваш фрейм данных в EPSG: 3857, используя df.to_crs(). В этом случае вы должны пропустить crs аргумент внутри ctx.add_basemap() функции.

person Subrat Prasad    schedule 18.05.2020

Я слишком новичок, чтобы добавлять комментарий, но я хотел указать тем, кто в комментариях говорит, что они получают ошибку 404. Проверьте заглавные буквы и т. Д. Для этого указаны URL-адреса Stamen. Например, нет вызова только заглавными буквами. Только первая буква должна быть заглавной. Например:

ctx.add_basemap(ax=ax,url=ctx.providers.Stamen.Toner, zoom=10)

person SirRacha    schedule 14.04.2020