v.cleanの使い方について

860 views
Skip to first unread message

たぬき

unread,
Mar 1, 2018, 1:52:01 AM3/1/18
to QGIS初心者質問グループ
お世話になっております。
操作や疑問について丁寧な説明をしてくださる皆様のおかげで、ようやくGRASSの機能も活用し始めるぐらいにはなりました。

トポロジチェッカーの機能を用いてエラーを確認すると、オーバーラップが数千件発生する状態に陥っています。
さすがに1つ1つ修正はしていられないので、代替えの手段として何か無いかを探ったところGRASSのv.cleanを使うという選択肢が見えてきました。

しかしv.cleanを初期設定のまま実行すると、"cleaned"と"error"というレイヤが出来上がりますが、どちらもデータは何も作られていません。
参考にした動画:

皆さんはv.cleanの機能を使われているでしょうか。必要な設定や注意すべき点などご存じであれば、差し支えなければご教示下さい。

GeoJsonで保存してCOORDINATE_PRECISIONのパラメータを変更して精度を落とすという投稿も参照させていただきましたが、属性テーブルに2バイト文字があると文字コードをshift_gisなどにしてもjsonファイルにしたタイミングで2バイト文字が文字化けしてしまい途方に暮れてます。

環境:
windows10 professional 64bit
QGIS 2.14.21

yoh_chan

unread,
Mar 1, 2018, 11:32:59 PM3/1/18
to QGIS初心者質問グループ
こんにちは。

QGISでGRASSの機能をあまり使用しないのですが、オンザフライ投影変換が有効になっている場合うまく動作しないことが多いため、もしこれが有効になっているようでしたら、プロジェクトのCRSと修正したいデータのCRSを合致させた上で、オンザフライ投影を無効にした状態で実行してみてはいかがでしょうか。

たぬき

unread,
Mar 4, 2018, 10:14:18 PM3/4/18
to QGIS初心者質問グループ
yoh_chan様

ご回答ありがとうございます。オンザフライ投影変換を無効にして実行してみましたが、結果は変わらずでした。

現状まだ未解決ですが。新たに新規作成したポリゴンに対してv.cleanを実行すると問題なく機能するので、編集しようとしているshapeファイル側の問題とみています。

v.cleanを実行するとcleanedおよびerrorのレイヤに何もデータが出てこないのは、実行時に次のようなエラーが出て来ることが原因だろうと見ています。
”属性の無いシェープファイルはread-onlyとみなされます”(shapefile without attribute are considered read-only.)

shapeファイルの属性データは当然ですが存在しているのですが、なぜかそれがread-onlyになっている?
windows側の設定ではフルコントロールになっているので、windowsのアクセス権の問題でもなさそう…

英語の場合のエラーの文言でgeographic information systemsなどのサイトで前例を探しても見つからず…
迷宮入りしました。 :-(

yoh_chan

unread,
Mar 5, 2018, 7:28:30 AM3/5/18
to QGIS初心者質問グループ
たぬきさま

お返事ありがとうございます。

試しに(トポロジエラー付きの)ポリゴンshpを作ってWindows環境下で以下を試してみましたが、再現できませんでした。
①属性テーブル(.dbf)を削除し、属性がない状態で実行
②地物数と属性数が合致しないデータを作って実行(地物数<属性数、属性数<地物数どちらも)
③shpファイル群をすべて読み取り専用に設定して実行

①②でも問題なく動作するようなので、属性の有無や更新の可否、地物との対応については問わずに動作するようです。
また③から、ソースファイルに対して非破壊的に動作するようです。

これらのことから、shpファイルの問題である可能性はありますが、ファイルモードの問題ではないように思います。

試せそうなこととして思いつくのは、以下のようなことでしょうか。
①QGISからshpファイルを別名で保存し、そのファイルを処理してみる
②地物を思い切って大半削除し、処理してみる(処理できるようであれば、特定の地物が原因かもしれません)
③ジオプロセシングではなく「QGIS with GRASS」またはGRASSからGRASS GIS自体で処理してみる

ご参考まで。

たぬき

unread,
Mar 8, 2018, 3:09:44 AM3/8/18
to QGIS初心者質問グループ
yoh_chan様

ご回答と再現テスト、ありがとうございます。大変恐れ入ります。
ご提案いただいた3点、いずれも試してみました。

①QGISからshpファイルを別名で保存し、そのファイルを処理してみる
 →結果は同じでした。

②地物を思い切って大半削除し、処理してみる(処理できるようであれば、特定の地物が原因かもしれません)
 →地物の削除量にかかわらず結果は同じでした。

③ジオプロセシングではなく「QGIS with GRASS」またはGRASSからGRASS GIS自体で処理してみる
 →GRASSでベクタレイヤを開こうとすると、エラーが出ます。
 「ベクトルマップ <xxxxxxx> にリンクするテーブル <xxxxxxx>は存在しません」
 ※ xxxxxxxはshapeファイル名

また、QGIS上でのv.clean実行時にログをよく見ると、「エラー:テーブル create table vevtor_5aa0e98cc8cd37 ( cat integer, .......... )」と、何かしら属性テーブルに関わるエラーがやはり出ています。

また、shapeをgeopackageに変換してからv.cleanを実行しても同じエラーがでました。

この作ったshapeファイルを数ヶ月遡った元のshapeファイルではv.cleanが機能したため、編集していく過程でおかしくなってしまったようです。
しばらく解決策を探ってみます。

yoh_chan

unread,
Mar 8, 2018, 6:23:05 AM3/8/18
to QGIS初心者質問グループ
たぬきさま

こんにちは。確認していただいてありがとうございます。

 →GRASSでベクタレイヤを開こうとすると、エラーが出ます。
 「ベクトルマップ <xxxxxxx> にリンクするテーブル <xxxxxxx>は存在しません」
 ※ xxxxxxxはshapeファイル名
GRASSへのベクタインポート自体ができないでしょうか。あるいはGRASSベクタレイヤはできるけれど、それを開こうとするとエラーが出るでしょうか。

また、QGIS上でのv.clean実行時にログをよく見ると、「エラー:テーブル create table vevtor_5aa0e98cc8cd37 ( cat integer, .......... )」と、何かしら属性テーブルに関わるエラーがやはり出ています。
エラーの内容としては、属性テーブルをGRASSの属性テーブルとして移行できなかったということによるものですので、やはり属性テーブルに問題がありそうです。

例えば、属性テーブルの列名に日本語を含むマルチバイト文字や、列名に使用できない特殊文字などが含まれている場合にこのようなことが起こるかもしれません。(値としてこうしたデータが入っていることは通常問題にはならないと思います。)または、何かの事情で列定義とデータの型に不一致が生じているような場合にも起こるかもしれません。

試しに、処理されているshapeファイル群のdbfファイルを除外(別の場所へ移動するか、拡張子を"dbf_"などに変更)した状態でv.cleanを実行するとどうなるでしょうか。

たぬき

unread,
Mar 8, 2018, 7:46:39 PM3/8/18
to QGIS初心者質問グループ
yoh_chan様

度重ねてのご回答、お礼申し上げます。
ご回答からヒントを得て、解決につなげることができました。

> GRASSへのベクタインポート自体ができないでしょうか。あるいはGRASSベクタレイヤはできるけれど、それを開こうとするとエラーが出るでしょうか。
 前者になります。

> 試しに、処理されているshapeファイル群のdbfファイルを除外(別の場所へ移動するか、拡張子を"dbf_"などに変更)した状態でv.cleanを実行するとどうなるでしょうか。
 dbfファイルを除外して実行してみると、v.cleanが動作しました。

列定義に異常が起きていることが原因であると考え、試しに新規フィールドを作り、その新規フィールド以外の列を全て削除してv.cleanを実行するとv.cleanが動作しました。

なので、以下の手順で解決しました。
(1)各地物のユニークIDとなる列を作成 (key列とする。ユニークIDは”既存の列データ+area($geometry)”などと組み合わせるとすぐに作れた)
(2)key列を含む全データをCSVにした後、key以外の列を削除
(3)v.cleanの実行(cleanedレイヤが作成される)
(4)デリミティッドテキストレイヤの追加からcsvをインポート
(5)出来上がったcleanedレイヤのプロパティ[結合]から、key列をターゲットフィールドとしてcsvを結合
(6)結合した状態のcleanedを別名で保存

考えてみれば、CSVで列定義作り直して…なんてすぐに思いつきそうなものでしたけど、
まだ試していませんでしたね…

ありがとうございました。
Reply all
Reply to author
Forward
0 new messages