QGISで点群データ(txt)からラスタ(tif)の一括作成

## QGISで点群データからTifを一括作成したいのでpythonコードを組んでみる
本記事は以下の記事を参考にしています。
・[三次元点群データをQGISでひり出してみた](https://qiita.com/Yfuruchin/items/7b9ea3e823824d2e4e86#las%E3%81%8B%E3%82%89dtm%E4%BD%9C%E6%88%90)
処理の大まかな流れとしてはtxt→las→dtm→tifの順で作成します。

### 事前準備
- QGIS 3.28.6
- [LAStoolsのセットアップ](https://qiita.com/Yfuruchin/items/7b9ea3e823824d2e4e86#lastools%E3%81%AE%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97)
- [FUSIONのセットアップ](https://qiita.com/Yfuruchin/items/7b9ea3e823824d2e4e86#fusion%E3%81%AE%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97)
※ LAStoolsとFUSIONの本体DL後のインストール先に関して
　 こちらの環境だと何故かCドライブ直下に置かないと動きませんでした
   もし動かないのであれば参考にされてください。
   (理由は分かりません、だれか教えてください)

#### 点群データ(txt)のフォーマット
| 1 | -14000 | 69712.16 | 59.38 | 2 |
| - | - | - | - | - |
| 2 | -14000 | 69714.98 | 60.93 | 1 |
| 3 | -14000 | 69715.75 | 61.02 | 1 |
| 4 | -14000 | 69728.65 | 53.12 | 1 |
| 5 | -14000 | 69744.88 | 50.03 | 1 |
| 6 | -14000 | 69706.35 | 54.81 | 2 |
| 7 | -14000 | 69747.85 | 48 | 2 |
| 8 | -14000 | 69748.55 | 49.81 | 1 |
| 9 | -14000 | 69719.77 | 54.95 | 2 |
| 10 | -14000 | 69741.7 | 51.9 | 1 |
| 11 | -14000 | 69703.45 | 62.23 | 1 |
| 12 | -14000 | 69720.27 | 49.39 | 5 |

上記はNo,X,Y,Z,flgのフォーマットとなります。

#### QGISのpythonコンソールからプログラムの実行
1. pythonコンソールを出す（右上側にある赤で囲まれたボタンを押下します）
![python押下.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637071/d58bee4c-8bc5-5620-11fe-13d6f8ea2448.png)

2. エディタを表示(黄色枠) 表示されない場合は左下の赤枠のボタンを押下
![エディタ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637071/920547bb-397a-60c6-c19f-11c14ff1ffdf.png)

3.以下のコードをエディタに張り付けます
 target_pathを作業対象フォルダの絶対パスで書き換えてください
 target_pathで指定した作業対象フォルダの中に不要なtxtは格納しないでください
```python:createTif.py
import processing
import os

"""
in: target_path  txtが入ったフォルダを指定
　　　　　　　     ※target_pathで指定したフォルダには作業対象の
　　　　　　　　　　  txt以外入れないでください
out: target_pathにtifとlasとdtmが作成される
"""
target_path = r"C:\Users\user\hogehoge"

for filename in os.listdir(target_path):
    if filename.endswith('.txt'):
        input_txt_path = os.path.join(target_path, filename)
        out_name = os.path.splitext(filename)[0] + ".las"
        out_las_path = os.path.join(target_path, out_name)
        # lasデータの作成
        try:
            processing.run("LAStools:Txt2Las", {'VERBOSE':False,
                                                'CPU64':True,
                                                'GUI':False,
                                                'INPUT_GENERIC':input_txt_path,
                                                'PARSE':'sxyz',
                                                # ※1
                                                'SKIP':0,
                                                'SCALE_FACTOR_XY':0.01,
                                                'SCALE_FACTOR_Z':0.01,
                                                'PROJECTION':1,
                                                # ※3
                                                'EPSG_CODE':6670,
                                                'UTM':0,
                                                'SP':0,
                                                'OUTPUT_LASLAZ':out_las_path,
                                                'ADDITIONAL_OPTIONS':''
                                                })
        except Exception:
        # ※2
            print("it's a decoding error, so ignore it.")
        
        # dtmデータの作成
        out_name = os.path.splitext(filename)[0] + ".dtm"
        out_dtm_path = os.path.join(target_path, out_name)
        processing.run("fusion:gridsurfacecreate", {'INPUT':out_las_path,
                                                    'CELLSIZE':0.1,
                                                    'XYUNITS':0,
                                                    'ZUNITS':0,
                                                    'VERSION64':True,
                                                    'OUTPUT_DTM':out_dtm_path,
                                                    'SPIKE':'',
                                                    'MEDIAN':'',
                                                    'SMOOTH':'',
                                                    'MINIMUM':'',
                                                    'CLASS':'',
                                                    'SLOPE':'',
                                                    'ADVANCED_MODIFIERS':''}
                                                    )
        # tifデータの作成
        out_name = os.path.splitext(filename)[0] + ".tif"
        out_tif_path = os.path.join(target_path, out_name)
        processing.run("fusion:dtm2ascii", {'INPUT':out_dtm_path,
                                            'CSV':False,
                                            'RASTER':False,
                                            'MULTIPLIER':None,
                                            'OUTPUT':out_tif_path
                                            })
print("finish")

```
※1 txtのフォーマットが変わった場合は'PARSE'のオプション変更が必要
　　現在のオプションの"sxyz"のsはskip対象列の事、txtが先頭からxyzの順で
　　並ぶのであればPARSEのオプションはxyzのみで良い
※2 LAStoolsのTxt2Lasでlasを作成する際に何故かUnicodeDecodeErrorになります。
    　　Errorは出てもlasはしっかり吐き出してくれているので問題視はしてないです。
　　UnicodeDecodeErrorを指定してcatchしようとしても何故か
　　catch出来ないので無理やりExceptionにしてます。
  　　つよつよエンジニアの方対策教えてください。
※3 座標系は'EPSG_CODE':6670,ここをいじくりまわしてください

4.赤枠の実行ボタン押下
![実行.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637071/f7312b36-444c-b035-0a73-6845c307e0cc.png)
めんどくさかったので終了時のダイアログは用意してないです。
コンソールにfinishと出たらokです。

例：作成したTIF
![スクリーンショット 2023-12-07 110220.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637071/92a2a6b1-aede-159a-430c-9c72573a1873.png)