Daily Archives: 12/10/2012

MapWinGISのちょっとした話題提供

MapWinGISのちょっとした話題提供

MapWinGISのちょっとした話題提供なんてお題ですが。。。

ここまで、いろいろとMapWInGIS.ocxをつかったGISプログラムのExample作成を行ってきました。 GISアプリケーションとしては、QGISがやはりOpen Source GISアプリケーションとしては頭一つ抜き出ているようですが、私のように標高データを使った土石流や河床変動数値計算を行うプログラムに組み込んで、プリポスト処理をするには、どうしても使いにくいのです。(そう考えているのは、知らないだけかも。。。)
確かにQGISは多数のOS上で動く非常に優れたGISアプリケーションであることには変わりないです。私もArcGISと併用して使っています。私自身がまだまだPythonの使い方を理解していない部分もありますが。。。
ClientのOSがほとんどWindowsであり、開発言語がVisual StudioでGUIを作成すると言う仕様の縛りもあるため、どうしてもMapWinGISを使うことが多くなります。
また、私自身が元々はFortran Programerなものでして、かつGISに関しては独学でありますので、いい加減な理解でしかないところもあります。

MapWinGISはversion 3.0くらいから注目していたのですが、そのころは、とても実用に耐えうるものではなかったように記憶しています。version 4.6、4.7から十分な機能と安定した動作ができるようになっています。
そして、現在は、Stable Releaseのversion 4.8.6となっています。MapWinGISのマニュアルについても使用例も含めてまとめられているので、非常に重宝してます。

MapWInGIS.ocxは、MapWindowのGIS Engineとして使われています。詳しくは、MapWindowのHPをご覧ください。
Tutorialでも書いていますが、MapWInGIS.ocxを単体でinstallしてGUIアプリケーションを作成することもできるのですが、いろいろと便利なdll類を使うためにMapwindowをinstallしてプログラムの作成をすることをお勧めします。

MapWindow、MapWinGISやSample codeもsvnで管理されているので、downloadして利用することができますし、私自身も利用しています。
参照先は、

をご覧ください。

MapWinGISを使った基本的なprogramについては、MapwingisのTutorialを見ていただくとして、ここではMapWindowのdllを使いながら、ちょいと便利かな???なProjectionViewerを作成してみます。

まずは、準備

開発環境は、Windows Xp SP3、Visual Studio 2010 Ultimateで行っていますが、Windows7 32bit 64bitでも大丈夫です。

MapWindowのinstall

まずは、MapWindow GIS v4.8.6 – Final release – 32Bitをdownloadしてきて、installします。
64bit版については、検証していませんので、注意してください。

MapWindowのinstall先はdefaultのfolderとして、以下説明します。

ocx,dllの登録

今回は、vb.netを使っていきます。visual studio起動後に、適当なprojectを作って下さい。Windows formアプリケーションを作成します。
一度、Debug modeでビルドして保存しておきます。

Map Controlの登録

今回は特に使わないのですが、MapWinGIS.ocxの登録を行います。

ツールボックス→アイテム選択→comコンポーネント→参照ボタンクリック→C:¥Program files¥MapWindow¥
からMapWinGIS.ocxを選択すると、ツールボックスにMap Controlが登録されます。

dllの登録

登録するdllは

  1. MapWinInterfaces.dll
  2. MapWindow.Controls.dll

の2つをMapWinGIS.ocxと同様にツールボックスに登録します。

まずは、アイテムの選択→.Net Framework コンポーネントのtab→参照ボタンをクリックして、MapWinInterfaces.dllを登録します。
MapWinInterfaces.dllの場所はC:¥Program Files¥MapWindowにあります。
MapWinInterfaces.dllを登録すると、名前がLegend、名前空間がLegendControlが下記のように表示されます。

blog.godo-tys.jp_wp-content_gallery_mapwingis_ex04_image02.jpg
MapWinInterfaces.dllの登録

またツールボックスには、Map Control とLegendが追加されているはずです。
blog.godo-tys.jp_wp-content_gallery_mapwingis_ex04_image03.jpg
MapWinGISタブに登録

続いて、MapWindow.Controls.dllMapWinInterfaces.dllと同じように登録します。
こんな感じで登録できます。
blog.godo-tys.jp_wp-content_gallery_foss4g_image01.jpg
MapWinControlタブに登録

6個のツールが登録されているはずです。
まずは、ここまで準備OKです。

Program Coding

まずは、From designをして、Codingします。

Form Design

Form designはこんな感じ、
blog.godo-tys.jp_wp-content_gallery_foss4g_image02.jpg
Projection Viewer Form Design

ProjectionMapのプロパティの変更
CursorMode → cmNone(Default mode)
SendMouseDown → True
SendMouseMove → True
SendMouseUp → false

ここで、mouse eventを利用するには、必ずSendMouse~~をtrueにしてください。falseではeventを捕まえることができません。

次に、ProjectionTreeViewも配置します。後は、TextBoxやもろもろを配置していきます。
ここいら辺は、最低限Visual studioの操作ができると言う前提で端折ってます。

Coding

それでは、Projection Viewer Form Designが配置できれば、codingを始めていきます。

frmProjection 作成時の処理

まずは、ImportsとPrivate宣言しておきます。

Imports System
Imports System.ComponentModel
Imports System.Windows.Forms
Imports System.IO
 
Imports MapWindow.Interfaces
Imports MapWindow.Controls
Imports MapWindow.Controls.Projections
 
'JGD2000 EPSG CODE
Private m_lastCode As Integer = 4612

次に、参照の追加で必要なdll類を追加しておきます。
追加元は、C:¥Program Files¥MapWindow¥内のdllを追加します。
追加すると、
blog.godo-tys.jp_wp-content_gallery_foss4g_image09.jpg
な感じになると思います。

frmProjection 作成時のSub New()のCodingは、

    Public Sub New()
        InitializeComponent()
 
        '実行時のFormの設定
        Me.Width = 800
        Me.Height = 600
 
        'Projections Folderの参照先
        Dim ProjectionPath As String = My.Application.Info.DirectoryPath & "Projections"
        'Dim ProjectionPath As String = "C:¥Program Files¥MapWindow¥Projections"
        If Not Directory.Exists(ProjectionPath) Then
            MessageBox.Show("EPSG Reference folderがありません: " & ProjectionPath & _
                            Environment.NewLine & "終了します...")
            Exit Sub
        End If
 
        '測地系、座標系のデータベース SQLite
        Dim files As String() = Directory.GetFiles(ProjectionPath, "*.db3")
        If files.Length <> 1 Then
            MessageBox.Show("座標系database db3ファイルが、" & _
                            files.Length.ToString() & " 見つかりました。" & _
                            Environment.NewLine & _
                            "Path : " & ProjectionPath & Environment.NewLine & _
                            "終了します...")
            Exit Sub
        Else
            Me.ProjectionTreeView1.Initialize(files(0), Nothing)
            Dim gcsCount As Integer, pcsCount As Integer
            Me.ProjectionTreeView1.RefreshList(gcsCount, pcsCount)
            lblGcsCount.Text = "Coordinate systems: " & gcsCount.ToString()
            lblPcsCount.Text = "Projections: " & pcsCount.ToString()
 
            ProjectionMap1.ShowRedrawTime = False
            ProjectionMap1.ShowVersionNumber = False
            ProjectionMap1.MapResizeBehavior = MapWinGIS.tkResizeBehavior.rbClassic
            ProjectionMap1.ZoomToMaxExtents()
        End If
 
        'ProjectionMapの初期化
        ProjectionMap1.LoadStateFromExeName(Application.ExecutablePath)
 
        '初期表示をJGD2000のEPSG:4612とする
        Dim list As IEnumerable(Of GeographicCS) = ProjectionTreeView1.CoordinateSystems.Where(Function(cs) cs.Code = m_lastCode)
        ProjectionTreeView1_CoordinateSystemSelected(DirectCast(list.First(), Territory))
        ProjectionMap1.CursorMode = MapWinGIS.tkCursorMode.cmNone
    End Sub

programの詳細については、commnetを見て下さい。
重要なことは、測地・座標系のDatabaseはSQLiteでProjections.db3となっています。またProjection Databaseの読み込みやTreeViewの表示などは、すべてMapWindow.Controls.Projections内のmethodとpropertyを設定するだけで使うことができます。
先人に感謝します。

上記のcodeだけでも使えますが、もうちょっと手を加えてみます。
ProjectionTreeViewの座標系を変更した時のeventを使ってProjectionMapも指定した座標系を表示するようにします。

    Private Sub ProjectionTreeView1_CoordinateSystemSelected(cs As MapWindow.Controls.Projections.Territory) Handles ProjectionTreeView1.CoordinateSystemSelected
        ProjectionMap1.DrawCoordinateSystem(cs)
        ProjectionMap1.ZoomToCoordinateSystem(cs)
 
        m_lastCode = cs.Code
        txtCode.Text = cs.Code.ToString()
        txtName.Text = cs.Name
        Dim coord As CoordinateSystem = TryCast(cs, CoordinateSystem)
        If coord IsNot Nothing Then
            txtRemarks.Text = If(coord.Remarks <> "", coord.Remarks, "No remarks")
            txtScope.Text = If(coord.Scope <> "", coord.Scope, "No description")
        End If
 
    End Sub

つぎに、ProjectionMapのCodingをします。
blog.godo-tys.jp_wp-content_gallery_foss4g_image10.jpg
の部分です。

    Private Sub ProjectionMap1_CoordinatesChanged(x As System.Double, y As System.Double, textX As System.String, textY As System.String) Handles ProjectionMap1.CoordinatesChanged
        lblX.Text = "Lon : " & textX    'Statusbar
        lblY.Text = "Lat : " & textY    'Statusbar
    End Sub
 
#Region "Mouse Event"
 
    Private Sub ToolNoneBtn_Click(sender As System.Object, e As System.EventArgs) Handles ToolNoneBtn.Click
        ProjectionMap1.CursorMode = MapWinGIS.tkCursorMode.cmNone
    End Sub
 
    Private Sub ToolFullExtentBtn_Click(sender As System.Object, e As System.EventArgs) Handles ToolFullExtentBtn.Click
        ProjectionMap1.ZoomToMaxExtents()
    End Sub
 
    Private Sub ToolZoominBtn_Click(sender As System.Object, e As System.EventArgs) Handles ToolZoominBtn.Click
        ProjectionMap1.CursorMode = MapWinGIS.tkCursorMode.cmZoomIn
    End Sub
 
    Private Sub ToolZoomoutBtn_Click(sender As System.Object, e As System.EventArgs) Handles ToolZoomoutBtn.Click
        ProjectionMap1.CursorMode = MapWinGIS.tkCursorMode.cmZoomOut
    End Sub
 
    Private Sub ToolPanBtn_Click(sender As System.Object, e As System.EventArgs) Handles ToolPanBtn.Click
        ProjectionMap1.CursorMode = MapWinGIS.tkCursorMode.cmPan
    End Sub
 
    Private Sub ToolZoomProjectionBtn_Click(sender As System.Object, e As System.EventArgs) Handles ToolZoomProjectionBtn.Click
        ProjectionMap1.ZoomToCoordinateSystem()
    End Sub
 
    Private Sub ToolPropertiesBtn_Click(sender As System.Object, e As System.EventArgs) Handles ToolPropertiesBtn.Click
        Dim code As Integer
        If Int32.TryParse(txtCode.Text, code) Then
            ProjectionTreeView1.ShowProjectionProperties(code)
        End If
    End Sub
#End Region

最後に、
blog.godo-tys.jp_wp-content_gallery_foss4g_image11.jpg
の部分をCodingします。

    Private Sub linkLabel1_LinkClicked(sender As System.Object, e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) Handles linkLabel1.LinkClicked
        Try
            Dim link As String = "http://spatialreference.org/ref/epsg/" + txtCode.Text & "/"
            System.Diagnostics.Process.Start(link)
        Catch ex As Exception
            MessageBox.Show("Linkが開けません。." & Environment.NewLine & ex.Message)
        End Try
    End Sub
 
    Private Sub txtCode_Validating(sender As Object, e As CancelEventArgs) Handles txtCode.Validating
        Me.ShowProjectionByCode()
    End Sub
 
    Private Sub txtCode_KeyPress(sender As Object, e As KeyPressEventArgs) Handles txtCode.KeyPress
        If e.KeyChar = CChar(ChrW(System.Windows.Forms.Keys.Return)) Then
            Me.ShowProjectionByCode()
        End If
    End Sub
 
    Private Sub ShowProjectionByCode()
        Dim val As Integer
        If Not Int32.TryParse(txtCode.Text, val) Then
            txtCode.Text = m_lastCode.ToString()
            val = m_lastCode
        End If
 
        If val = m_lastCode Then
            Return
        End If
 
        ' showing information on WGS 84
        Dim list As IEnumerable(Of GeographicCS) = ProjectionTreeView1.CoordinateSystems.Where(Function(cs) cs.Code = val)
        If list.Count() > 0 Then
            ProjectionTreeView1_CoordinateSystemSelected(DirectCast(list.First(), CoordinateSystem))
        Else
            Dim list2 As IEnumerable(Of ProjectedCS) = ProjectionTreeView1.Projections.Where(Function(cs) cs.Code = val)
            If list2.Count() > 0 Then
                ProjectionTreeView1_CoordinateSystemSelected(DirectCast(list2.First(), CoordinateSystem))
            Else
                txtCode.Text = m_lastCode.ToString()
                MessageBox.Show("座標系コードが見つかりません。EPSG CODE: " & val, "Projection Viewer", MessageBoxButtons.OK, MessageBoxIcon.Information)
            End If
        End If
    End Sub

txtCodeに直接EPSG CODEを書き込んで、Databaseを検索して、その結果を表示しています。
また、LinkLabelでspatialreference.orgのEPSG情報を表示します。

Program Codingはここまでです。
早速保存して、runしたいところですが、 ここで重要なfolderをcopyしておきます。
copy先は、このvisual studioのprojectを作ったfolderのBin¥Debug¥にcopyします。
copy元は、
blog.godo-tys.jp_wp-content_gallery_foss4g_image08.jpg
の赤枠のProjections folderです。

保存して実行してみましょう。

Programの実行

実行時の初期画面です。ProjectionTreeViewのJapanを展開しています。
blog.godo-tys.jp_wp-content_gallery_foss4g_image03.jpg
初期表示はJGD2000 EPSG 4612を表示しています。

次に、ProjectionTreeViewの移動をしてみましょう。
JapanのJDG2000平面直角座標IX系を選択します。
blog.godo-tys.jp_wp-content_gallery_foss4g_image04.jpg
ProjectionMapも同時に変更されます。

ProjectionMapのToolStripButtonのプロパティをクリックすると、Projection Properties DialognのDescription Tabが表示されます。
blog.godo-tys.jp_wp-content_gallery_foss4g_image05.jpg
JapanのJDG2000平面直角座標IX系の詳細情報が表示されます。

Area of use Tabを表示した場合、
blog.godo-tys.jp_wp-content_gallery_foss4g_image06.jpg
JapanのJDG2000平面直角座標IX系の詳細情報が表示されます。

ESRI WKT Tabを表示した場合、
blog.godo-tys.jp_wp-content_gallery_foss4g_image07.jpg
JapanのJDG2000平面直角座標IX系の詳細情報が表示されます。

いろいろと操作してみて下さい・。

最後に

MapWinGISのちょっとした話題提供として、MapWindowのdll類を使って、サクッとProjectionViewerを作成してみました。(「なんだよ、そんなの知っているよ」な方には申し訳ないですが。。。)
事前にdllで必要なMethodやPropertyが設定されているので、Codingは非常に少なくてすみます。
また、MapWindowをインストールすることで、LegendControl、MapWinGeoProcやMapUtilityのdllを使うことができますので、非常に強力なGISアプリケーションを作成することができます。そして、今回のProjectionViewerに手を加えてMapWinGeoProc.dllを使うようにすれば、測地・座標系変換も簡単にできます。
ただ、MapWinGISについては情報量も多いのですが、その他のdllについては情報が少ないのが難点です。でもSourceはあるので、なんとか解読していけますね。

今回は、vb.netd2010でしたが、C#でも、visual studio2008でも動作することができます。
簡単に自前のソフトウェアにちょっとしたGIS機能を付け加えるには良いと思います。その他のexampleについては、MapWinGISのTutorialを見て下さい。 まだ途中ですが。。。
参考として、source code sampleをアップしておきます。
ただし、あくまでの自分用のサンプルですので、バグなどがある可能性が高いので、原文のままの使用は避けてください。

サンプルコードを使って、お使いのPCの不具合が生じても一切責任は持てませんので、あくまでも自己責任にて使用してください。

MapWinGISよりも強力なDotSpatialを使えば、もっと簡単にもっとPower upしたGISアプリケーションを作成することができます。Pluginで機能追加していけば良いようですが、日本語の情報が全くないんですね。現状では、機能がてんこ盛りで使いこなすには時間がかかりそうです。
「だれかチャレンジしないかぁ?」と他力本願したとろで、本日のblogを終わります。

以 上

1 / 11

Social Widgets powered by AB-WebLog.com.