Come poligonizzare poligoni raster in formosi


13

Sto cercando una soluzione Python open source per convertire il raster in poligono (no ArcPy).

Conoscevo la funzione GDAL per convertire il raster in poligono, ed ecco il manuale: http://pcjericks.github.io/py-gdalogr-cookbook/raster_layers.html#polygonize-a-raster-band

Tuttavia, mi aspetto che l'output possa essere poligoni ben fatto o qualsiasi oggetto, temporaneamente in memoria, non salvato come file. Esiste un pacchetto o codice per gestire questo problema?

Se il raster è stato elaborato in una matrice numpy, l'approccio è elencato di seguito.

Risposte:


20

Usa rasterio di Sean Gillies. Può essere facilmente combinato con Fiona (lettura e scrittura shapefile) e formosa dello stesso autore.

Nello script rasterio_polygonize.py l'inizio è

import rasterio
from rasterio.features import shapes
mask = None
with rasterio.drivers():
    with rasterio.open('a_raster') as src:
        image = src.read(1) # first band
        results = (
        {'properties': {'raster_val': v}, 'geometry': s}
        for i, (s, v) 
        in enumerate(
            shapes(image, mask=mask, transform=src.affine)))

Il risultato è un generatore di funzionalità GeoJSON

 geoms = list(results)
 # first feature
 print geoms[0]
 {'geometry': {'type': 'Polygon', 'coordinates': [[(202086.577, 90534.3504440678), (202086.577, 90498.96207), (202121.96537406777, 90498.96207), (202121.96537406777, 90534.3504440678), (202086.577, 90534.3504440678)]]}, 'properties': {'raster_val': 170.52000427246094}}

Che puoi trasformare in geometrie formose

from shapely.geometry import shape
print shape(geoms[0]['geometry'])
POLYGON ((202086.577 90534.35044406779, 202086.577 90498.96206999999, 202121.9653740678 90498.96206999999, 202121.9653740678 90534.35044406779, 202086.577 90534.35044406779))

Crea geopandas Dataframe e abilita funzionalità facili da usare di join spaziale, stampa, salvataggio come geojson, file di forma ESRI ecc.

geoms = list(results)
import geopandas as gp
gpd_polygonized_raster  = gp.GeoDataFrame.from_features(geoms)

se il raster è stato elaborato come un array numpy, c'è un modo per convertire un array numpy in poligoni? Grazie!
Vicky Liau,

In teoria, sì
gene

1
La variabile maschera e il parametro nel tuo esempio sembrano non necessari. Vorrei tuttavia raccomandare di aggiungere if value > src.nodataalla comprensione dell'elenco per utilizzare il valore nodata della sorgente e scartare qualsiasi forma corrispondente ad essa. Non sono sicuro di cosa succederebbe se non ci fosse un nodata vaue. : o)
bugmenot123

3
nel frattempo hanno cambiato rasterio.drivers in rasterio.Env e src.affine in src.transform
Leo

3

Ecco la mia implementazione.

from osgeo import ogr, gdal, osr
from osgeo.gdalnumeric import *  
from osgeo.gdalconst import * 
import fiona
from shapely.geometry import shape
import rasterio.features

#segimg=glob.glob('Poly.tif')[0]
#src_ds = gdal.Open(segimg, GA_ReadOnly )
#srcband=src_ds.GetRasterBand(1)
#myarray=srcband.ReadAsArray() 
#these lines use gdal to import an image. 'myarray' can be any numpy array

mypoly=[]
for vec in rasterio.features.shapes(myarray):
    mypoly.append(shape(vec))

Il modo di installare rasterio è tramite 'conda install -c https://conda.anaconda.org/ioos rasterio', se c'è un problema di installazione.


Il risultato di rasterio è direttamente una matrice insensibile, quindi non è necessariomyarray=srcband.ReadAsArray() #or any array
gene

@gene ho rivisto la nota. Questa riga (myarray = srcband.ReadAsArray ()) usa gdal per importare l'immagine.
Vicky Liau,

importa l'immagine come una matrice numpy e rasterio importa direttamente l'immagine come una matrice numpy
gene

Questo ha funzionato per me, anche se ho dovuto indicizzare VEC perché veniva restituito come tupla. shape (vec [0])
user2723146
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.