Daily Archives: 11/24/2012

属性テーブルの表示example [Chapter 7-2]

属性テーブルの表示example

今回は、shape fileの属性値をDataGridView controlに表示するexampleにdbf操作のメニューを付け加えていきます。
元になるprogramは、属性テーブルの表示example [Chapter 7-1]のex07に付け加えていきます。

Program Coding

ToolBarに
blog.godo-tys.jp_wp-content_gallery_mapwingis_ex072_image11.jpg
属性値テーブルを表示formに

  1. Fieldの追加
  2. Fieldの削除
  3. Field名の変更

を追加します。

Form design

Main Form

Main Formの変更・追加はありません。
属性テーブルの表示example [Chapter 7-1]そのまんまです。

Attribute View Form

Main Formから呼び出すAttribute View Form designはこんな感じ、

blog.godo-tys.jp_wp-content_gallery_mapwingis_ex072_image01.jpg
Attribute View Form

それぞれ、編集メニューで呼び出すFormを3つ作ります。

Fieldの追加 Form

Attribute View Formから呼び出すAdd Field Form designはこんな感じ、

blog.godo-tys.jp_wp-content_gallery_mapwingis_ex072_image02.jpg
Add Field Form

Fieldの削除 Form

Attribute View Formから呼び出すDelete Field Form designはこんな感じ、

blog.godo-tys.jp_wp-content_gallery_mapwingis_ex072_image03.jpg
Delete Field Form

Field名の変更 Form

Attribute View Formから呼び出すRename Field Form designはこんな感じ、

blog.godo-tys.jp_wp-content_gallery_mapwingis_ex072_image04.jpg
Rename Field Form

Coding

それでは、 Fieldの追加 Formからcodingを始めていきます。

Fieldの追加 Form

まずは、Add Field FormのCodeは、

Public Class frmAddField
 
    Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
        If ValidateForm() Then
            Me.DialogResult = System.Windows.Forms.DialogResult.OK
            Me.Hide()
        End If
    End Sub
 
    Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
        Me.DialogResult = System.Windows.Forms.DialogResult.Cancel
        Me.Hide()
    End Sub
 
    Private Sub cmbFieldType_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbFieldType.SelectedIndexChanged
        fldPrecision.Enabled = (cmbFieldType.Text = "Double")
        lblPrecision.Enabled = (cmbFieldType.Text = "Double")
    End Sub
 
    Private Function ValidateForm() As Boolean
        Dim retval As Boolean = True
        Dim err_msg As String = "Errors:" & vbCrLf & "-------"
 
        If txtFieldName.Text = String.Empty OrElse txtFieldName.Text.Length < 1 Then
            err_msg &= vbCrLf & "無効なフィールド名"
            retval = False
        End If
        If cmbFieldType.Text = "[Select one]" Then
            err_msg &= vbCrLf & "フィールドタイプの選択"
            retval = False
        End If
 
        If retval = False Then MsgBox(err_msg)
        Return retval
    End Function
 
End Class

ComboBoxとTextBoxに値設定してるだけです。
ここで、注意事項

  1. フィールド名の長さは、10byteまでです。(アルファベットと数字と記号)
  2. 記号は”_”だけに統一した方がベストです。
  3. 日本語のフィールド名は使わない。

です。

Fieldの削除 Form

まずは、Delete Field FormのCodeは、

Public Class frmDelField
 
    Public t_sf As New MapWinGIS.Shapefile
 
    Private Sub frmDelFeild_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        'Add any initialization
        Dim i As Integer
        btnOK.Enabled = False
        For i = 0 To t_sf.NumFields - 1
            clb.Items.Insert(i, t_sf.Field(i).Name)
        Next
    End Sub
 
 
    Private Sub cmbField_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
        btnOK.Enabled = True
    End Sub
 
 
    Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
        If Not clb.CheckedItems.Count = 0 Then
            If MsgBox("選択したフィールドを削除します." & _
                      Environment.NewLine & Environment.NewLine & _
                      "よろしいですか?",
                      MsgBoxStyle.Exclamation Or MsgBoxStyle.YesNo,
                      "フィールド削除確認") = MsgBoxResult.Yes Then
                Me.DialogResult = Windows.Forms.DialogResult.OK
                Me.Hide()
            Else
                Me.DialogResult = Windows.Forms.DialogResult.Cancel
            End If
        Else
            Me.DialogResult = Windows.Forms.DialogResult.Cancel
            Me.Hide()
        End If
    End Sub
 
 
    Private Sub clb_ItemCheck(ByVal sender As Object, ByVal e As System.Windows.Forms.ItemCheckEventArgs) Handles clb.ItemCheck
        btnOK.Enabled = (clb.SelectedItems.Count > 0)
    End Sub
 
End Class

cmbFieldに対象となるShape fileのField名を入れてます。
また、削除対象のField名をチェックすることで選択します。

Field名の変更 Form

まずは、Rename Field FormのCodeは、

Public Class frmRenField
 
    Public t_sf As New MapWinGIS.Shapefile
    Public CurrentIndex As Integer
    Public retval As Integer
 
    Private Sub frmRenField_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        'Add any initialization after the InitializeComponent() call
        Dim i As Integer
        btnOK.Enabled = False
        For i = 0 To t_sf.NumFields - 1
            cmbField.Items.Insert(i, t_sf.Field(i).Name)
            If i = CurrentIndex Then
                cmbField.Text = t_sf.Field(i).Name
                btnOK.Enabled = True
            End If
        Next
    End Sub
 
    Private Sub cmbField_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmbField.SelectedIndexChanged
        btnOK.Enabled = True
        retval = cmbField.SelectedIndex
    End Sub
 
    Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
        If ValidateNewName() Then
            'If mapwinutility.logger.msg("Warning! This will permanently rename this field. Do you wish to proceed?", MsgBoxStyle.Exclamation Or MsgBoxStyle.YesNo, "Confirm rename") = MsgBoxResult.Yes Then
            Me.DialogResult = Windows.Forms.DialogResult.OK
            'End If
        Else
            MsgBox("Please enter only letters, numbers or _ (underscore) characters for the new name, and ensure that the name you have entered has no more than 11 characters", "Attribute Table Editor")
            'txtNewName.Focus()
        End If
    End Sub
 
    Private Function ValidateNewName() As Boolean
        Dim c As Char
 
        For Each c In txtNewName.Text
            If (Not Char.IsLetterOrDigit(c) And c <> "_") OrElse txtNewName.Text.Length > 11 Then Return False
        Next
        Return True
    End Function
 
End Class

Form Load時にcmbFieldにShape fileのField名を入れてます。

Attribute View Formのcodeing

それでは、次にField追加、Field削除、Field名変更のそれぞれのButton eventを実装します。

フィールドの追加

フィールドの追加のbutton click event発生時のcodingは、

    Private Sub フィールド追加ToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles フィールド追加ToolStripMenuItem.Click
        Dim dlg As frmAddField
 
        'Table編集の開始
        t_sf.StartEditingTable()
 
        dlg = New frmAddField
        dlg.TopMost = True
 
        If dlg.ShowDialog(Me) = System.Windows.Forms.DialogResult.OK Then
 
            If dlg.txtFieldName.Text = String.Empty OrElse dlg.txtFieldName.Text.Length < 1 Then
                MsgBox("フィールド名を正しく入力してください.",
                       MsgBoxStyle.DefaultButton1,
                       "Error Field Name")
                Exit Sub
            End If
 
            'Fieldの追加
            CreateField(dlg.txtFieldName.Text,
                        dlg.cmbFieldType.Text,
                        dlg.fldPrecision.Value,
                        dlg.fldWidth.Value)
 
            RefreshGrid()
 
            '編集終了
            t_sf.StopEditingTable()
 
        End If
    End Sub

CreateField関数でdbfにfieldを追加します。
subroutine RefreshGrid()でdbfを再度読み込んで、DataGridViewを新しいDataTableに更新します。

このCreateField関数の中で、t_sf.StartEditingTable()で編集の開始をTureとし、t_sf.StopEditingTable()で編集の終了をtrueして、編集時にだけdbfファイルを操作できるようにしています。Field削除、Field名変更も同様になっています。

Function CreateFieldは、

    Private Function CreateField(ByVal fldName As String, ByVal fldType As String, ByVal fldPrec As Integer, ByVal fldWidth As Integer) As Integer
        Dim i As Integer
        For i = 0 To t_sf.NumFields - 1
            If fldName = t_sf.Field(i).Name Then
                ' This is a duplicate entry, not allowed!
                MsgBox("追加したフィールド : " & fldName & _
                       "はすでに存在します。",
                       MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                       "Error Field")
                Return -999
                Exit Function
            End If
        Next
 
        Dim fld As MapWinGIS.Field
        fld = New MapWinGIS.Field
        fld.Name = fldName
        Select Case fldType
            Case "Double"
                fld.Type = MapWinGIS.FieldType.DOUBLE_FIELD
                fld.Precision = fldPrec
            Case "Integer"
                fld.Type = MapWinGIS.FieldType.INTEGER_FIELD
                fld.Precision = 0
            Case "String"
                fld.Type = MapWinGIS.FieldType.STRING_FIELD
                fld.Precision = 0
            Case "Else"
                MsgBox("予期せぬエラーが発生!")
        End Select
        fld.Key = ""
        fld.Width = fldWidth
 
        ' Added If False:
        If (t_sf.EditInsertField(fld, i) = False) Then
            ' False was returned!  Something is preventing me from adding the field
            Dim msg As String = "フィールドが追加せきませんでした。"
            MsgBox(msg, MsgBoxStyle.Information Or MsgBoxStyle.OkOnly, "Error")
            MsgBox(msg & ": " & t_sf.ErrorMsg(t_sf.LastErrorCode))
            Return -999
            Exit Function
        End If
 
        Return i
    End Function

重複するfieldのチェックを行った後に、t_sf.EditInsertField(fld, i)でdbfに追加します。
もし、追加できなかった場合は、戻り値として-999が返ってきます。
ここでは、CreateFieldのerrorはしていません。各自追加してみてください。

フィールドの削除

フィールドの削除のbutton click event発生時のcodingは、

    Private Sub フィールド削除ToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles フィールド削除ToolStripMenuItem.Click
        Dim dlg As New frmDelField
        dlg.t_sf = t_sf
 
        If dlg.ShowDialog(Me) = System.Windows.Forms.DialogResult.OK Then
            'Check for existing name
 
            'Table編集の開始
            t_sf.StartEditingTable()
 
 
            '削除処理をここに書く
 
 
            RefreshGrid()
 
            '編集終了
            t_sf.StopEditingTable()
        End If
 
    End Sub

この処理は各自付け加えて、Exerciseとして挑戦してください。

フィールド名の変更

フィールド名の変更のbutton click event発生時のcodingは、

    Private Sub フィールド名変更ToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles フィールド名変更ToolStripMenuItem.Click
        Dim dlg As New frmRenField
        dlg.t_sf = t_sf
        If DataGridView1.CurrentCell.ColumnIndex > 0 Then
            dlg.CurrentIndex = DataGridView1.CurrentCell.ColumnIndex - 1
        Else
            dlg.CurrentIndex = 0
        End If
 
        If dlg.ShowDialog(Me) = System.Windows.Forms.DialogResult.OK Then
            'Check for existing name - CDM for bugzilla 136
            For i As Integer = 0 To t_sf.NumFields - 1
                If t_sf.Field(i).Name.ToLower() = dlg.txtNewName.Text.ToLower() Then
                    MsgBox("フィールド名 : '" & dlg.txtNewName.Text & _
                           "' はすでに存在しています。フィールド名を変更してください。" & vbCrLf & _
                           "(Rename aborted)",
                           MsgBoxStyle.Exclamation, "Field Already Exists")
                    Exit Sub
                End If
            Next
 
            'Table編集の開始
            t_sf.StartEditingTable()
 
            'Rename
            t_sf.Field(dlg.retval).Name = dlg.txtNewName.Text
 
            RefreshGrid()
 
            '編集終了
            t_sf.StopEditingTable()
        End If
    End Sub

t_sf.Field(dlg.retval).Name = dlg.txtNewName.Textの部分がフィールド名の変更になります。

Programの実行

では、ex072を保存して実行してみましょう。

今回は、神奈川県のサンプルc14_regionDD.shpを読み込んだ後、属性値テーブル表示buttonをクリックして、属性値テーブル表示formを表示させます。
blog.godo-tys.jp_wp-content_gallery_mapwingis_ex072_image13.jpg
属性値テーブル表示画面

属性値テーブル表示の編集メニューのフィールド追加をclickします。
blog.godo-tys.jp_wp-content_gallery_mapwingis_ex072_image05.jpg
フィールド追加表示

フィールド追加を”test”を追加した状態
blog.godo-tys.jp_wp-content_gallery_mapwingis_ex072_image06.jpg
フィールド追加

属性値テーブル表示の編集メニューのフィールド名の変更をclickします。
blog.godo-tys.jp_wp-content_gallery_mapwingis_ex072_image07.jpg
フィールド名の変更表示

フィールド名のを”test”から”check”に変更した状態
blog.godo-tys.jp_wp-content_gallery_mapwingis_ex072_image08.jpg
フィールド名の変更後表示

属性値テーブル表示の編集メニューのフィールド削除をclickした時、field名がすべて表示されます。
blog.godo-tys.jp_wp-content_gallery_mapwingis_ex072_image09.jpg
フィールド削除初期画面表示

削除するfield名をチェックした時
blog.godo-tys.jp_wp-content_gallery_mapwingis_ex072_image10.jpg
フィールド削除選択後表示

削除後は、各自挑戦してくださいね。

今回のまとめ

では、今回のまとめを

  1. 別Formを作成して、属性値のテーブル編集の実装を行いました。
  2. フィールド追加、フィールド名変更、フィールド削除(半分ですが。)の実装を行いました。
  3. dbfの編集は、StartEditingTable()で始まり、StopEditingTable()で終わる。

次回[Chapter 7-3]では、メニューの属性検索をの実装を行い、検索・抽出の基本操作をやってみたいと考えています。
こんな感じの属性検索form
blog.godo-tys.jp_wp-content_gallery_mapwingis_ex072_image12.jpg
属性検索form例

vb.net2010だけでなく、C#でも、visual studio2008でも動作することができます。
簡単に自前のソフトウェアにちょっとしたGIS機能を付け加えるには良いと思います。
ex072のsource codeを公開しますので、活用してください。
ただし、あくまでの自分用のサンプルですので、バグなどがある可能性が高いので、原文のままの使用は避けてください。

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

Exercise

今回のProgramを少し発展させて以下の項目を付け加えてみてください。

  1. フィールド削除のcodeを追加する。
  2. DataGridViewでdbfの値を変更した場合、その変更を上書き保存するcodeを追加する。

1 / 11

Social Widgets powered by AB-WebLog.com.