Растеризиране на GDAL слой

Редактиране

Ето правилния начин да го направите и документация:

import random
from osgeo import gdal, ogr    

RASTERIZE_COLOR_FIELD = "__color__"

def rasterize(pixel_size=25):
    # Open the data source
    orig_data_source = ogr.Open("test.shp")
    # Make a copy of the layer's data source because we'll need to 
    # modify its attributes table
    source_ds = ogr.GetDriverByName("Memory").CopyDataSource(
            orig_data_source, "")
    source_layer = source_ds.GetLayer(0)
    source_srs = source_layer.GetSpatialRef()
    x_min, x_max, y_min, y_max = source_layer.GetExtent()
    # Create a field in the source layer to hold the features colors
    field_def = ogr.FieldDefn(RASTERIZE_COLOR_FIELD, ogr.OFTReal)
    source_layer.CreateField(field_def)
    source_layer_def = source_layer.GetLayerDefn()
    field_index = source_layer_def.GetFieldIndex(RASTERIZE_COLOR_FIELD)
    # Generate random values for the color field (it's here that the value
    # of the attribute should be used, but you get the idea)
    for feature in source_layer:
        feature.SetField(field_index, random.randint(0, 255))
        source_layer.SetFeature(feature)
    # Create the destination data source
    x_res = int((x_max - x_min) / pixel_size)
    y_res = int((y_max - y_min) / pixel_size)
    target_ds = gdal.GetDriverByName('GTiff').Create('test.tif', x_res,
            y_res, 3, gdal.GDT_Byte)
    target_ds.SetGeoTransform((
            x_min, pixel_size, 0,
            y_max, 0, -pixel_size,
        ))
    if source_srs:
        # Make the target raster have the same projection as the source
        target_ds.SetProjection(source_srs.ExportToWkt())
    else:
        # Source has no projection (needs GDAL >= 1.7.0 to work)
        target_ds.SetProjection('LOCAL_CS["arbitrary"]')
    # Rasterize
    err = gdal.RasterizeLayer(target_ds, (3, 2, 1), source_layer,
            burn_values=(0, 0, 0),
            options=["ATTRIBUTE=%s" % RASTERIZE_COLOR_FIELD])
    if err != 0:
        raise Exception("error rasterizing layer: %s" % err)

Оригинален въпрос

Търся информация как да използвам osgeo.gdal.RasterizeLayer() (документационният низ е много кратък и не мога да го намеря в документите за C или C++ API. Намерих само документ за java обвързвания).

Адаптирах единичен тест и го изпробвах на .shp направени от многоъгълници:

import os
import sys
from osgeo import gdal, gdalconst, ogr, osr
    
def rasterize():
    # Create a raster to rasterize into.
    target_ds = gdal.GetDriverByName('GTiff').Create('test.tif', 1280, 1024, 3,
            gdal.GDT_Byte)
    # Create a layer to rasterize from.
    cutline_ds = ogr.Open("data.shp")
    # Run the algorithm.
    err = gdal.RasterizeLayer(target_ds, [3,2,1], cutline_ds.GetLayer(0),
            burn_values=[200,220,240])
    if err != 0:
        print("error:", err)

if __name__ == '__main__':
    rasterize()

Работи добре, но всичко, което получавам, е черен .tif.

За какво е параметърът burn_values? Може ли RasterizeLayer() да се използва за растеризиране на слой с характеристики, оцветени по различен начин въз основа на стойността на атрибут?

Ако не може, какво да използвам? AGG подходящ ли е за изобразяване на географски данни (искам без антиалиасинг и много стабилен програма за изобразяване, способна да начертае правилно много големи и много малки елементи, вероятно от мръсни данни (изродени многоъгълници и т.н...), и понякога посочени в големи координати)?

Тук полигоните се различават по стойността на даден атрибут (цветовете нямат значение, просто искам да има различен за всяка стойност на атрибута).


person Luper Rouch    schedule 08.02.2010    source източник
comment
Благодаря Лупър, това беше много полезно за мен днес! в документацията на gdal е много трудно да се намери правилната информация...   -  person yosukesabai    schedule 27.11.2011
comment
Здравей @Luper, страхотно! Точно това търсих! Давате ли разрешение да включите (части от) вашия примерен код в GPLv3 лицензиран проект с отворен код, като се има предвид, че правилно приписвам вашето име и връзка към този въпрос?   -  person andreas-h    schedule 04.06.2013
comment
@andreas-h със сигурност няма проблем.   -  person Luper Rouch    schedule 04.06.2013
comment
@andreas-h окончателната форма на кода може да бъде намерена тук. Това също е GPLv3.   -  person Luper Rouch    schedule 04.06.2013
comment
@LuperRouch страхотно, благодаря за линка!   -  person andreas-h    schedule 04.06.2013
comment
Връзката към изображението е повредена, можете ли да я поправите?   -  person Yuchen    schedule 12.05.2015
comment
Не, за съжаление вече нямам изображенията и не ги намерих в интернет архива :(   -  person Luper Rouch    schedule 13.05.2015
comment
Здравей @Luper, има ли начин да направите това, без да използвате CopyDataSource, за да направите копие? По някаква причина тази стъпка се поврежда при мен (gdal 2.0.1, python 2.7.6). Благодаря!   -  person TM5    schedule 07.01.2016
comment
@TM5 можете да опитате, но IIRC, ако промените оригиналния източник на данни, той също ще го промени на диска   -  person Luper Rouch    schedule 12.01.2016
comment
Ти си спасител. Малка допълнителна забележка: ако се опитвате да растеризирате във формат като PNG, който не поддържа произволни записи (използван от RasterizeLayer), ще трябва да растеризирате в набор от данни в паметта, инстанциран като memory_dataset = gdal.GetDriverByName('MEM').Create('in mem', x_res,y_res, 3, gdal.GDT_Byte). След това можете да създадете PNG, като направите копие: gdal.GetDriverByName('PNG').CreateCopy('output.png', memory_dataset)   -  person Pathogen    schedule 28.06.2016


Отговори (1)


РЕДАКТИРАНЕ: Предполагам, че бих използвал qGIS python свързвания: http://www.qgis.org/wiki/Python_Bindings

Това е най-лесният начин, за който се сещам. Спомням си, че ръчно търкалях нещо преди, но е грозно. qGIS ще бъде по-лесно, дори ако трябва да направите отделна инсталация на Windows (за да накарате python да работи с него), след което да настроите XML-RPC сървър, за да го стартирате в отделен процес на python.

Можете да накарате GDAL да растеризира правилно, това също е страхотно.

Не съм използвал gdal известно време, но ето моето предположение:

burn_values е за фалшив цвят, ако не използвате Z-стойности. Всичко във вашия многоъгълник е [255,0,0] (червено), ако използвате burn=[1,2,3],burn_values=[255,0,0]. Не съм сигурен какво се случва с точките - те може да не се начертаят.

Използвайте gdal.RasterizeLayer(ds,bands,layer,burn_values, options = ["BURN_VALUE_FROM=Z"]), ако искате да използвате Z стойностите.

Просто извличам това от тестовете, които гледахте: http://svn.osgeo.org/gdal/trunk/autotest/alg/rasterize.py

Друг подход - издърпайте многоъгълните обекти и ги нарисувайте с форма, която може да не е привлекателна. Или разгледайте geodjango (мисля, че използва openlayers, за да изобразява в браузъри, използващи JavaScript).

Също така, трябва ли да растеризирате? Експортирането в pdf може да е по-добро, ако наистина искате точност.

Всъщност мисля, че открих, че използването на Matplotlib (след извличане и проектиране на функциите) е по-лесно от растеризирането и можех да получа много повече контрол.

РЕДАКТИРАНЕ:

Подход от по-ниско ниво е тук:

http://svn.osgeo.org/gdal/trunk/gdal/swig/python/samples/gdal2grd.py\

И накрая, можете да повторите многоъгълниците (след като ги трансформирате в локална проекция) и да ги начертаете директно. Но по-добре да нямате сложни многоъгълници, или ще имате малко мъка. Ако имате сложни полигони ... вероятно е най-добре да използвате shapely и r-tree от http://trac.gispython.org/lab, ако искате да навиете свой собствен плотер.

Geodjango може да е добро място да попитате .. те ще знаят много повече от мен. Имат ли пощенски списък? Наоколо има и много експерти по картографиране на Python, но изглежда никой от тях не се тревожи за това. Предполагам, че просто го чертаят в qGIS или GRASS или нещо подобно.

Сериозно, надявам се, че някой, който знае какво прави, може да отговори.

person wisty    schedule 08.02.2010
comment
Да, трябва да растеризирам (редактирах въпроса, за да покажа какво искам да направя). Може би там има опция като BURN_VALUE_FROM_Z, която може да използва атрибут? - person Luper Rouch; 08.02.2010
comment
Освен това не разбирам защо в крайна сметка получавам черно изображение в моя тест. - person Luper Rouch; 08.02.2010
comment
Успях да използвам RasterizeLayer с помощта на хората от #gdal. Проблемът беше в трансформацията/изместването на степента, трябва да накарате екстентите на източника и местоназначението да съвпадат или всичко се изрязва. Това всъщност е обяснено в документите, не знам как съм го пропуснал :D Благодаря все пак за вашето проучване, ще приема отговора ви и ще редактирам въпроса си с фиксирания код. - person Luper Rouch; 09.02.2010