Disperse overlapping points

A user recently asked if a geoprocessing tool existed to randomly disperse overlapping points inside an area or polygon. There is no specific tool, however, with a little Python code and the use of a geometry operator, this can be accomplished very quickly.

Here’s an illustration and the code recipe.

dispersepoints

import random
import arcpy

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)])
Advertisements