Como poligonizar raster para polígonos bem torneados


13

Estou procurando uma solução python de código aberto para converter raster em polígono (sem ArcPy).

Eu conhecia a função GDAL para converter raster em polígono, e aqui está o manual: http://pcjericks.github.io/py-gdalogr-cookbook/raster_layers.html#polygonize-a-raster-band

No entanto, espero que a saída possa ser polígonos bem torneados ou qualquer objeto, temporariamente na memória, não salvo como um arquivo. Existe algum pacote ou código para lidar com esse problema?

Se a varredura foi processada em uma matriz numpy, a abordagem é listada abaixo.

Respostas:


19

Use rasterio de Sean Gillies. Pode ser facilmente combinado com Fiona (ler e escrever shapefiles) e bem torneado do mesmo autor.

No script rasterio_polygonize.py, o início é

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)))

O resultado é um gerador de recursos do 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}}

Que você pode transformar em geometrias bem torneadas

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))

Crie geopandas Dataframe e permita funcionalidades fáceis de usar de junção espacial, plotagem, salve como geojson, arquivo de forma ESRI etc.

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

se a varredura foi processada como uma matriz numpy, existe alguma maneira de converter uma matriz numpy como polígonos? Obrigado!
Vicky Liau 03/04

Em teoria, sim-
gene

1
A variável de máscara e o parâmetro no seu exemplo parece desnecessário. No entanto, eu recomendaria adicionar if value > src.nodataà compreensão da lista o uso do valor nodata da fonte e descartar as formas correspondentes a ele. Não tenho certeza do que aconteceria se não houver nodata vaue. : o)
bugmenot123

3
Enquanto isso, eles mudaram rasterio.drivers para rasterio.Env e src.affine para src.transform
Leo

3

Aqui está a minha implementação.

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))

A maneira de instalar o rasterio é 'conda install -c https://conda.anaconda.org/ioos rasterio', se houver um problema de instalação.


O resultado da RasterIO é diretamente uma matriz numpy, portanto, você não precisamyarray=srcband.ReadAsArray() #or any array
gene

@gene Revisei a nota. Esta linha (myarray = srcband.ReadAsArray ()) usa gdal para importar a imagem.
Vicky Liau 04/04

importar a imagem como uma matriz e RasterIO numpy importação directamente a imagem como uma matriz numpy
gene

Isso funcionou para mim, embora eu tivesse que indexar o vec porque estava sendo retornado como uma tupla. shape (vec [0])
user2723146 09/10/19
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.