#python-3.x #geojson #geopandas #cartopy
Вопрос:
Я создаю карту мира с дорожками судов, предоставленными в GeoJSON — когда дорожка пересекает линию 180/-180, я получаю ошибочную линию по всему миру. Чтобы упростить вещи, я сократил количество дорожек.файл json в единственную дорожку, но обычный файл содержит несколько дорожек корабля.
Затем участок сохраняется в виде карты мира без границ с разрешением 4000×2000 пикселей — см.:
https://www.oceanic.udel.edu/globaldataview/rt_content/ships/latest/ship_locations.jpg
import os
import matplotlib as mpl
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import geopandas as gpd
def main():
tracks = gpd.read_file('https://www.researchvessels.org/data/tracks.json')
fig = plt.figure(dpi=100, figsize=(40, 20), frameon=False)
plt.axis('off')
ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree())
ax.set_extent([-180, 180, -90, 90], ccrs.PlateCarree())
ax.set_axis_off()
tracks.plot(ax=ax, color="yellow")
fig.add_axes(ax)
# Background Image below is available via https://www.researchvessels.org/data/nasa_bm_default.jpg
img = plt.imread('c:/scripts/NASA_BM_default.jpg')
img_extent = (-180, 180, -90, 90)
ax.imshow(img, origin='upper', extent=img_extent, transform=ccrs.PlateCarree(), aspect='auto')
fig.subplots_adjust(bottom = 0)
fig.subplots_adjust(top = 1)
fig.subplots_adjust(right = 1)
fig.subplots_adjust(left = 0)
plt.show()
plt.close(fig)
Ответ №1:
Чтобы правильно отобразить дорожки, вам необходимо очистить значения longitude
в дорожках, пересекающих линию даты.
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import geopandas as gpd
def sanitize_lonlist(lons):
new_list = []
oldval = 0
# used to compare with the adjacent longitudes
# and values exceed, disconnect linestring
treshold = 10
for ix,ea in enumerate(lons):
diff = oldval - ea
if (ix>0):
if (diff>treshold):
ea = ea 360
oldval = ea
new_list.append(ea)
return new_list
tracks = gpd.read_file('https://www.researchvessels.org/data/tracks.json')
# grab x and y of the first geometry object
xs = tracks.geometry[0].xy[0]
ys = tracks.geometry[0].xy[1]
ax = plt.axes(projection=ccrs.PlateCarree())
ax.set_global()
ax.coastlines()
# plot the geometry using sanitized values
ax.plot(sanitize_lonlist(xs), ys, transform=ccrs.PlateCarree(), color='red', lw=3)
plt.show()
Выход: