Як полігонізувати растр до витончених багатокутників


14

Я шукаю рішення з відкритим кодом python для перетворення растра в полігон (без ArcPy).

Я знав функцію GDAL для перетворення растра в полігон, і ось посібник: http://pcjericks.github.io/py-gdalogr-cookbook/raster_layers.html#polygonize-a-raster-band

Тим не менш, я очікую, що на виході можуть бути стрункі багатокутники або будь-який об'єкт, тимчасово в пам'яті, а не збережений як файл. Чи є якийсь пакет або код для вирішення цього питання?

Якщо растр був оброблений в масивному масиві, підхід наведено нижче.

Відповіді:


21

Використовуйте растеріо Шона Джиллі. Його можна легко комбінувати з Фіоною (читання і запис) і шейп - файли стрункою одного і того ж автора.

У сценарії rasterio_polygonize.py початок є

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

Результат - генератор функцій 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}}

Що ви можете перетворити на витончені геометрії

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

Створіть Geopandas Dataframe та надайте прості у використанні функціональні можливості просторового з'єднання, побудови графіків, збереження як geojson, ESRI shapefile тощо.

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

якщо растр обробляється як нумеровий масив, чи є який-небудь спосіб перетворити масив numpy як полігони? Спасибі!
Вікі Ляу

Теоретично, так
ген

1
Змінна та параметр маски у вашому прикладі здаються непотрібними. Однак я б рекомендував додати if value > src.nodataдо списку розуміння, щоб використовувати значення нодату джерела та відкинути будь-які фігури, що відповідають йому. Не впевнений, що буде, якщо немає нодату вауе, хоча. : o)
bugmenot123

3
тим часом вони змінили rasterio.drivers на rasterio.Env і src.affine на src.transform
Лев

4

Ось моя реалізація.

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

Спосіб встановлення rasterio - це "conda install -c https://conda.anaconda.org/ioos rasterio", якщо є проблема встановлення.


Результатом растеріо є безпосередньо нумерований масив, тому вам не потрібноmyarray=srcband.ReadAsArray() #or any array
ген

@gene Я переглянув замітку. Цей рядок (myarray = srcband.ReadAsArray ()) використовує gdal для імпорту зображення.
Вікі Ліу

імпортуйте зображення як масивний масив, а растеріо імпортуйте зображення безпосередньо як масивний масив
ген

Це працювало для мене, хоча мені довелося індексувати vec, оскільки він повертався як кортеж. форма (vec [0])
користувач2723146
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.