14

What I'm looking to do is put a 100 m buffer on a polygon, but rather than the buffer being at a fixed width "as the crow flies" I want it to follow the slopes of my Lidar DEM.

I have ArcMap (with 3D Analyst). Sadly no Spatial or Network Analyst Extension with ArcMap.

I have kind of been all turned around by the internet looking into Proximity Analysis, Path Distance Analysis, and Anisotropic Cumulative Cost. It looks like I need to somehow make a time-cost grid and find out how long it would take to reach 100 m from the polygon, but that seems rather backward. The vast majority of these tools seem to be made to find the easiest route between two points.

Has anyone done this before?

2
  • 1
    When you say you want to "follow the slopes", do you mean that if a DEM cell is 1m across its slope is flat, you would count that as 1m in your buffer, but if one side is 1m higher than the other, you would count that as 1.41m (the distance along the surface) ?
    – Dan C
    Jun 2, 2017 at 20:05
  • Exactly, in this case we need to show 100 m away from a wetland, and there's a ridge right beside it. I suppose I could use QGIS's Raster Calculator to convert the slope percent to meters based on the cell size of the raster. I wouldn't know how to add those up to 100 m without manually checking each pixel but yeah that's exactly what I'm talking about.
    – R. Laird
    Jun 2, 2017 at 22:12

1 Answer 1

7
+50

Workaround for what you describe in absence of spatial analyst:

arcpy.Buffer_analysis("target","../buffer.shp", "100 Meters")
arcpy.FeatureVerticesToPoints_management("buffer","../points.shp","ALL")
arcpy.AddField_management("points", "PID", "LONG")
arcpy.CalculateField_management("points", "PID", "[FID]")
arcpy.Near_analysis("points", "target","LOCATION")
arcpy.MakeXYEventLayer_management("points","NEAR_X","NEAR_Y","points_Layer")
arcpy.CopyFeatures_management("points_Layer","../from_points.shp")
arcpy.Merge_management("from_points;points","../pairs.shp")
arcpy.PointsToLine_management("pairs","../lines_2D.shp", "PID")
arcpy.InterpolateShape_3d("DEM","lines_2D","../lines_3D.shp")
arcpy.AddField_management("lines_3D", "XY", "TEXT")

Run this on new field (fixed on 05/02/2018):

def getPoint(shp):
 part=shp.getPart(0)
 n=len(part);L=0
 for i in xrange(n):
  p=part.getObject(i)
  x=p.X;y=p.Y;z=p.Z
  if i >0:
    dX=X-x;dY=Y-y;dZ=Z-z;dL=pow((dX*dX+dY*dY+dZ*dZ),0.5);L+=dL
  if L>=100: break
  X,Y,Z=x,y,z 
 xNew=x+dX/dL*(L-100);yNew=y+dY/dL*(L-100)
 return '%s %s' %(xNew,yNew)
#-----------------
getPoint( !Shape!)

Add X and Y fields to lines_3D and populate them using:

!XY!.split(" ")[0] and !XY!.split(" ")[1]

Make XY layer from above 2 fields, copy it to points feature class and use point to line to create buffer line inside original:

OUTPUT:

enter image description here

Conclusion:

Unless your terrain is extremely steep simple buffer will do the job, unless which looks very likely you are actually talking about flow length. Bad luck, because for that you need hydrological analysis toolbox from spatial analyst

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.