使用Python的交互式卫星地图

时间:2018-05-17 13:23:13

标签: python python-2.7 geospatial interactive satellite-image

我正在尝试将Lambert Conformal Conical卫星图像叠加到Holoviews交互式地图上。我可以很好地映射卫星图像,但我无法弄清楚如何正确地将此地图转换为Holoviews地图。下面是可重现的代码,我使用Unidata Siphon库获取数据。

导入包

from datetime import datetime
import matplotlib.pyplot as plt
from netCDF4 import Dataset
from siphon.catalog import TDSCatalog
import holoviews as hv
import geoviews as gv
import geoviews.feature as gf
from cartopy import crs
from cartopy import feature as cf

hv.extension('bokeh')

抓取数据并创建数字

date=datetime.utcnow()
idx=-2
regionstr = 'CONUS'
channelnum = 13
datestr = str(date.year) + "%02d"%date.month + "%02d"%date.day
channelstr = 'Channel' + "%02d"%channelnum

cat = TDSCatalog('http://thredds-test.unidata.ucar.edu/thredds/catalog/satellite/goes16/GOES16/' + regionstr +
    '/' + channelstr + '/' + datestr + '/catalog.xml')
ds = cat.datasets[idx].remote_access(service='OPENDAP')
x = ds.variables['x'][:]
y = ds.variables['y'][:]
z = ds.variables['Sectorized_CMI'][:]

proj_var = ds.variables[ds.variables['Sectorized_CMI'].grid_mapping]

# Create a Globe specifying a spherical earth with the correct radius
globe = ccrs.Globe(ellipse='sphere', semimajor_axis=proj_var.semi_major,
                   semiminor_axis=proj_var.semi_minor)

proj = ccrs.LambertConformal(central_longitude=proj_var.longitude_of_central_meridian,
                             central_latitude=proj_var.latitude_of_projection_origin,
                             standard_parallels=[proj_var.standard_parallel],
                             globe=globe)


fig = plt.figure(figsize=(14, 10))
ax = fig.add_subplot(1, 1, 1, projection=proj)
ax.coastlines(resolution='50m', color='lightblue')
ax.add_feature(cf.STATES, linestyle=':', edgecolor='lightblue')
ax.add_feature(cf.BORDERS, linewidth=1, edgecolor='lightblue')

for im in ax.images:
    im.remove()
im = ax.imshow(z, extent=(x.min(), x.max(), y.min(), y.max()), origin='upper', cmap='jet')
plt.colorbar(im)

Basic Plot

现在使用Holoviews(使用Bokeh后端)绘制交互式图像

goes = hv.Dataset((x, y, z),['Lat', 'Lon'], 'ABI13')
%opts Image (cmap='jet') [width=1000 height=800 xaxis='bottom' yaxis='left' colorbar=True toolbar='above' projection=proj] 
goes.to.image()* gf.coastline().options(projection=crs.LambertConformal(central_longitude=proj_var.longitude_of_central_meridian,central_latitude=proj_var.latitude_of_projection_origin,standard_parallels=[proj_var.standard_parallel],globe=globe))

Interactive Map

我不能正确地翻译它,尽管我发现有关Lambert Conformal Conical投影的Holoviews文档很稀疏。我愿意使用任何其他交互式地图包。我的主要愿望是能够相对快速地绘制,在图像上正确地获得状态/国家线,并且能够放大。我已尝试过folium但也陷入了预测问题。

1 个答案:

答案 0 :(得分:3)

所以我认为要理解的主要内容是documentation:是如何宣布预测的。 GeoViews中的元素(例如Image,Points等)有一个名为crs的参数,它声明了数据所在的坐标系,而projection plot选项声明了要将数据投影到显示的内容。

在你的情况下,我认为你想要在它已经存在的相同坐标系中显示图像(Lambert Conformal),所以从技术上讲,你不必在元素上声明坐标系(crs)完全可以使用hv.Image(完全不知道预测)。

据我所知,如果你使用GeoViews 1.5,你的代码应该已经按预期工作了,但这就是我要做的事情:

# Apply mask
masked = np.ma.filled(z, np.NaN)

# Declare image from data
goes = hv.Image((x, y, masked),['Lat', 'Lon'], 'ABI13')

# Declare some options
options = dict(width=1000, height=800, yaxis='left', colorbar=True,
               toolbar='above', cmap='jet', projection=proj)

# Display plot
gf.ocean * gf.land * goes.options(**options) * gf.coastline.options(show_bounds=False)

here

注意我们如何在图像上声明投影而不是crs。如果您确实想要在其中定义的不同投影中显示数据,则必须声明crs并使用gv.Image。在这种情况下,我建议在启用快速选项的情况下使用project_image(这可能会引入一些工件但更多更快):

# Apply mask
masked = np.ma.filled(z, np.NaN)

# Declare the gv.Image with the crs
goes = gv.Image((x, y, masked), ['Lat', 'Lon'], 'ABI13', crs=proj)

# Now regrid the data and apply the reprojection
projected_goes = gv.operation.project_image(goes, fast=False, projection=ccrs.GOOGLE_MERCATOR)

# Declare some options
options = dict(width=1000, height=800, yaxis='left', colorbar=True,
               toolbar='above', cmap='jet')

# Display plot
projected_goes.options(**options) * gv.tile_sources.ESRI.options(show_bounds=False)

enter image description here

另一个最后的提示,当您使用散景进行绘图时,您正在绘制的所有数据都将被发送到浏览器,因此在处理比您已经使用的图像更大的图像时,我建议使用全息视图的使用数据共享器的regrid操作在缩放时动态调整图像大小。要使用它,只需将操作应用于图像,如下所示:

from holoviews.operation.datashader import regrid
regridded = regrid(goes)
相关问题