Ich habe in der Graduiertenschule eine Reihe von ArcGIS VBA-Automatisierungen geschrieben. Sie sind jedoch vollständig von der Erweiterung ArcGIS Spatial Analyst abhängig, die nicht nur aus geschlossenen Quellen stammt, sondern bis zur Abschreckung teuer ist.
Da VBA veraltet ist und einige Forscher an der U immer noch meine VBA-Tools verwenden, dachte ich, es würde Spaß machen, sie in .Net neu zu schreiben. Mit mehr Erfahrung wird mir jedoch klar, dass es für den akademischen Gebrauch besser geeignet wäre, wenn diese Dienstprogramme offene Algorithmen verwenden würden.
Vor diesem Hintergrund betrachte ich Whitebox GAT als potenziellen Ersatz für die Hydrologie-Tools von Spatial Analyst und bin gespannt, ob es Erfolgsgeschichten oder zeitsparende "Fallstricke" im Zusammenhang mit der ArcGIS / Whitebox-Integration gibt.
Ich gehe davon aus, dass einige Leute die Implementierung von Saga, GRASS, R usw. gegenschlagen möchten. Wenn dies Ihre Position ist, beschreiben Sie bitte, warum eine Whitebox-Integration unklug wäre. Unterstützt es beispielsweise nur einige Eingabeformate, hat es einen schlechten Umgang mit großen Dateien (1-2 GB +) usw.
Ich habe ein bisschen mit der Whitebox-Benutzeroberfläche herumgespielt, und mit Hilfe ihrer Tutorials war es nicht schwierig, ein 30-Meter-DEM, das ich herumliegen hatte, vorzuverarbeiten. Nachdem ich die Hydro-Raster aneinandergereiht hatte, erstellte ich einen Stockpunkt und machte seine Wasserscheide. Dies war genug, um ein Gefühl für die Whitebox-Benutzererfahrung zu bekommen.
Whitebox kann mit .Net oder Python erweitert und / oder konsumiert werden. Nachdem ich einige Grundlagen in der Whitebox-Benutzeroberfläche gelernt hatte, dachte ich, ich würde die typischen DEM-Vorverarbeitungsaufgaben mit einer einfachen .NET-Automatisierung verketten (noch keine ArcMap). DEM-Vorverarbeitung bedeutet normalerweise Folgendes:
- setze keinen Datenwert (Whitebox benötigt dies, aber Arc hat es nie getan)
- Waschbecken füllen
- Erstellen Sie ein Raster für die Flussrichtung
- Erstellen Sie ein Flow-Akkumulations-Raster
Ich habe die folgende Windows Form "Anwendung" (aka WhiteboxDaisyChain
) zusammengestellt. Es nimmt ein Systemverzeichnis mit einem ArcGIS Grid (.FLT) und führt die oben genannten Aufgaben aus. Wenn Sie dies versuchen möchten, müssen Sie die kompilierten Binärdateien herunterladen , entpacken und dann alle .dll
Dateien aus ..\WhiteboxGAT_1_0_7\Plugins
Ihrem Projekt kopieren - ich habe alles eingefügt ..\WhiteboxDaisyChain\Whitebox
. In diesem Beispiel werden jedoch nur die vier DLLs
oben im Codebeispiel genannten benötigt.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
// 1) Create a new Windows Form
// 2) Put all these in a Whitebox folder in the C# project root.
// 3) Add project references to the following and create using statements:
using Interfaces; // requires Add Reference: Interfaces.dll
using ImportExport; // requires Add Reference: ImportExport.dll
using ConversionTools; // requires Add Reference: ConversionTools.dll
using flow; // requires Add Reference: flow.dll
namespace WhiteboxDaisyChain
{
// 4) Prepare to implement the IHost interface.
// 5) Right-click IHost, select "Implement interface.."
public partial class UI : Form, IHost
{
// 6) Add a BackgroundWorker object.
private BackgroundWorker worker;
public UI()
{
InitializeComponent();
// 7) Instantiate the worker and set "WorkerReportsProgress".
worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
}
// 8) Use some event to set things in motion.. i.e. Button click.
private void button1_Click(object sender, EventArgs e)
{
progressLabel.Text = "Running..";
// This is the path containing my ArcGrid .FLT.
// All processing will unfold to this directory.
string path = "C:\\xData\\TutorialData\\DemWhitebox\\";
string[] fltArgs = new string[1];
fltArgs[0] = path + "greene30.flt"; // in: Arc floating point grid
// creates a raster in Whitebox data model
ImportArcGrid importAG = new ImportArcGrid();
importAG.Initialize(this as IHost);
importAG.Execute(fltArgs, worker); // out: path + "greene30.dep"
// set the nodata value on the DEM
string[] noDataArgs = new string[2];
noDataArgs[0] = path + "greene30.dep"; // in: my raw DEM
noDataArgs[1] = "-9999"; // mine used -9999 as nodata value
SetNoData setNoData = new SetNoData();
setNoData.Initialize(this as IHost);
setNoData.Execute(noDataArgs, worker); // out: path + "greene30.dep"
// fill sinks in the DEM
string[] fillSinksArgs = new string[4];
fillSinksArgs[0] = path + "greene30.dep"; // in: my DEM with NoData Fixed
fillSinksArgs[1] = path + "greene30_fill.dep"; // out: my DEM filled
fillSinksArgs[2] = "50"; // the dialog default
fillSinksArgs[3] = "0.01"; // the dialog default
FillDepsBySize fillSinks = new FillDepsBySize();
fillSinks.Initialize(this as IHost);
fillSinks.Execute(fillSinksArgs, worker);
// create a flow direction raster
string[] flowDirArgs = new string[2];
flowDirArgs[0] = path + "greene30_fill.dep"; // in: my Filled DEM
flowDirArgs[1] = path + "greene30_dir.dep"; // out: flow direction raster
FlowPointerD8 flowDirD8 = new FlowPointerD8();
flowDirD8.Initialize(this as IHost);
flowDirD8.Execute(flowDirArgs, worker);
// create a flow accumulation raster
string[] flowAccArgs = new string[4];
flowAccArgs[0] = path + "greene30_dir.dep"; // in: my Flow Direction raster
flowAccArgs[1] = path + "greene30_acc.dep"; // out: flow accumulation raster
flowAccArgs[2] = "Specific catchment area (SCA)"; // a Whitebox dialog input
flowAccArgs[3] = "false"; // a Whitebox dialog input
FlowAccumD8 flowAccD8 = new FlowAccumD8();
flowAccD8.Initialize(this as IHost);
flowAccD8.Execute(flowAccArgs, worker);
progressLabel.Text = "";
progressLabel.Text = "OLLEY-OLLEY-OXEN-FREE!";
}
/* IHost Implementation Methods Below Here */
public string ApplicationDirectory
{
get { throw new NotImplementedException(); }
}
public void ProgressBarLabel(string label)
{
this.progressLabel.Text = "";
this.progressLabel.Text = label; // This is the only one I used.
}
public string RecentDirectory
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public bool RunInSynchronousMode
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public void RunPlugin(string PluginClassName)
{
throw new NotImplementedException();
}
public void SetParameters(string[] ParameterArray)
{
throw new NotImplementedException();
}
public void ShowFeedback(string strFeedback, string Caption = "GAT Message")
{
throw new NotImplementedException();
}
}
}
Bisher grabe ich das, aber ich habe noch keine wirkliche Erfolgsgeschichte oder Show-Stopper zu beschreiben. Mein nächstes Ziel wird es sein, interaktiv Pour Points von ArcMap einzureichen. Grundsätzlich möchte ich auf die Karte klicken ..get die Wasserscheide.