ชุดเดิม:
สร้าง pseudo-copy (CNTRL-drag in TOC) ของมันและทำให้อวกาศเข้าร่วมหนึ่งกับหลายคนด้วยโคลน ในกรณีนี้ฉันใช้ระยะทาง 500 เมตร ตารางผลลัพธ์:
ลบระเบียนออกจากตารางนี้โดยที่ PAR_ID = PAR_ID_1 - ง่าย
ทำซ้ำผ่านตารางและลบระเบียนที่ (PAR_ID, PAR_ID_1) = (PAR_ID_1, PAR_ID) ของระเบียนใด ๆ ข้างต้น ไม่ใช่เรื่องง่ายใช้ acrpy
คำนวณ centroid ที่เก็บกักน้ำ (UniqID = PAR_ID) พวกมันคือโหนดหรือเครือข่าย เชื่อมต่อพวกเขาด้วยเส้นโดยใช้ตารางเข้าร่วมเชิงพื้นที่ นี่เป็นหัวข้อแยกต่างหากที่ครอบคลุมบางแห่งในฟอรัมนี้
สคริปต์ด้านล่างจะถือว่าตารางของโหนดดูเหมือนว่า:
ที่ MUID มาจากผืน P2013 เป็นสนามที่จะสรุป ในกรณีนี้ = 1 สำหรับการนับเท่านั้น [rcvnode] - เอาต์พุตสคริปต์เพื่อเก็บ ID กลุ่มเท่ากับ NODEREC ของโหนดแรกในกลุ่ม / คลัสเตอร์ที่กำหนดไว้
ลิงก์โครงสร้างตารางที่มีฟิลด์สำคัญถูกเน้น
ไทม์สเก็บน้ำหนักลิงค์ / ขอบเช่นค่าใช้จ่ายในการเดินทางจากโหนดหนึ่งไปอีกโหนด เท่ากับ 1 ในกรณีนี้ค่าใช้จ่ายในการเดินทางไปยังเพื่อนบ้านทั้งหมดจึงเท่ากัน [fi] และ [ti] เป็นหมายเลขลำดับของโหนดที่เชื่อมต่อ หากต้องการเติมตารางนี้ให้ค้นหาฟอรัมนี้เกี่ยวกับวิธีกำหนดจากและไปยังโหนดที่จะลิงก์
สคริปต์ที่ปรับแต่งสำหรับ workbench ของฉันเอง mxd จะต้องมีการแก้ไขฮาร์ดโค้ดด้วยการตั้งชื่อฟิลด์และแหล่งที่มาของคุณ:
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)
ค้นหา LODER NODES
theNodesLayer = COMMON.getInfoFromTable(theT,1)
theNodesLayer = COMMON.isLayerExist(mxd,theNodesLayer)
รับเลเยอร์ลิงก์
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()
ตัวอย่างผลลัพธ์สำหรับ 6 กลุ่ม:
คุณจะต้องมีแพ็คเกจไซต์ NETWORKX
http://networkx.github.io/documentation/development/install.html
สคริปต์ใช้จำนวนคลัสเตอร์ที่ต้องการเป็นพารามิเตอร์ (6 ในตัวอย่างด้านบน) มันใช้โหนดและเชื่อมโยงตารางเพื่อสร้างกราฟที่มีน้ำหนัก / ระยะทางเท่ากันของขอบการเดินทาง (เท่า = 1) จะพิจารณาการรวมกันของโหนดทั้งหมดโดย 2 และคำนวณผลรวมของ [P2013] ในสองกลุ่มเพื่อนบ้าน เมื่ออัตราส่วนที่ต้องการสำเร็จเช่น (6-1) / 1 ที่การวนซ้ำครั้งแรกดำเนินการต่อด้วยเป้าหมายอัตราส่วนลดลงเช่น 4 เป็นต้นจนถึง 1 จุดเริ่มต้นมีความสำคัญมากดังนั้นให้แน่ใจว่าโหนด 'สิ้นสุด' ของคุณนั่งอยู่ด้านบน ของตารางโหนดของคุณ (การเรียงลำดับ?) ดู 3 กลุ่มแรกในเอาต์พุตตัวอย่าง ช่วยหลีกเลี่ยงการ 'ตัดกิ่ง' ในการทำซ้ำครั้งต่อไป
การปรับแต่งสคริปต์เพื่อทำงานจาก mxd:
- คุณไม่ต้องการนำเข้าคอมมอน มันเป็นของฉันเองที่อ่านตารางสภาพแวดล้อมของฉันเองโดยที่ nodes, theLinksLayer, linksFromI, linksTo ระบุ แทนที่บรรทัดที่เกี่ยวข้องด้วยการตั้งชื่อโหนดและเลเยอร์ลิงก์ของคุณเอง
- โปรดทราบว่าฟิลด์ P2013 สามารถเก็บอะไรก็ได้เช่นจำนวนผู้เช่าหรือพื้นที่พัสดุ ถ้าเป็นเช่นนั้นคุณอาจจัดกลุ่มรูปหลายเหลี่ยมให้มีจำนวนบุคคลโดยประมาณเท่ากันเป็นต้น