0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CADとGISをつなぐ ── LibreDWG × GDALでDWGをQGIS / ArcGIS Pro対応GeoPackageへ変換する【v0.3.4 改訂版】

0
Posted at

CADとGISをつなぐ ── LibreDWG × GDALでDWGをQGIS / ArcGIS Pro対応GeoPackageへ変換する【v0.3.4 改訂版】

はじめに

AutoCADのDWGを、そのままGISで使いたいことは結構あります。

河川図、道路図、施設台帳、測量図、等高線など、元データはCADで管理されているけれど、解析や地図表示はQGISやArcGIS Proで行いたい。そんな場面は少なくありません。

そこで、GNU LibreDWGとGDALを組み合わせて、DWGをGeoPackageへ変換するDocker環境を作ってきました。

最初の公開版では、

DWG
 ↓
DXF
 ↓
GDAL
 ↓
GeoPackage

という流れが中心でした。

その後、実際の業務DWGで検証を続けると、

  • DWG→DXFの段階で形状が正しいか確認したい
  • ArcGIS ProでDXFそのものも確認したい
  • CAD側はmm、GIS側はmというデータがある
  • DXFの座標は変更したくない
  • GeoPackageではEPSGをきちんと付けたい
  • Polygonの不正geometryを無理に成功扱いしたくない

といった要件が見えてきました。

そこでv0.3.4では、処理の役割を明確に分けています。


v0.3.4で何が変わったか

現在の処理は次のようになっています。

20260928_c01.png

一番大きな変更点は、DXFとGeoPackageの役割を分けたことです。

DXFはCAD側の確認用なので、元のCAD座標をそのまま保持します。

GeoPackageはGIS側で使うため、必要な倍率を適用して、指定したEPSGを付与します。

今回のようにCAD座標がmm、GIS座標がmの場合は、

DXF        : 元座標のまま
GeoPackage : XY × 0.001

です。


v0.3.4の成果物

入力DWGが、

河川網図.DWG

なら、正常終了時には同じベース名で次の4ファイルを作ります。

河川網図.dxf
河川網図.prj
河川網図.wld
河川網図.gpkg

v0.3.4では、これを基本成果物としています。

以前のように「DXFが必要な場合だけ --dxf を付ける」という考え方ではありません。

DWG→DXFの変換結果を確認できること自体が重要なので、DXFは必ず残します。


DXFはスケール変換しない

ここはv0.3.4でかなり重要な部分です。

例えば元DWGの座標が、

X = -64,000,000
Y = -130,000,000

だったとします。

この値がmm座標なら、GISでは、

X = -64,000 m
Y = -130,000 m

として使いたいところです。

ただし、DXFそのものを書き換えてしまうと、

DWG→DXF変換が正しかったのか
GIS用のスケール変換で変わったのか

が分からなくなります。

そこでDXFは、

X = -64,000,000
Y = -130,000,000

のまま保存します。

--scale-to-m はDXFには適用しません。


ArcGIS ProではPRJ + WLDを使う

DXFをArcGIS Proで正しい位置に表示するため、v0.3.4ではDXFと一緒に .prj と .wld を生成します。

例えば、

--epsg=6676

を指定すると、

JGD2011 / Japan Plane Rectangular CS VIII

としてPRJを作ります。

EPSG:6676はJGD2011 / 平面直角座標系VIII系で、単位はmetreです。

WLDは今回のmm→m運用に合わせて、次の固定値です。

0.0,0.0 0.0,0.0
1000.0,0.0 1.0,0.0

意味は、

CAD座標     GIS座標
0         → 0
1000 mm   → 1 m

です。

つまり、

scale       = 0.001
rotation    = 0
translation = 0,0

になります。

ArcGIS Proでは、

河川網図.dxf
河川網図.prj
河川網図.wld

を同じディレクトリに置いて読み込みます。

DXF自体は変更していませんが、ArcGIS Pro側ではWLDによって1/1000の位置に表示されます。

Esriのドキュメントでも、CADと同名のWLDを使ってoffset / scale / rotationを与える仕組みが説明されています。


GeoPackageは0.001倍して保存する

GeoPackage側は逆に、GISでそのまま使える座標として保存します。

今回の標準設定は、

--scale-to-m=0.001

です。

つまり、

GeoPackage座標 = DXF座標 × 0.001

です。

例えば、

DXF
X = -64,000,000

GeoPackage
X = -64,000

となります。

さらに、

--epsg=6676

を指定していれば、GeoPackage側にはEPSG:6676を設定します。

そのため、

DXF + PRJ + WLD

と、

GeoPackage

をArcGIS Proへ同時に追加すると、同じ位置に重なるのが正しい結果です。


v0.3.4の基本的な使い方

1. ZIPを展開する

下記よりダウンロードして下さい。
https://godo-tys.jp/downloads/dwg2geopackage_v0.3.4.zip

unzip dwg2geopackage_v0.3.4.zip
cd dwg2geopackage_v0.3.4
chmod +x ./scripts/*.sh

ホスト側で必要なのは基本的に、

Docker
Docker Compose v2

です。

LibreDWG、GDAL、Python側の処理はDockerイメージ内に入れています。


2. まずDocker環境を検証する

最初に、

./scripts/verify_docker.sh

を実行します。

v0.3.4では、単なるPythonのunit testだけではなく、

Docker Compose設定
 ↓
LibreDWG build
 ↓
LibreDWG version / commit確認
 ↓
pytest
 ↓
実GDAL DXF→GeoPackage
 ↓
EPSG確認
 ↓
scale確認
 ↓
DXF / PRJ / WLD / GPKG確認

まで確認する構成にしています。

LibreDWGはnightlyの、

0.14.8597
short commit: 34f02f5

を固定しています。

CAD変換ツールはライブラリ側の更新によって結果が変わる可能性があるため、

どのLibreDWGで変換したか

を追えるようにしています。


3. 実DWGを変換する

JGD2011 / 平面直角座標系VIII系、CAD単位mmの場合は次のように実行します。

./scripts/dwg2geopackage.sh \
  "/home/tys/dwg/input/河川図.DWG" \
  "/home/tys/dwg/output" \
  --epsg=6676 \
  --scale-to-m=0.001

正常終了すると、

/home/tys/dwg/output/
├── 河川図.dxf
├── 河川図.prj
├── 河川図.wld
├── 河川図.gpkg
└── logs/

となります。

ファイル名を個別指定しなくても、元DWGと同じベース名で出力します。


--epsg は座標系を指定する

今回は、

--epsg=6676

を使っています。

これは、

JGD2011 / Japan Plane Rectangular CS VIII
JGD2011 / 平面直角座標系VIII系

です。

国内の別の平面直角座標系を使う場合も、対象となるEPSGを指定します。

例えばJGD2011の平面直角座標系はEPSGコードが系ごとに分かれています。

重要なのは、

CAD座標値の意味
EPSG
単位

を混同しないことです。

--epsg は座標参照系を指定します。

--scale-to-m はCAD座標値をmetreへ変換する倍率です。

別の役割です。


Python主体の構成へ変更した

初期版ではShellとogr2ogrを中心に処理していました。

v0.3.xからは、変換ロジックをPythonへ移しています。

構成はおおよそ次のようになっています。

src/dwg2geopackage/
├── cli.py
├── dwg.py
├── libredwg.py
├── dxf.py
├── geopackage.py
├── pipeline.py
├── process.py
├── compare.py
└── errors.py

役割は、

dwg.py
  DWG version判定

libredwg.py
  LibreDWG実行
  DWG→DXF

dxf.py
  DXF header確認
  coordinate診断
  GDAL preflight

geopackage.py
  DXF→GeoPackage
  geometry分類
  scale適用
  EPSG設定

pipeline.py
  全工程の実行制御
  manifest生成

という形です。

Shell scriptは、

Dockerを起動する
Python CLIへ引数を渡す

程度の薄いラッパーにしています。

これで問題が起きたときに、

DWG読取りで失敗
DXF生成で失敗
DXF診断で失敗
GeoPackage生成で失敗
最終検証で失敗

を切り分けやすくなりました。


DWGと同じ世代のDXFを作る

DWGの先頭からバージョンを確認し、同世代のDXFへ変換します。

例えば、

AC1032

なら、

R2018 DWG
 ↓
R2018 DXF

です。

対応関係は次のように扱っています。

AC1014 -> R14
AC1015 -> R2000
AC1018 -> R2004
AC1021 -> R2007
AC1024 -> R2010
AC1027 -> R2013
AC1032 -> R2018

LibreDWGのdwg2dxfには--as r2018などの出力バージョン指定があります。

v0.3.4では、理由なく別世代へ落とすfallbackは使わず、元DWGと同じ世代を基本にしています。


DXFを先に診断する

以前は、

DWG
 ↓
GeoPackage

の結果だけを見ていました。

ただ、実データでLineやPolygonの形状に違和感が出たとき、

DWG自体がおかしいのか
LibreDWGでDXFへ変換した時点でおかしいのか
DXF→GeoPackageでおかしくなったのか

を分けられませんでした。

そこで現在は、

DWG
 ↓
DXF
 ↓
DXFを確認
 ↓
問題がなければGeoPackage

という考え方にしています。

DXF診断では、entity typeごとに、

entity count
coordinate count
extent
non-finite coordinate
極端に大きな座標

などを確認します。

ArcGIS ProでDXFそのものを表示できるようPRJ / WLDも一緒に作るので、GeoPackageへ進む前の確認がかなり楽になりました。


DXFが書き換わっていないことも確認する

v0.3.4では、GeoPackageを作る前後でDXFのSHA-256を比較します。

DXF生成
 ↓
SHA-256
 ↓
GeoPackage生成
 ↓
DXFのSHA-256を再計算
 ↓
一致確認

一致しなければエラーです。

これは、

GeoPackageを作るためにDXFを加工してしまった

という状態を防ぐためです。

DXFはあくまでLibreDWGから出したCAD側の確認用成果物として残します。


GeoPackageはgeometry typeごとに分ける

GDALのDXF Readerから読み込んだgeometryを、そのまま1つの混在レイヤへ入れるのではなく、GeoPackageでは分離します。

entities_point
entities_multipoint
entities_line
entities_polygon

Multipointがなければ空レイヤは作りません。

ArcGIS ProではPoint / Line / Polygonがfeature classとして分かれている方が扱いやすいためです。

属性についても、DXFから取得できる、

Layer
SubClasses
EntityHandle
Text

などを可能な範囲で保持します。

追跡用として、

source_fid
cad_style

なども追加しています。


Polygonを無理に成功扱いしない

CADのHATCHなどは、CAD上では見た目が正常でも、GIS Polygonとしては不正になることがあります。

例えば、

Self-intersection
Hole lies outside shell
Too few points

といったケースです。

Polygon候補は必要に応じてMakeValid()を使います。

それでもGIS Polygonとして成立しないものは、無理にgeometryとして保存せず、rejectedとして扱います。

つまり、

変換コマンドが最後まで動いた

だけで成功とは判断しません。


GeoPackage生成後も検証する

v0.3.4では一時GeoPackageへ書き込み、検証後に最終ファイルとして公開します。

DXF
 ↓
.tmp.gpkg
 ↓
検証
 ├─ FAIL -> tmpを削除
 └─ PASS -> 正式な .gpkg へ置換

確認している主な内容は、

SQLite integrity_check
EPSG
Feature count
Layer count
Extent
finite coordinate
geometry type

です。

正常な既存GeoPackageがある場合、新しい変換が失敗したからといって先に消さないようにしています。


現在残っている注意点

実DWGでは、いくつか警告が出る場合があります。

CP932 / UTF-8

一部のDWG / DXFでは、

One or several characters couldn't be converted correctly
from CP932 to UTF-8

が出ることがあります。

Geometryそのものとは別ですが、日本語TEXTやLayer名などの属性文字列については引き続き確認が必要です。

3Dと2D

Sub-geometry ... coordinate dimension 3,
but container has 2

という警告が出ることがあります。

平面GISとしてXYだけを使うデータでは大きな問題にならない場合がありますが、Zを必要とする用途では別途扱いを決める必要があります。

CAD PolygonとGIS Polygonは同じではない

CAD上で正常に見えるHATCHでも、GIS Polygonとしては、

Self-intersection
Hole lies outside shell
Too few points

になる場合があります。

このため、v0.3.4ではrejectedを成功件数へ混ぜないようにしています。


このツールの役割

このツールは、

AutoCADの図面を完全に再現するCADエンジン

を目指しているわけではありません。

目的は、

DWG
 ↓
CADとして確認可能なDXF
 +
GISで使えるGeoPackage

を再現可能なDocker環境で作ることです。

最終的には、

DWG受領
 ↓
DWG→DXF
 ↓
ArcGIS ProでDXF確認
 ↓
GeoPackage
 ↓
PostGIS
 ↓
WebGIS

という流れにつなげたいと考えています。

CADデータを毎回手作業でGIS形式へ変換する部分を自動化できれば、その後のWebGISや空間解析へかなりつなげやすくなります。


今回の改訂で変わった考え方

初期版では、

DWGをGeoPackageへ変換できるか

が中心でした。

v0.3.4では少し考え方が変わっています。

DWG
 ↓
DXFという確認可能な中間成果物を残す
 ↓
ArcGIS Proでも確認できるようPRJ / WLDを付ける
 ↓
同じDXFからGeoPackageを作る
 ↓
座標・geometry・件数を検証する

です。

これなら、GeoPackageがおかしかったときにも、

DWG→DXFの問題
DXF→GISの問題
元CADデータの問題

を切り分けやすくなります。

実データを扱うツールでは、単に「変換できた」より、こちらの方が重要だと思っています。


まとめ

v0.3.4では、DWGから次の4ファイルを標準成果物として出力するようになりました。

input.dwg
 ↓
input.dxf
input.prj
input.wld
input.gpkg

役割は、

DXF
  CAD座標のまま

PRJ
  --epsgで指定した座標参照系

WLD
  ArcGIS Pro用の1/1000変換

GeoPackage
  --scale-to-m=0.001を適用
  EPSGを設定

です。

今回のJGD2011 / 平面直角座標系VIII系なら、

./scripts/dwg2geopackage.sh \
  input.DWG \
  output \
  --epsg=6676 \
  --scale-to-m=0.001

で使えます。

DWGからGISデータを作る処理は、変換部分だけを見ると簡単そうですが、実際には、

DWG世代
DXF
文字コード
単位
座標系
CAD geometry
GIS geometry
ArcGIS互換性
検証

を一つずつ分けて考えた方が安定します。

v0.3.4で、ようやくその役割分担がかなり整理できました。

次はこのGeoPackageをPostGISへ登録し、OpenLayersから表示できるところまでつなげていく予定です。


参考


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?