Відповіді:
Вибір створений для подібних проблем. Подумайте про це як про "перемикання" (або "випадок") версії "кон", що є реалізацією алгебри карти "якщо ... ще".
Якщо, наприклад, є 3 растри, що перекриваються, виглядатиме синтаксис (Python)
inPositionRaster = 1 + int(3 * CreateRandomRaster())
Pick(inPositionRaster, [inRas01, inRas02, inRas03])
Зверніть увагу, що pick
індексація починається з 1, а не з 0.
(див. нитку коментарів)
Щоб впоратися зі значеннями NoData, спочатку потрібно вимкнути обробку NoData ArcGIS. Зробіть це, створивши сітки, які мають спеціальне (але дійсне) значення замість NoData, наприклад 99999 (або що завгодно: але переконайтесь, що виберіть значення, яке більше, ніж будь-яке дійсне число, яке може з’явитися: це буде зручно пізніше) . Це вимагає використання запиту IsNull, як у
p01 = Con(IsNull(inRas01), 99999, inRas01)
p02 = Con(IsNull(inRas02), 99999, inRas01)
p03 = Con(IsNull(inRas03), 99999, inRas01)
Наприклад, розглянемо випадок цих однорядних сіток (NoData показано як "*"):
inRas01: 1 2 19 4 * * * *
inRas02: 9 2 * * 13 14 * *
inRas03: 17 * 3 * 21 * 23 *
Результат - поставити 99999 на місце кожного "*".
Далі уявіть всі ці растрові як плоскі масиви дерев'яних блоків з NoData, що відповідають пропущеним блокам (отворам). Коли ви вертикально укладете ці растри, блоки потраплять у будь-які отвори під ними. Нам потрібна така поведінка, щоб уникнути вибору значень NoData: ми не хочемо вертикальних прогалин у стеках блоків. Порядок блоків у кожній вежі насправді не має значення. З цією метою ми можемо отримати кожну вежу, класифікуючи дані :
q01 = Rank(1, [p01, p02, p03])
q02 = Rank(2, [p01, p02, p03])
q03 = Rank(3, [p01, p02, p03])
У прикладі ми отримуємо
q01: 1 2 3 4 13 14 23 99999
q02: 9 2 19 99999 21 99999 99999 99999
q03: 17 99999 99999 99999 99999 99999 99999 99999
Зверніть увагу, що ранги - від найнижчого до найвищого, так що q01 містить найнижчі значення в кожному місці, q02 містить друге-найнижнє тощо. Коди NoData не починають відображатися, поки не будуть зібрані всі дійсні числа, оскільки ці коди мають більше , ніж будь-які дійсні числа.
Щоб уникнути вибору цих кодів NoData під час випадкового вибору, вам потрібно знати, скільки блоків складено в кожному місці: це говорить про те, скільки дійсних значень відбувається. Один із способів вирішити це - підрахувати кількість кодів NoData і відняти їх від загальної кількості сіток вибору:
n0 = 3 - EqualToFrequency(99999, [q01, q02, q03])
Це дає
n0: 3 2 2 1 2 1 1 0
Щоб обробити випадки, коли n = 0 (тому для вибору немає нічого), встановіть їх на NoData:
n = SetNull(n0 == 0, n0)
Тепер
n: 3 2 2 1 2 1 1 *
Це також гарантує, що ваші (тимчасові) коди NoData зникнуть під час остаточного розрахунку. Створення випадкових значень між 1 і n:
inPositionRaster = 1 + int(n * CreateRandomRaster())
Наприклад, може виглядати такий растр
inPositionRaster: 3 2 1 1 2 1 1 *
Усі його значення лежать між 1 і відповідним значенням у [n].
Виберіть значення точно, як і раніше:
selection = Pick(inPositionRaster, [q01, q02, q03])
Це призведе до
selection: 17 2 3 4 21 14 23 *
Щоб переконатися, що все в порядку, спробуйте вибрати всі вихідні комірки з кодом NoData (99999 у цьому прикладі): їх не повинно бути.
Хоча цей запущений приклад використовує лише три сітки для вибору, я написав це таким чином, що легко узагальнює будь-яку кількість сіток. З великою кількістю сіток написання сценарію (для переходу на повторні операції) буде неоціненним.
pick
: якщо inPositionRaster і вибраний растр мають дійсні значення в комірці, то ймовірно результат для цієї комірки має бути значення вибраного растру, незалежно від того, що може містити будь-яка інша растра). Яку альтернативну поведінку ви думаєте?
Використання python та ArcGIS 10 та використання функції con, яка має такий синтаксис:
Con (in_conditional_raster, in_true_raster_or_constant, {in_false_raster_or_constant}, {where_clause})
Ідея тут полягає у тому, щоб перевірити, чи є значення у випадковому растрі менше 0,5, якщо він вибирається растровим1, інакше виберіть растровий2. NoData
+ data = NoData
тому спочатку встановіть ці перекласифікуючі значення NoData
на 0:
import arcpy
from arcpy import env
from arcpy.sa import *
env.workspace = "C:/sapyexamples/data"
ras1_NoNull = Con(IsNull("elevation1"),0, "elevation1") # remove NoData
ras2_NoNull = Con(IsNull("elevation2"),0, "elevation2") # remove NoData
randRaster = CreateRandomRaster(100, 2, Extent(0, 0, 150, 150)) # raster generated between 0 and 1; 100 is seed value
outCon = Con(randRaster < 0.5, ras1_NoNull, ras2_NoNull)
outCon.save("C:/outcon.img") # save raster
РЕДАКТУВАТИ: Щойно зрозумів, що ви не додаєте NoData
значення, щоб шматок можна було залишити.
Con(IsNull(ras1), 0, ras2)
NoData
? Це просто переконатися, що їх не вибирають, коли вибірково вибирають?
Я б просто створив випадковий растр ( довідка ) однакового розміру та розміру комірок. Потім за допомогою CON ( довідки ) встановіть його для вибору значення з 1-го растру, якщо комірка з рандомізованого растру має значення <128 (якщо випадковий растр буде 0 - 255), інакше виберіть значення з другого растру.
Сподіваюся, що це має сенс :)