Mai mult

Transformând shapefile în mască și calculând media

Transformând shapefile în mască și calculând media


Am folosit Python pentru a procesa tablouri uriașe stocate ca fișiere NetCDF. Aș dori să calculez media unei zone definite de un fișier shapefile. Tocmai am instalat GDAL, dar dacă există alte instrumente pe care ar trebui să le folosesc, vă rugăm să ne anunțați.

Așadar, întrebarea mea principală este cum îmi pot transforma fișierul de formă într-o mască?

Apoi utilizați masca mea pentru a calcula media NumPy a matricei mele în zona măștii?

shp = "country.shp" array = mynumpyarray mask = useGDALtochangeshapefiletomask meanofarea = N.sens (matrice, limite = mască)

Am reușit să-mi convertesc fișierul shapef al unui raster folosind link-ul gdal_RasterizeLayer furnizat și apoi un tablou mascat folosind

maskarray = mask_ds.GetRasterBand (1) .ReadAsArray ()

Acum este doar o chestiune de potrivire a dimensiunii mele NetCDF cu rasterul / maskarray-ul meu. Iată ce măsuri am cerut.

extensia mea shapefile / raster: x_min, x_max, y_min, y_max 140.962408758 149.974994992 -39.1366533667 -33.9813898583 extinderea fișierului netcdf: longitudine min: 139.8 longitudine maximă: 150.0 min latitudine -39.2 latitudine maximă: -33.6 LAT dimensiune 106 LON dimensiune 193

Căutați funcția gdal.RasterizeLayer.

Puteți utiliza apoi ReadAsArray pentru a transforma poligonul rasterizat într-o matrice numpy.

Pe baza extinderii fișierului NetCDF și a rândurilor / coloanelor, următorul cod ar trebui să vă genereze o mască numid 0-1 care se potrivește exact cu NetCDF.

shapefile = r 'oricare ar fi calea dvs. de shapefile' xmin, ymin, xmax, ymax = [139,8, -39,2,150.0, -33,6] # Extensiile dvs., așa cum sunt date mai sus ncols, nrows = [193,106] # Your row / cols as done above maskvalue = 1 xres = (xmax-xmin) / float (ncols) yres = (ymax-ymin) / float (nrows) geotransform = (xmin, xres, 0, ymax, 0, -yres) src_ds = ogr.Open (shapefile ) src_lyr = src_ds.GetLayer () dst_ds = gdal.GetDriverByName ('MEM'). Creați (", ncols, nrows, 1, gdal.GDT_Byte) dst_rb = dst_ds.GetRasterBand (1) dst_rb.Fill (0) #initial cu zerouri dst_rb.SetNoDataValue (0) dst_ds.SetGeoTransform (geotransform) err = gdal.RasterizeLayer (dst_ds, [1], src_lyr, burn_values ​​= [maskvalue]) dst_ds.FlushCache () mask_arr = dst_dsR ( )

Poate că cea mai ușoară soluție este să apelați gdal_rasterize din codul dvs. Python (utilizațisubproces.callsausubproces.check_call), fie folosind fișierul NetCDF ca destinație, fie creați un fișier imagine separat (GeoTIFF este întotdeauna un pariu bun) și încărcați-l într-o matrice numpy. Poate fi posibil să utilizați formatul In Memory Raster al GDAL, dar nu sunt sigur ce suport există în Python și cum s-ar juca cu matrici numpy.

Există o cheltuială cu apelarea unui subproces și încărcarea unei imagini, dar aceasta va fi probabil amortizată până la timpul necesar pentru a realiza rasterizarea efectivă.

Dacă doriți să vă rulați propriul, ați putea scrie un simplu randator de scanare, dar bănuiesc că ar fi mai plin și posibil mai lent dacă este scris în Python pur.


Acum, în 2017, folosescrasterio.mask.maskșifionapentru a rasteriza fișierul de formă și apoi pentru a aplica setul de date netCDF folosindxarray.


Acum, în 2019, există https://github.com/corteva/rioxarray pentru a facilita integrarearasterioșixarray. Decuparea unui set de date (de exemplu, de la NetCDF) cu o geometrie este listată ca exemplu aici: https://corteva.github.io/rioxarray/stable/examples/clip_geom.html


Priveste filmarea: Am intrat în mare la ora 00:00! ERA UN RECHIN