J'ai un tableau de données en grille avec une latitude/longitude associée et je veux utiliser Cartopy pour déterminer si chaque cellule de grille particulière est sur l'océan ou la terre.
Je peux obtenir simplement les données terrestres depuis l'interface de Cartopy
land_10m = cartopy.feature.NaturalEarthFeature('physical', 'land', '10m')
Je peux ensuite obtenir les géométries
all_geometries = [geometry for geometry in land_50m.geometries()]
Mais je ne sais pas comment utiliser ces géométries pour tester si un emplacement particulier est sur la terre ou non.
Cette question semble avoir déjà été posée Mask Ocean or Land from data using Cartopy et la solution était en gros "utilisez basemap à la place", ce qui est un peu insatisfaisant.
\======== Mise à jour ========
Merci à bjlittle, j'ai une solution qui fonctionne et génère le graphique ci-dessous
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()
Cependant, c'est extrêmement lent et finalement je devrai le faire à l'échelle mondiale à une résolution beaucoup plus élevée.
Est-ce que quelqu'un a des suggestions sur la façon d'adapter ce qui précède pour être plus rapide?
\==== Mise à jour 2 ====
Préparer les polygones fait une ÉNORME différence
Ajouter ces deux lignes a accéléré un exemple à 1 degré de 40 secondes à 0,3 seconde
from shapely.prepared import prep
land_polygons_prep = [prep(land_polygon) for land_polygon in land_polygons]
L'exemple que j'ai exécuté à 0,1 degré et qui a pris plus d'une demi-heure (c'est-à-dire qu'il s'est exécuté pendant le déjeuner) se termine maintenant en 1,3 seconde :-)