I have a shapefile layer with polygons for the 50 U.S. states ("States"). I also have a point featureclass with potentially many overlapping points at the centroid of each state polygon ("Dots").
I want to use the CreateRandomPoints_management() function to find new placements for all the points in each state, essentially creating a 1:1 dot density map with clickable point features.
Here's the workflow I have envisioned:
I've tried several times to write this code, but my arcpy chops aren't that great yet. Any ideas or examples would be greatly appreciated!
Solved! Go to Solution.
Solved: Re: Dispersing geocoded points within a Polygon - Esri Community
Hope the following script works for you (Courtesy @XanderBakker and ArcPy Team)
#-------------------------------------------------------------------------------
# Name: Disperse3.py
# Purpose: Disperse points in multiple polygons
# Author: arcpy Team
# http://arcpy.wordpress.com/2013/06/07/disperse-overlapping-points/
# Created: 02-dec-2013
#-------------------------------------------------------------------------------
import arcpy
import random
def main():
fcPoints = r"C:\Project\_Forums\Disperse\test.gdb\points3"
fcPolygon = r"C:\Project\_Forums\Disperse\test.gdb\Polygons"
arcpy.env.overwriteOutput = True
with arcpy.da.SearchCursor(fcPolygon, ("SHAPE@")) as cursor:
for row in cursor:
polygon = row[0]
disperse_points(fcPoints, polygon)
del row
print "ready..."
def point_in_poly(poly, x, y):
pg = arcpy.PointGeometry(arcpy.Point(x, y), poly.spatialReference)
return poly.contains(pg)
def disperse_points(in_points, polygon):
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[0][0], p[0][1]):
# I changed code here!
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 # don't update location if point doesn't originally falls inside current polygon
if __name__ == '__main__':
main()
*Change the path of the point and polygon feature classes in Line No. 13/14.
Solved: Re: Dispersing geocoded points within a Polygon - Esri Community
Hope the following script works for you (Courtesy @XanderBakker and ArcPy Team)
#-------------------------------------------------------------------------------
# Name: Disperse3.py
# Purpose: Disperse points in multiple polygons
# Author: arcpy Team
# http://arcpy.wordpress.com/2013/06/07/disperse-overlapping-points/
# Created: 02-dec-2013
#-------------------------------------------------------------------------------
import arcpy
import random
def main():
fcPoints = r"C:\Project\_Forums\Disperse\test.gdb\points3"
fcPolygon = r"C:\Project\_Forums\Disperse\test.gdb\Polygons"
arcpy.env.overwriteOutput = True
with arcpy.da.SearchCursor(fcPolygon, ("SHAPE@")) as cursor:
for row in cursor:
polygon = row[0]
disperse_points(fcPoints, polygon)
del row
print "ready..."
def point_in_poly(poly, x, y):
pg = arcpy.PointGeometry(arcpy.Point(x, y), poly.spatialReference)
return poly.contains(pg)
def disperse_points(in_points, polygon):
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[0][0], p[0][1]):
# I changed code here!
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 # don't update location if point doesn't originally falls inside current polygon
if __name__ == '__main__':
main()
*Change the path of the point and polygon feature classes in Line No. 13/14.
Thanks, Jayanta! That function does look like it might do what I need.