У мене є Arc / Info Binary Grid --- конкретно, растр накопичення потоку ArcGIS ---, і я хотів би визначити всі клітини, що мають конкретне значення (або в діапазоні значень). Зрештою, мені б хотілося сформулювати точку зображень цих комірок.
Я можу використовувати QGIS, щоб відкрити hdr.adf і отримати цей результат, робочий процес такий:
- QGIS> Растрове меню> Растровий калькулятор (позначте всі точки з цільовим значенням)
- QGIS> Растрове меню> Полігонізувати
- QGIS> Векторне меню> Підменю Геометрія> Центроїди полігонів
- Відредагуйте центроїди, щоб видалити небажані поліцентроїди (ті = 0)
Такий підхід "виконує роботу", але мені це не подобається, оскільки він створює 2 файли, які я повинен видалити, тоді я повинен видалити небажані записи (файли) з форм-файлу центроїдів (тобто ті = 0).
До цього питання підходить існуюче питання, але воно розроблене для ArcGIS / ArcPy, і я хотів би залишитися в просторі FOSS.
Чи є у когось існуючий рецепт / скрипт GDAL / Python, який допитує значення растрових комірок, і коли знайдено цільове значення --- або значення в цільовому діапазоні ---, запис додається до файлу форми? Це дозволить не тільки уникнути взаємодії з інтерфейсом користувача, але й створить чистий результат за один прохід.
Я зняв це, працюючи проти однієї з презентацій Кріса Гаррарда , але растрова робота не в моїй рубці, і я не хочу забивати питання своїм слабким кодом.
Якщо хтось захоче грати з точним набором даних, я розміщую його як .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)
Однак це не спрацювало. І я не думав намагатися гортати значення у виразі Numpy om_henners, неправильно вважаючи, що гортання їх у будь-якому рядку рівнозначне. Я думаю, що реальна проблема стосується відповідно значень x_size
та y_size
, відповідно, 30
і -30
які застосовуються, коли індекси рядків і стовпців використовуються для обчислення координат точок для комірок.
[Оригінал редагування]
@om_henners, я пробую ваше рішення, узгоджуючись з кількома репліками для створення точкових файлів за допомогою ogr ( Invisibleroads.com , Кріс Гаррард ), але у мене виникає проблема, коли точки з’являються так, ніби відображені через проходження лінії через 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())
форму вашої форми (замість того, щоб створювати проекцію з відомої рядка програми).