Cara mempolimerisasi raster ke poligon yang indah

13

Saya mencari solusi python open-source untuk mengkonversi raster ke polygon (tidak ada ArcPy).

Saya memang tahu fungsi GDAL untuk mengubah raster menjadi poligon, dan ini adalah manualnya: http://pcjericks.github.io/py-gdalogr-cookbook/raster_layers.html#polygonize-a-raster-band

Namun demikian, saya berharap bahwa output dapat berupa poligon atau objek apa pun, sementara dalam memori, tidak disimpan sebagai file. Apakah ada paket atau kode untuk menangani masalah ini?

Jika raster telah diproses dalam array numpy, pendekatannya tercantum di bawah ini.

Vicky Liau
sumber

Jawaban:

20

Gunakan rasterio Sean Gillies. Hal ini dapat dengan mudah dikombinasikan dengan Fiona (membaca dan menulis shapefile) dan rupawan dari penulis yang sama.

Dalam skrip rasterio_polygonize.py awalnya adalah

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

Hasilnya adalah generator fitur 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}}

Anda bisa mengubahnya menjadi geometri yang indah

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

Buat geopandas Dataframe dan aktifkan fungsi spasial, plot, simpan sebagai geojson, ESRI shapefile, dll. Yang mudah digunakan.

geoms = list(results)
import geopandas as gp
gpd_polygonized_raster  = gp.GeoDataFrame.from_features(geoms)
gen
sumber
jika raster telah diproses sebagai array numpy, apakah ada cara untuk mengubah array numpy menjadi poligon? Terima kasih!
Vicky Liau
Secara teori, ya-
gen
1
Variabel dan parameter mask dalam contoh Anda tampaknya tidak perlu. Namun saya akan merekomendasikan untuk menambah if value > src.nodatapemahaman daftar untuk memanfaatkan nilai nodata sumber dan membuang segala bentuk yang sesuai dengannya. Tidak yakin apa yang akan terjadi jika tidak ada nodata vaue. : o)
bugmenot123
3
sementara itu mereka mengubah rasterio.drivers menjadi rasterio.Env dan src.affine menjadi src.transform
Leo
3

Ini implementasi saya.

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

Cara menginstal rasterio adalah dengan 'conda install -c https://conda.anaconda.org/ioos rasterio', jika ada masalah instalasi.

Vicky Liau
sumber
Hasil rasterio secara langsung adalah array yang numpy, oleh karena itu Anda tidak perlumyarray=srcband.ReadAsArray() #or any array
gen
@ gen saya merevisi catatan itu. Baris ini (myarray = srcband.ReadAsArray ()) menggunakan gdal untuk mengimpor gambar.
Vicky Liau
mengimpor gambar sebagai array numpy dan rasterio mengimpor langsung gambar sebagai array numpy
gen
Ini bekerja untuk saya walaupun saya harus mengindeks vec karena sedang dikembalikan sebagai tuple. bentuk (vec [0])
user2723146