Select to view content in your preferred language

Efficiently replacing target landcover class with neighbourhood majority class

1031
3
02-16-2014 09:16 PM
MalcolmNunn
Deactivated User
Hi

I have a soil type classification that has 8 classes: 7 soil classes and water. For the purposes of feeding the soil type layer into a model, I need to eliminate the water class and replace it with the existing (nearby) soil types. I've been attempting to do this by 'growing out' the majority soil type in the neighbourhood surrounding the water pixels.

My current thinking for doing this is to run a script iteratively that produces a focal statistics raster then run a Con statement, to replace any water pixel with the neighbourhood majority.

# Input soil type raster
ras1 = arcpy.Raster(r"C:\spatial_data\soils.gdb\soiltype")

# Produce a focal statistics raster that takes the majority value in a circle (radius = 5)
focal_ras = sa.FocalStatistics(ras1, sa.NbrCircle(5), "MAJORITY")

# if the pixel is water (VALUE == 6), use the neighbourhood majority statistic
out_ras = sa.Con(ras1 == 6, focal_ras, ras1)


This erodes the edges of rivers and lakes very slowly however, since the pixels towards the centre will have water as the majority. If I make all the water NoData first, and change the Con statement to:
out_ras = sa.Con(sa.IsNull(ras1), focal_ras, ras1)

then it works much faster, however as my area of interest is an island, this also results in my entire raster 'growing' into the NoData ocean around it (island).

I'm sure what I'm doing is horribly inefficient and poor practice. Can anyone advise on a better way of achieving this simplistic replacement of a class?

Cheers
Mal
0 Kudos
3 Replies
RamB
by
Frequent Contributor
Hi,

Just thinking of this case, I think it will work

Convert your raster to point layer. Delete all your water points. From the remaining points, generate a surface using interpolation tools like IDW . Once you understand with IDW you could go deep with more specific methods of kriging, spline, natural neighbour, trend etc, even manipulate your data so that it produces desired results.  

regards,
0 Kudos
MalcolmNunn
Deactivated User
Thanks for the response.

I am not entirely sure that what you suggest would achieve a sensible result. Since this is categorical data (7 discrete soil types), I would think that spatial interpolation would result in erroneous values. Eg if I were to try to interpolate the area of a river that is surrounded by soil types 1, 2, and 7, wouldn't I end up with an interpolated value between these ranges?

Perhaps there is a method that is suited to categorical data though?

It was this issue that made look at simple neighbourhood majority kernels to grow the bordering soil types inwards... just seems terribly inefficient!

Cheers
Mal
0 Kudos
RamB
by
Frequent Contributor
That will not be a problem. Here in picture you can see. The violet are water bodies, and in the second image, the water gets classified as surrounding landuse type. I made random points in each landuse, you can be more specific in choosing the location of points. I just do it for methodology.

in case one where, water body circle is half half in two landuses, blue and orange, half the circle goes to blue (green in new IDW) and half the circle go to orange (yellow in new IDW)

in case two where water body is eclipse shape, completely within orange landuse, then it is completely absorbed into yellow landuse in the new IDW.

I did it roughly, you can spend more time and make it more accurate, you can even use the barrier line in IDW so that cells values dont creep into others and you preserve the original shape. later you can reclassify your IDW raster to have the same 7 landuse classes.

then what you want can be made. 🙂



regards,
0 Kudos