import random import arcpy arcpy.env.workspace = ???D:\???\database.gdb??? in_points = ???D:\???\???\geodatabase.gdb\Geocoding_Results.shp??? polygon = ???D:\???\geodatabase.gdb\zipcode.shp??? 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: 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)])
Solved! Go to Solution.
if point_in_poly(polygon, p[0][0], p[0][1]):
#------------------------------------------------------------------------------- # 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 #------------------------------------------------------------------------------- def main(): global arcpy, random import arcpy, random 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()
#------------------------------------------------------------------------------- # 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[0] # take first polygon break del row disperse_points(fcPoints,polygon) print "ready..." 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: 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)]) if __name__ == '__main__': main()
polygon = row[0] # take first polygon
Thank you very much! Now the script is running. However all points get unique coordinates outside any of the zip polygons. It looks like this:
These are the overlapping points in the Zip areas:
[ATTACH=CONFIG]29415[/ATTACH]
After running the script I get this:
[ATTACH=CONFIG]29416[/ATTACH]
Both shapefiles have the same coordinate system.
Perhaps my error is here:polygon = row[0] # take first polygon
Should this value be changed? In the ZIP file there are only the Polygons you see in the first picture.
In any case I have to thank you very much.
Best regards
MP
#------------------------------------------------------------------------------- # Name: Disperse2.py # Purpose: Disperse points in multiple polygons # Author: arcpy Team # http://arcpy.wordpress.com/2013/06/07/disperse-overlapping-points/ # Created: 29-11-2013 #------------------------------------------------------------------------------- def main(): global arcpy, random import arcpy, random fcPoints = r"C:\Project\_Forums\Disperse\test.gdb\points_joined" # points after spatial join fcPolygon = r"C:\Project\_Forums\Disperse\test.gdb\Polygons" fldID = 'myID' # polygon ID field in point FC after spatial join arcpy.env.overwriteOutput = True with arcpy.da.SearchCursor(fcPolygon, ("SHAPE@",fldID)) as cursor: for row in cursor: polygon = row[0] myId = row[1] expression = arcpy.AddFieldDelimiters(fcPoints, fldID) + " = {0}".format(myId) disperse_points(fcPoints,polygon,expression) 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, expression): lenx = polygon.extent.width leny = polygon.extent.height with arcpy.da.UpdateCursor(in_points, "SHAPE@XY", where_clause=expression) as points: for p in points: 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)]) if __name__ == '__main__': main()
if point_in_poly(polygon, p[0][0], p[0][1]):
#------------------------------------------------------------------------------- # 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 #------------------------------------------------------------------------------- def main(): global arcpy, random import arcpy, random 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()
Xander:
I am fairly new to python and arcpy.
I was curious how to get your code Disperse3.py into the correct syntax and indentation where it will run correctly.
Thank you.
John Shell
Hi John,
The code would probably be something like this:
#-------------------------------------------------------------------------------
# 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()
Just make sure to input points and polygons featureclasses mentioned on line 13 and 14 to point to the correct locations. Also, it would be better to work on a copy of the original data, since the code will update the point featureclass.