The trick here to work with smaller extracts from massive flow direction raster.
The script below does exactly this, growing processing extent from initial buffer (radius) around point equal to (1000*cell size). When no growth in catchment size found it proceeds to next pour point, saving output in wshed_0000.shp, wshed_0001.shp etc in outFolder folder :)
Script looks stupid because I've tried to use multiprocessor and failed. Couldn't force arcpy to recognise availability of spatial analyst extension in multiprocessor pool. This is why add this script to your toolbox with no parameters.
On my rather good machine it took 9 minutes to process 3 points (each took 5 iterations).
I suggest try first with 3 points only and change nPoints to 7000, if you are happy with the performance. Also it is worth including extreme size catchments in this original subset to see if 1000 cells is a good 1st approximation, change it if it result in to many iterations for supposedly smallest catchment.
Good question! Good luck!
# Description:
# muliple watersheds
# ---------------------------------------------------------------------------
# Import arcpy module
import arcpy
from arcpy import env
from arcpy.sa import Watershed
# things to change
pourPoints=r'd:\scratch\pour_points.shp'
fDir=r'd:\scratch\fdir'
outFolder=r'd:\aerials\images'
radius=1000
nPoints=3
nProcessors=4
env.workspace = outFolder
env.pyramid='NONE'
env.rasterStatistics = 'NONE'
fDir=arcpy.Raster(fDir)
env.snapRaster = fDir
cSize=fDir.meanCellHeight
env.cellSize = cSize
ext=arcpy.Describe(fDir).extent
extract,wshed,rdlayer='xtrct','wshed','RL'
def function(inputs):
fid,pnt=inputs
suffix=str(fid).zfill(4)
quer='"FID" = '+str(fid);
thePoint='layer'+suffix
arcpy.MakeFeatureLayer_management(pourPoints,thePoint,quer)
outFile='wshed_'+suffix+'.shp'
i,nTotal=radius,1
while True:
bFirst=cSize*i
arcpy.AddMessage('Trying buffer %i' %bFirst)
buf=pnt.buffer(bFirst)
buf=buf.clip(ext)
anExtent=buf.extent
env.extent=anExtent
envelope='%f %f %f %f' %(anExtent.XMin, anExtent.YMin, anExtent.XMax, anExtent.YMax,)
arcpy.Clip_management(fDir,envelope,extract,buf)
oneGrid=Watershed (extract, thePoint, "FID")
oneGrid.save(wshed)
lmax=arcpy.Raster(wshed)
arcpy.MakeRasterLayer_management(lmax, rdlayer)
tbl=arcpy.da.TableToNumPyArray(rdlayer,("value","count"))
fLine=tbl[0]
newTotal=fLine[1]
if newTotal==nTotal: break
nTotal=newTotal
i=2*i
arcpy.RasterToPolygon_conversion(lmax, outFile, "NO_SIMPLIFY", "Value")
for elm in [extract,wshed]:
arcpy.Delete_management(elm)
arcpy.AddMessage ('Processed %i' %fid)
return outFile
if __name__ == "__main__":
g = arcpy.Geometry()
geometryList=arcpy.CopyFeatures_management(pourPoints,g)
for i in range(0,nPoints,nProcessors):
bList,m = [],0
for j in range(i,min(i+4,nPoints)):
m+=1; bList.append([j,geometryList[j]])
for elm in bList:
out=function(elm)