Loop through features and create euclidean distance raster per feature

4938
22
Jump to solution
08-07-2013 08:27 AM
KarenHornigold
New Contributor
Hi,

I am completely new to Python, but need to turn to it due to the nature of my research.

I have a point shapefile with 45,000 points ('visits') spread across the UK and I want to obtain a euclidean distance raster (with a cut off of say 100km).

I know the tool I need to use to create the distance raster is Euclidean Distance, but I need to iteratively select each point (by 'visitID') from the shapefile and create a distance raster for each one in turn.

Can anyone direct me to useful resources or share their scripting wisdom?

Thank you in advance!
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
by Anonymous User
Not applicable
I actually only need the ascii file as I can read this into R where I am doing my analysis.


WOW! That is good news...Well you can eliminate the last part then!  The way I wrote that is to have it delete the ascii files after the conversion...I have eliminated the convert ascii to raster so you will just have ascii files.  This will probably do all 45k points in a few short hours.

I have just attached a new toolbox, this one has 2 tools...The first one is the tool that converts each ascii to raster...You do not want to use this one. Use the (ascii) one. This will just write out ascii files and not convert to raster...These ascii files can still be used in ArcMap...If you pull them in they will be projected properly.

So if you use the (ascii) tool, it will hopefully be done before you leave the office today on all 45K points!  I usually do not spend this much time working on a problem I find on the forums, but this one really interested me.  I think this tool is useful.  Let me know how it works for you!

One more note....Be sure to pull a few of the ascii rasters into ArcMap overlaid with your points to make sure they are centered...You also may want to use 110 meters for the distance parameter to be safe.  Enjoy!

View solution in original post

0 Kudos
22 Replies
by Anonymous User
Not applicable
Something like this would work, but it would be painfully slow to make a separate distance raster for all 45k points. This selects each point one at a time by its 'visitID' and from the selection runs a Euclidean Distance with max dist set for 100. I used a cell size of 10. Each raster is named "dist_" + the visitID of the point.

import arcpy
arcpy.CheckOutExtension('Spatial')
from arcpy.sa import *

# set output workspace
arcpy.env.workspace = r'C:\TEMP\Output_Rasters'
arcpy.env.overwriteOutput = True

# your points
points = r'C:\TEMP\Stream_points.shp'

# oid field and list of id's 
ids = list(r.visitID for r in arcpy.SearchCursor(points))

# loop through table to make a distance raster for each point
# EucDIstance(points, max_distance, cell_size)  <-- parameters
lyr = arcpy.MakeFeatureLayer_management(points, 'points_lyr')
for i in ids:
    query = '{0} = {1}'.format(arcpy.AddFieldDelimiters(points,'visitID'),i)
    arcpy.SelectLayerByAttribute_management(lyr, 'NEW_SELECTION', query)
    eucDist = EucDistance(lyr, 100, 10)
    eucDist.save('dist_%s' %i)
    print 'Created Euclidean Distance raster for point ID: %s' %i
print 'Done'


Make sure the 'visitID's highlighted in red are the correct field name and matching case.
0 Kudos
KarenHornigold
New Contributor
Thank you for your quick reply and for providing code! I shall try it out and let you know.

With gratitude
0 Kudos
KarenHornigold
New Contributor
So I just ran the script on a sample of 10 points and it works perfectly.

However, it took 10 minutes for 10 points, so a quick scaling up led to an estimate of one month to run on 45,000 points!

Is there any alternative, more efficient way?

Thanks again.
0 Kudos
by Anonymous User
Not applicable
Is there any alternative, more efficient way?


Sure, running Euclidean Distance on the whole shapefile at once!  Of course, you do not always have this luxury.  Is it absolutely necessary to have an individual raster for each point?  As long as your points aren't within 100 m of each other, there should not be any overlap. 

If you don't care so much about having ugly rasters you could use a cell size of 20.  That could speed it up a little bit, but it will still take forever with 45k points.
0 Kudos
KarenHornigold
New Contributor
Is it absolutely necessary to have an individual raster for each point?


Yes, I need one raster per point as I want to find out distance weighted population surrounding each point. Also my points are very dense in some places with only a few meters between, so there would be an overlap whatever distance cut off I decide to use.
0 Kudos
KarenHornigold
New Contributor
I attempted to turn the script into a custom tool, but can't get it working. The problem seems to be with how to replace 'VISITID' as a specified field, to use instead the field that is selected in the dialogue box. Can you take a look at my script to see what I'm doing wrong?

import arcpy
from arcpy import env
arcpy.CheckOutExtension('Spatial')
from arcpy.sa import *

# set parameters (needed for dialgue box)
points = arcpy.GetParameterAsText(0)
field = arcpy.GetParameterAsText(1)

# set output workspace
outWorkspace = arcpy.GetParameterAsText(2)
arcpy.env.overwriteOutput = True

# oid field and list of id's
ids = list(r.field for r in arcpy.SearchCursor(points))

# loop through table to make a distance raster for each point
# EucDIstance(points, max_distance, cell_size)  <-- parameters
lyr = arcpy.MakeFeatureLayer_management(points, 'points_lyr')
for i in ids:
    query = '{0} = {1}'.format(arcpy.AddFieldDelimiters(points, field),i)
    arcpy.SelectLayerByAttribute_management(lyr, 'NEW_SELECTION', query)
    eucDist = EucDistance(lyr, 10000, 1000)
    eucDist.save('dist_%s' %i)
    print 'Created Euclidean Distance raster for point ID: %s' %i
print 'Done'

Thanks
0 Kudos
by Anonymous User
Not applicable
Since you are wanting to supply the field name as a variable, try changing this line:

# oid field and list of id's 
ids = list(r.getValue(field) for r in arcpy.SearchCursor(points))


Note that the above is the 10.0 cursor. I was not sure if you have 10.1 or 10.2 yet, but if you do, you can use a da" rel="nofollow" target="_blank">http://resources.arcgis.com/en/help/main/10.1/index.html#//018w00... cursor (data access) like this:

# oid field and list of id's 
ids = list(r[0] for r in arcpy.da.SearchCursor(points, [field]))


So if you have 10.0 use the first option, or if you have 10.1 or above use the second. Also, for future reference, try posting your code using the code tags by using the # button or you can manually type it like this:

[noparse]
if condition:
     # do stuff
# more code

[/noparse]

By using the code tags, it will make the code look like this:

if condition:
     # do stuff
# more code


Indentation is very important in python so it makes it easier to spot errors when you use the code tags. You can see the full BB Code List [url=http://forums.arcgis.com/misc.php?do=bbcode]here[/url] Good luck!
0 Kudos
KarenHornigold
New Contributor
Thanks for your reply!

I got the following error message:

Messages
Executing: IterativeEuclideanDistance C:\Docs\ArcGIS\Dorset_sample.shp VISITID C:\Docs\ArcGIS\DORSET
Start Time: Thu Aug 08 14:25:23 2013
Running script IterativeEuclideanDistance...

Traceback (most recent call last):
  File "C:\Docs\ArcGIS\Scripts\IterativeEucDist.py", line 15, in <module>
    ids = list(r[0] for r in arcpy.SearchCursor(points,[field]))
  File "C:\Docs\ArcGIS\Scripts\IterativeEucDist.py", line 15, in <genexpr>
    ids = list(r[0] for r in arcpy.SearchCursor(points,[field]))
TypeError: 'Row' object does not support indexing

Failed to execute (IterativeEuclideanDistance).
Failed at Thu Aug 08 14:25:23 2013 (Elapsed Time: 0.00 seconds)
0 Kudos
KarenHornigold
New Contributor
Sorry I noticed I missed the 'da' in searchcursor. So I ran it again with this corrected and got the following error:

Messages
Executing: IterativeEuclideanDistance C:\Docs\ArcGIS\Dorset_sample.shp VISITID C:\Docs\ArcGIS\DORSET
Start Time: Thu Aug 08 14:32:28 2013
Running script IterativeEuclideanDistance...

Traceback (most recent call last):
  File "C:\Docs\ArcGIS\Scripts\IterativeEucDist.py", line 24, in <module>
    eucDist.save('dist_%s' %i)
RuntimeError: ERROR 010093: Output raster format UNKNOWN is unsupported.

Failed to execute (IterativeEuclideanDistance).
Failed at Thu Aug 08 14:33:10 2013 (Elapsed Time: 42.00 seconds)
0 Kudos