###20250729_LatestVersion
###Get the Tiff Data by assigning the file name directly
import rasterio
import matplotlib.pyplot as plt
import numpy as np
import os
from rasterio.enums import Resampling
from rasterio.merge import merge # Ensure merge is imported
def merge_elevation_tiles(tile_dir, output_filepath):
"""
Reads specific GeoTIFF elevation tiles in the specified directory,
merges them into a single GeoTIFF file, and saves it.
Args:
tile_dir (str): Path to the directory containing GeoTIFF files.
output_filepath (str): Output path for the merged GeoTIFF file.
Returns:
str: Path to the merged GeoTIFF file (on success), or None (on failure).
"""
# ユーザーが指定したGeoTIFFファイル名のリスト
specific_tile_filenames = [
'ALPSMLC30_N034E134_DSM.tif',
'ALPSMLC30_N033E134_DSM.tif',
'ALPSMLC30_N034E133_DSM.tif',
'ALPSMLC30_N033E133_DSM.tif',
'ALPSMLC30_N032E133_DSM.tif',
'ALPSMLC30_N033E132_DSM.tif',
'ALPSMLC30_N034E132_DSM.tif',
'ALPSMLC30_N032E132_DSM.tif',
'ALPSMLC30_N033E131_DSM.tif',
'ALPSMLC30_N034E131_DSM.tif',
'ALPSMLC30_N032E131_DSM.tif',
'ALPSMLC30_N031E131_DSM.tif',
'ALPSMLC30_N034E130_DSM.tif',
'ALPSMLC30_N033E130_DSM.tif',
'ALPSMLC30_N032E130_DSM.tif',
'ALPSMLC30_N031E130_DSM.tif',
'ALPSMLC30_N030E130_DSM.tif'
]
src_files_to_mosaic = []
# 指定されたファイル名リストをイテレートしてGeoTIFFを開く
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 in the directory. Exiting.")
return None
print(f"Merging {len(src_files_to_mosaic)} tiles...")
# Merge the datasets; resampling='nearest' for discrete elevation values
mosaic, out_transform = merge(src_files_to_mosaic, resampling=Resampling.nearest)
# Convert to float32 if needed to save memory (from float64)
if mosaic.dtype == np.float64:
mosaic = mosaic.astype(np.float32)
print("Converted mosaic to float32 to save memory.")
# Copy 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], # New height of the merged mosaic
"width": mosaic.shape[2], # New width of the merged mosaic
"transform": out_transform, # New georeferencing transform
"crs": src_files_to_mosaic[0].crs, # Coordinate Reference System (assumed consistent)
"nodata": src_files_to_mosaic[0].nodata # NoData value
})
# Close all source files to release resources
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
def plot_elevation_tile(filepath):
"""
指定されたGeoTIFF標高ファイルをMatplotlibで表示します。
Args:
filepath (str): 表示するGeoTIFFファイルのパス。
"""
try:
with rasterio.open(filepath) as src:
# 標高データを読み込む(通常はバンド1)
elevation_data = src.read(1)
# NoData値が存在する場合、それをNaN(非数)に変換してプロット時に無視されるようにする
if src.nodata is not None:
elevation_data[elevation_data == src.nodata] = np.nan
# プロットのセットアップ
plt.figure(figsize=(10, 8)) # 図のサイズを設定
# 画像として標高データを表示
# extent: データの地理的な範囲を設定し、軸のラベルを地理座標にする
# cmap: カラーマップ(標高データに適した'viridis'を使用)
# origin: 画像の原点(GeoTIFFは通常左上が原点)
# vmin, vmax: カラーマップの最小値と最大値を設定し、色の範囲を固定する
# ここでは、データの2パーセンタイルと98パーセンタイルを使用
# これにより、外れ値がカラーマップの表示範囲を歪めるのを防ぐ
valid_elevation_data = elevation_data[~np.isnan(elevation_data)]
if valid_elevation_data.size > 0:
vmin = np.percentile(valid_elevation_data, 2)
vmax = np.percentile(valid_elevation_data, 98)
else:
vmin = np.min(elevation_data[~np.isnan(elevation_data)]) if not np.all(np.isnan(elevation_data)) else 0
vmax = np.max(elevation_data[~np.isnan(elevation_data)]) if not np.all(np.isnan(elevation_data)) else 100
# 画像の表示範囲を設定 (左経度, 右経度, 下緯度, 上緯度)
# rasterioのboundsは (left, bottom, right, top) の順
bounds = src.bounds
extent = [bounds.left, bounds.right, bounds.bottom, bounds.top]
im = plt.imshow(
elevation_data,
cmap='viridis', # 標高データに適したカラーマップ
origin='upper', # 画像の原点を左上に設定
extent=extent, # 地理的な範囲を設定
vmin=vmin, # カラーマップの最小値
vmax=vmax # カラーマップの最大値
)
plt.title(f'Elevation Data: {os.path.basename(filepath)}')
plt.xlabel('Longitude')
plt.ylabel('Latitude')
plt.colorbar(im, label='Elevation (meters)') # カラーバーを追加
plt.grid(True, linestyle=':', alpha=0.7) # グリッドを追加
plt.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__":
# Define the directory where GeoTIFF files are extracted
extracted_data_dir = '/content/extracted_elevation_data/N030E130_N035E135'
# Define the output path for the merged GeoTIFF file
output_merged_filepath = os.path.join(extracted_data_dir, 'merged_5x5_elevation.tif')
print("Starting GeoTIFF tile merging process...")
merged_file_path = merge_elevation_tiles(extracted_data_dir, output_merged_filepath)
if merged_file_path:
print(f"\nSuccessfully merged all tiles. Now analyzing statistics for: {merged_file_path}")
try:
with rasterio.open(merged_file_path) as src:
# Read the entire merged data
merged_elevation_data = src.read(1)
# Convert NoData values to NaN
if src.nodata is not None:
merged_elevation_data[merged_elevation_data == src.nodata] = np.nan
# Get valid (non-NaN) elevation data for statistics
valid_merged_elevation_data = merged_elevation_data[~np.isnan(merged_elevation_data)]
if valid_merged_elevation_data.size > 0:
print(f"Merged data original pixel size: {src.height}x{src.width} pixels")
print(f"Merged data geographical bounds (Lon/Lat): Left={src.bounds.left:.2f}, Bottom={src.bounds.bottom:.2f}, Right={src.bounds.right:.2f}, Top={src.bounds.top:.2f}")
print(f"Merged data elevation range: Min={np.min(valid_merged_elevation_data):.2f}m, Max={np.max(valid_merged_elevation_data):.2f}m")
print(f"Merged data mean elevation: {np.mean(valid_merged_elevation_data):.2f}m")
print(f"Merged data standard deviation: {np.std(valid_merged_elevation_data):.2f}m")
print(f"Merged data 2nd percentile: {np.percentile(valid_merged_elevation_data, 2):.2f}m")
print(f"Merged data 98th percentile: {np.percentile(valid_merged_elevation_data, 98):.2f}m")
else:
print("No valid elevation data found in the merged file for statistics.")
except Exception as e:
print(f"An error occurred during statistics analysis of the merged file: {e}")
else:
print("GeoTIFF file merging failed, cannot proceed with statistics analysis.")
コメント
コメントを投稿