MapWinGISでContour Generation
自前のプログラムで標高データからコンター図を作成する必要があったので、作ってみました。
ArcGISではラスター解析はoptionで別売りだし、QGISとかでもできるのですが、自前のプログラムには組み込めないんですよね。 ましてやvb.netでは。
今回のsampleは、必要最低限の機能しか持っていないので、MapWinGISのtutorialに付け加えれば、操作性も向上できると思います。
元になるprogramは、Mapコントロールの追加example [Chapter 2]にコンター作成機能を付け加えてました。
コンター作成のプログラムは、MapWindowのPluginを参考にしました。svnでソースを取得することができますので、ぜひ参考にすると良いと思います。詳しくは、MapWindow Source Code Repositoryを見てください。
Program Coding
今回は、Mapコントロールの追加example [Chapter 2]に若干付け加えます。
Form design
Main Form
Contour Generation Option Form
Coding
それでは、Contour Generation Option Formからcodingを始めていきます。
参照の追加で、MapWinUtility.dllを追加を忘れないように。
Contour Generation
コンターを作成するのに、必要な情報は、
-
入力raster
-
出力shape file
-
コンター間隔
-
No Data Value
が必要になります。
まずは、dllをimportsしておきます。
Imports System Imports AxMapWinGIS Imports MapWinGIS Imports MapWinUtility
次に 変数の宣言
Public t_legend As New LegendControl.Legend Public t_handle As Integer Public gridFile As String Private inputGridFile As String = "" Private chb3D As Boolean = False
publicな部分は、Main Formから呼び出す時に使います。
コンターは、bool Utils.GenerateContourを参考に作成します。
bool Utils.GenerateContour ( string pszSrcFilename, string pszDstFilename, double dfInterval, double dfNoData, bool Is3D, object dblFLArray, ICallback cBack ) This program generates a vector contour file from the input raster elevation model (DEM). See the description of approriate routine in GDAL Tools. Parameters: bstrSrcFilename The name of the source file. bstrDstFilename The name of the output file. bstrOptions Options of the routine. cBack The callback object. Returns: True on success and false otherwise.
コンター作成のメインは、
'Contour Generate Dim u As New MapWinGIS.Utils If rdCI.Checked Then boolRes = u.GenerateContour(actualInput, txtOutputSF.Text, Double.Parse(txtInterval.Text), Double.Parse(txtNoData.Text), chb3D, 0.0) Else boolRes = u.GenerateContour(actualInput, txtOutputSF.Text, 0.0, Double.Parse(txtNoData.Text), chb3D, dblArray) End If
rdCIはコンター間隔を一定値、もしくは固定値で行うかのチェック値です。そのrdCIによってGenerateContourの引数を変えています。
Generate button event内の実装は
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click Dim dblArray() As Double = Nothing Dim boolRes As Boolean Try Try If System.IO.File.Exists(txtOutputSF.Text) Then If (MapWinUtility.Logger.Msg(txtOutputSF.Text.ToString & " already exists. Do you want to replace it?", MsgBoxStyle.OkCancel, "Save As") = Microsoft.VisualBasic.MsgBoxResult.Ok) Then Kill(txtOutputSF.Text) Kill(Mid(txtOutputSF.Text, 1, Len(txtOutputSF.Text) - 4) & ".shx") Kill(Mid(txtOutputSF.Text, 1, Len(txtOutputSF.Text) - 4) & ".dbf") Else Me.Cursor = Windows.Forms.Cursors.Default Me.Close() Exit Sub End If End If Catch ex As Exception MapWinUtility.Logger.Msg(ex.Message.ToString) Me.Cursor = Windows.Forms.Cursors.Default Me.Close() Exit Sub End Try Dim actualInput As String = inputGridFile 'Rob Cairns 4-Mar-06: There is a problem with this function somewhere 'It shifts the contour half a pixel up and to the right 'The latest gdal build recognises .asc format so I have made a temporary 'fix by circumventing this conversion for AAIGrid formats If inputGridFile.ToLower().EndsWith("arc") Or inputGridFile.ToLower().EndsWith("bgd") Then 'If it's not a GDAL-compatible format, must interchange the filename actualInput = System.IO.Path.GetDirectoryName(inputGridFile) & "" & _ System.IO.Path.GetFileNameWithoutExtension(inputGridFile) & _ ".tif" Try Dim formatChange As New MapWinGIS.Grid formatChange.Open(inputGridFile, MapWinGIS.GridDataType.UnknownDataType, True, MapWinGIS.GridFileType.UseExtension) formatChange.Save(actualInput, MapWinGIS.GridFileType.GeoTiff) formatChange.Close() Catch ex As Exception If Not System.IO.File.Exists(actualInput) Then MapWinUtility.Logger.Msg("Aborting: An error occurred while translating the grid. The error follows." & vbCrLf & vbCrLf & ex.ToString) Exit Sub End If End Try End If 'Contour Generate Dim u As New MapWinGIS.Utils If rdCI.Checked Then boolRes = u.GenerateContour(actualInput, txtOutputSF.Text, Double.Parse(txtInterval.Text), Double.Parse(txtNoData.Text), chb3D, 0.0) Else boolRes = u.GenerateContour(actualInput, txtOutputSF.Text, 0.0, Double.Parse(txtNoData.Text), chb3D, dblArray) End If 'Clean up If Not actualInput = inputGridFile Then Try Kill(actualInput) Catch End Try End If Me.Close() Catch ex As Exception End Try End Sub
.ascと.bgd形式のgridの場合は、tifに一度変換しないとだめなようです。
後は、他のcontrol類のevent実装して、Contour Generation Option Formを作成します。
その他は省略。。。
次に、Contour Generation Option Formを呼び出すためのMain Formのcodeingを行います。
Main Formのcodeing
Raster Layersでgridデータを呼び出します。button click event発生時のcodingは、
Private Sub AddRasterLayer() Dim grid As New MapWinGIS.Grid Dim gridScheme As MapWinGIS.GridColorScheme Dim image As MapWinGIS.Image Dim utils As MapWinGIS.Utils Dim openDlg As OpenFileDialog = New OpenFileDialog() Dim handle As Integer Dim ext As String 'initialize dialog openDlg.Filter = grid.CdlgFilter '"Supported Formats|*.bgd;*.asc;*.img;*.tif|Binary Grids (*.bgd)|*.bgd|ASCII Grids (*.asc)|*.asc|Image Grids (*.img)|*.img|TIFF Raster (*.tif)|*.tif" openDlg.CheckFileExists = True If (openDlg.ShowDialog(Me) = DialogResult.OK) Then 'get the extension of the file ext = System.IO.Path.GetExtension(openDlg.FileName) utils = New MapWinGIS.UtilsClass() gridScheme = New MapWinGIS.GridColorScheme() grid = New MapWinGIS.GridClass() 'open the grid grid.Open(openDlg.FileName, MapWinGIS.GridDataType.UnknownDataType, True, MapWinGIS.GridFileType.UseExtension) 'create a coloring scheme for the image gridScheme.UsePredefined(System.Convert.ToDouble(grid.Minimum), System.Convert.ToDouble(grid.Maximum), MapWinGIS.PredefinedColorScheme.SummerMountains) image = New MapWinGIS.Image() 'convert the grid to a image image = utils.GridToImage(grid, gridScheme) 'add the image to the legend and map handle = Legend1.Layers.Add(image, True) 'grid filname set gridFilename(handle) = openDlg.FileName If (Legend1.Layers.IsValidHandle(handle)) Then 'set the layer name 'Legend1.Map.set_LayerName(handle, System.IO.Path.GetFileNameWithoutExtension(grid.Filename)) Legend1.Map.LayerName(handle) = System.IO.Path.GetFileNameWithoutExtension(grid.Filename) 'set's the legend layer type, this displays a default icon in the legend (line shapefile, point shapefile,polygon shapefile,grid,image) Legend1.Layers.ItemByHandle(handle).Type = MapWindow.Interfaces.eLayerType.Grid 'set coloring scheme AxMap1.SetImageLayerColorScheme(Legend1.SelectedLayer, gridScheme) Legend1.Layers.ItemByHandle(Legend1.SelectedLayer).Refresh() End If 'close the grid grid.Close() End If End Sub
でrasterファイルだけを呼び出しています。Map上はimagefileとして変換しなければ表示できないので、image = utils.GridToImage(grid, gridScheme)でimageに変換しています。
その際に、gridファイル名がNullになってしまうため、gridFilenam()にファイル名を入れておきます。
次に、Contour button click event発生時のcodingは、
Private Sub ToolStripButton2_Click(sender As System.Object, e As System.EventArgs) Handles ToolStripButton2.Click If AxMap1.NumLayers > 0 Then Dim frmGenerateContour As New ContourGenerate() frmGenerateContour.t_legend = Legend1 frmGenerateContour.t_handle = layerHandle frmGenerateContour.GridFile = gridFilename(layerHandle) frmGenerateContour.Show(Me) End If End Sub
で、MapWInGISのtutorialで別Formの呼び出しでのcodingと同じ形式です。
Programの実行
では、ToolContourを保存して実行してみましょう。
legendで選択したRaster Layerのコンターを作成します。 layerを選択して、contour buttonをクリックします。
今回は、神奈川県のサンプルrasterを読み込んで表示させます。
神奈川県のサンプルraster file表示
Contour buttonをクリックして、Contour Generation Option Formを表示させます。
Contour Generation Option Form表示画面
今回のまとめ
-
MapWinUtilityを使ってcontour作成のcodeing実装を行いました。
-
別Formを作成して、contour Generation Oprion表示を行いました。
vb.net2010だけでなく、C#でも、visual studio2008でも動作することができます。
簡単に自前のソフトウェアにちょっとしたGIS機能を付け加えるには良いと思います。
Contour Generate sampleのsource codeを公開しますので、活用してください。
ただし、あくまでの自分用のサンプルですので、バグなどがある可能性が高いので、原文のままの使用は避けてください。
サンプルコードおよびサンプルデータを使って、お使いのPCの不具合が生じても一切責任は持てませんので、あくまでも自己責任にて使用してください。
最近のコメント