前回:https://shikuuk.blogspot.com/2025/07/pythonjaxaalos2.html
第3部は2つ(以上)の5*5タイルを読み込み、そのDataをMargeしてMosicImageにしたあと、MatplotlibでTry to drawとThinkします。
ALOSはJapanDomainだけでなくGlobalなElavationDataをContainしているAs、例えばIndonesiaのSumatraIslandをDrawにTryします。
まずはALOSのDownLoadHPでIndonesiaSumatraIslandのAroundのConditionをConfirmします。
SumatraIslandは5*5のTileでViewすると、North-WestはN10-E95で、そこからS05E105のTileまでがArea we should readのRegionと思われます。
一度にそこまで進めると、Errorが出た時が面倒くさいので、まずはN10-E95とN5-E100の2つのTileを処理するところからはじめてみました。従来のCodeを使って当該2TilesをDownLaodし、MatplotlibでDrawすると、以下のOutputになります。ColarのContourFigureとLineのContour Figureを作成していますが、最初、ColorのContourFigureでは海岸線が見づらくて、LineContourを追加したところ、LineContourもColorContourによく似た表示になりました。「なぜかなぁ?」とちょっと悩みましたが、ContourLineの間隔、言い換えれば等高線の間隔が小さすぎるということが原因でした。下のLineContourは標高値200m間隔になっています。これでもまだごちゃごちゃしていて見づらい感じは残っています。
例えばContourの間隔を500mにすると、このようなFigureにbecomeしました。
import rasterio
import matplotlib.pyplot as plt
import numpy as np
import os
from skimage.transform import downscale_local_mean
import math # mathモジュールのインポートを追加
def plot_merged_elevation(filepath):
"""
指定されたGeoTIFF標高ファイルをMatplotlibでGoogle Colabの出力ウィンドウに直接表示します。
メモリ使用量を抑えるために、データをリサイズしてからプロットします。
Args:
filepath (str): 表示するGeoTIFFファイルのパス。
"""
if not os.path.exists(filepath):
print(f"エラー: GeoTIFFファイル '{filepath}' が見つかりません。")
return
try:
with rasterio.open(filepath) as src:
# 標高データを読み込む(通常はバンド1)
elevation_data = src.read(1)
print(f"オリジナルデータのサイズ: {elevation_data.shape}")
# 巨大なデータセットをリサイズしてメモリを節約
# 8分の1にリサイズする例 (ダウンサンプリング)
downscaled_elevation = downscale_local_mean(elevation_data, (8, 8))
print(f"リサイズ後のデータのサイズ: {downscaled_elevation.shape}")
# リサイズされたデータにNoData値が存在する場合、それをNaN(非数)に変換
if src.nodata is not None:
# 浮動小数点型に変換してからNaNを代入
if downscaled_elevation.dtype != np.float64:
downscaled_elevation = downscaled_elevation.astype(np.float64)
downscaled_elevation[downscaled_elevation == src.nodata] = np.nan
# プロットのセットアップ
fig, ax = plt.subplots(figsize=(10, 8))
# 画像として標高データを表示
valid_downscaled_data = downscaled_elevation[~np.isnan(downscaled_elevation)]
if valid_downscaled_data.size > 0:
vmin = np.nanpercentile(valid_downscaled_data, 2)
vmax = np.nanpercentile(valid_downscaled_data, 98)
else:
vmin, vmax = None, None
# 画像の表示範囲を設定 (左経度, 右経度, 下緯度, 上緯度)
bounds = src.bounds
extent = [bounds.left, bounds.right, bounds.bottom, bounds.top]
im = ax.imshow(
downscaled_elevation,
cmap='viridis',
origin='upper',
extent=extent,
vmin=vmin,
vmax=vmax
)
ax.set_aspect('equal') # アスペクト比を等しく設定
ax.set_title(f'Downscaled Elevation Data (Color Map): {os.path.basename(filepath)}')
ax.set_xlabel('Longitude')
ax.set_ylabel('Latitude')
fig.colorbar(im, ax=ax, label='Elevation (meters)')
ax.grid(True, linestyle=':', alpha=0.7)
fig.tight_layout()
plt.show()
except rasterio.errors.RasterioIOError as e:
print(f"エラー: GeoTIFFファイル '{filepath}' を開けませんでした: {e}")
except Exception as e:
print(f"予期せぬエラーが発生しました: {e}")
def plot_merged_elevation_contour(filepath):
"""
指定されたGeoTIFF標高ファイルをMatplotlibでGoogle Colabの出力ウィンドウに直接表示します。
メモリ使用量を抑えるためにデータをリサイズし、等高線マップとしてプロットします。
背景の着色は行いません。
Args:
filepath (str): 表示するGeoTIFFファイルのパス。
"""
if not os.path.exists(filepath):
print(f"エラー: GeoTIFFファイル '{filepath}' が見つかりません。")
return
try:
with rasterio.open(filepath) as src:
# 標高データを読み込む(通常はバンド1)
elevation_data = src.read(1)
print(f"オリジナルデータのサイズ: {elevation_data.shape}")
# 巨大なデータセットをリサイズしてメモリを節約
# 8分の1にリサイズする例 (ダウンサンプリング)
downscaled_elevation = downscale_local_mean(elevation_data, (8, 8))
print(f"リサイズ後のデータのサイズ: {downscaled_elevation.shape}")
# リサイズされたデータにNoData値が存在する場合、それをNaN(非数)に変換
if src.nodata is not None:
# 浮動小数点型に変換してからNaNを代入
if downscaled_elevation.dtype != np.float64:
downscaled_elevation = downscaled_elevation.astype(np.float64)
downscaled_elevation[downscaled_elevation == src.nodata] = np.nan
# プロットのセットアップ
fig, ax = plt.subplots(figsize=(10, 8))
# 画像の表示範囲を設定 (左経度, 右経度, 下緯度, 上緯度)
bounds = src.bounds
extent = [bounds.left, bounds.right, bounds.bottom, bounds.top]
# 等高線を描画
valid_data = downscaled_elevation[~np.isnan(downscaled_elevation)]
if valid_data.size > 0:
min_elev = np.nanmin(valid_data)
max_elev = np.nanmax(valid_data)
# 等高線の間隔を調整(例:200mごと)
levels = np.arange(math.floor(min_elev / 200) * 200, math.ceil(max_elev / 200) * 200 + 200, 200)
else:
levels = None # 有効なデータがない場合は等高線を描画しない
if levels is not None and len(levels) > 1:
# 等高線プロット (背景のimshowは削除)
contour_plot = ax.contour(
downscaled_elevation,
levels=levels,
cmap='terrain', # 地形に適したカラーマップ
linewidths=0.4, # 線の太さを0.8から0.4に変更
extent=extent, # 地理的な範囲を設定
origin='upper' # 画像の原点を左上に設定
)
# 等高線にラベルを追加
# inline_spacingを大きくして、ラベルの表示数を減らす
ax.clabel(contour_plot, inline=True, fontsize=8, fmt='%1.0f', inline_spacing=10)
else:
print("Warning: Not enough valid elevation data or levels to draw contours.")
ax.set_aspect('equal') # アスペクト比を等しく設定
# ax.imshow() を削除したため、背景は透明になります
# 必要であれば、ax.set_facecolor('lightgray') などで単一の背景色を設定できます
ax.set_title(f'Downscaled Elevation Data (Contour Map): {os.path.basename(filepath)}')
ax.set_xlabel('Longitude')
ax.set_ylabel('Latitude')
# 等高線マップではカラーバーは必須ではないため、削除
# fig.colorbar(im, ax=ax, label='Elevation (meters)')
ax.grid(True, linestyle=':', alpha=0.7)
fig.tight_layout()
plt.show()
except rasterio.errors.RasterioIOError as e:
print(f"エラー: GeoTIFFファイル '{filepath}' を開けませんでした: {e}")
except Exception as e:
print(f"予期せぬエラーが発生しました: {e}")
# --- メイン実行ブロック ---
if __name__ == "__main__":
# 結合されたGeoTIFFファイルが保存されているディレクトリ
extracted_data_dir = '/content/all_unzip_files'
# 結合されたGeoTIFFファイルのパス
merged_elevation_filepath = os.path.join(extracted_data_dir, 'merged_elevation.tif')
# カラーマップで標高データを表示
print("--- カラーマップで標高データを表示 ---")
plot_merged_elevation(merged_elevation_filepath)
# 等高線マップで標高データを表示
print("\n--- 等高線マップで標高データを表示 ---")
plot_merged_elevation_contour(merged_elevation_filepath)
次は、All parts of SumatraIslandのALOS_DEM_DataのGetにTryします。
まず最初にALOSのHP(https://www.eorc.jaxa.jp/ALOS/aw3d/index.htm)からSmatraIslandのDEM_DataをPCにDownLoadしたあと、TheseFilesをGoogleDriveにUploadします。
次に、GoogleDriveにUploadしたZipFileのUnzipOperationですが、これまではCode内にFilenameを1つずつWriteしていましたが、面倒くさいので、ALOS_DEM_Dataを取得する範囲をNorth-WestCornerとSouth-EastCounerのLogitude,Latitudeから、その中に含まれているはずのLongtudeとLatitudeそれぞれ5degreeごとにAutomaticにForRoopを使ってFilenameをCreateしておき、当該FilenemaがGoogleDrive上にあればUnzipOperationに繊維、当該FilenameがExitしないならそのFilenameをIgnore、skipするCodeをMasterGeminiにAsk for Creatingしました。
# 20250806_Latest version
# Automatically Create the zip filenames from subject area's north-west lon, lat and south-west lon, lat
import os
import zipfile
import math
from google.colab import drive
def generate_alos_zip_filenames(nw_lat, nw_lon, se_lat, se_lon):
"""
指定された北西隅角と南東隅角の緯度経度に基づいて、
該当するALOS 5x5タイルZIPファイルのファイル名を生成します。
ALOS 5x5タイルZIPの命名規則は、SW_LAT_LON_NE_LAT_LON.zip形式です。
例: N005E095_N010E100.zip は、緯度5N-10N、経度95E-100Eの範囲を示します。
Args:
nw_lat (float): 北西隅角の緯度 (例: 10.0)
nw_lon (float): 北西隅角の経度 (例: 95.0)
se_lat (float): 南東隅角の緯度 (例: 0.0)
se_lon (float): 南東隅角の経度 (例: 100.0)
Returns:
list: 生成されたZIPファイル名のリスト。
"""
zip_filenames = []
# 5度グリッドの開始緯度・経度を計算
# 緯度は南から北へ、経度は西から東へループ
start_lat_grid = math.floor(se_lat / 5) * 5
end_lat_grid = math.ceil(nw_lat / 5) * 5
start_lon_grid = math.floor(nw_lon / 5) * 5
end_lon_grid = math.ceil(se_lon / 5) * 5
current_lat_grid = start_lat_grid
while current_lat_grid < end_lat_grid:
current_lon_grid = start_lon_grid
while current_lon_grid < end_lon_grid:
# 5x5ブロックの南西隅角
sw_lat = current_lat_grid
sw_lon = current_lon_grid
# 5x5ブロックの北東隅角
ne_lat = current_lat_grid + 5
ne_lon = current_lon_grid + 5
# ファイル名コンポーネントのフォーマット
# 緯度: Nで北、Sで南。3桁でゼロ埋め。
sw_lat_str = f"N{sw_lat:03d}" if sw_lat >= 0 else f"S{-sw_lat:03d}"
ne_lat_str = f"N{ne_lat:03d}" if ne_lat >= 0 else f"S{-ne_lat:03d}"
# 経度: Eで東、Wで西。3桁でゼロ埋め。
sw_lon_str = f"E{sw_lon:03d}" if sw_lon >= 0 else f"W{-sw_lon:03d}"
ne_lon_str = f"E{ne_lon:03d}" if ne_lon >= 0 else f"W{-ne_lon:03d}"
zip_filename = f"{sw_lat_str}{sw_lon_str}_{ne_lat_str}{ne_lon_str}.zip"
zip_filenames.append(zip_filename)
current_lon_grid += 5
current_lat_grid += 5
return zip_filenames
def unzip_alos_data(zip_files_full_paths, output_dir):
"""
指定されたZIPファイルのリストを解凍し、指定されたディレクトリにすべての内容を抽出します。
ファイルは元のサブフォルダ構造を維持して保存されます。
Args:
zip_files_full_paths (list): 解凍するZIPファイルのフルパスのリスト。
output_dir (str): 解凍したファイルを保存する出力ディレクトリのパス。
"""
# 出力ディレクトリが存在しない場合は作成
os.makedirs(output_dir, exist_ok=True)
print(f"解凍先ディレクトリが作成されました: {output_dir}")
# 各ZIPファイルを解凍
for zip_file_path in zip_files_full_paths:
try:
with zipfile.ZipFile(zip_file_path, 'r') as zip_ref:
print(f"'{os.path.basename(zip_file_path)}' を解凍中...")
# ZIPファイル内のディレクトリ構造を維持して解凍
zip_ref.extractall(output_dir)
print(f"'{os.path.basename(zip_file_path)}' を '{output_dir}' に正常に解凍しました。")
except FileNotFoundError:
print(f"エラー: ファイル '{zip_file_path}' が見つかりません。スキップします。")
except zipfile.BadZipFile:
print(f"エラー: ファイル '{zip_file_path}' は有効なZIPファイルではありません。スキップします。")
except Exception as e:
print(f"'{zip_file_path}' の解凍中に予期せぬエラーが発生しました: {e}。スキップします。")
print("\n解凍処理が完了しました。")
print(f"解凍先ディレクトリ '{output_dir}' の内容:")
print(os.listdir(output_dir))
# --- メイン実行ブロック ---
if __name__ == "__main__":
# Google Driveをマウント
print("Google Driveをマウント中...")
drive.mount('/content/drive')
print("Google Driveのマウントが完了しました。")
# --- 解凍したいエリアの緯度経度を入力 ---
# 例: スマトラ島周辺の特定のエリア (N000E095_N005E100.zip と N005E095_N010E100.zip を含む範囲)
# 北西隅角 (緯度, 経度)
area_nw_lat = 10.0
area_nw_lon = 95.0
# 南東隅角 (緯度, 経度)
area_se_lat = -10
area_se_lon = 110.0
print(f"\n指定されたエリア: 北西 ({area_nw_lat}N, {area_nw_lon}E) - 南東 ({area_se_lat}N, {area_se_lon}E)")
# 該当するZIPファイル名を生成
generated_zip_filenames = generate_alos_zip_filenames(
area_nw_lat, area_nw_lon, area_se_lat, area_se_lon
)
if not generated_zip_filenames:
print("指定されたエリアに該当するZIPファイル名が生成されませんでした。")
else:
print("\n生成されたZIPファイル名リスト:")
for fname in generated_zip_filenames:
print(f"- {fname}")
# ZIPファイルが格納されているGoogle Drive上のディレクトリ
google_drive_zip_dir = '/content/drive/MyDrive/Colab Notebooks/20240805_ALOS_DEM'
# 解凍するZIPファイルのフルパスのリストを作成
zip_files_full_paths = [
os.path.join(google_drive_zip_dir, fname) for fname in generated_zip_filenames
]
# 解凍したファイルを保存する新しいディレクトリ
output_directory = '/content/extracted_alos_data'
# 関数を呼び出して解凍処理を実行
unzip_alos_data(zip_files_full_paths, output_directory)
>>Output<<
Google Driveをマウント中...
Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount("/content/drive", force_remount=True).
Google Driveのマウントが完了しました。
指定されたエリア: 北西 (10.0N, 95.0E) - 南東 (-10N, 110.0E)
生成されたZIPファイル名リスト:
- S010E095_S005E100.zip
- S010E100_S005E105.zip
- S010E105_S005E110.zip
- S005E095_N000E100.zip
- S005E100_N000E105.zip
- S005E105_N000E110.zip
- N000E095_N005E100.zip
- N000E100_N005E105.zip
- N000E105_N005E110.zip
- N005E095_N010E100.zip
- N005E100_N010E105.zip
- N005E105_N010E110.zip
解凍先ディレクトリが作成されました: /content/extracted_alos_data
エラー: ファイル '/content/drive/MyDrive/Colab Notebooks/20240805_ALOS_DEM/S010E095_S005E100.zip' が見つかりません。スキップします。
'S010E100_S005E105.zip' を解凍中...
'S010E100_S005E105.zip' を '/content/extracted_alos_data' に正常に解凍しました。
'S010E105_S005E110.zip' を解凍中...
'S010E105_S005E110.zip' を '/content/extracted_alos_data' に正常に解凍しました。
エラー: ファイル '/content/drive/MyDrive/Colab Notebooks/20240805_ALOS_DEM/S005E095_N000E100.zip' が見つかりません。スキップします。
'S005E100_N000E105.zip' を解凍中...
'S005E100_N000E105.zip' を '/content/extracted_alos_data' に正常に解凍しました。
'S005E105_N000E110.zip' を解凍中...
'S005E105_N000E110.zip' を '/content/extracted_alos_data' に正常に解凍しました。
'N000E095_N005E100.zip' を解凍中...
'N000E095_N005E100.zip' を '/content/extracted_alos_data' に正常に解凍しました。
'N000E100_N005E105.zip' を解凍中...
'N000E100_N005E105.zip' を '/content/extracted_alos_data' に正常に解凍しました。
エラー: ファイル '/content/drive/MyDrive/Colab Notebooks/20240805_ALOS_DEM/N000E105_N005E110.zip' が見つかりません。スキップします。
'N005E095_N010E100.zip' を解凍中...
'N005E095_N010E100.zip' を '/content/extracted_alos_data' に正常に解凍しました。
エラー: ファイル '/content/drive/MyDrive/Colab Notebooks/20240805_ALOS_DEM/N005E100_N010E105.zip' が見つかりません。スキップします。
エラー: ファイル '/content/drive/MyDrive/Colab Notebooks/20240805_ALOS_DEM/N005E105_N010E110.zip' が見つかりません。スキップします。
解凍処理が完了しました。
解凍先ディレクトリ '/content/extracted_alos_data' の内容:
['S005E105_N000E110', 'N000E100_N005E105', 'S010E105_S005E110', 'N000E095_N005E100', 'N005E095_N010E100', 'S010E100_S005E105', 'S005E100_N000E105']
次に、それぞれのZipFilenameに基づいて別々のFolderに格納されたDataFileを新たに作成した1つのFolderに格納しなおします。このCodeもMasterGeminiにCreatしてもらいました。(別々のFolderに格納されたままだと、それぞれのFolderに必要なFileを探しに行かないといけないので面倒です。ですので、1つのFolderにまとめておいて、そのFolderの中だけを検索して必要なFileを取り出すようにしました。)
# 20250801_Update
# Collect Tile Files to one Folder
import os
import shutil
def move_files_from_subdirectories(source_dir, destination_dir):
"""
指定されたソースディレクトリにあるサブディレクトリ内のすべてのファイルを、
新しいデスティネーションディレクトリに移動します。
Args:
source_dir (str): 移動元のルートディレクトリのパス。
destination_dir (str): 移動先のディレクトリのパス。
"""
# 移動先ディレクトリが存在しない場合は作成
os.makedirs(destination_dir, exist_ok=True)
print(f"Destination directory created at: {destination_dir}")
# ソースディレクトリ内のファイルとフォルダをリストアップ
for item in os.listdir(source_dir):
source_path = os.path.join(source_dir, item)
# サブディレクトリのみを対象にファイルを移動
if os.path.isdir(source_path):
print(f"Processing subdirectory: {source_path}")
# サブディレクトリ内のファイルをすべてリストアップ
for filename in os.listdir(source_path):
file_path = os.path.join(source_path, filename)
if os.path.isfile(file_path):
# 移動先に同じファイル名が存在しないか確認
dest_path = os.path.join(destination_dir, filename)
if os.path.exists(dest_path):
print(f"Warning: File '{filename}' already exists in the destination. Skipping.")
continue
# ファイルを移動
try:
shutil.move(file_path, destination_dir)
print(f"Moved file: {file_path} -> {destination_dir}")
except Exception as e:
print(f"Error moving file {file_path}: {e}")
# ファイルを移動した後に空になったサブディレクトリを削除
try:
os.rmdir(source_path)
print(f"Removed empty directory: {source_path}")
except OSError as e:
print(f"Error removing directory {source_path}: {e}")
elif os.path.isfile(source_path):
# ソースディレクトリ直下のファイルも移動
print(f"Processing file: {source_path}")
dest_path = os.path.join(destination_dir, item)
if os.path.exists(dest_path):
print(f"Warning: File '{item}' already exists in the destination. Skipping.")
continue
try:
shutil.move(source_path, destination_dir)
print(f"Moved file: {source_path} -> {destination_dir}")
except Exception as e:
print(f"Error moving file {source_path}: {e}")
print("\nFile moving process completed.")
print(f"Content of the new directory '{destination_dir}':")
print(os.listdir(destination_dir))
print(f"Content of the original directory '{source_dir}':")
print(os.listdir(source_dir))
# --- メイン実行ブロック ---
if __name__ == "__main__":
# ZIP解凍で生成されたファイルが格納されているディレクトリ
source_directory = '/content/extracted_alos_data'
# 移動先の新しいディレクトリ名
new_directory_name = 'all_unzip_files'
# 新しいディレクトリのフルパス
destination_directory = os.path.join('/content', new_directory_name)
# 関数を呼び出してファイル移動処理を実行
move_files_from_subdirectories(source_directory, destination_directory)
このFolderの中にあるFileからDEM_Data_FileであるFilenameの末尾が‘DSM.tif’となっているものを全てTakeOutしたうえで、それらのFileのDEM_DataをMargeして大きなDEM_Modelを作成します。このCodeももちろんMasterGeminiのSuggestionです。
# 20250806_Update
# recognize automatcally '***DSM.tif' files
import rasterio
import os
import numpy as np
from rasterio.enums import Resampling
from rasterio.merge import merge
def merge_alos_tiles(tile_dir, output_filepath):
"""
指定されたディレクトリ内の末尾が'DSM.tif'のすべてのALOS GeoTIFFファイルを読み込み、結合し、新しいファイルとして保存します。
Args:
tile_dir (str): GeoTIFFファイルが格納されているディレクトリのパス。
output_filepath (str): 結合されたGeoTIFFファイルの出力パス。
Returns:
str: 結合されたGeoTIFFファイルのパス (成功した場合)、またはNone (失敗した場合)。
"""
src_files_to_mosaic = []
# ディレクトリ内を検索して、末尾が'DSM.tif'のファイルを見つける
specific_tile_filenames = [f for f in os.listdir(tile_dir) if f.endswith('DSM.tif')]
# 指定されたファイル名リストをループしてファイルを開く
for filename in specific_tile_filenames:
filepath = os.path.join(tile_dir, filename)
if not os.path.exists(filepath):
print(f"Warning: Specified file '{filepath}' does not exist. Skipping.")
continue
try:
src_files_to_mosaic.append(rasterio.open(filepath))
except rasterio.errors.RasterioIOError as e:
print(f"Warning: Could not open {filepath} (possibly corrupted or not a valid GeoTIFF): {e}. Skipping.")
except Exception as e:
print(f"Warning: Unexpected error opening {filepath}: {e}. Skipping.")
if not src_files_to_mosaic:
print("No valid GeoTIFF tile files found to merge from the specified list. Exiting.")
return None
print(f"Merging {len(src_files_to_mosaic)} tiles...")
# Merge the datasets
mosaic, out_transform = merge(src_files_to_mosaic, resampling=Resampling.nearest)
# Get metadata from the first source file and update with merged properties
out_meta = src_files_to_mosaic[0].meta.copy()
out_meta.update({
"driver": "GTiff",
"height": mosaic.shape[1],
"width": mosaic.shape[2],
"transform": out_transform,
"crs": src_files_to_mosaic[0].crs,
"nodata": src_files_to_mosaic[0].nodata
})
# Close all source files
for src in src_files_to_mosaic:
src.close()
# Save the merged mosaic to a new GeoTIFF file
try:
with rasterio.open(output_filepath, "w", **out_meta) as dest:
dest.write(mosaic)
print(f"Successfully merged tiles to '{output_filepath}'.")
return output_filepath
except Exception as e:
print(f"Error saving merged GeoTIFF: {e}")
return None
# --- Main Execution Block ---
if __name__ == "__main__":
# Define the directory where GeoTIFF files are extracted
extracted_data_dir = '/content/all_unzip_files'
# Define the output path for the merged GeoTIFF file in Google Colab's file system
output_merged_filepath = os.path.join(extracted_data_dir, 'merged_elevation.tif')
print("Starting GeoTIFF tile merging process...")
# 関数からselected_filenames引数を削除
merged_file_path = merge_alos_tiles(extracted_data_dir, output_merged_filepath)
if merged_file_path:
print(f"\nSuccessfully merged all tiles. The merged file is saved to your Google Colab file system at: {merged_file_path}")
else:
print("GeoTIFF file merging failed.")
これでスマトラ島全体のALOSの30mResolutionのDigitalElevationDataをGetすることができました。これをMatplotlibでPlotすると次のような画像が得られました。
コメント
コメントを投稿