Bộ gốc:
Tạo giả sao chép (kéo CNTRL trong TOC) của nó và làm cho không gian nối từ một đến nhiều với bản sao. Trong trường hợp này tôi đã sử dụng khoảng cách 500m. Bảng đầu ra:
Xóa các bản ghi khỏi bảng này trong đó PAR_ID = PAR_ID_1 - dễ dàng.
Lặp lại qua bảng và xóa các bản ghi trong đó (PAR_ID, PAR_ID_1) = (PAR_ID_1, PAR_ID) của bất kỳ bản ghi nào phía trên nó. Không dễ dàng như vậy, sử dụng acrpy.
Tính toán trọng tâm lưu vực (UniqID = PAR_ID). Chúng là các nút hoặc mạng. Kết nối chúng bằng các đường bằng cách sử dụng bảng nối không gian. Đây là chủ đề riêng biệt chắc chắn được đề cập ở đâu đó trên diễn đàn này.
Kịch bản dưới đây giả định rằng bảng nút trông như thế:
trong đó MUID đến từ bưu kiện, P2013 là lĩnh vực để tóm tắt. Trong trường hợp này = 1 chỉ tính. [rcvnode] - đầu ra tập lệnh để lưu trữ ID nhóm bằng NODEREC của nút đầu tiên trong nhóm / cụm được xác định.
Cấu trúc bảng liên kết với các trường quan trọng được tô sáng
Times lưu trữ trọng lượng liên kết / cạnh, tức là chi phí di chuyển từ nút này sang nút khác. Bằng 1 trong trường hợp này để chi phí đi lại cho tất cả hàng xóm là như nhau. [fi] và [ti] là số nút liên tiếp được kết nối. Để điền vào bảng này, hãy tìm kiếm diễn đàn này về cách gán từ và đến các nút để liên kết.
Script tùy chỉnh cho mxd bàn làm việc của riêng tôi. Phải được sửa đổi, mã hóa cứng với việc đặt tên của các trường và nguồn:
import arcpy, traceback, os, sys,time
import itertools as itt
scriptsPath=os.path.dirname(os.path.realpath(__file__))
os.chdir(scriptsPath)
import COMMON
sys.path.append(r'C:\Users\felix_pertziger\AppData\Roaming\Python\Python27\site-packages')
import networkx as nx
RATIO = int(arcpy.GetParameterAsText(0))
try:
def showPyMessage():
arcpy.AddMessage(str(time.ctime()) + " - " + message)
mxd = arcpy.mapping.MapDocument("CURRENT")
theT=COMMON.getTable(mxd)
TÌM KIẾM
theNodesLayer = COMMON.getInfoFromTable(theT,1)
theNodesLayer = COMMON.isLayerExist(mxd,theNodesLayer)
NHẬN LIÊN KẾT
theLinksLayer = COMMON.getInfoFromTable(theT,9)
theLinksLayer = COMMON.isLayerExist(mxd,theLinksLayer)
arcpy.SelectLayerByAttribute_management(theLinksLayer, "CLEAR_SELECTION")
linksFromI=COMMON.getInfoFromTable(theT,14)
linksToI=COMMON.getInfoFromTable(theT,13)
G=nx.Graph()
arcpy.AddMessage("Adding links to graph")
with arcpy.da.SearchCursor(theLinksLayer, (linksFromI,linksToI,"Times")) as cursor:
for row in cursor:
(f,t,c)=row
G.add_edge(f,t,weight=c)
del row, cursor
pops=[]
pops=arcpy.da.TableToNumPyArray(theNodesLayer,("P2013"))
length0=nx.all_pairs_shortest_path_length(G)
nNodes=len(pops)
aBmNodes=[]
aBig=xrange(nNodes)
host=[-1]*nNodes
while True:
RATIO+=-1
if RATIO==0:
break
aBig = filter(lambda x: x not in aBmNodes, aBig)
p=itt.combinations(aBig, 2)
pMin=1000000
small=[]
for a in p:
S0,S1=0,0
for i in aBig:
p=pops[i][0]
p0=length0[a[0]][i]
p1=length0[a[1]][i]
if p0<p1:
S0+=p
else:
S1+=p
if S0!=0 and S1!=0:
sMin=min(S0,S1)
sMax=max(S0,S1)
df=abs(float(sMax)/sMin-RATIO)
if df<pMin:
pMin=df
aBest=a[:]
arcpy.AddMessage('%s %i %i' %(aBest,sMax,sMin))
if df<0.005:
break
lSmall,lBig,S0,S1=[],[],0,0
arcpy.AddMessage ('Ratio %i' %RATIO)
for i in aBig:
p0=length0[aBest[0]][i]
p1=length0[aBest[1]][i]
if p0<p1:
lSmall.append(i)
S0+=p0
else:
lBig.append(i)
S1+=p1
if S0<S1:
aBmNodes=lSmall[:]
for i in aBmNodes:
host[i]=aBest[0]
for i in lBig:
host[i]=aBest[1]
else:
aBmNodes=lBig[:]
for i in aBmNodes:
host[i]=aBest[1]
for i in lSmall:
host[i]=aBest[0]
with arcpy.da.UpdateCursor(theNodesLayer, "rcvnode") as cursor:
i=0
for row in cursor:
row[0]=host[i]
cursor.updateRow(row)
i+=1
del row, cursor
except:
message = "\n*** PYTHON ERRORS *** "; showPyMessage()
message = "Python Traceback Info: " + traceback.format_tb(sys.exc_info()[2])[0]; showPyMessage()
message = "Python Error Info: " + str(sys.exc_type)+ ": " + str(sys.exc_value) + "\n"; showPyMessage()
Ví dụ đầu ra cho 6 nhóm:
Bạn sẽ cần gói trang web NETWORKX
http://networkx.github.io/documentation/development/install.html
Script lấy số cụm yêu cầu làm tham số (6 trong ví dụ trên). Nó đang sử dụng các nút và các bảng liên kết để tạo một biểu đồ có trọng lượng / khoảng cách các cạnh di chuyển bằng nhau (Times = 1). Nó xem xét sự kết hợp của tất cả các nút bằng 2 và tính tổng [P2013] trong hai nhóm lân cận. Khi đạt được tỷ lệ yêu cầu, ví dụ (6-1) / 1 ở lần lặp đầu tiên, tiếp tục với mục tiêu tỷ lệ giảm, tức là 4, v.v. cho đến 1. Điểm bắt đầu có tầm quan trọng rất lớn, vì vậy hãy đảm bảo các nút 'cuối' của bạn nằm ở trên cùng của bảng nút của bạn (sắp xếp?) Xem 3 nhóm đầu tiên trong đầu ra ví dụ. Nó giúp tránh 'cắt cành' ở mỗi lần lặp tiếp theo.
Tùy chỉnh tập lệnh để làm việc từ mxd:
- bạn không cần nhập hàng. Đó là điều của riêng tôi, đọc bảng môi trường của riêng tôi, trong đóNodesLayer, theLinksLayer, linksFromI, linksToI đã chỉ định. Thay thế các dòng có liên quan bằng cách đặt tên riêng của các nút và các lớp liên kết.
- Lưu ý rằng trường P2013 có thể lưu trữ bất cứ thứ gì, ví dụ như số lượng người thuê hoặc khu vực bưu kiện. Nếu vậy, bạn có thể gom các đa giác để giữ số lượng người bằng nhau, v.v.