Set originale:
Crea una pseudo-copia (trascinamento CNTRL in TOC) e crea l'unione spaziale da una a molte con il clone. In questo caso ho usato la distanza 500m. Tabella di output:
Rimuovi i record da questa tabella in cui PAR_ID = PAR_ID_1 - facile.
Scorrere la tabella e rimuovere i record in cui (PAR_ID, PAR_ID_1) = (PAR_ID_1, PAR_ID) di qualsiasi record sopra di essa. Non così facile, usa acrpy.
Calcola i centroidi del bacino (UniqID = PAR_ID). Sono nodi o rete. Collegali per linee usando la tabella dei join spaziali. Questo argomento separato è sicuramente trattato da qualche parte in questo forum.
Lo script seguente presuppone che la tabella dei nodi sia simile a quella:
dove MUID proveniva da pacchi, P2013 è il campo da riassumere. In questo caso = 1 solo per il conteggio. [rcvnode] - output dello script per memorizzare l'ID del gruppo uguale a NODEREC del primo nodo nel gruppo / cluster definito.
Collega la struttura della tabella con i campi importanti evidenziati
Il negozio memorizza i tempi / peso del bordo, ovvero il costo del viaggio da un nodo all'altro. Uguale a 1 in questo caso in modo che il costo del viaggio per tutti i vicini sia lo stesso. [fi] e [ti] sono il numero sequenziale di nodi collegati. Per popolare questa tabella cerca in questo forum come assegnare da e ai nodi per il collegamento.
Script personalizzato per il mio workbench mxd. Deve essere modificato, codificato con la tua denominazione dei campi e delle fonti:
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)
TROVA STRATO NODI
theNodesLayer = COMMON.getInfoFromTable(theT,1)
theNodesLayer = COMMON.isLayerExist(mxd,theNodesLayer)
OTTIENI LO STRATO DEI LINK
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()
Esempio di output per 6 gruppi:
È necessario il pacchetto del sito NETWORKX
http://networkx.github.io/documentation/development/install.html
Lo script accetta il numero richiesto di cluster come parametro (6 nell'esempio precedente). Utilizza tabelle di nodi e collegamenti per creare un grafico con uguale peso / distanza dei bordi della corsa (tempi = 1). Considera la combinazione di tutti i nodi per 2 e calcola il totale di [P2013] in due gruppi di vicini. Quando viene raggiunto il rapporto richiesto, ad es. (6-1) / 1 alla prima iterazione, continua con l'obiettivo di rapporto ridotto, ovvero 4, ecc. Fino a 1. I punti di partenza sono di enorme importanza, quindi assicurarsi che i nodi 'end' siano posizionati in alto della tabella dei nodi (ordinamento?) Vedi i primi 3 gruppi nell'output di esempio. Aiuta a evitare il "taglio dei rami" ad ogni iterazione successiva.
Personalizzazione degli script per funzionare da mxd:
- non è necessario importare COMUNE. È la mia cosa, che legge la mia tabella di ambiente, dove specificato theNodesLayer, theLinksLayer, linksFromI, linksToI. Sostituisci le linee pertinenti con la tua denominazione di nodi e livelli di collegamenti.
- Si noti che il campo P2013 può memorizzare qualsiasi cosa, ad esempio il numero di inquilini o l'area dei pacchi. In tal caso, potresti raggruppare poligoni per contenere approssimativamente lo stesso numero di persone, ecc.