14.4. 属性テーブルの操作

属性テーブルは選択されたレイヤの地物の情報を表示します。各行は(ジオメトリを持つ持たないに関わらず)1つの地物を表し、各列はその地物のある特定の情報を持っています。属性テーブルの地物は検索、選択、移動および編集が可能です。

14.4.1. 序文: 空間情報のあるテーブル、空間情報のないテーブル

QGISでは、空間情報を持つレイヤも、持たないレイヤも読み込むことができます。現状では、OGR、区切りテキストや、PostgreSQL、MSSQL、SpatiaLite、DB2、Oracleプロバイダがサポートされています。読み込まれた全てのレイヤは レイヤ パネルにリストされます。レイヤの空間情報が定義されているか否かによって、マップ上で操作できるか否かが決まります。

空間情報を持たないテーブルは、属性テーブルビューを使用して閲覧や編集ができます。さらに、これをフィールドの参照値に使用することも可能です。例えば、空間情報を持たないテーブルの列を使用して、編集モード中の特定のベクタレイヤに追加される属性値に許容される値や範囲を定義することができます。詳しくは、 属性フォームプロパティ セクションの編集ウィジェットを参考にしてください。

14.4.2. 属性テーブルのインターフェイスの紹介

ベクタレイヤの属性テーブルを開くには、 レイヤパネル 内でレイヤをクリックしてアクティブにします。次に、メインメニューの レイヤ メニューから、 openTable 属性テーブルを開く を選択します。レイヤを右クリックして、メニューから openTable 属性テーブルを開く を選択するか、属性ツールバーの openTable 属性テーブルを開く ボタンをクリックしても開くことができます。ショートカットキーがお好みなら、 F6 を押すと属性テーブルが開きます。 Shift+F6 は、選択した地物でフィルタリングされた属性テーブルを開き、 Ctrl+F6 は表示されている地物のみでフィルタリングされた属性テーブルを開きます。

これにより、レイヤの地物属性を表示するウィンドウが開きます( figure_attributes_table )。 設定 ► オプション ► データソース メニューの設定により、属性テーブルはドックウィンドウとして開くか、または通常のウィンドウで開きます。レイヤ内の地物数の合計や、選択中の地物数、フィルタリングされた地物数が属性テーブルのタイトルに表示されます。また、レイヤが空間的に制限されているかどうかも表示します。

../../../_images/vectorAttributeTable.png

図 14.68 地域レイヤの属性テーブル

属性テーブルウィンドウの上部にあるボタンには以下の機能があります。

表 14.1 利用可能なツール

アイコン

ラベル

目的

デフォルトのショートカット

toggleEditing

編集モード切替

編集機能を有効にする

Ctrl+E

multiEdit

マルチエディットモード切替

多くの地物の複数のフィールドを更新する

saveEdits

編集内容の保存

現在の修正を保存する

refresh

テーブルを再読み込み

newTableRow

地物追加

ジオメトリを持っていない地物を新規追加します

deleteSelectedFeatures

選択地物の削除

選択された地物をレイヤから削除します

editCut

選択行を切り取ってクリップボードへ

Ctrl+X

copySelected

選択している行をクリップボードへコピーする

Ctrl+C

editPaste

クリップボードから地物を貼り付ける

コピーされた地物を新規地物として挿入します

Ctrl+V

expressionSelect

式による地物選択

selectAll

すべて選択

レイヤ内のすべての地物を選択します

Ctrl+A

invertSelection

選択部分を反転する

レイヤ内の現在の選択状態を反転します

Ctrl+R

deselectActiveLayer

レイヤ内の全地物を選択解除

現在のレイヤ内のすべての地物の選択を解除します

Ctrl+Shift+A

filterMap

フォームによる地物選択/フィルタ

Ctrl+F

selectedToTop

選択を一番上に

選択した行をテーブルの先頭行に移動します

panToSelected

選択した行の地物にパン

Ctrl+P

zoomToSelected

選択した行の地物にズームする

Ctrl+J

newAttribute

新規フィールド

データソースに新しいフィールドを追加します

Ctrl+W

deleteAttribute

フィールド削除

データソースからフィールドを削除します

calculateField

フィールド計算機を開く

多数の地物のフィールドを連続的に更新します

Ctrl+I

conditionalFormatting

条件付き書式

表の書式設定を有効にします

dock

属性テーブルをドッキング

属性テーブルをウィンドウにドッキング/ドッキング解除します

actionRun

アクション

レイヤに関連したアクションをリストします

注釈

データ形式やご使用のQGISバージョンでビルドされたOGRライブラリによっては、一部のツールが利用できない場合があります。

これらのボタンの下には、クイックフィールド計算バー( 編集モード でのみ有効)があり、レイヤ内の地物のすべてまたは一部に計算結果を素早く適用できます。このバーは calculateField フィールド計算機 と同様の を使用します( 属性値の編集 参照)。

14.4.2.1. テーブル表示 vs フォーム表示

QGISは属性テーブル内のデータを簡単に操作するための2つの表示モードが用意されています。

  • openTable テーブル表示 は、複数の地物の値を表形式で表示します。各行は1つの地物を、各列はフィールドを表しています。

  • formView フォーム表示 は、最初のパネルに 地物の表示名 が表示され、クリックした表示名の属性のみを2つ目のパネルに表示します。最初のパネルの上部には、属性( カラムプレビュー )や を使用して「表示名」を指定することができるプルダウンメニューがあります。このプルダウンメニューには、再利用のために最後に使用した10個の式も含まれています。フォーム表示はレイヤのフィールドの設定( 属性フォームプロパティ 参照)を使用します。最初のパネルの下部にある矢印ボタンを使用して、地物識別子の順番にブラウズできます。リスト内で黄色でマーカーを付けた地物は、キャンバス上で選択されて黄色で表示されます。属性テーブルの上部にある zoomToSelected を使用すると、選択した地物にズームすることができます。リスト内でエントリ(の四角でない場所)をクリックすると地物が赤色で点滅し、その地物がどこにあるのか確認できます。

あるモードから他方のモードへの切り替えは、ダイアログの右下にある対応するアイコンをクリックすることによって行えます。

設定 ► オプション ► データソース メニューで、属性テーブルのオープン時の デフォルトビュー モードを指定することもできます。 「直前の表示形式」、「テーブル表示」または「フォーム表示」にすることができます。

../../../_images/attribute_table_views.png

図 14.69 属性テーブルのテーブル表示(上)とフォーム表示(下)

14.4.2.2. 列の設定

テーブル表示の場合に列見出しを右クリックすると、属性テーブルで何をどのように表示するかを設定するためのツールにアクセスできます。

列の非表示・整理とアクションの有効化

列見出しを右クリックすると、列を属性テーブルから隠すかどうかを選択できます。列の非表示の解除や順序の変更といった、列の動作変更を一度にするには、 列の整理... を選択します。このダイアログでは、以下のことができます:

  • チェックして列を表示 / チェックを外して列を非表示にできます

  • アイテムをドラッグ&ドロップして、属性テーブル内の列の順序が変更できます。この変更はテーブルの表示のためのものであり、レイヤのデータソースのフィールドの順序は変更されないことに注意してください。

  • 新しい仮想の アクション 列を有効にして、各行にドロップダウンボックスやボタンのリストを表示できます。アクションについての詳細は アクションプロパティ を参照してください。

列の幅の修正

列の幅は、列見出しを右クリックして、次のいずれかを選択することで設定できます:

  • 幅の設定... 希望する幅の値を入力します。デフォルトでは、現在の値がウィジェットに表示されます

  • 自動サイズ は、列に合わせて最適なサイズに変更します。

また、列見出しの右側の境界をドラッグしても列幅を変更できます。新しい列サイズはレイヤに保持され、次に属性テーブルを開いたときに復元されます。

列による並べ替え

テーブルは列見出しをクリックすることで任意の列でソートできます。小さな矢印はソート順を示しています(下向きは先頭行から値を降順で、上向きは先頭行から値を昇順で並べることを意味します)。列見出しのコンテキストメニューの 並べ替え オプションを使用して式を書くことでも行を並べ替えることができます。例えば、複数の列を使用して行を並べ替えるには concat(col0, col1) と書きます。

フォーム表示では、地物識別子は sort プレビュー式で並べ替え オプションを使用してソートできます。

ちなみに

異なる型の列に基づいた並べ替え

文字列型の列と数値型の列に基づいて属性テーブルを並べ替えようとすると、予期しない結果となることがあります。これは、式 concat("USE", "ID") が文字列値を返す(つまり 'Borough105' < 'Borough6' である)ために起こります。この問題を回避するには、例えば、 concat("USE", lpad("ID", 3, 0)) とすると、 'Borough105' > 'Borough006' を返します。

14.4.2.3. 条件式を使ったテーブルセルの書式設定

以下に基づいたカスタム条件式による条件付き書式設定を使用して、属性テーブル内で特に注目したい地物を強調表示させることができます。

  • ジオメトリ(例:マルチパート地物、面積が小さい地物、定義された地図範囲内にある地物などを識別する)

  • フィールド値(例:しきい値との比較や、空のセルを区別するなど)

テーブル表示の属性ウィンドウの右上にある conditionalFormatting をクリックして、条件付き書式パネルを有効にできます(フォーム表示では使用できません)。

この新しいパネルでは、 radioButtonOnフィールド または radioButtonOff行全体 の書式レンダリングに新ルールを追加することができます。新ルールを追加すると、以下のものを定義するためのフォームが開きます:

  • ルールの名前

  • 何らかの 式ビルダー 関数を使用した条件式

  • 書式設定:プリセット書式のリストから選択するか、以下のプロパティに基づいて作成できます。

    • 背景色とテキスト色

    • アイコンを使用するかどうか

    • 太字、イタリック、下線、取り消し線

    • フォント

../../../_images/attribute_table_conditional_formating.png

図 14.70 属性テーブルの条件付き書式

14.4.3. 属性テーブルの地物とのやりとり

14.4.3.1. 地物の選択

テーブル表示では、属性テーブルの各行はレイヤ内の個別地物の属性を表します。ある行を選択するとその地物が選択され、同様に、(ジオメトリのあるレイヤの場合は)マップキャンバスで地物を選択すると属性テーブル内の行が選択されます。マップキャンバス(または属性テーブル)で選択された地物の組み合わせが変更された場合、それに応じて属性テーブル(またはマップキャンバス)の選択が更新されます。

行の左端にある行番号をクリックすることで、行を選択することができます。 Ctrl キーを押しながらクリックすると、 複数の行 をマークすることができます。 Shift キーを押しながら行の左側にある複数の行ヘッダをクリックすると、 連続選択 ができます。現在のカーソル位置とクリックした行の間のすべての行が選択されます。属性テーブルのセルをクリックしてカーソル位置を移動しても、行の選択は変わりません。また、メインキャンバス内で選択を変更しても、属性テーブルのカーソル位置は移動しません。

属性テーブルのフォーム表示では、地物はデフォルトで左側パネル内において表示フィールド( 表示名プロパティ 参照)の値によって識別されています。この識別子はパネルの上部にあるドロップダウンリストを使用して、既存のフィールドを選択するか、カスタム式を使用して置き換えることができます。また、ドロップダウンメニューから地物フォームのリストをソートすることもできます。

左側のパネルで値をクリックすると、右側のパネルにその地物の属性が表示されます。地物を選択するには、識別子の左にある四角いシンボルの中をクリックします。デフォルトでは、シンボルが黄色に変わります。テーブル表示と同様、これまでに紹介したキーボードの組み合わせで複数の地物を選択することができます。

マウスで地物を選択するだけでなく、属性テーブルのツールバーにある以下のようなツールを使用して、地物の属性に基づいた自動選択を行うことができます(詳細や使用例については、 自動選択 および次のセクションを参照):

  • expressionSelect 式による地物選択...

  • formSelect 値による地物選択...

  • deselectActiveLayer レイヤ内の全地物を選択解除

  • selectAll すべて選択

  • invertSelection 選択部分を反転する

フォームによるフィルタと地物選択 を使って地物を選択することもできます。

14.4.3.2. 地物のフィルタリング

属性テーブルで地物を選択したら、テーブルにこれらのレコードのみを表示したい場合があります。これは、属性テーブルダイアログの左下にあるドロップダウンリストから 選択した地物を表示 アイテムを使用すると簡単にできます。このリストには、次のようなフィルタがあります:

  • 全地物を表示

  • 選択した地物を表示

  • 地図上に表示されている地物を表示

  • 編集された地物と新しい地物を表示

  • 属性フィルタ ― ユーザーがフィールドの値に基づいてフィルタリングできるようになります:リストからカラムを選択し、値を入力して Enter を押すと、フィルタリングを行います。すると、フィルタに一致する地物のみが属性テーブルに表示されます。

  • 詳細フィルタ(式) ー 式ビルダーダイアログを開きます。ここでは、テーブルの行にマッチさせるための 複雑な式 を作成することができます。例えば、複数のフィールドを使用してテーブルをフィルタできます。OKボタンを押すと、そのフィルタ式がフォームの下部に表示されます。

これらは フォームによる地物フィルタ でも利用可能です。

注釈

属性テーブルからレコードをフィルタリングしても、レイヤから地物がフィルタリングされるわけではありません。地物はテーブルから一時的に非表示になるだけで、マップキャンバスからはアクセスでき、フィルタを取り除いてもアクセスすることができます。フィルタでレイヤから地物を実際に隠すには、 クエリビルダ を使用してください。

ちなみに

地図上に表示されている地物を表示 によるデータソースフィルタリングの更新

パフォーマンス上の理由で、属性テーブルに表示される地物がテーブルを開いたときのキャンバス範囲に空間的に制限されている場合(設定方法は データソースオプション を参照)、新しいキャンバス範囲で 地図に表示されている地物を表示 を選択すると、空間的な制限が更新されます。

14.4.3.3. フォームによるフィルタと地物選択

filterMap フォームによる地物選択/フィルタ をクリックするか、または Ctrl+F を押すと、属性テーブルダイアログをフォーム表示に切り替え、各ウィジェットが検索変数に置き換わります。

ここで説明するこのツールの機能は、 値による地物選択 で説明されているものと同様です。そちらには、すべての演算子と選択モードについての説明があります。

../../../_images/tableFilteredForm.png

図 14.71 フィルタフォームでフィルタされた属性テーブル

属性テーブルから地物を選択/フィルタする際には、フィルタを定義したり、絞り込んだりできる 地物をフィルタする ボタンがあります。このボタンを押すと 詳細フィルタ(式) オプションがトリガーされ、対応したフィルタ式がフォームの下部にある編集可能なテキストウィジェットに表示されます。

すでにフィルタされた地物がある場合は、 地物をフィルタする ボタンの隣にあるドロップダウンリストを使用してフィルタを絞り込むことができます。オプションは次のとおりです。

  • フィルタの絞り込み ("AND")

  • フィルタを拡げる ("OR")

フィルタを削除するには、左下のプルダウンメニューから 全地物を表示 オプションを選択するか、または式をクリアして 適用 ボタンをクリックするか Enter キーを押します。

14.4.4. 地物に関するアクション

ユーザーはコンテキストメニューを使用していくつかの地物操作が可能です:

  • 地物を すべて選択するCtrl+A

  • セルの内容をコピーする で、セルの内容をクリップボードにコピーする

  • 地物を選択することなく 地物にズーム

  • 地物を選択することなく 地物にパン

  • 地物をフラッシュ で、マップキャンバス内で強調表示

  • フォームを開く :そのクリックされた地物にフォーカスした状態で、属性テーブルをフォーム表示に切り替えます

../../../_images/copyCellContent.png

図 14.72 「セルの内容をコピーする」ボタン

属性データを外部プログラム(Excel、LibreOffice、QGIS、カスタムWebアプリケーションなど)で使用したい場合には、1つまたは複数の行を選択して copySelected 選択している行をクリップボードへコピーする ボタンを押すか、 Ctrl+C を押します。

設定 ► オプション ► データソース メニューでは、 地物のコピー ドロップダウンリストで貼り付け形式を指定できます:

  • プレーンテキスト(ジオメトリなし)

  • プレーンテキスト(WKTジオメトリ)

  • GeoJSON

このコンテキストメニューでアクションのリストを表示することもできます。これは レイヤプロパティ ► アクション タブから有効にできます。アクションの詳細については アクションプロパティ を参照してください。

14.4.4.1. 選択地物を新規レイヤとして保存する

選択した地物はOGRでサポートする任意のベクタ形式として保存することができ、また別の座標参照系(CRS)に変換することもできます。 レイヤ パネルのレイヤのコンテキストメニューから エクスポート ► 選択地物の保存... をクリックすると、出力データセットの名前や形式、CRSを定義し保存します( 既存のレイヤから新しいレイヤを作成する のセクションを参照)。 checkbox 選択地物のみ保存する にチェックが入っているのがわかります。また、ダイアログ内でOGR作成オプションを指定することもできます。

14.4.5. 属性値の編集

属性値の編集は以下の方法で行うことができます。

  • 新しい値をセルに直接入力します。属性テーブルがテーブル表示でもフォーム表示でも可能です。従って、変更はセルごと、地物ごとに行われます。

  • フィールド計算機 を使用して、あるフィールド列全体に対して連続して更新を行います。フィールドは既存のものでも、新しく作られたものでもよいですが、更新は複数の地物に対して行われます。これは仮想フィールドを作るためにも使用することができます。

  • クイックフィールド 計算バー を使用します。上と同じですが既存のフィールドに対してのみ使用できます。

  • マルチエディット モードを使用します。複数の地物の複数のフィールドを連続して更新します。

14.4.5.1. フィールド計算機を使用する

属性テーブルの calculateField フィールド計算機 ボタンを使うと、既存の属性値もしくは定義された関数に基づいて計算を行うことができます。例えば、ジオメトリ地物の長さや面積の計算ができます。計算結果は既存のフィールドの更新や、新しいフィールド(これは 仮想 フィールドも可)への書き込みに使うことができます。

フィールド計算機 は編集をサポートするすべてのレイヤで利用可能です。フィールド計算機のアイコンをクリックすると、ダイアログを開きます( 図 14.73 参照)。レイヤが編集モードでない場合には警告が表示され、フィールド計算機を使用すると、計算が行われる前にレイヤが編集モードに変わります。

式ビルダー ダイアログをベースにしたフィールド計算機ダイアログは、式を定義し、それを既存のもしくは新規作成フィールドに適用するための完璧なインターフェイスを提供します。フィールド計算機ダイアログを使うには、以下について選択する必要があります:

  1. レイヤの全体に計算を適用したいのか、それとも選択した地物のみに適用したいのか

  2. 計算によって新しいフィールドを作りたいのか、それとも既存のフィールドを更新したいのか

../../../_images/fieldcalculator.png

図 14.73 フィールド計算機

新しいフィールドを作ることを選んだ場合には、フィールドの名前やフィールド型(整数値、小数点付き数値、日付、テキストなど)を入力する必要があり、必要ならばフィールド長や精度も入力します。例えば、フィールド長が10で精度を3とすると、これは小数点より前に7桁あり、小数部が3桁の数値ということになります。

タブを使用している場合のフィールド計算機の動作を簡単な例で説明します。QGISサンプルデータセットから、 railroads レイヤの長さを km 単位で計算したいとします:

  1. QGISでシェープファイル railroads.shp をロードし、 openTable 属性テーブルを開く 押します。

  2. toggleEditing 編集モード切替 をクリックし、 calculateField フィールド計算機 ダイアログを開きます。

  3. checkbox 新しいフィールドを作成 チェックボックスを選択し、新しいフィールドに計算を保存するようにします。

  4. 出力する属性(フィールド)の名前length_km に設定します。

  5. フィールド型 として 小数点付き数値(real) を選択します。

  6. フィールド長10 に、 精度3 に設定します。

  7. ジオメトリ グループ内の $length をダブルクリックし、フィールド計算機の式ボックスにジオメトリの長さを入力します。

  8. フィールド計算機の式ボックスで / 1000 を入力して式を完成させ、 OK をクリックします。

  9. これで、属性テーブルに新しい length_km フィールドが出来ました。

14.4.5.2. 仮想フィールドの作成

仮想フィールドとは、オンザフライで計算される式に基づいたフィールドのことです。式の基礎となるパラメータが変更されると値が自動的に更新されます。式の設定は一度だけでよく、基礎となる値が変更されるたびにフィールドの再計算を行う必要はありません。例えば、地物をデジタイジングするたびに面積を評価する場合や、変更の可能性がある(例: now() 関数を使用する)日付間の期間を自動的に計算する場合などで、仮想フィールドを使用するのが良いでしょう。

注釈

仮想フィールドの使用

  • 仮想フィールドはレイヤの属性として永続的ではありません。つまり、仮想フィールドを作成したプロジェクトファイル内にのみ保存され、そこでのみ利用可能です。

  • フィールドは作成時にのみ、仮想フィールドに設定することができます。仮想フィールドは、レイヤプロパティダイアログのフィールドタブに紫色の背景で表示され、通常の物理フィールドや結合されたフィールドとは区別できるようになっています。仮想フィールドの式は、「コメント」列の式ボタンを押すことで、後で編集することができます。ボタンを押すと式エディタウィンドウが開き、仮想フィールドの式の修正ができます。

14.4.5.3. クイックフィールド計算バーを使用する

フィールド計算機がいつでも利用可能なのに対して、属性テーブルの上部にあるクイックフィールド計算バーは、レイヤが編集モードにある場合にのみ表示されます。式エンジンのおかげで、クイックフィールド計算バーを使えば既存のフィールドの編集がより素早くできるようになります。

  1. ドロップダウンリストから更新したいフィールドを選択します。

  2. テキストボックスに直接書くか、 expression 式ボタンを使用して値や式を入力します。

  3. 必要に応じて、 すべて更新選択を更新 、または フィルタされたものを更新 ボタンをクリックします。

../../../_images/fieldcalculatorbar.png

図 14.74 クイックフィールド計算バー

14.4.5.4. 複数のフィールドの編集

これまでのツールとは異なり、マルチエディットモードでは、さまざまな地物の複数の属性を同時に編集できます。レイヤを編集モード切り替えて、以下の操作によりマルチエディット機能にアクセスできます。

  • 属性テーブルダイアログ内のツールバーの multiEdit マルチエディットモード切替 ボタンを押す

  • または、 編集 ► multiEdit 選択地物の属性変更 メニューを選択する

注釈

属性テーブルのツールとは異なり、 編集 ► 選択地物の属性変更 オプションを選択すると現れる、変更する属性値を入力するためのダイアログはモーダルなダイアログです。したがって、実行前に地物の選択が必要です。

複数のフィールドを一度に編集するには:

  1. 編集したい地物を選択します。

  2. 属性テーブルツールバーから multiEdit をクリックします。これによりダイアログがフォーム表示に切り替わります。地物の選択はこの段階でも行うことができます。

  3. 属性テーブルの右側には、選択した地物のフィールド(と値)が表示されています。新しいウィジェットが各フィールドの横に表示され、現在のマルチエディット状態を表示します。

    • multiEditMixedValues 選択した地物はフィールドに異なる値を有しています。値は空で表示され、各地物は元の値を持っています。ウィジェットのドロップダウンリストから、フィールドの値をリセットすることができます。

    • multiEditSameValues 選択した地物は全てフィールドに同じ値を持っており、フォームに表示される値を保持します。

    • multiEditChangedValues フィールドの値が編集され、入力した値を選択した地物すべてに適用しようとする状態です。ダイアログの上部には、変更を適用するか、リセットするかを案内するメッセージが表示されます

    これらのウィジェットのいずれかをクリックすると、フィールドの現在の値を設定するか、元の値にリセットできます。つまり、フィールド単位で変更をロールバックできます。

    ../../../_images/attribute_multiedit.png

    図 14.75 複数地物のフィールドの編集

  4. 変更したいフィールドを編集します。

  5. 上部のメッセージ内の 変更の適用 をクリックするか、または左側パネルの別の地物をクリックします。

選択した地物すべて に変更が適用されます。地物が選択されていない場合、テーブル全体が変更内容で更新されます。変更は単一の編集コマンドとして行われます。したがって、undo 元に戻す を押すと、選択したすべての地物の属性変更を一度にロールバックします。

注釈

複数編集モードは「自動生成」または「ドラッグ&ドロップ」のフォームでのみ利用可能です( データに合わせてフォームをカスタマイズする 参照)。カスタムUIフォームではサポートされていません。

14.4.6. 1対多または多対多のリレーションの作成

「リレーション」は、データベースでよく使用される技術です。その概念は、異なるレイヤ(テーブル)の地物(行)がお互いに属することができるというものです。

14.4.6.1. 1対Nリレーションの導入

例として、アラスカのすべての地域(ポリゴン)を有するレイヤがあり、名前、領域タイプ、(主キーとして機能する)ユニークなIDといった属性を持っているとします。

それから、地域にある空港の情報を持った別のポイントレイヤまたはテーブルがあり、これらの情報も把握したいとします。ほとんどの地域には複数の空港があるため、これらを地域レイヤに追加する場合は、外部キーを使って1対多のリレーションを作成する必要があります。

../../../_images/relations1.png

図 14.76 空港とアラスカの地域

1対Nリレーションのレイヤ

QGISでは、テーブルとベクタレイヤの間に違いはありません。基本的には、ベクタレイヤとはジオメトリを持っているテーブルのことです。このため、テーブルはベクタレイヤとして追加することができます。 1対Nリレーションのデモンストレーションとして、 regions シェープファイルと、regionsレイヤへの外部キーフィールド( fk_region )を持つ airports シェープファイルを読み込んでみましょう。これは、各空港はそれぞれただ1つの地域に属し、各地域は空港をいくつでも持つことができることを意味します(典型的な1対多関係です)。

1対Nリレーションの外部キー

空港属性テーブルの既存の属性に加えて、外部キーとして動作する別のフィールド fk_region が必要です(データベースを持っている場合には、このフィールドに制約を定義することになるでしょう)。

このフィールド fk_region には、必ず地域のIDが入ります。これは、空港が属する地域へのポインタのように見ることができます。また、編集用のカスタム編集フォームを設計でき、QGISはその設定についての処理をします。これはさまざまなプロバイダに対応しており(シェープファイルやCSVファイルも使用可)、しなければならないのは、QGISにテーブル間の関係を伝えることだけです。

1対Nリレーションの定義

まず最初に行うのは、レイヤ間の関係をQGISに知らせることです。これは、 プロジェクト ► プロパティ... で行います。 リレーション タブを開き、 signPlus リレーションを追加 をクリックします。

  • 名前 はタイトルとして使用されます。これはわかりやすい文字列で、リレーションが何のために用いられるのかを説明するものであるべきです。ここでは、単に airport_relation と名前を付けましょう。

  • 被参照レイヤ(親) 親レイヤとも呼ばれ、プライマリキーを持っており、参照されるレイヤです。この例では、 regions レイヤです。参照レイヤのプライマリキーを定義する必要があり、ここでは ID を指定します。

  • 参照元レイヤ(子) 子レイヤとも呼ばれ、外部キーフィールドを持ったレイヤです。この例では、 airports レイヤが該当します。参照元レイヤには他のレイヤを指す参照フィールドを指定する必要があり、ここでは fk_region とします。

    注釈

    場合によっては、レイヤ内の地物を一意に識別するためには複数のフィールドが必要となることがあります。このようなレイヤとのリレーションを作成するためには、 複合キー 、すなわち、一致するフィールドの複数ペアが必要です。 signPlus 複合外部キーとしてペアのフィールドを追加 ボタンを使用して、必要な数のペアを追加できます。

  • Id は内部的な目的で使用され、ユニークでなければなりません。これは カスタムフォーム を作成するために必要となる場合があります。空のままにしておくと自動でIdを作成しますが、扱いやすいように自分でIdを指定することもできます。

  • リレーションの強度 は、親子レイヤ間のリレーションの強さを設定します。デフォルトの Association タイプは、親レイヤが子レイヤに 単に リンクされていることを意味します。一方、 コンポジション タイプは、親レイヤを複製するときに子レイヤも複製されます。

../../../_images/relations2.png

図 14.77 regionsレイヤとairportsレイヤ間のリレーションの追加

リレーション タブでは、 signPlus リレーションを検索 ボタンを押して、読み込んだレイヤの利用可能なリレーションをプロバイダから取得することもできます。この機能はPostgreSQLやSpatiaLiteといったデータプロバイダに保存されたレイヤで使用可能です。

1対Nリレーションのフォーム

これで、QGISはリレーションを把握できました。これはQGISが生成するフォームを改善するために利用されます。デフォルトのフォームのメソッド(自動生成)を変更していないので、改善はフォームに新しいウィジェットが追加されるのみです。それでは、凡例のregionsレイヤを選択して、識別ツールを使ってみましょう。設定によってはフォームが直接開くこともありますが、識別ダイアログのアクションから選択して地物フォームを開く必要があるかもしれません。

../../../_images/relations3.png

図 14.78 airportsへのリレーションを持つregionsの識別ダイアログ

見ればわかるとおり、この特定の地域に割り当てられた空港が全てテーブル表示されています。また、いくつかのボタンも用意されています。早速見てみましょう。

  • toggleEditing ボタンは編集モードを切り替えるためのものです。regionsレイヤの地物の地物フォームを開いていますが、このボタンはairportsレイヤの編集モードを切り替えることに注意してください。ただしこのテーブルは、airportsレイヤの地物を表しています。

  • saveEdits ボタンは、全ての編集を保存するためのものです。

  • newTableRow ボタンは、airportsレイヤの属性テーブルに新しいレコードを追加します。デフォルトでこの新しい空港は現在の地域に割り当てられます。

  • capturePointnewTableRow と同じですが、レコード追加前にマップキャンバスで空港のジオメトリのデジタイズができます。なお、アイコンはジオメトリタイプに応じて変わります。

  • duplicateFeature ボタンは1つまたは複数の子地物のコピーができます。

  • deleteSelectedFeatures ボタンは、選択した空港を永続的に削除します。

  • link シンボルをクリックすると、新しいダイアログが開き、既存の空港を選択して現在の地域に割り当てることができます。これは、誤って違う地域の上に空港を作成してしまった場合に便利です。

  • unlink シンボルは、選択した空港を現在の地域からリンク解除し、効果的に未割り当て状態(外部キーをNULLに設定)にします。

  • zoomToSelected ボタンを押すと、選択した子地物にマップをズームさせます。

  • 右にある formViewopenTable の2つのボタンは、テーブル表示とフォーム表示を切り替えます。後者は、すべての空港を個別のフォームで表示します。

上記の例では、参照元レイヤがジオメトリを持っている(つまり、単なる英数字のテーブルではない)ので、上記の手順では、対応するジオメトリ地物を持たないエントリがレイヤの属性テーブルに作成されます。ジオメトリを追加するには、以下の操作を行います。

  1. 参照元レイヤの openTable 属性テーブルを開く を選択します。

  2. 被参照レイヤの地物フォーム内で追加したレコードを選択します。

  3. addPart 部分を追加 デジタイジングツールを使用して、選択した属性テーブルのレコードとジオメトリを結びつけます。

airportsテーブルで作業しているのなら、 fk_region フィールド(リレーションを作成するために使用するフィールド)には、「リレーションの参照」ウィジェットが自動的に設定されます。詳細は リレーションの参照ウィジェット を参照してください。

airportsレイヤのフォームには、 fk_region フィールドの右側に formView ボタンがあることがわかります。このボタンをクリックすると、regionsレイヤのフォームが開きます。このウィジェットで、簡単に素早くリンクしている親地物のフォームを開くことができます。

../../../_images/relations4.png

図 14.79 regionsへのリレーションを持つairportsの識別ダイアログ

「リレーションの参照」ウィジェットには、親レイヤのフォームを子レイヤに埋め込むオプションもあります。これは、airportsレイヤの プロパティ ► 属性フォーム メニューから設定できます。 fk_region フィールドを選択して、 埋め込みフォームの表示 オプションにチェックを入れてください。

今、地物フォームダイアログを見ると、regionsのフォームがairportsのフォームの中に組み込まれていて、現在の空港を別の地域に割り当てることができるコンボボックスもあることがわかります。

../../../_images/relations5.png

さらに、airportsレイヤの編集モードを切り替えると、 fk_region フィールドにオートコンプリート機能も追加されます。入力中に regionsレイヤの id フィールドの値がすべて表示されることがわかります。ここで、airportsレイヤの プロパティ ► 属性フォーム メニューの 新しい地物の追加 オプションを選択した場合、 signPlus ボタンを使用してregionsレイヤのポリゴンをデジタイズすることができます。

子レイヤは、 値による地物選択 ツールで子レイヤの属性に基づいて親レイヤの地物を選択するために使うこともできます。

図 14.80 では、空港の平均高度が海抜500mより高い地域すべてを選択しています。

フォームには多数のさまざまな集計関数があることがわかります。

../../../_images/relation_select_by_value.png

図 14.80 子レイヤの値で親レイヤの地物を選択する

14.4.6.2. 多対多(N対M)リレーションの導入

N対Mのリレーションとは、2つのテーブル間の多数対多数の関係のことです。例えば、 airports レイヤと airlines レイヤを考えてみましょう。空港には複数の航空会社が乗り入れており、航空会社は複数の空港に乗り入れています。

以下のSQLコードは、 locations という名前のPostgreSQL/PostGISスキーマに、N対Mリレーションに必要な3つのテーブルを作成します。このコードは、PostGISの データベース ► DBマネージャ…pgAdmin のような外部ツールを使って実行できます。airportsテーブルには airports レイヤが、airlinesテーブルには airlines レイヤが格納されます。どちらのテーブルにも、わかりやすくするためにいくつかのフィールドが使われています。 トリッキー な部分は airports_airlines テーブルです。このテーブルは、すべての空港に対するすべての航空会社(またはその逆)をリストアップするために必要です。この種のテーブルは ピボットテーブル として知られています。このテーブルの 制約 は、両方とも互いのレイヤにある場合にのみ、空港と航空会社を関連づけられるものとすることを強制します。

CREATE SCHEMA locations;

CREATE TABLE locations.airports
(
   id serial NOT NULL,
   geom geometry(Point, 4326) NOT NULL,
   airport_name text NOT NULL,
   CONSTRAINT airports_pkey PRIMARY KEY (id)
);

CREATE INDEX airports_geom_idx ON locations.airports USING gist (geom);

CREATE TABLE locations.airlines
(
   id serial NOT NULL,
   geom geometry(Point, 4326) NOT NULL,
   airline_name text NOT NULL,
   CONSTRAINT airlines_pkey PRIMARY KEY (id)
);

CREATE INDEX airlines_geom_idx ON locations.airlines USING gist (geom);

CREATE TABLE locations.airports_airlines
(
   id serial NOT NULL,
   airport_fk integer NOT NULL,
   airline_fk integer NOT NULL,
   CONSTRAINT airports_airlines_pkey PRIMARY KEY (id),
   CONSTRAINT airports_airlines_airport_fk_fkey FOREIGN KEY (airport_fk)
      REFERENCES locations.airports (id)
      ON DELETE CASCADE
      ON UPDATE CASCADE
      DEFERRABLE INITIALLY DEFERRED,
   CONSTRAINT airports_airlines_airline_fk_fkey FOREIGN KEY (airline_fk)
      REFERENCES locations.airlines (id)
      ON DELETE CASCADE
      ON UPDATE CASCADE
      DEFERRABLE INITIALLY DEFERRED
 );

PostgreSQLの代わりに、GeoPackageを使うこともできます。この場合には、3つのテーブルは データベース ► DBマネージャ… を使用して手動で作成します。GeoPackageにはスキーマが無いため、 locations の接頭辞は不要です。

airports_airlines テーブルの外部キー制約は、 テーブル ► テーブルを作成…テーブル ► テーブルの編集… では作成することができません。このため、このテーブルは データベース ► SQLウィンドウ… を使用して作成する必要があります。GeoPackageは ADD CONSTRAINT 文をサポートしていないため、 airports_airlines テーブルは2段階で作成する必要があります。:

  1. テーブル ► テーブルを作成… を使用して、 id フィールドのみを持つテーブルを準備します。

  2. データベース ► SQLウィンドウ… を使用して、以下のSQLコードを入力し実行します:

    ALTER TABLE airports_airlines
       ADD COLUMN airport_fk INTEGER
       REFERENCES airports (id)
       ON DELETE CASCADE
       ON UPDATE CASCADE
       DEFERRABLE INITIALLY DEFERRED;
    
    ALTER TABLE airports_airlines
       ADD COLUMN airline_fk INTEGER
       REFERENCES airlines (id)
       ON DELETE CASCADE
       ON UPDATE CASCADE
       DEFERRABLE INITIALLY DEFERRED;
    

それから、上で説明したようにQGISで2つの 1対多のリレーション を設定します。

  • airlines テーブルとピボットテーブルの間のリレーション

  • airports テーブルとピボットテーブルとの間の第2のリレーション

これを行うためのより簡単な方法(PostgreSQLのみ)は、 プロジェクト ► プロパティ ► リレーションリレーションを検索 を使用することです。QGISは自動的にデータベース内の全てのリレーションを読み込むので、必要な2つのリレーションを選択するだけで設定ができます。最初にQGISプロジェクトに3つのテーブルを読み込むことを忘れないようにしてください。

../../../_images/relations6.png

図 14.81 リレーションと自動検索

airportairline を削除する場合、QGISは airports_airlines テーブルの関連するレコードを削除しません。この作業は、現在の例のようにピボットテーブルの作成時に正しい 制約 を指定すれば、データベースによって行われます。

注釈

N対Mのリレーションと自動トランザクショングループを組み合わせる

このようなコンテキストで作業する場合は、 プロジェクトのプロパティ ► データソース► でトランザクションモードを有効にする必要があります。 QGISは、すべてのテーブル(航空会社、空港、ピボットテーブル)の行を追加または更新できる必要があります。

最後に、 レイヤプロパティ ► 属性フォーム で、 airportsairlines レイヤに対して正しい「要素数」を選択する必要があります。最初のレイヤには airlines (id) オプションを、2番目のレイヤには airports (id) オプションを選択する必要があります。

../../../_images/relations7.png

図 14.82 関係の要素数の設定

これで、サブフォーム内で 子地物の追加既存の子地物をリンク を使用してairlineにairportを(そしてairportにairlineを)関連付けることができるようになりました。 airports_airlines テーブルにはレコードが自動的に挿入されます。

../../../_images/relations8.png

図 14.83 airportsとairlinesのN対Mリレーション

注釈

多対1リレーション 要素数を使用する

N対Mリレーションでピボットテーブルを隠すことが望ましくない場合があります。これは主に、リレーションシップが確立されたときにのみ値を持つことができる属性がリレーションシップに存在するというのが理由です。テーブルが(ジオメトリフィールドを持つ)レイヤの場合、ピボットテーブルの外部キーフィールドで 地図上の地物特定 オプション( レイヤプロパティ ► 属性フォーム ► 利用可能なウィジェット ► フィールド )を有効にするとよいかもしれません。

注釈

ピボットテーブルの主キー

ピボットテーブルの主キーには複数のフィールドを使用しないでください。QGIS は単一の主キーを想定しているため、 constraint airports_airlines_pkey primary key (airport_fk, airline_fk) のような制約は機能しません。