我在地图上有一个点网格,我想检测哪个点位于陆地或海洋中。我试图用3种方式做到这一点但不满意。
使用maskoceans
,一个简单的例子是:
from mpl_toolkits.basemap import maskoceans
import numpy
# my grid is given by lons and lats 1D arrays.
Array = numpy.ma.zeros((lats.size,lons,size))
Lons,Lats = numpy.meshgrid(lons,lats)
MaskedArray = maskoceans(Lons,Lats,Array,resolution='f',grid=1.25)
现在我MaskedArray
屏蔽了海洋上的位置。与其他方法相比,此方法真正快,但在海岸附近不准确小规模。在下图中,红点被识别为陆地,黑点被识别为海洋。如你所见,即使我使用了resolution='f'
(完全重新洗脱)和最小的蒙版网格(grid=1.25
),海洋中的红点也被标记为红色的土地。似乎f
maskoceans
分辨率与f
分辨率Basemap
的顺序不同。
Image of points detected with maskoceans
使用basemap.is_land()
。例如:
# Create a basemap object, this takes a while!
MinLat = numpy.min(lats) - 0.01
MinLon = numpy.min(lons) - 0.01
MaxLat = numpy.max(lats) + 0.01
MaxLon = numpy.max(lons) + 0.01
MidLat = numpy.mean(lats)
MidLon = numpy.mean(lons)
from mpl_tookits.basemap import Basemap
map = Basemap(projection='aeqd',llcrnrlat=MinLat,llcrnrlon=MinLon,urcrnrlat=MaxLat,urcrnrlon=MaxLon,area_thresh=0.01,lon_0=MidLon,lat_0=MidLat,resolution='f')
Array = numpy.zeros((lats.size,lons.size),dtype=bool)
for j in range(lats.size):
for i in range(lons.size):
x,y = map(lon[i],lat[j])
if map.is_land(x,y):
Array[j,i] = True
这是最准确的方法。如下图所示,可以正确检测所有点。 is_land()
的一大问题是非常慢。对于大网格,这种方法需要几分钟(非常大的网格需要一小时),maskoceans
需要不到一秒钟。
Image of points detected with Basemap.is_land
使用Polygon.contains_point
。查看示例here。这对我不起作用,因为海岸线的多边形应该关闭才能使用conians_point
。因此,应使用
map
对象
map = Basemap(projection='aeqd',lon_0=0,resolution='f')
如果地图是在lon和lat的窗口上定义的,则海岸线多边形不会关闭。但是使用全分辨率加载完整的地图需要很长的时间和内存,甚至可以检测到一个点。
是否有另一种方法可以识别给定网格上的陆地/海洋点?如果修正了解决问题,则更愿意使用maskoceans
。可以将maskoceans()
的分辨率提高到Basemap
?