QGIS – 属性データの項目名変更

項目名の制限と対策

QGISは属性名の長さが半角10文字以内と短いため使い難い。より長い文字列を項目名として使う対策として2通りある。

  1. 項目名を編集する方法
  2. 項目の別名を定義する方法

項目名自体を編集するには、プロセッシングツールを使う必要があり、新しいShapeファイルへ書き出すことになるので手間がかかる。

項目の別名は通常メニューから操作でき、新しいShapeファイルも作成されない。

項目名を編集する方法

各レイヤの属性データの項目名を変更方法として、Table Managerというプラグインの利用が紹介されているが、これを実行してみたところ「最新バージョンではQGIS内でテーブル操作が可能となっており、プラグインの仕様はデータの破壊の可能性が・・・」といった趣旨の警告ダイアログが立ち上がる。

プロセッシングツールの「フィールドのリファクタリング」を用いるとよいらしいので、メニューからたどってみると、属性テーブルの項目情報が表示され、それらが変更可能になっていた。

メモとして手順だけを示しておく。

  1. 「プロセッシング」→「ツールボックス」でプロセッシングツールボックスが開く
  2. 「QGISジオアルゴリズム」→「ベクターテーブルツール」と階層をたどると「フィールドのリファクタリング」が見つかる
  3. それをダブルクリックするとダイアログが立ち上がり、属性テーブルの項目情報が表示される。
  4. 入力レイヤを選択
    • “Do you want to reset the field mapping?”のダイアログに「はい」
  5. フィールドマッピングエリアで、項目名(Name)の書き換え
  6.  Refactordで新しいファイルの保存場所とファイル名を指定
    • System(UTF-8にしたらエラーになって文字化けした)
  7. Run
    • Pythonでエラーが出るが気にしない

注意点

新しいShapeファイルの書き出しは、フォルダが空の場合は早いが、既に同名のshpファイルがある場合は極端に処理が重くなる

項目名の別名を定義する方法

レイヤのプロパティから、各項目の別名を入力・設定することができる。この方法は新しいShapeファイルを生成しないので時間がかからない。

レイヤーのプロパティーを表示

項目名を変更するレイヤーを右クリックして「プロパティー」を選択。

レイヤプロパティダイアログで以下のように操作する。

  1. 左側のタブ中、「属性フォーム」を選択
  2. 項目名を変更したいフィールドを選択し、別名(Alias)に好みの項目名を入力
  3. OKボタンをクリック

これによって、属性テーブルを表示させたとき項目名に別名が表示されるようになる。

 

QGIS – デフォルト座標系の設定

QGISでデフォルトの座標系(CRS: Coordinate Reference System)を設定するには以下のように操作する。

「設定」→「オプション」でオプションダイアログ|CRSが開くので、「常に次のCRSで新プロジェクトを開始する」の「CRSの選択」ボタンを押す。

qgis-settings-crs1

「空間参照システム」ダイアログが開くので、「フィルター」の欄に”JGD2000″と入力。

qgis-settings-crs2

「世界中の空間参照システム」のエリアのトップにJGD2000/EPSG4612が表示されるので、それを選択して「OK」。

 

MANDARA – 国土数値情報(高速道路)のインポート

概要

MANDARAは国土数値情報など複数の地図データ形式を取り込むことができる。高速道路データを国土数値情報のダウンロードサービスからダウンロードしてMANDARAに取り込んだので、その過程をメモ。国土数値情報の高速道路時系列の内容についてはこちら

国土数値情報では、全国の高速道路のリンクと接合部のデータがJPGIS形式で提供されているものの、MANDARAでJPGISで取り込み可能なのは「行政区域(面)」、鉄道(線)」、「公共施設」のみ。

旧統一フォーマット形式で「道路」のデータCSVで提供されているが、こちらは平成7年度と年次が古いので使い難い。

ところで、先のJPGIS形式のデータをダウンロードするとShape形式(shp)やdbfファイルもついてくる。これらを取り込むことで、地図ファイルデータと属性データとして取り込むことができる。この取り込み方法には、属性データまで一括して取り込む方法と、地図ファイルと属性データを別々にファイル化して取り込む方法がある。

たとえば高速道路の場合、xmlファイルと別に、路線についてはN06-15_HighwaySection、ICやJCTなどのジョイントについてはN06-15_Jointといったファイル名が付され、それぞれに拡張子shp、dbf、shxの3種類のファイルが得られる。

方法1:地図と属性の一括取り込み

  1. 作業用のフォルダに3つの拡張子(shp、dbf、shx)のファイルを保存
  2. MANDARAを起動した直後のダイアログで「シェープファイル読み込み」を選択
  3. shpファイルを参照・選択して読み込み
    • 複数のshpファイルを読み込むことができ、それぞれ別のレイヤの属性として取り込まれる
    • 地図データは、一つのファイルに複数のオブジェクトグループとして取り込まれる

この方法の特徴は以下の通り。

  • 路線と結節点のオブジェクト名は、元のオブジェクト名が基本になる
    • ファイル名を使うと[ファイル名].[オブジェクト連番]になる
    • 複数のShapeファイルを取り込んでファイル名を使わないと[ファイル連番].[オブジェクト連番]になる
  • 地図ファイルを分離するには、「編集」メニューからマップエディタを開き、地図ファイルとして保存
  • 属性データはdbfファイルに保存された順番・内容のまま
    • 集成したい場合は属性データの編集で行う

方法2:地図と属性を別々にファイル化

地図データの取得

  1. マップエディタを起動
  2. 「地図データ取得」→「シェープファイル」でダイアログが開く
  3. よみこむShapeファイルを選択していく
  4. 「オブジェクト名のヘッダにファイル名をつける」のチェックを入れる/はずす
  5. 座標系、測地系、投影法を確認して「ファイル変換」ボタンを押す
  6. このあと必要なら、オブジェクト名を一括変換

参考:オブジェクト名の変更と属性データの取り込み

オブジェクト名の変更

Shapeファイルを読み込んだままの状態では、オブジェクト名は単なる連番か、その前にファイル名が付されたものになる。オブジェクト名に路線名を入れたかったのと、連番の桁数を固定長としたかったので、次のようにした。

  1. dbfファイルを表計算ソフトで開く
  2. 路線名のデータをコピーして別シートに貼り付け
  3. 同じ項目数の連番を生成して値コピー
  4. 固定長の連番を文字列化し路線名と合体させて新たなオブジェクト名とする
  5. 元の連番を1列目、新たなオブジェクト名を2列目に配置して、2列分の全データをコピー
  6. マップエディタのオブジェクト名の一括変換でオブジェクト名を変換

属性データの取り込み

種別や車線数などの基本データをCSV化して、後で利用しやすいようにしておく。

  1. dbfファイルを表計算ソフトで開く
  2. 先頭列を確保し、マップエディタのオブジェクト名のコピー機能を利用して、オブジェクト名をコピー・ペースト
  3. 不要なデータ項目(列)を削除
  4. 項目名を適宜修正
  5. ファイルをCSV形式で保存

 

MANDARA – オブジェクトの操作

マップエディタ

オブジェクトの検索

マップエディタで開いている地図ファイルのオブジェクトは、「編集」→「オブジェクト名関係」→「オブジェクト名検索」で開くダイアログで検索できる。

ただし、通常オブジェクトと集成オブジェクトを同時に検索することができない点に注意。

オブジェクト編集の対象は通常オブジェクトと集成オブジェクトをトグルで切り替えるが、この設定が検索にも影響する。

  1. オブジェクト編集モードで「編集対象選択」を押すとだいあろぐがたちあがある
  2. 「オブジェクトのタイプ」で「通常」か「集成」のどちらかを選択
  3. 「編集」メニューからオブジェクト検索のダイアログを開くと、「オブジェクトのタイプ」が上で選択した方(通常/集成)になっていて、選択されていない方はグレイアウトになっている

オブジェクト名一括変換

オブジェクト名の一括変換は、あらかじめ表計算ソフトで作成したデータをクリップボードにコピーして、その内容で一括変換を行う。

変換データの準備

表の構成は、1列目が元のオブジェクト名、2列目が新しいオブジェクト名1、3列目は必要に応じて新しいオブジェクト名2。

一括変換操作

表のデータを準備した後、以下のように操作。

  1. 表計算ソフトの対象エリアを選択してコピー
  2. 「編集」→「オブジェクト名関係」→「オブジェクト名一括変換」
  3. 「クリップボードのデータをもとに一括してオブジェクト名を変換します」のダイアログで「はい」のボタンを押す

オブジェクト名のコピー

地図ファイルデータのオブジェクト名をクリップボードへコピーし、表計算ソフトなどへ貼り付けて利用することができる。データの一括作成・変更に便利。

  1. 「編集」→「オブジェクト名関係」→「クリップボードへオブジェクト名のコピー」でダイアログが立ち上がる
  2. 必要なオブジェクト名を絞り込み・指定
  3. 「オブジェクト名1をコピー」などのボタンを押してクリップボードへコピー
  4. 表計算ソフトなどへ貼り付ける

 

 

MANDARA – 地図ファイルだけの表示について

地図ファイルだけを表示する3つの方法

地図データのオブジェクトを、主題図での統計操作ではなく絵柄として描画させたいとき、トライアル・アンド・エラーでわかったことをメモ。数値処理を意図しないで地図だけを表示させたい時、次の3つの方法があるらしい。

  1. 白地図データのレイヤを設定して読み込み、直接表示させる方法
  2. 属性データでダミーオブジェクトを表示させる方法
  3. カテゴリ・データを使って表示させる方法

いろいろ試してみたところ、3のカテゴリ・データを使う方法が柔軟で手軽なようだ。

白地図データを直接表示させる方法

まず、地図ファイルからレイヤを構成する。

  1. 白地図データ表示を指定してダイアログを表示
    • MANDARA起動時のダイアログで「白地図・初期属性データ表示」を選択
    • MANDARAメニューの「ファイル」→「白地図・初期属性データ表示」
  2. 「地図ファイル」エリアの「参照」ボタンを押して地図ファイルを指定
  3. 既に1つレイヤが登録されているので、そのレイヤで表示するオブジェクトグループを選択
  4. さらに「レイヤ追加」ボタンを押して新規レイヤを追加し、表示するオブジェクトグループを選択
  5. 「OK」ボタンを押して設定終了→主題図メニューへ
    • このとき、同じレイヤに異なる形状のオブジェクトグループを指定すると「形状の異なるオブジェクトグループが指定されています」とエラーになる

形状が異なるオブジェクトグループは同じレイヤに指定できないので、レイヤ分類は多くの場合必要になる。

次に、各レイヤを重ね合わせ表示させる。

  1. 「データ表示」タブで「対象レイヤ」を選択して、「重ね合わせセット」ボタンを押す
    1. 「重ね合わせ表示」タブの「重ね合わせデータ」に登録されたことが確認できる
  2. 以後、同じ手順で対象レイヤを指定して重ね合わせセット
  3. 「重ね合わせ表示」タブで「描画開始」ボタンを押して地図を表示
  4. 必要に応じてMANDARAの形式でデータ・設定を保存

この方法の特徴は以下の通り。

  • 特に新たな属性データを準備する必要がない
  • レイヤの変更が柔軟に行えない
    • 変更のたびに「白地図・初期属性データ表示」からやり直さなければならない
  • オブジェクトの表示色はオブジェクト作成時のものではなく、データ表示のペイントで設定する必要がある

ダミーオブジェクトグループを定義する方法

以下のようなCSVファイルを準備して読み込む。ただし見やすさのため、区切りのcommaの後にTABを入れている。

あるいは必要最低限のタグだけを残すと、以下でもok。

ダミーオブジェクトを指定することで、それらについては属性データがなくても表示される。ただし実体オブジェクトとその属性データが全くないとエラーになるので、最低でも一つ、この例では「北海道」というオブジェクトを準備している。

この方法の特徴は以下の通り。

  • 同じCSVファイルを再利用可能
  • 地図だけの表示でも最低一つの実体オブジェクトが必要となり、その表示方法の設定が必要になる

カテゴリ・データを使う方法

以下のようなCSVファイルを準備して読み込む。

表示は以下の手順で。

  1. 各レイヤ・カテゴリのデータ表示パターンを設定する
  2. 必要ななレイヤ・データ項目を重ね合わせる。

この方法の特徴は以下の通り。

  1. 同じCSVファイルを再利用可能
  2. セットした表示パターンをセーブ可能
  3. レイヤを別ファイルにして、データ挿入が可能
    • 使用する地図ファイルは共通していなければならない

 

 

MANDARA – オブジェクトの種類と作成

オブジェクトの種類

形状の種類

点オブジェクト
図形としては位置情報だけを持つ。場所や建物などに使う。
線オブジェクト
端点と任意個数の通過点を持つ折れ線。道路や鉄道などに使う。
面オブジェクト
複数のラインで囲まれた閉じた面。自治体区域などのエリアに使う。

包含関係の種類

通常オブジェクト
それ自身が点/線/面の形状で規定される。集成オブジェクトの構成要素となりうる。
集成オブジェクト
通常オブジェクトや集成オブジェクトの集合体としてのオブジェクト。集成オブジェクトの構成要素となりうる。たとえば最小単位としての市区町村を通常オブジェクトとして、複数の市区町村オブジェクトからなる集成オブジェクトとしての都道府県オブジェクトを構成するなど。

通常オブジェクトの作成

通常オブジェクトを作成・格納するのは地図データファイル(MPF)で、マップエディタ上で複数種類のオブジェクトを作成していく。

点オブジェクトの作成

  1. マップエディタで「オブジェクト編集」を選択
  2. 「新規オブジェクト」ボタンを押すと、画面中央に新たな点オブジェクトが表示される
  3. 点の位置はマウスカーソルを矢印の状態にしてドラッグ
    • 左上に座標または経緯度が表示される。
  4. オブジェクトの名前とオブジェクトグループを入力・選択して「登録」ボタンを押す

線オブジェクトの作成

まず必要に応じて、新たな線種とオブジェクトグループを登録する。

線種の新規登録

  1. 「設定」→「線種設定」→「線種設定」でダイアログ表示
  2. 「線種追加」ボタンを押すと、新規の線種が追加される
    • 線種の名称(ex. 道路)とタイプ(通常オブジェクト/オブジェクトグループ連動)を選択
    • 「パターン」をクリックして線の色とタイプを選択
  3. 「OK」ボタンを押して線種を登録

オブジェクトグループの新規登録

  1. 「設定」→「オブジェクトグループ設定」→「オブジェクトグループ設定」でダイアログ表示
  2. 「グループ追加」ボタンで新規グループが追加される
    • 名称を入力
    • タイプと形状を選択
    • 使用する線種を選択
  3. 「OK」ボタンを押してオブジェクトグループを登録

作成の第1ステップは、オブジェクトの実体としての線を描く。

  1. マップエディタで「ライン編集」を選択
  2. 「新規ライン」ボタンを押すと、画面中央に両端点と中点を持ったラインが表示される
  3. ラインの各点を必要な位置に移動
  4. 通過点の追加削除
    • リンク部分をクリックして新しい通過点を追加
    • 既存の通過点を右クリックして削除
  5. 「登録」ボタンを押してラインを登録

第2ステップは、オブジェクトの作成とラインの関係づけ

  1. 「オブジェクト編集」を選択
  2. 「新規オブジェクト」ボタンを押すと、画面中央に新たな点オブジェクトが表示される
  3. オブジェクトの名称を入力
  4. 目的のオブジェクトグループを選択
    • このとき線形状のオブジェクトグループを選択すると「オブジェクトグループの形状が異なります。」と表示されるが、かまわず「はい」を押す
  5. 目的のラインをクリックするとラインが赤色に変わり、形状が点から線に変わる
  6. オブジェクト代表点をラインの上などに移動して位置決め
  7. 「登録」ボタンを押してオブジェクトを登録

面オブジェクトの作成

  1. まず、必要に応じて線種とオブジェクトを新規登録(線オブジェクトの作成を参照)。
  2. 第1ステップの面の描画は線オブジェクトと同じ手順だが、最後にループとすること。
  3. 第2ステップのオブジェクトの登録は線オブジェクトと同じ。

集成オブジェクトの作成

 

Path2D

概要

Path2DはJavaScriptによるWeb APIの一つで、一連のサブパスを保持する。Path2Dの内容は後に一度に描画される。

コンストラクタ

Path2Dのコンストラクタは3種類。

Path2D()
空のPath2Dオブジェクトをつくる。
Path2D(path)
既存のPath2Dオブジェクトを複製する。
Path2D(d)
SVGパスの文字列を与えてオブジェクトをつくる。

パスの追加

addPath(path)
現在のパスにpathを追加する。

パスの操作

moveTo(x, y)
(x, y)の点に移動する。
lineTo(x, y)
現在の点から(x, y)の点まで直線を引く。
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
現在の点から(x, y)の点までベジエ曲線を描く。
quadraticCurveTo(cpx, cpy, x, y)
現在の点から(x, y)の点まで二次ベジエ曲線を描く。
arcTo(x1, y1, x2, y2, radius)
現在の点から、指定した制御点と半径で円弧を描く。
arc(x, y, radius, startAngle, endAngle, anticlockwise)
(x, y)を中心とした半径radiusの円弧を描く。startAndleが開始角、endAngleが終了角で、デフォルトは時計回りだがanticlockwiseをtrueにすると反時計回りに描く。
ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise)
(x, y)を中心とし、xyの2方向の半径を指定して楕円(弧)を描く。rotationは楕円全体の傾き。その他はarc()と同じ意味。
rect(x, y, width, height)
(x, y)から幅width、高さheightの長方形を描く。

 

BrythonでPath2Dオブジェクトを使う

Brythonでcanvasに描画をする場合、取得したcontextに直接描いていくほかに、Path2Dオブジェクトにサブパスを追加していってから最後に描くという方法がある(HTML5のcanvasを参照)。

BrythonにはPath2Dオブジェクトは実装されていないが、JavaScriptの組み込みクラスを扱う方法によって、Path2Dオブジェクトを使えるようになる。

 

 

BrythonでJavaScriptの組み込みクラスを使う

次の手順でBrythonからJavaScriptのクラスを直接使うことができる。JavaScript側の自作クラスをPythonで使う例はいくつか見かけたが、組込関数はどうかと思って試してみた。

  • browserモジュールからwindowオブジェクトをインポートする
  • JSConstructor()関数の引数にJavaScriptの組み込みクラスのコンストラクタを与えてPythonとしてのコンストラクタを得る
    • ()や引数はつけない
    • 引数に与えるJavaScriptのコンストラクタはwindowオブジェクトに属している
  • 上のコンストラクタを使ってインスタンスを生成

たとえばJavaScriptの組込クラスArrayを使ってみる。

Arrayオブジェクトをつくると、Pythonのリストとして生成されているらしい。メソッドも使えそう。

ところがtoString()メソッドを使おうとするとエラーに。

これを見ると、JavaScriptのコンストラクタを使っているが、Pythonではリストとして解釈されるので、メソッドが存在しない、とエラーになる。上のreverse()sort()は、JavaScriptのArrayクラスのメソッドではなく、Pythonのリストオブジェクトのメソッドとして解釈・実行されたということになる。

Pythonのクラスに定義されていないプロパティにアクセスした場合もエラーになる。

もともとBrythonに該当するものがないJavaScriptのクラスの場合。たとえばPath2Dをつくってみると、JSObjectでラップされたオブジェクトになっているらしい。

このPath2DオブジェクトのmoveTo()lineTo()といったメソッドは問題なく機能して、canvasに描画することができる。

 

Python3 – 関数の引数は値渡しか

参照渡しだが値は保護

以下のコードを実行すると、関数実行の前後で引数に渡した変数の値が影響を受けていない。挙動だけ見ると値渡し(call by value)だが、Pythonの関数引数は参照渡し(call by reference)だという。

実際には、引数を受け取った段階では、元の引数オブジェクトへの参照が渡されているが、その内容が変更されたときに新しいオブジェクトが生成され、元の変数の内容は保たれるらしい。

だが、時には関数に渡した引数の内容を、関数で変更したいような時がある(たとえばシステムの状態に関するフラグの変更など)。そのような変数をglobal定義してもよいが、やはり全体系への汚染のことを考えると気持ちはよくない。

リストを使った場合

以下の例では、要素を1つ持つリストをつくり、そのリストを関数に渡して、関数内でリストの要素の値を変更している。

リストなどのミュータブルなオブジェクトの場合、その内容が関数内での変更の影響を受けている。

クラスを使った場合

以下の例では、カウンタをプロパティに持つクラスをつくり、そのインスタンスを関数に渡して、関数内でインスタンスのカウンタの値を変更している。

変数の内容を特定の関数で変更させたい場合、リストよりもクラスを使った方が意味づけができてよいのではないか。