Repository for Ideas & Research
Open Source GIS, Hydrologic Modeling, Optimization

How to create features using ArcPy

import numpy as np
import random

def createCircle(x, y, radius):
    pnts = []
    for theta in np.arange(0, 2*math.pi, 0.1):
        xx = x + radius * math.cos(theta)
        yy = y + radius * math.sin(theta)
        pnts.append(arcpy.Point(xx, yy))
    return arcpy.Polygon(arcpy.Array(pnts))

# get basic info
aprx = arcpy.mp.ArcGISProject('CURRENT')
m = aprx.activeMap
mv = m.defaultView
c = mv.camera
extent = c.getExtent()
radius = extent.width / 20.0

################################################################################
# new shapefile with just one circle
x = extent.lowerLeft.X + random.random() * extent.width
y = extent.lowerLeft.Y + random.random() * extent.height
circ = createCircle(x, y, radius)
# circ or [circ]
arcpy.CopyFeatures_management(circ, r'c:\tmp\one_circle.shp')

################################################################################
# new shapefile with multiple circles
x = extent.lowerLeft.X + random.random() * extent.width
y = extent.lowerLeft.Y + random.random() * extent.height
circ2 = createCircle(x, y, radius)
arcpy.CopyFeatures_management([circ, circ2], r'c:\tmp\two_circles.shp')

################################################################################
# new shapefile with 100 random circles
# create a temporary feature class
# not necessary, but to show how to use cursors
fc = arcpy.CreateFeatureclass_management('in_memory', 'tmp', 'POLYGON')[0]
arcpy.AddField_management(fc, 'radius', 'FLOAT')

# create circle features with the fixed radius
with arcpy.da.InsertCursor(fc, ['SHAPE@', 'radius']) as cur:
    for i in range(0, 100):
        x = extent.lowerLeft.X + random.random() * extent.width
        y = extent.lowerLeft.Y + random.random() * extent.height
        circ = createCircle(x, y, radius)
        cur.insertRow([circ, radius])

# update some features' radius
with arcpy.da.UpdateCursor(fc, ['SHAPE@', 'radius']) as cur:
    for row in cur:
        if random.random() < 0.5:
            x = row[0].centroid.X
            y = row[0].centroid.Y
            r = random.random()*2*radius
            circ = createCircle(x, y, r)
            cur.updateRow([circ, r])

# create an empty feature set
fs = arcpy.FeatureSet()
# load the in-memory feature class into the feature set
fs.load(fc)
# write out the loaded features into a shapefile
fc_path = r'c:\tmp\random_circles.shp'
fs.save(fc_path)
m.addDataFromPath(fc_path)
# or to automatically add this feature class to the map
#arcpy.CopyFeatures_management(fs, fc_path)

################################################################################
# search for features whose radius is greater than 0.5*radius
count = 0
search_radius = 0.5*radius
with arcpy.da.SearchCursor(fc_path, ['*'], 'radius > %f' % search_radius) as cur:
    for row in cur:
        count += 1
total_count = len(arcpy.da.FeatureClassToNumPyArray(fs, 'OID@'))
print('{} of {} features have a radius greater than {}'.format(count, total_count, search_radius))