Select to view content in your preferred language

Conditional statement to force two raster elevation surfaces to not intersect

106
2
Friday
JohnEsch2
Occasional Contributor

Using ArcGIS Pro, I have 2 raster elevation surfaces over a large area I will call Upper and Lower which should never intersect. The Upper should always be above the Lower surface. The elevation difference varies between the two surfaces.  But because of errors or inconsistency in the data occasionally they intersect and for instance over a small area the Lower may rise above the upper. I am looking at creating a conditional statement where if the Lower>Upper it takes the average elevation distance between the two surfaces in the local area (beyond the erroneous intersection) between the two surface and pushes down the lower surface by that amount so the two surfaces no longer intersect and in the area of the erroneous intersection and the Lower is now below the Upper by the average elevation difference between them in the local area. 

0 Kudos
2 Replies
BrennanSmith1
Frequent Contributor

If you have Spatial Analyst, you could do this using Focal Statistics and Set Null.  Just be sure to update the neighborhood size (nbr_size variable) to reflect your actual data.

import arcpy
from arcpy.sa import *

# === CONFIGURATION ===
upper_raster_name = "Upper_Surface"   # Name of upper raster layer in Pro
lower_raster_name = "Lower_Surface"   # Name of lower raster layer in Pro
output_lower_name = "Lower_Corrected" # Output corrected lower surface
nbr_size = 50                         # Neighborhood size in cells (must span error gaps)
# =====================

arcpy.env.overwriteOutput = True

upper = Raster(upper_raster_name)
lower = Raster(lower_raster_name)

# Isolate valid positive differences (Upper - Lower > 0)
diff = upper - lower
valid_diff = SetNull(diff <= 0, diff)

# Compute local average gap using surrounding valid data
local_avg_diff = FocalStatistics(valid_diff, NbrRectangle(nbr_size, nbr_size, "CELL"), "MEAN", "DATA")

# Apply conditional adjustment where Lower >= Upper
fixed_lower = Con(lower >= upper, upper - local_avg_diff, lower)

# Save output
fixed_lower.save(output_lower_name)

 

0 Kudos
Robert_LeClair
Esri Esteemed Contributor

You can model this in ArcGIS Pro with Raster Calculator using a Con (conditional) that only modifies the “bad” cells (where Lower > Upper) and uses Focal Statistics (Mean) to estimate the local typical separation outside/around the error.

Try these steps using the Raster Calculator:
Compute the separation (gap) raster:
gap = upper - lower
Get a local mean gap (choose a neighborhood large enough to extend beyond the erroneous intersection)
gapMean = FocalStatistics(gap, NbrRectangle(15,15,"CELL"), "MEAN")
Lower only where it violates Upper, using the local mean gap
lower_fixed = Con(lower > upper, upper - gapMean, lower)

This sets the corrected lower surface to be below the upper by the local average gap (rather than just clamping to upper).

0 Kudos