私が持っているARC / INFOバイナリグリッドを具体的には、ArcGISのは累積ラスタを流し--- ---と私は特定の値(または値の範囲で)を有する全ての細胞を同定したいと思います。最終的に、これらのセルを表すポイントのシェープファイルが欲しいです。
QGISを使用してhdr.adfを開き、この結果を取得できます。ワークフローは次のとおりです。
- QGIS>ラスターメニュー>ラスター計算機(すべてのポイントを目標値でマーク)
- QGIS>ラスターメニュー>ポリゴン化
- QGIS>ベクトルメニュー>ジオメトリサブメニュー>ポリゴン重心
- 重心を編集して、不要なポリ重心を削除します(これらの重心= 0)
このアプローチは「仕事をします」が、削除しなければならない2つのファイルを作成し、重心のシェイプファイルから不要なレコードを削除する必要があるため、私には魅力的ではありません(つまり、それらは0です)。
既存の質問は、この主題に近づくが、それは、ArcGISの/ ArcPyに合わせだ、と私はFOSSのスペースに滞在したいと思います。
ラスターのセル値を調べる既存のGDAL / Pythonレシピ/スクリプトがあり、ターゲット値(またはターゲット範囲内の値)が見つかった場合、レコードがシェープファイルに追加されますか?これにより、UIの相互作用が回避されるだけでなく、単一のパスでクリーンな結果が作成されます。
Chris Garrardのプレゼンテーションの1つに対して作業することでショットを撮りましたが、ラスター作業は私の操舵室にありません。また、弱いコードで質問を混乱させたくありません。
正確なデータセットを使用したい場合は、ここに.zipとして配置します。
[メモの編集]後世のためにこれを残してください。om_hennersとのコメント交換を参照してください。基本的に、x / y(行/列)の値は反転しました。元の答えには次の行がありました:
(y_index, x_index) = np.nonzero(a == 1000)
このように反転します:
(x_index, y_index) = np.nonzero(a == 1000)
スクリーンショットに示されている問題に初めて遭遇したとき、ジオメトリを誤って実装したかどうか疑問に思い、次の行でx / y座標値を反転させて実験しました。
point.SetPoint(0, x, y)
..なので..
point.SetPoint(0, y, x)
しかし、それはうまくいきませんでした。そして、om_hennersのNumpy式で値を反転させようとは考えていませんでした。どちらの行で値を反転しても同等であると間違って信じていました。私は、本当の問題がに関する考えるx_size
とy_size
、それぞれの値、30
および-30
行と列のインデックスは、細胞のための計算点の座標に使用されている場合に適用されます。
[オリジナル編集]
@ om_henners、ogr(invisibleroads.com、Chris Garrard)を使用してポイントシェープファイルを作成するためのいくつかのレシピと協力して、あなたのソリューションを試していますが、ポイントがライン通過を越えて反映されるかのように表示される問題があります315/135度まで。
水色の点:上記のQGISアプローチによって作成された
紫色のポイント:以下のGDAL / OGR pyコードによって作成
[解決済み]
このPythonコードは、@ om_hennersによって提案された完全なソリューションを実装します。私はそれをテストしましたが、動作します。ありがとう!
from osgeo import gdal
import numpy as np
import osgeo.ogr
import osgeo.osr
path = "D:/GIS/greeneCty/Greene_DEM/GreeneDEM30m/flowacc_gree/hdr.adf"
print "\nOpening: " + path + "\n"
r = gdal.Open(path)
band = r.GetRasterBand(1)
(upper_left_x, x_size, x_rotation, upper_left_y, y_rotation, y_size) = r.GetGeoTransform()
a = band.ReadAsArray().astype(np.float)
# This evaluation makes x/y arrays for all cell values in a range.
# I knew how many points I should get for ==1000 and wanted to test it.
(y_index, x_index) = np.nonzero((a > 999) & (a < 1001))
# This evaluation makes x/y arrays for all cells having the fixed value, 1000.
#(y_index, x_index) = np.nonzero(a == 1000)
# DEBUG: take a look at the arrays..
#print repr((y_index, x_index))
# Init the shapefile stuff..
srs = osgeo.osr.SpatialReference()
#srs.ImportFromProj4('+proj=utm +zone=15 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs')
srs.ImportFromWkt(r.GetProjection())
driver = osgeo.ogr.GetDriverByName('ESRI Shapefile')
shapeData = driver.CreateDataSource('D:/GIS/01_tutorials/flow_acc/ogr_pts.shp')
layer = shapeData.CreateLayer('ogr_pts', srs, osgeo.ogr.wkbPoint)
layerDefinition = layer.GetLayerDefn()
# Iterate over the Numpy points..
i = 0
for x_coord in x_index:
x = x_index[i] * x_size + upper_left_x + (x_size / 2) #add half the cell size
y = y_index[i] * y_size + upper_left_y + (y_size / 2) #to centre the point
# DEBUG: take a look at the coords..
#print "Coords: " + str(x) + ", " + str(y)
point = osgeo.ogr.Geometry(osgeo.ogr.wkbPoint)
point.SetPoint(0, x, y)
feature = osgeo.ogr.Feature(layerDefinition)
feature.SetGeometry(point)
feature.SetFID(i)
layer.CreateFeature(feature)
i += 1
shapeData.Destroy()
print "done! " + str(i) + " points found!"
srs.ImportFromWkt(r.GetProjection())
既知のプロジェクト文字列から投影を作成する代わりに)ラスター投影をシェープファイル投影として使用できます。