Kategorien

Geometric Network in ArcGIS

Letzthin war ich ziemlich stark damit beschäftigt, mit ArcGIS Analysen auf einem Gewässernetzwerk durchzuführen. ArcGIS kennt zwei Arten von Netzwerken: zum einen die geometrischen Netzwerke und zum anderen die komplexeren topologischen Netzwerke, für die die “Network Analyst Extension” benötigt wird. In diesem Fall reichte für die Analyse ein geometrisches Netzwerk aus. Konkret musste ich für einen Satz von Punkten auf dem Netzwerk (in diesem Falle Kläranlagen) den nächstliegenden Q347-Punkt ober- und unterhalb herausfinden. Dies konnte ich relativ leicht mit einer Tracing-Funktion erreichen. Dazu musste ich nur das Developer Sample “Next Upstream Device Task” umschreiben und anpassen. Dies arbeitet hauptsächlich mit dem ITraceFlowSolver-Interface und dort mit der Funktion FindFlowEndElements. Das Resultat dieser Funktion können allerdings mehrere Elemente sein (Flüsse vereinigen sich und können sich u.U. auch verzweigen), aus denen ich dann das am nächsten liegende herausfiltern musste (unter Einbezug der FindPath-Funktion des ITraceFlowSolver-Interfaces).

So weit so gut. Etwas komplizierter war die zweite Aufgabe. Für jeden der oben erwähnten Punkte musste ich berechnen, wieviele Kilometer Gewässernetz oberhalb liegen. Hierfür gibt es im ITraceFlowSolver2-Interface die Funktion FindAccumulation. Diese gibt als Resultat alle jene Gewässerabschnitte zurück, die oberhalb eines Punktes liegen. Hier begannen nun die Probleme. Im Prinzip ging es nun nur noch darum, die Länge aller jener Gewässerabschnitte zu berechnen. Die FindAccumulation-Funktion gibt nicht die normale Feature-ID der Gewässerabschnitte zurück sondern die Network-ID, welche nicht identisch zu sein braucht. Nun habe ich nach kurzer Durchsicht des Objektmodells eine vielversprechende Funktion gefunden. Das IGeometricNetwork-Interface bietet die Funktion GeometryForEdgeID, welche mir für jede Network-ID die dazugehörige Geometrie und damit auch die Länge zurückgibt. Und tatsächlich, damit konnte ich die gesuchte Gewässernetzlänge berechnen. Doch bei Punkten die relativ weit unten im Netzwerk liegen (z.B. am Unterlauf von Rhein, Aare oder Rhone) und somit eine sehr grosse Gewässernetzlänge oberhalb aufweisen, dauerte die Berechnung ziemlich lange (bis zu einer Stunde) oder ArcMap stürzte gar ohne Fehlermeldung ab. Zuerst vermutete ich das Probleme in der FindAccumulation-Funktion, da ich mir schon vorstellen konnte, dass auf dem recht detaillierten Gewässernetz eine solche Funktion recht viel Zeit in Anspruch nehmen konnte. In der “Utility Network Analyst Toolbar” gibt es jedoch den Task “Find Upstream Accumulation”, mit dem ich ein paar dieser problematischen Berechnungen von Hand durchführte. Und dort dauerte dies jeweils nur wenige Sekunden, also konnte die Tracing-Funktion nicht das Problem sein. Damit wendete ich mich der GeometryForEdgeID-Funktion zu, die nun der Übeltäter zu sein schien. Als Ersatz fand ich das IEIDHelper-Interface, mit dem man für jede Network-ID ein IEIDInfo-Interface holen kann, welches das gesuchte Geometry-Attribut aufweist. Ein kurzer Test zeigte mir, dass auf diese Weise die Berechnung der Gewässernetzlänge nur wenige Sekunden dauerte. Dieser Weg war also der deutlich schnellere. Wahrscheinlich liegt es daran, dass die ursprünglich gebrauchte GeometryForEdgeID-Funktion im ganzen Netzwerk nach der übergebenen Network-ID sucht (keine Ahnung, ob hier ein Index existiert) — immerhin besteht das Netzwerk aus mehreren Hunderttausend Abschnitten –, was deutlich langsamer ist als der Weg über das IEIDInfo-Interface.

Langer Rede kurzer Sinn: es lohnt sich, das Arcobjects-Objektmodell sehr genau zu studieren, und nicht immer die erstbeste Lösung zu verwenden. Meistens gibt es in ArcObjects immer mehrere Wege zum Ziel, die Herausforderung ist dann jeweils, den geeignetsten zu finden.

Leave a Reply

  

  

  

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>