나는있어 아크 / 정보 이진 그리드 --- 특히,는 ArcGIS가 축적 래스터 흐름 --- 나는 특정 값을 갖는 모든 셀을 확인하고 싶습니다 (또는 값의 범위에서). 궁극적으로, 나는이 세포들을 나타내는 점들의 shapefile을 원합니다.
QGIS를 사용하여 hdr.adf를 열고이 결과를 얻을 수 있습니다. 워크 플로는 다음과 같습니다.
- QGIS> 래스터 메뉴> 래스터 계산기 (모든 포인트를 목표 값으로 표시)
- QGIS> 래스터 메뉴> 다각형
- QGIS> 벡터 메뉴> 형상 하위 메뉴> 다각형 중심
- 원치 않는 폴리 중심을 삭제하기 위해 중심을 편집하십시오 (그들 = 0)
이 접근 방식은 "작업을 수행하지만"삭제해야하는 2 개의 파일을 생성하기 때문에 마음에 들지 않습니다. 그런 다음 중심의 쉐이프 파일 (예 : 그 = 0)에서 원치 않는 레코드를 제거해야합니다.
기존의 문제는이 주제에 접근하지만, 그것은는 ArcGIS / ArcPy에 맞게 조정, 그리고 나는 FOSS 공간에 머물 싶습니다.
누구나 래스터의 셀 값을 조사하는 기존 GDAL / Python 레시피 / 스크립트가 있고 목표 값 또는 목표 범위의 값이 발견되면 레코드가 셰이프 파일에 추가됩니까? 이렇게하면 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 표현의 값을 뒤집으려고하지 않았다고 생각했습니다. I 진짜 문제는 관련된 생각 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())
알려진 프로젝트 문자열에서 투영을 생성하는 대신 래스터 투영을 쉐이프 파일 투영으로 사용할 수 있습니다 .