Set asli:
Buat pseudo-copy (seret CNTRL di TOC) dari itu dan buat spasial satu dengan banyak orang dengan klon. Dalam hal ini saya menggunakan jarak 500m. Tabel output:
Hapus catatan dari tabel ini tempat PAR_ID = PAR_ID_1 - mudah.
Iterasi melalui tabel dan hapus rekaman di mana (PAR_ID, PAR_ID_1) = (PAR_ID_1, PAR_ID) dari semua catatan di atasnya. Tidak mudah, gunakan acrpy.
Hitung centroid tangkapan (UniqID = PAR_ID). Mereka adalah node atau jaringan. Hubungkan mereka dengan garis menggunakan tabel bergabung spasial. Ini adalah topik terpisah yang pasti dibahas di suatu tempat di forum ini.
Script di bawah ini menganggap bahwa tabel node terlihat seperti itu:
di mana MUID berasal dari bidang, P2013 adalah bidang untuk diringkas. Dalam hal ini = 1 untuk penghitungan saja. [rcvnode] - output skrip untuk menyimpan ID grup sama dengan NODEREC dari node pertama dalam grup / cluster yang ditentukan.
Tautan struktur tabel dengan bidang-bidang penting yang disorot
Times menyimpan link / edge weight, yaitu biaya perjalanan dari node ke node. Sama dengan 1 dalam hal ini sehingga biaya perjalanan ke semua tetangga adalah sama. [fi] dan [ti] adalah nomor urut dari node yang terhubung. Untuk mengisi tabel ini, cari di forum ini tentang cara menetapkan dari dan ke simpul yang akan ditautkan.
Script disesuaikan untuk meja kerja saya sendiri mxd. Harus dimodifikasi, hardcoded dengan penamaan bidang dan sumber Anda:
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)
TEMUKAN LAPANG NODES
theNodesLayer = COMMON.getInfoFromTable(theT,1)
theNodesLayer = COMMON.isLayerExist(mxd,theNodesLayer)
DAPATKAN LAPIS LINKS
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()
Contoh output untuk 6 grup:
Anda akan memerlukan paket situs NETWORKX
http://networkx.github.io/documentation/development/install.html
Script mengambil jumlah cluster yang diperlukan sebagai parameter (6 pada contoh di atas). Ia menggunakan tabel simpul dan tautan untuk membuat grafik dengan bobot / jarak tepi perjalanan yang sama (Times = 1). Itu mempertimbangkan kombinasi semua node dengan 2 dan menghitung total [P2013] dalam dua kelompok tetangga. Ketika rasio yang diperlukan tercapai, misalnya (6-1) / 1 pada iterasi pertama, dilanjutkan dengan target rasio yang dikurangi, yaitu 4, dll. Hingga 1. Titik awal sangat penting, jadi pastikan simpul 'ujung' Anda berada di atas dari tabel node Anda (pengurutan?) Lihat 3 grup pertama dalam contoh output. Ini membantu untuk menghindari 'pemotongan cabang' di setiap iterasi berikutnya.
Kustomisasi skrip untuk bekerja dari mxd:
- Anda tidak perlu mengimpor UMUM. Adalah hal saya sendiri, yang membaca tabel lingkungan saya sendiri, di manaNodesLayer, theLinksLayer, linksFromI, linksToI ditentukan. Ganti baris yang relevan dengan penamaan node dan lapisan tautan Anda sendiri.
- Perhatikan bahwa bidang P2013 dapat menyimpan apa pun, misalnya jumlah penyewa atau area parsel. Jika demikian, Anda dapat mengelompokkan poligon untuk menampung kira-kira jumlah orang yang sama dll.