If these points are randomly generated (e.g. for sampling and/or QA purposes) you could try running the Create Random Points tool twice, once for the "A" and once for the "B" sites, add a field and calculate to "A" / "B", then Merge the results into a single feature class. I tested this approach, generating a total of 1000 points and the results are okay but there are still isolated clusters of points with the same value.
A second approach requires scripting in Python. Essentially the logic is
- Choose the first feature (ObjectID = 1) in an existing feature class and set its attribute to "A"
- Find the closest feature to ObjectID 1 and set its attribute to "B"
- Move to that feature and find the next closest feature that hasn't
been attributed and set its attribute to "A"
- Rinse and repeat until all features have been attributed.
This method produces a better distribution of "A"s and "B"s.
Here is the code that was used for the second method. It produces a CSV file that is used to join to the input feature class (using ObjectID as the link field).
print "Importing modules"
import sys
import arcpy
import math
#------------------------------------------------------------------------------------------
def CalcDist(fromPnt, toPnt):
dx = toPnt[1] - fromPnt[1]
dy = toPnt[2] - fromPnt[2]
aDist = math.sqrt(dx ** 2 + dy ** 2)
return aDist
#------------------------------------------------------------------------------------------
arcpy.env.overwriteOutput = True
aFC = r"C:\temp\scratch.gdb\_aaa"
startOID = 1
aSR = arcpy.Describe(aFC).spatialReference
print "Creating list of coords"
# Create a list of the Object IDs and coords
aCoords = []
aRows = arcpy.da.SearchCursor(aFC, ["OID@", "SHAPE@X", "SHAPE@Y"])
for aRow in aRows:
aCoords.append((aRow[0], aRow[1], aRow[2]))
if aRow[0] == startOID:
popList = (aRow[0], aRow[1], aRow[2])
onPoint = (aRow[0], aRow[1], aRow[2])
del aRow, aRows
# Setup output CSV file
aFile = open(r"c:\temp\AB.csv", "w")
aFile.write("OID,Recode")
print "Finding closest points and assign A and B to alternate records"
aID = "B"
aFile.write("\n" + str(startOID) + ",A")
while len(aCoords) > 1:
aDistance = 9999999
for aPoint in aCoords:
if aPoint[0] <> startOID:
aPD = CalcDist(onPoint, aPoint)
if aPD <= aDistance:
aDistance = aPD
PID = aPoint[0]
toPoint = aPoint
else:
popList = aPoint
# write result to console and output file
print "Closest OID to " + str(startOID) + " is " + str(PID)
aFile.write("\n" + str(toPoint[0]) + "," + aID)
# drop the point from the list and start the show again iterating onto the found point
onPoint = toPoint
startOID = PID
aCoords.remove(popList)
if aID == "A":
aID = "B"
else:
aID = "A"
aFile.close()