Select to view content in your preferred language

Pull values from raster within buffer around point

187
2
a month ago
ZoeZaloudek
Occasional Contributor

I have a set of points.  For each point, I want the values from a raster within a buffer radius around the point.  The radius of the buffer can vary.  Once I have these values, I compare them to a value from the point attributes.  I'm checking to see if at least one value from the raster is +/- 1.0 from the point's value.  I have figured out how to do this with ArcPy, however I have thousands of points and it takes about 30 seconds to run just 10 points.  Is there a faster way to do this?

I'm running Python 3.11:

with arcpy.da.UpdateCursor(TestPts, fields, wclause) as cursor:
    for row in cursor:
        # Create a buffer polygon geometry around this point
        geom = row[0]
        buff = geom.buffer(thisbuffdist)
        # Set the extent to just the buffer polygon
        arcpy.env.extent = buff.extent
        # Extract raster cells within the buffer
        OutRasEBM = ExtractByMask(Ras, buff, 'INSIDE')
        # Convert extracted Raster to numpy array
        arr = arcpy.RasterToNumPyArray(OutRasEBM)
        # Clear buff and OutRasEBM from memory
        del buff, OutRasEBM
        # Find if a value in the array is within 1 foot of pointvalue
        pointvalue = row[1]
        diffarr = arr - pointvalue
        for rw in diffarr:
            for x in rw:
                if x > -1.0 and x < 1.0:
                    row[2] = 'P'
                    break
        cursor.updateRow(row)

 

0 Kudos
2 Replies
TonyAlmeida
Occasional Contributor III

Try

 

with arcpy.da.UpdateCursor(TestPts, fields, wclause) as cursor:
    for row in cursor:
        geom = row[0]
        buff = geom.buffer(thisbuffdist)
        arcpy.env.extent = buff.extent

        # Extract raster cells within the buffer based on attribute condition
        expression = f"VALUE >= {row[1] - 1.0} AND VALUE <= {row[1] + 1.0}"
        OutRasEBM = ExtractByAttributes(Ras, expression)

        # Convert extracted Raster to numpy array
        arr = arcpy.RasterToNumPyArray(OutRasEBM)

        # Check if any value in the array meets the condition
        if (arr > row[1] - 1.0).any() and (arr < row[1] + 1.0).any():
            row[2] = 'P'

        cursor.updateRow(row)

 

DuncanHornby
MVP Notable Contributor

Here is a superior method that can be done in three tools that will process hundreds of points in a few seconds. I present it as a model so its easier to understand, and you can convert this to python if you so wish.

As a side note reviewing your code thisbuffdist never changes within the loop so your buffer distance is constant for the points, my logic follows this logic.

So here is some sample data, a green sample point and the background raster labelled with its cell values. The circle is showing a radius, in this case 100m to depict the neighbourhood.

DuncanHornby_0-1721320270179.png

 The three step model is this:

DuncanHornby_1-1721320487250.png

The focal statistics tool is set to create a circular neighbourhood and extract the RANGE within that neighbourhood. This range value is passed through to the points and then I simply select all points with a range > 1.

Here is a screenshot showing 3 points selected whilst 1 remains unselected (dark blue) to prove that the logic works.

DuncanHornby_2-1721320825764.png

 

Tags (1)
0 Kudos