Смотрите эту ссылку для более подробной информации.
Проблема:
Я хочу перебрать непрерывный растр (тот, у которого нет таблицы атрибутов), ячейка за ячейкой и получить значение ячейки. Я хочу взять эти значения и выполнить для них условия, эмулируя шаги алгебры карты, подробно описанные ниже, без фактического использования растрового калькулятора.
В ответ на запрос комментариев ниже, я добавил подробности, предоставив предысторию проблемы и обосновав необходимость реализации метода как такового в разделе ниже под названием «Необходим анализ:».
Анализ, предложенный ниже, хотя и имеет отношение к моей проблеме, предоставляя справочную информацию, не нуждается в реализации в ответе. Объем вопроса касается только итерации непрерывного растра для получения / установки значений ячеек.
Необходим анализ:
Если выполняется ЛЮБОЕ из следующих условий, присвойте выходной ячейке значение 1. Только присвойте выходной ячейке значение 0, если ни одно из условий не выполнено.
Условие 1: если значение ячейки больше, чем верхняя и нижняя ячейки, укажите значение 1:
Con("raster" > FocalStatistics("raster", NbrIrregular("C:\filepath\kernel_file.txt"), "MAXIMUM"), 1, 0)
Где файл ядра выглядит так:
3 3
0 1 0
0 0 0
0 1 0
Условие 2: если значение ячейки больше, чем у левой и правой ячейки, укажите значение 1:
Con("raster" > FocalStatistics("raster", NbrIrregular("C:\filepath\kernel_file.txt"), "MAXIMUM"), 1, 0)
Где файл ядра выглядит так:
3 3
0 0 0
1 0 1
0 0 0
Условие 3: если значение ячейки больше, чем у верхнего и нижнего ячеек, укажите значение 1:
Con("raster" > FocalStatistics("raster", NbrIrregular("C:\filepath\kernel_file.txt"), "MAXIMUM"), 1, 0)
Где файл ядра выглядит так:
3 3
1 0 0
0 0 0
0 0 1
Условие 4: Если значение ячейки больше, чем у нижнего левого и верхнего правого ячеек, задайте значение 1:
Con("raster" > FocalStatistics("raster", NbrIrregular("C:\filepath\kernel_file.txt"), "MAXIMUM"), 1, 0)
Где файл ядра выглядит так:
3 3
0 0 1
0 0 0
1 0 0
Условие 5: если любая из соседних ячеек имеет значение EQUAL для центральной ячейки, присвойте выходному растру значение 1 ( используя фокусное многообразие с двумя расчетами ближайших окрестностей )
Почему бы не использовать алгебру карт?
Ниже было отмечено, что моя проблема может быть решена с помощью алгебры карт, но, как видно выше, это всего шесть вычислений растра, плюс один для объединения всех растров, созданных вместе. Мне кажется, что гораздо эффективнее переходить от ячейки к ячейке и выполнять все сравнения сразу в каждой ячейке, вместо того, чтобы перебирать каждую по отдельности семь раз и использовать довольно много памяти для создания семи растров.
Как решить проблему?
Приведенная выше ссылка рекомендует использовать интерфейс IPixelBlock, однако из документации ESRI неясно, осуществляете ли вы доступ к самому значению одной ячейки через IPixelBlock, или если вы обращаетесь к нескольким значениям ячеек из размера установленного IPixelBlock. Хороший ответ должен предложить метод доступа к значениям ячеек непрерывного растра и дать объяснение методологии, лежащей в основе кода, если это не очевидно.
В итоге:
Каков наилучший метод для обхода каждой ячейки в НЕПРЕРЫВНОМ растре (у которого нет таблицы атрибутов ) для доступа к значениям ее ячеек?
Хороший ответ не должен реализовывать шаги анализа, описанные выше, он должен только предоставить методологию для доступа к значениям ячеек растра.
Ответы:
Я вижу, что это уже было решено с помощью Original Poster (OP), но я опубликую простое решение на python на тот случай, если кто-нибудь в будущем заинтересуется различными способами решения этой проблемы. Я неравнодушен к программному обеспечению с открытым исходным кодом, поэтому вот решение, использующее GDAL в python:
Реализуйте функцию так:
Затем выполните итерацию ваших данных с помощью вложенного цикла:
Или, может быть, вы хотите сгладить двумерный массив с помощью понимания списка:
В любом случае, при переборе данных по ячейкам можно добавлять некоторые условия в ваш цикл для изменения / редактирования значений. Посмотрите этот сценарий, который я написал для разных способов доступа к данным: https://github.com/azgs/hazards-viewer/blob/master/python/zonal_stats.py .
источник
Обновить! Numpy решение:
Таким образом, получение готового массива обратно в растр с использованием arcpy является проблематичным. arcpy.NumPyArrayToRaster является коротким и имеет тенденцию переопределять экстенты, даже если вы передаете ему свои координаты LL.
Я предпочитаю сохранить как текст.
Я использую Python как 64-битный для скорости - на данный момент это означает, что я не могу передать numpy.savetxt заголовок. Поэтому мне нужно открыть вывод и добавить заголовок ASCII, который хочет Arc, прежде чем конвертировать ASCII в растр
Numpy версия запускает мой сдвиговый растр, умножения и сложения намного быстрее (1000 итераций за 2 минуты), чем arcpy версия (1000 итераций за 15 минут)
Старая версия Я могу удалить это позже, я просто написал похожий сценарий. Я пытался конвертировать в точки и использовать курсор поиска. Я получил только 5000 итераций за 12 часов. Итак, я искал другой путь.
Мой способ сделать это - перебрать координаты центра ячейки каждой ячейки. Я начинаю в верхнем левом углу и двигаюсь справа налево. В конце ряда я опускаюсь вниз и снова начинаю слева. У меня есть 240-метровый растр с 2603 столбцами и 2438 строками, так что всего 6111844 ячеек. Я использую переменную итератора и цикл while. См. ниже
Несколько замечаний: 1 - нужно знать координаты экстента
2 - запустить с точечными координатами для центра ячейки - сдвинуть на 1/2 размера ячейки от значений экстента
3 - Мой сценарий использует значение ячейки, чтобы вытянуть растр, зависящий от значения, а затем сместить этот растр в центр исходной ячейки. Это добавляет нулевой растр для расширения экстента перед добавлением в окончательный растр. Это всего лишь пример. Здесь вы можете поместить свои условные операторы (второй оператор if в цикле while).
4 - Этот сценарий предполагает, что все растровые значения могут быть преобразованы как целые числа. Это означает, что вам нужно сначала избавиться от данных. Con IsNull.
6 - Я до сих пор не доволен этим, и я работаю над тем, чтобы полностью избавиться от этого. Я бы предпочел разыгрывать массивы и делать там математику, а затем возвращать ее в Арк.
источник
Попробуйте использовать IGridTable, ICursor, IRow. Этот фрагмент кода предназначен для обновления значений растровых ячеек, однако он показывает основы итерации:
Как я могу добавить новое поле в таблицу атрибутов растра и пройти по нему?
Пройдя по таблице, вы можете получить значение строки определенного поля, используя
row.get_Value(yourfieldIndex)
. Если вы GoogleВы должны быть в состоянии получить множество примеров, показывающих это.
Надеюсь, это поможет.
источник
Как насчет радикальной идеи, это потребует от вас программирования на python или ArcObjects.
источник
Решение:
Я решил это ранее сегодня. Код является адаптацией этого метода . Концепция этого не была ужасно сложной, когда я выяснил, что на самом деле делают объекты, используемые для взаимодействия с растром. Приведенный ниже метод принимает два набора входных данных (inRasterDS и outRasterDS). Они оба представляют собой один и тот же набор данных, я просто сделал копию inRasterDS и передал ее в метод как outRasterDS. Таким образом, они оба имеют одинаковый экстент, пространственную привязку и т. Д. Метод считывает значения из inRasterDS, ячейка за ячейкой, и сравнивает их с ближайшими соседями. Он использует результаты этих сравнений в качестве сохраненных значений в outRasterDS.
Процесс:
Я использовал IRasterCursor -> IPixelBlock -> SafeArray, чтобы получить значения пикселей, и IRasterEdit, чтобы записывать новые значения в растр. Когда вы создаете IPixelBlock, вы указываете машине размер и местоположение области, в которую вы хотите читать / записывать. Если вы хотите редактировать только нижнюю половину растра, установите это в качестве параметров IPixelBlock. Если вы хотите зациклить весь растр, вы должны установить IPixelBlock равным размеру всего растра. Я делаю это в методе ниже, передавая размер IRasterCursor (pSize), затем получая PixelBlock от растрового курсора.
Другой ключ заключается в том, что вы должны использовать SafeArray для взаимодействия со значениями в этом методе. Вы получаете IPixelBlock от IRasterCursor, затем SafeArray от IPixelBlock. Затем вы читаете и пишете в SafeArray. Когда вы закончите чтение / запись в SafeArray, запишите весь свой SafeArray обратно в IPixelBlock, затем запишите свой IPixelBlock в IRasterCursor, а затем, наконец, используйте IRasterCursor, чтобы установить местоположение для начала записи, и IRasterEdit, чтобы выполнить саму запись. Этот последний шаг - то, где вы фактически редактируете значения набора данных.
источник
Растровые данные AFAIK можно прочитать тремя способами:
Не изобретая колесо, я предлагаю прочитать эти поучительные слайды Криса Гаррарда.
Таким образом, наиболее эффективным методом является чтение данных по блокам, однако это приведет к потере данных в соответствии пикселей, расположенных за границами блоков, при применении фильтра. Таким образом, безопасный альтернативный способ должен состоять в том, чтобы читать все изображение одновременно и использовать простой подход.
Что касается вычислений, вместо этого я должен использовать gdalfilter.py и неявно подход VRT KernelFilteredSource, чтобы применять необходимые фильтры и, прежде всего, избегать тяжелых вычислений.
источник