C#でGISデータ(shpファイル)を開く DotSpatialによる方法

DotSpatialは.NET向けのオープンソースの地理情報システムライブラリである.これを使ってGISで用いられるshpファイル(とセットのshxファイルとdbfファイル)を読み込む.

DotSpatialのインストール

Nuget経由でインストール可能.プロジェクトを右クリックして「NuGetパッケージの管理」を選択する.オンラインから「DotSpatial」で検索.たくさん出てくるが,ここでは「DotSpatial.Controls」選択してインストール.

f:id:whoopsidaisies:20140914212117p:plain

Mapコントロールの追加

GISデータ表示用のコントロールが用意されているのでそれを使ってみる.

まず,一度プロジェクトをビルドする.そうするとDotSpatialのDLLが実行ファイルのディレクトリにコピーされる.

ツールボックスの適当なところでクリックして「アイテムの選択(I)...」を選択.
f:id:whoopsidaisies:20140914212749p:plain

「.NET Framework コンポーネント」タブの「参照(B)...」ボタンを押して,「(実行ファイルのパス)\DotSpatial.Controls.dll」を選択したらOK.

f:id:whoopsidaisies:20140914212821p:plain

f:id:whoopsidaisies:20140914213930p:plain

そうすると「Map」というコントロールが追加されているのでフォームに追加する.
f:id:whoopsidaisies:20140914213818p:plain

シェープファイルの読み込み

シェープファイルは「全国市区町村界データ | データ製品 | 製品 | ESRIジャパン株式会社」でESRI Japanが配布している全国市区町村界データを使う.ダウンロードして解答したら以下のコードを追加する.

map1.AddLayer(@"D:\Users\whoops\Downloads\japan_ver72\japan_ver72.shp");

実行すると以下のように地図が表示される.

f:id:whoopsidaisies:20140914214517p:plain

属性情報の表示 Infoモード

上の状態だと地図が表示されるだけで何もできないためMapコントロールのモードを変える.以下のようにコードを追加してInfoモードにする.

map1.AddLayer(@"D:\Users\whoops\Downloads\japan_ver72\japan_ver72.shp");
map1.FunctionMode = DotSpatial.Controls.FunctionMode.Info;

これで実行すると以下のようにクリックした位置の市町村の情報を見れる.

f:id:whoopsidaisies:20140914214930p:plain

領域の選択 Selectモード

Selectモードににするとドラッグで領域指定できる.

map1.FunctionMode = DotSpatial.Controls.FunctionMode.Select;

f:id:whoopsidaisies:20140915002531p:plain

選択しただけだと何も表示されないので,TextBoxに選択された領域の情報を表示してみる.MAPコントロールのMouseUpイベントを追加して以下のコードを書き込む.

private void map1_MouseUp(object sender, MouseEventArgs e)
{
    textBox1.Text = "";
    // MAPコントロールが保持しているレイヤーデータを取得
    var featureLayer = map1.Layers[0] as DotSpatial.Symbology.FeatureLayer;
            
    // すべてのデータについてループ
    for (int i = 0; i < featureLayer.DrawnStates.Length; ++i)
    {
        // 選択されているかどうか判別
        if (featureLayer.DrawnStates[i].Selected == true)
        {
            // i番目の属性情報取得
            var feature = featureLayer.FeatureSet.GetFeature(i);

            // DataRowからフィールド名でアクセス
            textBox1.Text += System.String.Format(
                "{0} : {1} {2} {3}人",
                feature.DataRow["JCODE"],
                feature.DataRow["KEN"],
                feature.DataRow["SIKUCHOSON"],
                feature.DataRow["P_NUM"]
                )
                + System.Environment.NewLine;
        }
    }
}

選択されているかどうかはレイヤーデータのDrawnStatesプロパティに格納されている.

属性情報はFeatureSetプロパティに格納されていてGetFeatureメソッドで指定した番号のデータを取得できる.

各属性情報へは,DataRawにフィールド名を指定することで取得できる.このサンプルで使っているフィールド名は「全国市区町村界データ | データ製品 | 製品 | ESRIジャパン株式会社」を参照.

実行してドラッグで領域選択すると以下のようにTextBoxに情報が表示される.
f:id:whoopsidaisies:20140915004858p:plain

MAPコントロールなしで読み込み

MAPコントロールを配置しなくてもDataManagerクラスのOpenFileメソッドを使えばシェープファイルは読み込める.

以下にシェープファイルを読み込んで,0番目のデータの座標を出力するコードを載せる.

// シェープファイルの読み込み
var layer = DotSpatial.Data.DataManager.DefaultDataManager.OpenFile(@"D:\Users\whoops\Downloads\japan_ver72\japan_ver72.shp") 
    as DotSpatial.Data.FeatureSet;
// 0番目のデータの座標を表示
foreach (var cordinate in layer.GetFeature(0).Coordinates)
{
    Console.WriteLine(cordinate.ToString());
}

実行結果
f:id:whoopsidaisies:20140915010455p:plain

コントロールを使わない方法だけを使う場合NuGetで「DotSpatial.Data」をインストールすればできる.