我有一个Arc / Info Binary Grid(具体地说,是ArcGIS流累积栅格),并且我想识别所有具有特定值(或值范围)的像元。最终,我想要一个表示这些单元的点的shapefile。
我可以使用QGIS打开hdr.adf并获得此结果,工作流程为:
- QGIS>栅格菜单>栅格计算器(用目标值标记所有点)
- QGIS>栅格菜单>多边形
- QGIS>矢量菜单>几何子菜单>多边形形心
- 编辑质心以删除不需要的多质心(这些质心= 0)
这种方法“完成了任务”,但是对我来说并不有吸引力,因为它创建了两个我必须删除的文件,然后我必须从形心的shapefile中删除不需要的记录(即那些= 0)。
一个现有的问题可以解决这个问题,但是它是针对ArcGIS / ArcPy量身定制的,我想留在FOSS领域。
是否有人拥有可查询栅格像元值的现有GDAL / Python配方/脚本,并且在找到目标值(或目标范围内的值)时,将记录添加到shapefile中?这样不仅可以避免与UI的交互,而且还可以通过一次创建干净的结果。
我通过与Chris Garrard的一个演示文稿进行对比而对此进行了射击,但是光栅工作不在我的操盘手,并且我不想用我的弱代码使问题变得混乱。
如果有人希望使用确切的数据集,我将它作为.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)制作点shapefile的一些方法配合使用,但是我遇到了一个问题,即这些点的显示好像在一条直线上反射一样通过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())
(而不必从已知的proj字符串创建投影)。