Solo una actualización. Después de seguir los consejos de Whuber, descubrí que la Matriz Generar Pesos Espaciales simplemente usa bucles y diccionarios de Python para determinar vecinos. Reproduje el proceso a continuación.
La primera parte recorre cada vértice de cada grupo de bloques. Crea un diccionario con coordenadas de vértice como las claves y una lista de ID de grupos de bloques que tienen un vértice en esa coordenada como valor. Tenga en cuenta que esto requiere un conjunto de datos topológicamente limpio, ya que solo la superposición perfecta de vértices / vértices se registrará como una relación vecina. Afortunadamente, los archivos de forma de grupo de bloques TIGER de la Oficina del Censo están bien en este sentido.
La segunda parte recorre cada vértice de cada grupo de bloques nuevamente. Crea un diccionario con ID de grupo de bloque como claves y las ID de vecino de ese grupo de bloque como valores.
# Create dictionary of vertex coordinate : [...,IDs,...]
BlockGroupVertexDictionary = {}
BlockGroupCursor = arcpy.SearchCursor(BlockGroups.shp)
BlockGroupDescription = arcpy.Describe(BlockGroups.shp)
BlockGroupShapeFieldName = BlockGroupsDescription.ShapeFieldName
#For every block group...
for BlockGroupItem in BlockGroupCursor :
BlockGroupID = BlockGroupItem.getValue("BKGPIDFP00")
BlockGroupFeature = BlockGroupItem.getValue(BlockGroupShapeFieldName)
for BlockGroupPart in BlockGroupFeature:
#For every vertex...
for BlockGroupPoint in BlockGroupPart:
#If it exists (and isnt empty interior hole signifier)...
if BlockGroupPoint:
#Create string version of coordinate
PointText = str(BlockGroupPoint.X)+str(BlockGroupPoint.Y)
#If coordinate is already in dictionary, append this BG's ID
if PointText in BlockGroupVertexDictionary:
BlockGroupVertexDictionary[PointText].append(BlockGroupID)
#If coordinate is not already in dictionary, create new list with this BG's ID
else:
BlockGroupVertexDictionary[PointText] = [BlockGroupID]
del BlockGroupItem
del BlockGroupCursor
#Create dictionary of ID : [...,neighbors,...]
BlockGroupNeighborDictionary = {}
BlockGroupCursor = arcpy.SearchCursor(BlockGroups.shp)
BlockGroupDescription = arcpy.Describe(BlockGroups.shp)
BlockGroupShapeFieldName = BlockGroupDescription.ShapeFieldName
#For every block group
for BlockGroupItem in BlockGroupCursor:
ListOfBlockGroupNeighbors = []
BlockGroupID = BlockGroupItem.getValue("BKGPIDFP00")
BlockGroupFeature = BlockGroupItem.getValue(BlockGroupShapeFieldName)
for BlockGroupPart in BlockGroupFeature:
#For every vertex
for BlockGroupPoint in BlockGroupPart:
#If it exists (and isnt interior hole signifier)...
if BlockGroupPoint:
#Create string version of coordinate
PointText = str(BlockGroupPoint.X)+str(BlockGroupPoint.Y)
if PointText in BlockGroupVertexDictionary:
#Get list of block groups that have this point as a vertex
NeighborIDList = BlockGroupVertexDictionary[PointText]
for NeighborID in NeighborIDList:
#Don't add if this BG already in list of neighbors
if NeighborID in ListOfBGNeighbors:
pass
#Add to list of neighbors (as long as its not itself)
elif NeighborID != BlockGroupID:
ListOfBGNeighbors.append(NeighborID)
#Store list of neighbors in blockgroup object in dictionary
BlockGroupNeighborDictionary[BlockGroupID] = ListOfBGNeighbors
del BlockGroupItem
del BlockGroupCursor
del BlockGroupVertexDictionary
En retrospectiva, me doy cuenta de que podría haber usado un método diferente para la segunda parte que no requirió recorrer el archivo de forma nuevamente. Pero esto es lo que usé, y funciona bastante bien incluso para miles de grupos de bloques a la vez. No he intentado hacerlo con todo Estados Unidos, pero puede ejecutarse para todo un estado.