栅格化 GDAL 图层

发布于 2024-08-20 10:44:24 字数 3523 浏览 9 评论 0原文

编辑

这是执行此操作的正确方法,以及文档

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 是否适合渲染地理数据(我想要抗锯齿和非常强大的渲染器,能够正确绘制非常大和非常小的特征,可能来自“脏数据”(退化多边形等...),有时在大坐标中指定)?

在这里,多边形通过属性值来区分(颜色并不重要,我只想为属性的每个值都有一个不同的颜色)。

Edit

Here is the proper way to do it, and the documentation:

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)

Original question

I'm looking for information on how to use osgeo.gdal.RasterizeLayer() (the docstring is very succinct, and I can't find it in the C or C++ API docs. I only found a doc for the java bindings).

I adapted a unit test and tried it on a .shp made of polygons:

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

It runs fine, but all I obtain is a black .tif.

What's the burn_values parameter for ? Can RasterizeLayer() be used to rasterize a layer with features colored differently based on the value of an attribute ?

If it can't, what should I use ? Is AGG suitable for rendering geographic data (I want no antialiasing and a very robust renderer, able to draw very large and very small features correctly, possibly from "dirty data" (degenerate polygons, etc...), and sometimes specified in large coordinates) ?

Here, the polygons are differentiated by the value of an attribute (the colors don't matter, I just want to have a different one for each value of the attribute).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情话墙 2024-08-27 10:44:24

编辑:我想我会使用 qGIS python 绑定: http://www.qgis.org/wiki/Python_Bindings

这是我能想到的最简单的方法。我记得以前用手卷过一些东西,但很难看。 qGIS 会更容易,即使您必须进行单独的 Windows 安装(以使 python 能够使用它),然后设置一个 XML-RPC 服务器以在单独的 python 进程中运行它。

我可以让 GDAL 正确光栅化,这也很棒。

我已经有一段时间没有使用 gdal 了,但这是我的猜测:

如果您不使用 Z 值,burn_values 用于假颜色。如果您使用 burn=[1,2,3],burn_values=[255,0,0][255,0,0](红色) >。我不确定点会发生什么 - 它们可能不会绘制。

如果您想使用 Z 值,请使用 gdal.RasterizeLayer(ds,bands,layer,burn_values, options = ["BURN_VALUE_FROM=Z"])。

我只是从您正在查看的测试中提取此内容: http:// /svn.osgeo.org/gdal/trunk/autotest/alg/rasterize.py

另一种方法 - 将多边形对象拉出,并使用 shapely 绘制它们,这可能不那么有吸引力。或者看看 geodjango (我认为它使用 openlayers 使用 JavaScript 绘制到浏览器中)。

另外,需要光栅化吗?如果你确实想要精确的话,pdf 导出可能会更好。

实际上,我认为我发现使用 Matplotlib(在提取和投影特征之后)比光栅化更容易,而且我可以获得更多的控制权。

编辑:

较低级别的方法在这里:

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

最后,您可以迭代多边形(将它们转换为本地投影之后),并直接绘制它们。但你最好不要有复杂的多边形,否则你会有点悲伤。如果您有复杂的多边形...您可能最好使用 http://trac.gispython 中的 shapely 和 r-tree .org/lab 如果您想推出自己的绘图仪。

Geodjango 可能是一个询问的好地方..他们会比我知道更多。他们有邮件列表吗?周围也有很多 python 地图专家,但他们似乎都不担心这一点。我猜他们只是用 qGIS 或 GRASS 之类的东西来绘制它。

说实话,我希望有知道自己在做什么的人能够回复。

EDIT: I guess I'd use qGIS python bindings: http://www.qgis.org/wiki/Python_Bindings

That's the easiest way I can think of. I remember hand rolling something before, but it's ugly. qGIS would be easier, even if you had to make a separate Windows installation (to get python to work with it) then set up an XML-RPC server to run it in a separate python process.

I you can get GDAL to rasterize properly that's great too.

I haven't used gdal for a while, but here's my guess:

burn_values is for false color if you don't use Z-values. Everything inside your polygon is [255,0,0] (red) if you use burn=[1,2,3],burn_values=[255,0,0]. I'm not sure what happens to points - they might not plot.

Use gdal.RasterizeLayer(ds,bands,layer,burn_values, options = ["BURN_VALUE_FROM=Z"]) if you want to use the Z values.

I'm just pulling this from the tests you were looking at: http://svn.osgeo.org/gdal/trunk/autotest/alg/rasterize.py

Another approach - pull the polygon objects out, and draw them using shapely, which may not be attractive. Or look into geodjango (I think it uses openlayers to plot into browsers using JavaScript).

Also, do you need to rasterize? A pdf export might be better, if you really want precision.

Actually, I think I found using Matplotlib (after extracting and projecting the features) was easier than rasterization, and I could get a lot more control.

EDIT:

A lower level approach is here:

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

Finally, you can iterate over the polygons (after transforming them into a local projection), and plot them directly. But you better not have complex polygons, or you will have a bit of grief. If you have complex polygons ... you are probably best off using shapely and r-tree from http://trac.gispython.org/lab if you want to roll your own plotter.

Geodjango might be a good place to ask .. they will know a lot more than me. Do they have a mailing list? There's also lots of python mapping experts around, but none of them seem to worry about this. I guess they just plot it in qGIS or GRASS or something.

Seriously, I hope that somebody who knows what they are doing can reply.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文