Originalset:
Erstellen Sie eine Pseudokopie (CNTRL-Drag in TOC) davon und stellen Sie eine räumliche Verknüpfung eins zu viele mit dem Klon her. In diesem Fall habe ich eine Entfernung von 500 m verwendet. Ausgabetabelle:
Entfernen Sie Datensätze aus dieser Tabelle, wobei PAR_ID = PAR_ID_1 - einfach.
Durchlaufen Sie die Tabelle und entfernen Sie Datensätze, wobei (PAR_ID, PAR_ID_1) = (PAR_ID_1, PAR_ID) eines darüber liegenden Datensatzes ist. Nicht so einfach, benutze acrpy.
Berechnen Sie die Einzugsgebiete (UniqID = PAR_ID). Sie sind Knoten oder Netzwerk. Verbinden Sie sie durch Linien mithilfe einer räumlichen Verknüpfungstabelle. Dies ist ein separates Thema, das sicherlich irgendwo in diesem Forum behandelt wird.
Das folgende Skript geht davon aus, dass die Knotentabelle folgendermaßen aussieht:
Wo MUID von Paketen kam, ist P2013 ein Feld zum Zusammenfassen. In diesem Fall = 1 nur zum Zählen. [rcvnode] - Skriptausgabe zum Speichern der Gruppen-ID gleich NODEREC des ersten Knotens in der definierten Gruppe / dem definierten Cluster.
Verknüpft die Tabellenstruktur mit hervorgehobenen wichtigen Feldern
Times speichert das Link- / Kantengewicht, dh die Reisekosten von Knoten zu Knoten. In diesem Fall gleich 1, sodass die Reisekosten für alle Nachbarn gleich sind. [fi] und [ti] sind die fortlaufende Anzahl verbundener Knoten. Um diese Tabelle zu füllen, durchsuchen Sie dieses Forum nach der Zuordnung von und zu zu verknüpfenden Knoten.
Skript angepasst für meine eigene Workbench mxd. Muss geändert und mit Ihrer Benennung der Felder und Quellen fest codiert werden:
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)
NODES LAYER FINDEN
theNodesLayer = COMMON.getInfoFromTable(theT,1)
theNodesLayer = COMMON.isLayerExist(mxd,theNodesLayer)
GET LINKS LAYER
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()
Ausgabebeispiel für 6 Gruppen:
Sie benötigen das Site-Paket NETWORKX
http://networkx.github.io/documentation/development/install.html
Das Skript verwendet die erforderliche Anzahl von Clustern als Parameter (6 im obigen Beispiel). Es werden Knoten- und Verknüpfungstabellen verwendet, um ein Diagramm mit gleichem Gewicht / Abstand der Verfahrkanten zu erstellen (Zeiten = 1). Es berücksichtigt die Kombination aller Knoten mit 2 und berechnet die Summe von [P2013] in zwei Gruppen von Nachbarn. Wenn das erforderliche Verhältnis erreicht ist, z. B. (6-1) / 1 bei der ersten Iteration, wird das Ziel mit reduziertem Verhältnis, dh 4 usw., bis 1 fortgesetzt. Startpunkte sind von großer Bedeutung. Stellen Sie daher sicher, dass Ihre Endknoten oben sitzen Ihrer Knotentabelle (Sortierung?) Siehe die ersten 3 Gruppen in der Beispielausgabe. Es hilft, das Schneiden von Zweigen bei jeder nächsten Iteration zu vermeiden.
Skriptanpassung für mxd:
- Sie müssen GEMEINSAM nicht importieren. Es ist mein eigenes Ding, das meine eigene Umgebungstabelle liest, in der theNodesLayer, theLinksLayer, linksFromI, linksToI angegeben sind. Ersetzen Sie relevante Zeilen durch Ihre eigene Benennung von Knoten und Verknüpfungsebenen.
- Beachten Sie, dass im Feld P2013 alles gespeichert werden kann, z. B. Anzahl der Mieter oder Paketfläche. In diesem Fall können Sie Polygone gruppieren, um ungefähr die gleiche Anzahl von Personen usw. aufzunehmen.