How can I disperse points within polygons using ArcGIS?

I have huge number of points. These points are within polygons. I want to disperse the points in the polygons randomly. I tried to use the disperse point extension in Arcview, but it was not useful for me. Disperse Markers tool in ArcGIS toolbox was also not useful and can’t create permanent disperse points, it just creates a view of point disperse. Are there any tools or scripts to disperse points in polygons? There are two potentially helpful, but old ArcScripts:

Point Randomiser v1.3

• Constrain Shift by Polygon. Use a polygon theme to constrain the random movement of points. This option causes points to be randomly shifted ONLY within the confines of the polygon within which they originally fall. Users can elect to use ALL or SELECTED polygons for restraining.

Point Dispersion Wizard

The Point Dispersion Wizard disperses coincident points radially, linearly, randomly within a specified radius and randomly within a containing polygon. In addition, each dispersion pattern comes with a set of user specified options. Dispersed points can be displayed as graphics in the existing theme, clipped to a new theme, or dispersed in a new theme. It was written for ArcView 3.1 using the Dialog Designer. Be sure to study the included READ_ME.txt file as it explains the usage of the Point Dispersion Wizard, especially as it pertains to the randomly within a containing polygon dispersion pattern which behaves somewhat differently than the other dispersion patterns. The random dispersion pattern options use a prime modulus multiplicative linear congruential generator to generate random variates from the uniform distribution on the interval [0,1] based on Marse and Roberts (1983).

• point dispersion wizard only use for coincident point. – BBG_GIS Apr 6 '13 at 15:31
• @wetland, have you tested Point Randomiser v1.3? I'm suspicious that it may be too out of date. – Aaron Apr 6 '13 at 15:35
• Point Randomiser is very nice Extension . thank you – BBG_GIS Apr 7 '13 at 5:29

A useful question, but given that ArcScripts aren't supported by the more recent versions of Arc below is some code I subsequently found in trying to solve this problem that was written by someone at Arc. It does the same job as the scripts for ArcGIS 10.0 onwards (sources below).

Note that this is currently set up to only run on the first polygon in the feature class, so the break in the first for loop would need to be removed and bring the disperse_points function in to work through an entire dataset.

#-------------------------------------------------------------------------------
# Name:        Disperse.py
# Purpose:     Disperse points in polygon
# Author:      arcpy Team
#              http://arcpy.wordpress.com/2013/06/07/disperse-overlapping-points/
# Created:     27-11-2013
#-------------------------------------------------------------------------------

def main():
global arcpy, random
import arcpy, random
fcPoints = r"C:\Project\_Forums\Disperse\test.gdb\points" # edit this
fcPolygon = r"C:\Project\_Forums\Disperse\test.gdb\polygon" # edit this

with arcpy.da.SearchCursor(fcPolygon, "SHAPE@") as cursor:
for row in cursor:
polygon = row # take first polygon
break
del row

disperse_points(fcPoints,polygon)

def point_in_poly(poly, x, y):
"""Returns if the point is inside the polygon.

Parameters:
poly: arcpy.Polygon() geometry
x:    x coordinate (float)
y:    y coordinate (float)

"""
pg = arcpy.PointGeometry(arcpy.Point(x, y), poly.spatialReference)
return poly.contains(pg)

def disperse_points(in_points, polygon):
"""Randomly disperse points inside a polygon.

Parameters:
in_points:  Point feature class/layer (with or without selection)
polygon:    arcpy.Polygon() geometry

"""

lenx = polygon.extent.width
leny = polygon.extent.height

with arcpy.da.UpdateCursor(in_points, "SHAPE@XY") as points:
for p in points:
if point_in_poly(polygon, p, p):
x = (random.random() * lenx) + polygon.extent.XMin
y = (random.random() * leny) + polygon.extent.YMin
inside = point_in_poly(polygon, x, y)
while not inside:
x = (random.random() * lenx) + polygon.extent.XMin
y = (random.random() * leny) + polygon.extent.YMin
inside = point_in_poly(polygon, x, y)
points.updateRow([(x, y)])
else:pass

if __name__ == '__main__':
main()

https://geonet.esri.com/thread/84797#356094 - Includes an edit to identify if the point is in the current polygon.

https://arcpy.wordpress.com/2013/06/07/disperse-overlapping-points/ - Original post of the code.

Another option would be to use Quantum GIS. There is a tool called 'Random points' (located on the toolbar under Vector > Research Tools > Random points) that will create X number of points inside a polygon. You could create the same number points as your original dataset then take that shapefile back to ArcGIS and do a join that way the random points would now have the attribute data.

If you need an even distribution of the points then use the 'Regular points' tool. Thats located just below the 'Random points' tool in the Vector > Research Tools toolbar.

• That may work for a single polygon, but how would you assign the correct attributes for points contained within multiple polygons. In other words, how would you ensure that point attribute x is associated with random points in polygon x, rather than random points in polygon y? – Aaron Apr 6 '13 at 15:05
• I don't know the answer to that. I just wanted to let you know that I read your comment. – Taylor H. Apr 6 '13 at 15:09
• @Taylor H there are many many polygons and many many points. – BBG_GIS Apr 6 '13 at 17:30