Bir Arc / Info Binary Grid --- özellikle bir ArcGIS akış birikim rasterim var ve belirli bir değere (veya bir değer aralığında) sahip tüm hücreleri tanımlamak istiyorum. Nihayetinde, bu hücreleri temsil eden noktaların şekil dosyası istiyorum.
Ben hdr.adf açmak ve bu sonucu almak için QGIS kullanabilirsiniz, iş akışı:
- QGIS> Tarama menüsü> Tarama Hesaplayıcısı (tüm noktaları hedef değerle işaretleyin)
- QGIS> Tarama menüsü> Çokgenleştir
- QGIS> Vektör menüsü> Geometri alt menüsü> Çokgen sentroidleri
- İstenmeyen poli centroidleri silmek için sentroidleri düzenleyin (bunlar = 0)
Bu yaklaşım "işi yapar", ancak silmem gereken 2 dosya oluşturduğu için bana hitap etmiyor, sonra istenmeyen kayıtları (lar) centroids dosya biçiminden (yani = 0) kaldırmak zorundayım.
Bir varolan soru konuya bakış, ama o ArcGIS / ArcPy için uygun hale gelecek ve ben FOSS uzayda kalmak istiyorum.
Herhangi bir raster hücre değerlerini sorgulayan mevcut bir GDAL / Python tarifi / komut dosyası var mı ve bir hedef değer - veya hedef aralıktaki bir değer bulunduğunda şekil dosyasına bir kayıt eklenir mi? Bu sadece UI etkileşimini önlemekle kalmaz, aynı zamanda tek bir geçişte temiz bir sonuç yaratır.
Chris Garrard'ın sunumlarından birine karşı çalışarak bir çekim yaptım , ancak raster çalışması tekerlek evimde değil ve soruyu zayıf kodumla karıştırmak istemiyorum.
Herkesin tam veri kümesinin oynamasını isterse, buraya .zip olarak koydum .
[Notları Düzenle] Bunu gelecek nesiller için geride bırakmak. Om_henners ile görüş alışverişine bakın. Temelde x / y (satır / sütun) değerleri çevrildi. Orijinal cevapta şu satır vardı:
(y_index, x_index) = np.nonzero(a == 1000)
ters, şöyle:
(x_index, y_index) = np.nonzero(a == 1000)
Ekran görüntüsünde gösterilen sorunla ilk karşılaştığımda, geometriyi yanlış uygulayıp uygulamadığımı merak ettim ve bu satırdaki x / y koordinat değerlerini çevirerek denedim:
point.SetPoint(0, x, y)
..gibi..
point.SetPoint(0, y, x)
Ancak bu işe yaramadı. Ve om_henners'ın Numpy ifadesindeki değerleri çevirmeyi denemedim, yanlış bir şekilde her iki hatta çevirmenin eşdeğer olduğuna inanıyorum. Gerçek bir sorun ile ilgilidir düşünmek x_size
ve y_size
sırasıyla değerleri 30
ve -30
satır ve sütun indisleri hücreleri için hesapla noktası koordinatları için kullanıldığında uygulanır.
[Orijinal Düzenleme]
@om_henners, ogr ( invisibleroads.com , Chris Garrard ) kullanarak nokta şekil dosyaları yapmak için birkaç tarifle birlikte çözümünüzü deniyorum , ancak noktaların bir çizgi boyunca yansıtılmış gibi göründüğü bir sorun yaşıyorum 315/135 derece arasında.
Açık mavi noktalar : yukarıdaki QGIS yaklaşımım tarafından oluşturuldu
Mor noktalar : aşağıda GDAL / OGR py kodu ile oluşturulmuştur
[Çözülmüş]
Bu Python kodu, @om_henners tarafından önerilen tam çözümü uygular. Test ettim ve işe yarıyor. Teşekkürler dostum!
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())
(bilinen bir proje dizesinden bir projeksiyon oluşturmak yerine).