我有一个带有相关纬度/经度的网格数据数组,我想使用Cartopy查找每个特定网格单元格是在海洋还是陆地上。
我可以简单地从Cartopy Feature接口获取陆地数据。
但我无法弄清如何使用这些几何图形来测试特定位置是否在陆地上。
这个问题似乎以前就出现过使用Cartopy从数据中掩盖海洋或陆地,解决方案基本上是“改用basemap”,这有点不令人满意。
======== 更新 ========
感谢bjlittle,我有了一个可行的解决方案,并生成了下面的绘图。
我可以简单地从Cartopy Feature接口获取陆地数据。
land_10m = cartopy.feature.NaturalEarthFeature('physical', 'land', '10m')
我可以获得几何信息
all_geometries = [geometry for geometry in land_50m.geometries()]
但我无法弄清如何使用这些几何图形来测试特定位置是否在陆地上。
这个问题似乎以前就出现过使用Cartopy从数据中掩盖海洋或陆地,解决方案基本上是“改用basemap”,这有点不令人满意。
======== 更新 ========
感谢bjlittle,我有了一个可行的解决方案,并生成了下面的绘图。
from IPython import embed
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader
from shapely.geometry import Point
import cartopy
land_10m = cartopy.feature.NaturalEarthFeature('physical', 'land', '10m')
land_polygons = list(land_10m.geometries())
lats = np.arange(48,58, 0.1)
lons = np.arange(-5,5, 0.1)
lon_grid, lat_grid = np.meshgrid(lons, lats)
points = [Point(point) for point in zip(lon_grid.ravel(), lat_grid.ravel())]
land = []
for land_polygon in land_polygons:
land.extend([tuple(point.coords)[0] for point in filter(land_polygon.covers, points)])
fig = plt.figure(figsize=(8, 8))
ax = fig.add_axes([0, 0, 1, 1], projection=ccrs.PlateCarree())
ax.add_feature(land_10m, zorder=0, edgecolor='black', facecolor=sns.xkcd_rgb['black'])
xs, ys = zip(*land)
ax.scatter(xs, ys, transform=ccrs.PlateCarree(),
s=12, marker='s', c='red', alpha=0.5, zorder=2)
plt.show()
然而,这种方法非常缓慢,最终我需要在更高的分辨率下进行全局操作。
有人有什么建议可以使上述方法更快吗?
==== 更新2 ====
准备多边形会有很大的改善作用。
添加这两行代码将把一个1度的示例从40秒加速到0.3秒。
from shapely.prepared import prep
land_polygons_prep = [prep(land_polygon) for land_polygon in land_polygons]
我之前运行的例子在0.1度下运行了半个多小时(也就是在午饭时间运行),现在只需要1.3秒就能完成 :-)