7
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?

MATLAB/SimulinkAdvent Calendar 2023

Day 18

日本の標高データをMATLABで活用 - モザイク結合 -

Last updated at Posted at 2023-12-17

目次

はじめに
今回やること
フォルダを読み込む
2次メッシュに当てはめるための格子を作成する
3次メッシュ番号を抜き出す
3次メッシュデータを決まった場所に格納する
データのない箇所を探す
データを読み込む
データの欠損部分をNaNで埋める
画像データを上下逆にする
モザイク結合
出力
閑話休題:EPSG
出力結果
おまけ
参考


はじめに

暇な人向け挨拶はこちら

やあみんな!俺だ!

シンボリックは数式。俺はこじき!それじゃあ!!

やあみんな俺だ.png
※この画像は載せるのをやめる予定でしたが強い要望のため掲載しました。


本件は日本の標高データをMATLABで活用 - GeoTiff変換 -の続きです。

先回はDEMデータをGeoTiffファイルにしました。

しかしきれいに繋がらなかったり、そもそも3次メッシュが一部欠損してたり…

これらを(0, 0) ~ (9,9)までの区画に当てはめて2次メッシュをきれいに結合します。

モザイク結合についてはラスターの統合 - モザイクを見てください。

今回やること

3次メッシュを100枚集めて結合し2次メッシュにします。

イメージとしては以下のように3次メッシュ5841-46-43を(4, 3)に当てはめていく感じです。

image_0.png

フォルダを読み込む

先回作った5841-46-XXのメッシュでXXは(0, 0) ~ (9, 9)にそれぞれ当てはまる合計100このtifファイルがあるはずです。

まずは先回作ったtmpファイル内の中を見ていきましょう。

clc,clear,close all;
path = 'FG-GML-5841-46-DEM1A\tmp';
fnames = dir(fullfile(path,"*.tif"));

path = fnames(1).folder;
file = {fnames.name}';
fsize =  length(file);

後は100枚のファイルを並べてモザイク結合を…

fprintf("tifファイルは%0iこ",fsize)

ん…?

tifファイルは82こ

そうです。3次メッシュが100こない場合もあります。

今回のファイルだと00の次が10になっていることがわかります。

image_1.png

これは後で全てNaNのダミーデータを作って無理やり当てはめます。

2次メッシュに当てはめるための格子を作成する

先程の画像のような格子をcell配列で作り、各cellに3次メッシュ情報をぶち込めばOKです。

この時にGeoTiffファイルがない部分には同じサイズのNaN行列を入れ込みます。

3次メッシュ番号を抜き出す

まずは番地に当てはめるために番号を抽出しましょう。

[~,name,~] = fileparts(file);
name = cell2mat(name);
rr  = str2double(string(name(:,end-1:end)));
disp(rr(1:4))
     0
    10
    11
    14

3次メッシュデータを決まった場所に格納する

次に全部Falseにした10×10の配列を作成します。

これは後でどこに3次メッシュデータがあるかを探索するように使います。

IDX1 = false(10);
IDX2 = IDX1;

次に1桁目と2桁目を分離させ、行番号と列番号を抽出します。

10a + b ⇒ (a, b) にする感じです。

またMATLABなので(1, 1)からスタートする必要があるため1を各桁に加算します。

10の位と1の位を分割し、1からスタートさせるよう加算します。

digits = [floor(rr./10), rem(rr,10)] + 1;
disp(digits(1:4,:))
     1     1
     2     1
     2     2
     2     5

GeoTiffファイルを入れるため10×10のcell配列を作ります。

Rasters = cell(10);

最初のcell部分はTrueにしておきます。
今回は(0, 0)スタートなので以下の部分がTrueになる感じです。

image_3.png

IDX1(digits(:,1), digits(:,2)) = true;

データのない箇所を探す

データのあるファイルの出力先をIDX2であぶりだします。

idx1 = sub2ind(size(IDX1),digits(:,1),digits(:,2));
IDX2(idx1) = true;

わかりやすいように図示します。

データがない箇所を黒、データがある場所が白です。

figure
image(IDX2)
axis xy
colormap([0, 0, 0; 1, 1, 1])
colorbar('Ticks',[0,1],'TickLabels',{'データ無','データ有'})

figure_0.png

右下がデータないんですね。多分海だからでしょうね。

データを読み込む

各GeoTIFFファイルを読み込み、緯度経度高度を各配列に格納します。

Lats = zeros(fsize,2);
Lons = Lats;
RSzs = Lats;

for ii = 1:length(idx1)
    [Z,Ref] = readgeoraster(fullfile(path,file{ii}),'OutputType','double');
    Rasters(idx1(ii)) = {Z};
    Lats(ii,:) = Ref.LatitudeLimits;
    Lons(ii,:) = Ref.LongitudeLimits;
    RSzs(ii,:) = Ref.RasterSize;
end

データの欠損部分をNaNで埋める

排他的論理和でFalseとTrueを反転させます。

IDX3 = xor(IDX1,IDX2);

Raster内で埋める必要があるところを750×1125のNaN配列で埋めます。

idx2 = find(IDX3);
Rasters(idx2) = {nan(RSzs(1,:))};

残りは画像として排除していいのでNAN埋めします。

idx3 = find(~IDX1);
Rasters(idx3) = {nan(RSzs(1,:))};

画像データを上下逆にする

上下を反対にして一枚のdoubleデータにします。

MATLABでは左上が(0, 0)ですが、2次メッシュの当てはめ方は左下が(0, 0)です。

なので flip関数 で順序を入れ替える必要があります。

check = flip(Rasters);
Rasters = cell2mat(flip(Rasters));
Rasters = Rasters(:,~all(isnan(Rasters),1));
Rasters = Rasters(~all(isnan(Rasters),2),:);

モザイク結合

緯度・経度・高度情報(750×1125)をcell配列の決められた番地に格納していきます。

結合は georefcells で出来ます。

LatsLim = [min(Lats(:,1)), max(Lats(:,2))];
LonsLim = [min(Lons(:,1)), max(Lons(:,2))];
R = georefcells(LatsLim, LonsLim,size(Rasters),"ColumnsStartFrom","north");

MATLAB上で問題ないか見てみましょう。

geoshow(uint8(Rasters),R)

image.png
できてそうですね。

1m間隔のメッシュをgeoshowで確認しようとするとめっちゃメモリ使います。
特にライブスクリプトはクラッシュもあります。
気を付けましょう。

出力

さて出力します。

geotiffwrite('GeoTiff_Merge.tif',single(Rasters),R,"CoordRefSysCode",'EPSG:6668')
disp('嗚呼…モザイク結合完了…')
嗚呼…モザイク結合完了…

嗚呼…モザイク結合完了…(画像略)

閑話休題:EPSG

EPSGとはGISで使用される様々な要素に必要なパラメータを1つにまとめたものです。

それらの集合体同士を区別するためにEPSGコードで割り振ってるんですね。

実は地球は丸くなくて楕円体で近似を取っています。

そして日本の標高の基準は、測量法で平均海面と定められています。

この平均海面を仮想的に陸地へ延長した面をジオイドといいます。

image_6.png

つまり
image_5.png

EPSGコードから場所とかを参照して高さを求めてるんですね(テキトー解釈)。

なんだかとってもおもしろいよね。

※けっこうテキトーな事を言ってるので各自確認してください。
 今回はジオイドモデルではなく、数値標高モデルを使ってます。

出力結果

さて結果を見てみましょう。

今回もフリーソフト QGIS で確認します。

image_7.png

きちんとできていることがわかりました。

おまけ

実はアプリも作ってます。

こちらは waitbar 等のメッセージボックスを入れてUIをあげてます。

image_8.png

こいつはライトニングトーク用かなあ。

参考

7
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
7
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?