Tôi đã có một Lưới nhị phân Arc / Info --- cụ thể, một raster tích lũy dòng ArcGIS --- và tôi muốn xác định tất cả các ô có một giá trị cụ thể (hoặc trong một phạm vi giá trị). Cuối cùng, tôi muốn một shapefile các điểm đại diện cho các ô này.
Tôi có thể sử dụng QGIS để mở hdr.adf và nhận được kết quả này, quy trình làm việc là:
- QGIS> Trình đơn raster> Máy tính raster (đánh dấu tất cả các điểm bằng giá trị đích)
- QGIS> Menu raster> Đa giác
- QGIS> Menu Vector> menu con Hình học> Nhân đa giác
- Chỉnh sửa các centroid để xóa các polyroid không mong muốn (những người = 0)
Cách tiếp cận này "thực hiện công việc", nhưng nó không hấp dẫn tôi vì nó tạo ra 2 tệp tôi phải xóa, sau đó tôi phải xóa (các) bản ghi không mong muốn khỏi shapefile của centroid (tức là = 0).
Một câu hỏi hiện có tiếp cận chủ đề này, nhưng nó phù hợp với ArcGIS / ArcPy và tôi muốn ở lại trong không gian FOSS.
Có ai có công thức / tập lệnh GDAL / Python hiện có để thẩm vấn các giá trị ô của raster không và khi tìm thấy giá trị đích --- hoặc giá trị trong phạm vi đích ---, một bản ghi sẽ được thêm vào shapefile? Điều này không chỉ tránh tương tác UI mà còn tạo ra kết quả rõ ràng trong một lần chạy.
Tôi đã bắn nó bằng cách làm việc với một trong những bài thuyết trình của Chris Garrard , nhưng công việc raster không phải trong nhà xe của tôi và tôi không muốn làm lộn xộn câu hỏi với mã yếu của mình.
Nếu ai muốn có bộ dữ liệu chính xác để chơi, tôi đặt nó ở đây dưới dạng .zip .
[Chỉnh sửa ghi chú] Để lại điều này cho hậu thế. Xem trao đổi bình luận với om_henners. Về cơ bản, các giá trị x / y (hàng / cột) đã được lật. Câu trả lời ban đầu có dòng này:
(y_index, x_index) = np.nonzero(a == 1000)
đảo ngược, như thế này:
(x_index, y_index) = np.nonzero(a == 1000)
Khi lần đầu tiên tôi gặp vấn đề được minh họa trong ảnh chụp màn hình, tôi tự hỏi liệu tôi có triển khai hình học không chính xác không và tôi đã thử nghiệm bằng cách lật các giá trị tọa độ x / y trong dòng này:
point.SetPoint(0, x, y)
..như..
point.SetPoint(0, y, x)
Tuy nhiên điều đó đã không làm việc. Và tôi đã không nghĩ sẽ thử lật các giá trị trong biểu thức Numpy của om_henners, tin sai rằng việc lật chúng ở một trong hai dòng là tương đương. Tôi nghĩ rằng vấn đề thực sự liên quan đến các giá trị x_size
và y_size
, tương ứng 30
và -30
, được áp dụng khi các chỉ số hàng và cột được sử dụng để tính tọa độ điểm cho các ô.
[Chỉnh sửa gốc]
@om_henners, tôi đang thử giải pháp của bạn, phối hợp với một vài người nhận để tạo các shapefile điểm bằng cách sử dụng ogr ( invisibleroads.com , Chris Garrard ), nhưng tôi gặp vấn đề khi các điểm xuất hiện như thể được phản ánh qua một dòng xuyên qua 315/135 độ.
Điểm màu xanh nhạt : được tạo bởi phương pháp QGIS của tôi , ở trên
Điểm màu tím : được tạo bởi mã py GDAL / OGR , bên dưới
[Đã giải quyết]
Mã Python này thực hiện giải pháp hoàn chỉnh theo đề xuất của @om_henners. Tôi đã thử nó và nó hoạt động. Cảm ơn người đàn ông!
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())
(thay vì phải tạo phép chiếu từ chuỗi proj đã biết).