【发布时间】:2018-11-15 15:40:33
【问题描述】:
我有一个带有关联纬度/经度的网格数据数组,我想使用 Cartopy 来查找每个特定的网格单元是在海洋上还是在陆地上。
我可以简单地从 Cartopy Feature 界面获取土地数据
land_10m = cartopy.feature.NaturalEarthFeature('physical', 'land', '10m')
然后我可以得到几何图形
all_geometries = [geometry for geometry in land_50m.geometries()]
但我不知道如何使用这些几何图形来测试特定位置是否在陆地上。
这个问题似乎是在Mask Ocean or Land from data using Cartopy 之前提出的,解决方案几乎是“改用底图”,这有点不令人满意。
======== 更新========
感谢 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 秒 :-)
【问题讨论】: