GDAL-シンプルな最小コストパス分析の実行


8

gdalを使用して簡単な最小コストパス分析を実行する方法を調査しています。簡単に言うと、デムの傾きを唯一のコスト要因として使用することです。

私はpythonまたは.netバインディングを使用することを好みますが、何でも取ります。誰でも良いチュートリアルなどを提案できますか?


3
分析的な質問については、おそらくより良い...データ形式抽象化ライブラリではなく、GISを使う
markusN

2
好奇心から、アプリケーションは何ですか?DEMの勾配が移動コストの現実的な代用となるものを考えるのは困難です。これはあなたが必要なものだと確信していますか?このコードを書く努力をした後で、それが実際に問題を解決していないことがわかったとしたら、残念です。
whuber

ある種の重力依存分散モデルをモデル化する場合、勾配は移動コストとして役立つ可能性がありますが、勾配だけでなく、他のいくつかの要因も予想されます。
MappaGnosis、2012

また、ルートが下り坂または上り坂を直接進んでいない場合でも、通常、勾配は各セルの最大勾配を示します。
マシュースネイプ

回答:


8

次のスクリプトは、最小コストのパス分析を実行します。入力パラメーターは、コストサーフェスラスター(勾配など)と開始および停止座標です。作成されたパスを持つラスターが返されます。skimageライブラリとGDAL が必要です。

たとえば、ポイント1とポイント2の間の最小コストパスは、勾配ラスターに基づいて作成されます。 ここに画像の説明を入力してください

import gdal, osr
from skimage.graph import route_through_array
import numpy as np


def raster2array(rasterfn):
    raster = gdal.Open(rasterfn)
    band = raster.GetRasterBand(1)
    array = band.ReadAsArray()
    return array  

def coord2pixelOffset(rasterfn,x,y):
    raster = gdal.Open(rasterfn)
    geotransform = raster.GetGeoTransform()
    originX = geotransform[0]
    originY = geotransform[3] 
    pixelWidth = geotransform[1] 
    pixelHeight = geotransform[5]
    xOffset = int((x - originX)/pixelWidth)
    yOffset = int((y - originY)/pixelHeight)
    return xOffset,yOffset

def createPath(CostSurfacefn,costSurfaceArray,startCoord,stopCoord):   

    # coordinates to array index
    startCoordX = startCoord[0]
    startCoordY = startCoord[1]
    startIndexX,startIndexY = coord2pixelOffset(CostSurfacefn,startCoordX,startCoordY)

    stopCoordX = stopCoord[0]
    stopCoordY = stopCoord[1]
    stopIndexX,stopIndexY = coord2pixelOffset(CostSurfacefn,stopCoordX,stopCoordY)

    # create path
    indices, weight = route_through_array(costSurfaceArray, (startIndexY,startIndexX), (stopIndexY,stopIndexX),geometric=True,fully_connected=True)
    indices = np.array(indices).T
    path = np.zeros_like(costSurfaceArray)
    path[indices[0], indices[1]] = 1
    return path

def array2raster(newRasterfn,rasterfn,array):
    raster = gdal.Open(rasterfn)
    geotransform = raster.GetGeoTransform()
    originX = geotransform[0]
    originY = geotransform[3] 
    pixelWidth = geotransform[1] 
    pixelHeight = geotransform[5]
    cols = array.shape[1]
    rows = array.shape[0]

    driver = gdal.GetDriverByName('GTiff')
    outRaster = driver.Create(newRasterfn, cols, rows, gdal.GDT_Byte)
    outRaster.SetGeoTransform((originX, pixelWidth, 0, originY, 0, pixelHeight))
    outband = outRaster.GetRasterBand(1)
    outband.WriteArray(array)
    outRasterSRS = osr.SpatialReference()
    outRasterSRS.ImportFromWkt(raster.GetProjectionRef())
    outRaster.SetProjection(outRasterSRS.ExportToWkt())
    outband.FlushCache()    

def main(CostSurfacefn,outputPathfn,startCoord,stopCoord):

    costSurfaceArray = raster2array(CostSurfacefn) # creates array from cost surface raster

    pathArray = createPath(CostSurfacefn,costSurfaceArray,startCoord,stopCoord) # creates path array

    array2raster(outputPathfn,CostSurfacefn,pathArray) # converts path array to raster


if __name__ == "__main__":
    CostSurfacefn = 'CostSurface.tif'
    startCoord = (345387.871,1267855.277)
    stopCoord = (345479.425,1267799.626)
    outputPathfn = 'Path.tif'
    main(CostSurfacefn,outputPathfn,startCoord,stopCoord)

私はあなたの答えが好きです。より広い地域でコスト値が同じである湖などをどのように処理しますか。私の道は、期待どおりに続く前にエリアが覆われるまで、湖や蛇のように蛇行します。ありがとう。
マイケル

私はこれに長い間取り組んでいません。おそらくあなたはすでにこれを考えていましたが、私は湖のコストを本当に高く設定しました。このように、小道は湖を避けなければなりませんね。
ustroetz 2017

ええ、私は湖を0を少し超えるように設定しました。そうすると、コストがかかり、蛇行が消えます。
マイケル

3

生成されたノード間のコストとして勾配を使用するA *検索アルゴリズムを使用できます。それがどのように見えるかをすばやく視覚化するには:

アニメ化された星

A *検索アルゴリズム(Wiki) および Python A *検索アルゴリズム(SO)を参照してください

A *を理解する。

スロープマップには、そこにオプションがあります- ここに1つあります。

勾配マップ(ラスター)を使用すると、GDALを使用してその中からコスト値を取得できます。


2
勾配ラスターをグラフにして、指摘したPython A *検索アルゴリズムコードで使用できるようにする方法を説明できますか?GDALを使用してラスターから値を取得する方法を知っています。しかし、それをグラフとして使用するために何を格納する必要があるのか​​(例:辞書?)?
ustroetz 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.