Tôi đã được truyền cảm hứng bởi @FelixIP, nhưng tôi muốn viết một giải pháp mà không cần tham gia hoặc tạo các tệp bổ sung, vì mạng của tôi khá lớn với các ống 400K + và các nút 500K +.
Cấu trúc mạng hình học buộc X, Y của các nút và các đầu ống phải trùng nhau. Bạn có thể truy cập các vị trí này với các mã thông báo hình dạng trong các con trỏ hình cung và khớp với chúng. Mã thông báo hình dạng cho các dòng trả về một mảng các đỉnh theo thứ tự mà chúng được vẽ. Trong mạng của tôi, thứ tự vẽ của các đường ống rất nhiều QA'd vì chúng tôi sử dụng điều này để đặt hướng dòng chảy. Vì vậy, đỉnh đầu tiên là điểm bắt đầu của đường ống và đỉnh cuối cùng là điểm cuối của đường ống.
Tham khảo: ASSETID = id của pipe, UNITID = id id ở đầu ống, UNITID2 = id id ở cuối ống.
nodes = "mergeNodes"
pipes = "SEWER_1"
nodeDict = {}
pipeDict = {}
#populate node dictionary with X,Y as the key and node ID as the value
for node in arcpy.da.SearchCursor(nodes, ["UNITID", "SHAPE@XY"]):
nodeDict[(node[1][0], node[1][1])] = node[0]
#populate pipe dictionary with pipe ID as the key and list of X,Y as values
#vertices populated in the order that the line was draw
#so that [0] is the first vertex and [-1] is the final vertex
for pipe in arcpy.da.SearchCursor(pipes, ["ASSETID", "SHAPE@"]):
for arrayOb in pipe[1]:
for point in arrayOb:
if pipe[0] in pipeDict:
pipeDict[pipe[0]].append((point.X, point.Y))
else:
pipeDict[pipe[0]] = [(point.X, point.Y)]
#populate UNITID with the first vertex of the line
#populate UNITID2 with the final vertex of the line
with arcpy.da.UpdateCursor(pipes, ["ASSETID", "UNITID", "UNITID2"]) as cur:
for pipe in cur:
if pipeDict[pipe[0]][0] in nodeDict:
pipe[1] = nodeDict[pipeDict[pipe[0]][0]]
if pipeDict[pipe[0]][-1] in nodeDict:
pipe[2] = nodeDict[pipeDict[pipe[0]][-1]]
cur.updateRow(pipe)