Skip to main content
Added language tag
Source Link
Hornbydd
  • 44.6k
  • 5
  • 42
  • 84
import arcpy
from arcpy import env
env.overwriteOutput = True
singleLine=r"in_memory\line"
singleBuffer=r"in_memory\pgon"
mxd = arcpy.mapping.MapDocument("CURRENT")
lines = arcpy.mapping.ListLayers(mxd,"LINES")[0]
buffers = arcpy.mapping.ListLayers(mxd,"BUFFERS")[0]
curT=arcpy.da.InsertCursor(buffers,"SHAPE@")
with arcpy.da.SearchCursor(lines,["SHAPE@","AREA_M2"]) as cursor:
    for shp,target in cursor:
        part=shp.getPart(0);origList=list(part)
##      get last vertices vector
        p1,p2=origList[-2],origList[-1]
        dX=p2.X-p1.X; dY=p2.Y-p1.Y; d1=pow(dX*dX+dY*dY,0.5)
        dXend=dX/d1;dYend=dY/d1
##      get first vertices vector
        p1,p2=origList[1],origList[0]
        dX=p2.X-p1.X; dY=p2.Y-p1.Y; d2=pow(dX*dX+dY*dY,0.5)
        dXstart=dX/d2;dYstart=dY/d2
##      define bounds
        L=target/shp.length/2
        low=L/2;high=L*2
        while True:
            middle=0.5*(low+high)
##      extend line        
            p1=arcpy.Point(origList[-1].X+middle*dXend,origList[-1].Y+middle*dYend)
            p2=arcpy.Point(origList[0].X+middle*dXstart,origList[0].Y+middle*dYstart)
            extList=[p2]+origList+[p1]
            extLine=arcpy.Polyline(arcpy.Array(extList))
            arcpy.CopyFeatures_management(extLine, singleLine)
##      get buffer ind repeat        
            arcpy.Buffer_analysis(singleLine, singleBuffer, middle,"FULL","FLAT","NONE","","PLANAR")            
            with arcpy.da.SearchCursor(singleBuffer,"SHAPE@") as inMem:
                for r in inMem:
                    pgon=r[0]
#       tolerance                    
            if (high-low)<0.01: break
            curArea=pgon.area
            if curArea<target:low=middle
            else:high=middle
        arcpy.AddMessage("Difference {:8.2f}%".format((curArea-target)/target*100))
        curT.insertRow((pgon,))
arcpy.Delete_management("in_memory")
        
import arcpy
from arcpy import env
env.overwriteOutput = True
singleLine=r"in_memory\line"
singleBuffer=r"in_memory\pgon"
mxd = arcpy.mapping.MapDocument("CURRENT")
lines = arcpy.mapping.ListLayers(mxd,"LINES")[0]
buffers = arcpy.mapping.ListLayers(mxd,"BUFFERS")[0]
curT=arcpy.da.InsertCursor(buffers,"SHAPE@")
with arcpy.da.SearchCursor(lines,["SHAPE@","AREA_M2"]) as cursor:
    for shp,target in cursor:
        part=shp.getPart(0);origList=list(part)
        ##  get last vertices vector
        p1,p2=origList[-2],origList[-1]
        dX=p2.X-p1.X; dY=p2.Y-p1.Y; d1=pow(dX*dX+dY*dY,0.5)
        dXend=dX/d1;dYend=dY/d1
        ##  get first vertices vector
        p1,p2=origList[1],origList[0]
        dX=p2.X-p1.X; dY=p2.Y-p1.Y; d2=pow(dX*dX+dY*dY,0.5)
        dXstart=dX/d2;dYstart=dY/d2
        ##  define bounds
        L=target/shp.length/2
        low=L/2;high=L*2
        while True:
            middle=0.5*(low+high)
            ##  extend line        
            p1=arcpy.Point(origList[-1].X+middle*dXend,origList[-1].Y+middle*dYend)
            p2=arcpy.Point(origList[0].X+middle*dXstart,origList[0].Y+middle*dYstart)
            extList=[p2]+origList+[p1]
            extLine=arcpy.Polyline(arcpy.Array(extList))
            arcpy.CopyFeatures_management(extLine, singleLine)
            ##  get buffer and repeat        
            arcpy.Buffer_analysis(singleLine, singleBuffer, middle,"FULL","FLAT","NONE","","PLANAR")            
            with arcpy.da.SearchCursor(singleBuffer,"SHAPE@") as inMem:
                for r in inMem:
                    pgon=r[0]
            #  tolerance                    
            if (high-low)<0.01: break
            curArea=pgon.area
            if curArea<target:low=middle
            else:high=middle
        arcpy.AddMessage("Difference {:8.2f}%".format((curArea-target)/target*100))
        curT.insertRow((pgon,))
arcpy.Delete_management("in_memory")
        
import arcpy
from arcpy import env
env.overwriteOutput = True
singleLine=r"in_memory\line"
singleBuffer=r"in_memory\pgon"
mxd = arcpy.mapping.MapDocument("CURRENT")
lines = arcpy.mapping.ListLayers(mxd,"LINES")[0]
buffers = arcpy.mapping.ListLayers(mxd,"BUFFERS")[0]
curT=arcpy.da.InsertCursor(buffers,"SHAPE@")
with arcpy.da.SearchCursor(lines,["SHAPE@","AREA_M2"]) as cursor:
    for shp,target in cursor:
        part=shp.getPart(0);origList=list(part)
##      get last vertices vector
        p1,p2=origList[-2],origList[-1]
        dX=p2.X-p1.X; dY=p2.Y-p1.Y; d1=pow(dX*dX+dY*dY,0.5)
        dXend=dX/d1;dYend=dY/d1
##      get first vertices vector
        p1,p2=origList[1],origList[0]
        dX=p2.X-p1.X; dY=p2.Y-p1.Y; d2=pow(dX*dX+dY*dY,0.5)
        dXstart=dX/d2;dYstart=dY/d2
##      define bounds
        L=target/shp.length/2
        low=L/2;high=L*2
        while True:
            middle=0.5*(low+high)
##      extend line        
            p1=arcpy.Point(origList[-1].X+middle*dXend,origList[-1].Y+middle*dYend)
            p2=arcpy.Point(origList[0].X+middle*dXstart,origList[0].Y+middle*dYstart)
            extList=[p2]+origList+[p1]
            extLine=arcpy.Polyline(arcpy.Array(extList))
            arcpy.CopyFeatures_management(extLine, singleLine)
##      get buffer ind repeat        
            arcpy.Buffer_analysis(singleLine, singleBuffer, middle,"FULL","FLAT","NONE","","PLANAR")            
            with arcpy.da.SearchCursor(singleBuffer,"SHAPE@") as inMem:
                for r in inMem:
                    pgon=r[0]
#       tolerance                    
            if (high-low)<0.01: break
            curArea=pgon.area
            if curArea<target:low=middle
            else:high=middle
        arcpy.AddMessage("Difference {:8.2f}%".format((curArea-target)/target*100))
        curT.insertRow((pgon,))
arcpy.Delete_management("in_memory")
        
import arcpy
from arcpy import env
env.overwriteOutput = True
singleLine=r"in_memory\line"
singleBuffer=r"in_memory\pgon"
mxd = arcpy.mapping.MapDocument("CURRENT")
lines = arcpy.mapping.ListLayers(mxd,"LINES")[0]
buffers = arcpy.mapping.ListLayers(mxd,"BUFFERS")[0]
curT=arcpy.da.InsertCursor(buffers,"SHAPE@")
with arcpy.da.SearchCursor(lines,["SHAPE@","AREA_M2"]) as cursor:
    for shp,target in cursor:
        part=shp.getPart(0);origList=list(part)
        ##  get last vertices vector
        p1,p2=origList[-2],origList[-1]
        dX=p2.X-p1.X; dY=p2.Y-p1.Y; d1=pow(dX*dX+dY*dY,0.5)
        dXend=dX/d1;dYend=dY/d1
        ##  get first vertices vector
        p1,p2=origList[1],origList[0]
        dX=p2.X-p1.X; dY=p2.Y-p1.Y; d2=pow(dX*dX+dY*dY,0.5)
        dXstart=dX/d2;dYstart=dY/d2
        ##  define bounds
        L=target/shp.length/2
        low=L/2;high=L*2
        while True:
            middle=0.5*(low+high)
            ##  extend line        
            p1=arcpy.Point(origList[-1].X+middle*dXend,origList[-1].Y+middle*dYend)
            p2=arcpy.Point(origList[0].X+middle*dXstart,origList[0].Y+middle*dYstart)
            extList=[p2]+origList+[p1]
            extLine=arcpy.Polyline(arcpy.Array(extList))
            arcpy.CopyFeatures_management(extLine, singleLine)
            ##  get buffer and repeat        
            arcpy.Buffer_analysis(singleLine, singleBuffer, middle,"FULL","FLAT","NONE","","PLANAR")            
            with arcpy.da.SearchCursor(singleBuffer,"SHAPE@") as inMem:
                for r in inMem:
                    pgon=r[0]
            #  tolerance                    
            if (high-low)<0.01: break
            curArea=pgon.area
            if curArea<target:low=middle
            else:high=middle
        arcpy.AddMessage("Difference {:8.2f}%".format((curArea-target)/target*100))
        curT.insertRow((pgon,))
arcpy.Delete_management("in_memory")
        
added 11 characters in body
Source Link
FelixIP
  • 23.3k
  • 3
  • 31
  • 62

The class of problems you are dealing with has no analytical solution. However an accurate estimate can be found numerically through iterations, tries and errors but much quicker by using one of well known root-finding techniques. I used the method of bisection that is not very efficient. The golden section or others might converge faster. Nevertheless in takestook only 18 iterations to find buffer distance, accurate to 0.01 m for 12 km long shape with 1000 vertices shown above. As for it’s accuracy, gauge by yourself, I am struggling to express it using percents.

The class of problems you are dealing with has no analytical solution. However an accurate estimate can be found numerically through iterations, tries and errors but much quicker by using one of well known root-finding techniques. I used the method of bisection that is not very efficient. The golden section or others might converge faster. Nevertheless in takes only 18 iterations to find buffer distance, accurate to 0.01 m for 12 km long shape with 1000 vertices. As for it’s accuracy, gauge by yourself, I am struggling to express it using percents.

The class of problems you are dealing with has no analytical solution. However an accurate estimate can be found numerically through iterations, tries and errors but much quicker by using one of well known root-finding techniques. I used the method of bisection that is not very efficient. The golden section or others might converge faster. Nevertheless in took only 18 iterations to find buffer distance, accurate to 0.01 m for 12 km long shape with 1000 vertices shown above. As for it’s accuracy, gauge by yourself, I am struggling to express it using percents.

deleted 30 characters in body
Source Link
FelixIP
  • 23.3k
  • 3
  • 31
  • 62
import arcpy
from arcpy import env
env.overwriteOutput = True
singleLine=r"in_memory\line"
singleBuffer=r"in_memory\pgon"
 
mxd = arcpy.mapping.MapDocument("CURRENT")
lines = arcpy.mapping.ListLayers(mxd,"LINES")[0]
buffers = arcpy.mapping.ListLayers(mxd,"BUFFERS")[0]
curT=arcpy.da.InsertCursor(buffers,"SHAPE@")
 
with arcpy.da.SearchCursor(lines,["SHAPE@","AREA_M2"]) as cursor:
    for shp,target in cursor:
        part=shp.getPart(0);origList=list(part)
##      get last vertices vector
        p1,p2=origList[-2],origList[-1]
        dX=p2.X-p1.X; dY=p2.Y-p1.Y; d1=pow(dX*dX+dY*dY,0.5)
        dXend=dX/d1;dYend=dY/d1
##      get first vertices vector
        p1,p2=origList[1],origList[0]
        dX=p2.X-p1.X; dY=p2.Y-p1.Y; d2=pow(dX*dX+dY*dY,0.5)
        dXstart=dX/d2;dYstart=dY/d2
##      define bounds
        L=target/shp.length/2
        low=L/2;high=L*2
            
        while True:
            middle=0.5*(low+high)
##      extend line        
            p1=arcpy.Point(origList[-1].X+middle*dXend,origList[-1].Y+middle*dYend)
            p2=arcpy.Point(origList[0].X+middle*dXstart,origList[0].Y+middle*dYstart)
            extList=[p2]+origList+[p1]
            extLine=arcpy.Polyline(arcpy.Array(extList))
            arcpy.CopyFeatures_management(extLine, singleLine)
##      get buffer ind repeat        
            arcpy.Buffer_analysis(singleLine, singleBuffer, middle,"FULL","FLAT","NONE","","PLANAR")            
            with arcpy.da.SearchCursor(singleBuffer,"SHAPE@") as inMem:
                for r in inMem:
                    pgon=r[0]
#       tolerance                    
            if (high-low)<0.01: break
            curArea=pgon.area
            if curArea<target:low=middle
            else:high=middle
        arcpy.AddMessage("Difference {:8.2f}%".format((curArea-target)/target*100))
        curT.insertRow((pgon,))
arcpy.Delete_management("in_memory")
        
import arcpy
from arcpy import env
env.overwriteOutput = True
singleLine=r"in_memory\line"
singleBuffer=r"in_memory\pgon"
 
mxd = arcpy.mapping.MapDocument("CURRENT")
lines = arcpy.mapping.ListLayers(mxd,"LINES")[0]
buffers = arcpy.mapping.ListLayers(mxd,"BUFFERS")[0]
curT=arcpy.da.InsertCursor(buffers,"SHAPE@")
 
with arcpy.da.SearchCursor(lines,["SHAPE@","AREA_M2"]) as cursor:
    for shp,target in cursor:
        part=shp.getPart(0);origList=list(part)
##      get last vertices vector
        p1,p2=origList[-2],origList[-1]
        dX=p2.X-p1.X; dY=p2.Y-p1.Y; d1=pow(dX*dX+dY*dY,0.5)
        dXend=dX/d1;dYend=dY/d1
##      get first vertices vector
        p1,p2=origList[1],origList[0]
        dX=p2.X-p1.X; dY=p2.Y-p1.Y; d2=pow(dX*dX+dY*dY,0.5)
        dXstart=dX/d2;dYstart=dY/d2
##      define bounds
        L=target/shp.length/2
        low=L/2;high=L*2
            
        while True:
            middle=0.5*(low+high)
##      extend line        
            p1=arcpy.Point(origList[-1].X+middle*dXend,origList[-1].Y+middle*dYend)
            p2=arcpy.Point(origList[0].X+middle*dXstart,origList[0].Y+middle*dYstart)
            extList=[p2]+origList+[p1]
            extLine=arcpy.Polyline(arcpy.Array(extList))
            arcpy.CopyFeatures_management(extLine, singleLine)
##      get buffer ind repeat        
            arcpy.Buffer_analysis(singleLine, singleBuffer, middle,"FULL","FLAT","NONE","","PLANAR")            
            with arcpy.da.SearchCursor(singleBuffer,"SHAPE@") as inMem:
                for r in inMem:
                    pgon=r[0]
#       tolerance                    
            if (high-low)<0.01: break
            curArea=pgon.area
            if curArea<target:low=middle
            else:high=middle
        arcpy.AddMessage("Difference {:8.2f}%".format((curArea-target)/target*100))
        curT.insertRow((pgon,))
arcpy.Delete_management("in_memory")
        
import arcpy
from arcpy import env
env.overwriteOutput = True
singleLine=r"in_memory\line"
singleBuffer=r"in_memory\pgon"
mxd = arcpy.mapping.MapDocument("CURRENT")
lines = arcpy.mapping.ListLayers(mxd,"LINES")[0]
buffers = arcpy.mapping.ListLayers(mxd,"BUFFERS")[0]
curT=arcpy.da.InsertCursor(buffers,"SHAPE@")
with arcpy.da.SearchCursor(lines,["SHAPE@","AREA_M2"]) as cursor:
    for shp,target in cursor:
        part=shp.getPart(0);origList=list(part)
##      get last vertices vector
        p1,p2=origList[-2],origList[-1]
        dX=p2.X-p1.X; dY=p2.Y-p1.Y; d1=pow(dX*dX+dY*dY,0.5)
        dXend=dX/d1;dYend=dY/d1
##      get first vertices vector
        p1,p2=origList[1],origList[0]
        dX=p2.X-p1.X; dY=p2.Y-p1.Y; d2=pow(dX*dX+dY*dY,0.5)
        dXstart=dX/d2;dYstart=dY/d2
##      define bounds
        L=target/shp.length/2
        low=L/2;high=L*2
        while True:
            middle=0.5*(low+high)
##      extend line        
            p1=arcpy.Point(origList[-1].X+middle*dXend,origList[-1].Y+middle*dYend)
            p2=arcpy.Point(origList[0].X+middle*dXstart,origList[0].Y+middle*dYstart)
            extList=[p2]+origList+[p1]
            extLine=arcpy.Polyline(arcpy.Array(extList))
            arcpy.CopyFeatures_management(extLine, singleLine)
##      get buffer ind repeat        
            arcpy.Buffer_analysis(singleLine, singleBuffer, middle,"FULL","FLAT","NONE","","PLANAR")            
            with arcpy.da.SearchCursor(singleBuffer,"SHAPE@") as inMem:
                for r in inMem:
                    pgon=r[0]
#       tolerance                    
            if (high-low)<0.01: break
            curArea=pgon.area
            if curArea<target:low=middle
            else:high=middle
        arcpy.AddMessage("Difference {:8.2f}%".format((curArea-target)/target*100))
        curT.insertRow((pgon,))
arcpy.Delete_management("in_memory")
        
added 1219 characters in body
Source Link
FelixIP
  • 23.3k
  • 3
  • 31
  • 62
Loading
Source Link
FelixIP
  • 23.3k
  • 3
  • 31
  • 62
Loading