Chỉ là một bản cập nhật. Sau khi làm theo lời khuyên của Whuber, tôi thấy rằng Ma trận trọng lượng không gian đơn giản chỉ sử dụng các vòng lặp và từ điển Python để xác định hàng xóm. Tôi đã sao chép quá trình dưới đây.
Phần đầu tiên lặp qua mọi đỉnh của mọi nhóm khối. Nó tạo ra một từ điển với tọa độ đỉnh là các khóa và danh sách ID nhóm khối có đỉnh ở tọa độ đó làm giá trị. Lưu ý rằng điều này đòi hỏi một bộ dữ liệu gọn gàng về mặt tôpô, vì chỉ có chồng chéo đỉnh / đỉnh hoàn hảo mới đăng ký như một mối quan hệ láng giềng. May mắn thay, các shapefile nhóm khối điều tra của Cục điều tra dân số là ổn về vấn đề này.
Phần thứ hai lặp lại qua mọi đỉnh của mỗi nhóm khối một lần nữa. Nó tạo ra một từ điển với ID nhóm khối làm khóa và ID của hàng xóm của nhóm đó làm giá trị.
# 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
Nhìn lại, tôi nhận ra rằng tôi có thể đã sử dụng một phương pháp khác cho phần thứ hai mà không yêu cầu lặp lại thông qua shapefile một lần nữa. Nhưng đây là những gì tôi đã sử dụng và nó hoạt động khá tốt ngay cả với 1000 nhóm khối cùng một lúc. Tôi đã không thử làm điều đó với toàn bộ Hoa Kỳ, nhưng nó có thể thực thi cho toàn bộ tiểu bang.