海上の太陽光発電所に最適なとこってどこなんだろうか？　候補地探索編

# はじめに
　先日[[1]](#参考サイト)の記事で「調査領域が日本周辺という大きい地域で大まかに適地を見ているだけ（より細かい解像度で見る必要あり）」という課題を挙げました。
　ただ解像度を上げてみるといっても「だいたいここらへん」といった当たりは最初につけないといけません。そこで本記事では「水深が浅くて比較的日射量が高いところ」はどこかという、おおまかな候補地探索をしてみたいと思います。

# 実行環境
- CPU:  CORE i5 8th Gen
- メモリ: 8GB
- OSと環境: Window11にAnacondaをインストールした環境
- プログラミング言語とバージョン：python 3.11.5

# 使用したデータ
[[1]](#参考サイト)の記事でダウンロードした以下のデータを用います。
- 日射量のデータ
    - 気象データセット: ECMWF(欧州中期予報センター) ERA5
    - 期間: ERA5で公開されている2022年の全ての日時
    - 領域: 日本周辺　北緯:24°～46° 東経122°～153°
    - 項目: surface_thermal_radiation_downwards(地球表面の水平面に到達する太陽放射)
    -  形式: netCDF


- 水深のデータ
    - 地形データセット:NOAA ETOPO1
    - ダウンロードしたデータファイル: ETOPO1_Bed_g_gmt4.grd

# 海上の太陽光発電所の候補地として抽出した条件
1. 水深が500m以下
2. 水深が500m以下の場所の中で月平均の日射量がトップ3以内

水深が浅い≒海岸からの距離が近いと仮定して、このような条件にしました。
本当は海岸からの距離も計算したかったのですが、なかなかうまくいかず、本記事のコーディングの対象からは外しました。

## 作成したコード

```
import xarray as xr
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import rasterio
from rasterio.windows import from_bounds

# 初期化
valid_locations_all_months = pd.DataFrame()

# ETOPO1データの読み込み
with rasterio.open('ETOPO1_Bed_g_gmt4.grd') as etopo_dataset:
    window = from_bounds(122, 24, 153, 46, etopo_dataset.transform)
    etopo_data = etopo_dataset.read(1, window=window)
    etopo_transform = etopo_dataset.window_transform(window)
    etopo_lon = np.linspace(etopo_transform.c, etopo_transform.c + etopo_transform.a * etopo_data.shape[1], etopo_data.shape[1])
    etopo_lat = np.linspace(etopo_transform.f, etopo_transform.f + etopo_transform.e * etopo_data.shape[0], etopo_data.shape[0])

# NetCDFファイルの読み込み
data = xr.open_dataset('download_surface_solar_radiation_downwards_2022.nc')

# 日射量データの選択
solar_radiation = data['ssrd'] / 1000000  # MJ/m^2への単位変換

# 月ごとの平均の計算
monthly_mean = solar_radiation.groupby('time.month').mean('time')

# カラーバーのリミットの定義
colorbar_max = monthly_mean.max().values
colorbar_min = monthly_mean.min().values

for month in range(1, 13):
    plt.figure(figsize=(12, 8))
    ax = plt.axes(projection=ccrs.PlateCarree())
    ax.set_extent([122, 153, 24, 45])

    # 月ごとの日射量データの選択
    monthly_data = monthly_mean.sel(month=month)

    # ヒートマップの作成
    mesh = ax.pcolormesh(data.longitude, data.latitude, monthly_data,
                         shading='auto', cmap='viridis',
                         vmin=colorbar_min, vmax=colorbar_max)

    # 水深のコンターを追加(1000m間隔)
    contour_levels = np.arange(-10000, 1, 1000)
    contours = ax.contour(etopo_lon, etopo_lat, etopo_data, levels=contour_levels,
                          colors='grey', linestyles='solid', linewidths=0.5, transform=ccrs.PlateCarree())
    coastline = ax.contour(etopo_lon, etopo_lat, etopo_data, levels=[0],
                           colors='black', linestyles='solid', linewidths=0.5, transform=ccrs.PlateCarree())

    # 水深値のラベル追加
    ax.clabel(contours, inline=True, fontsize=8, fmt='%1.0f m')

    # 水深500m以下の領域を特定
    shallow_areas = etopo_data <= 500

    # 日射量データと対応する緯度経度
    flat_solar = monthly_data.stack(all_coords=("latitude", "longitude"))
    flat_solar_lats = flat_solar.coords["latitude"].values
    flat_solar_lons = flat_solar.coords["longitude"].values

    # トップ3の日射量を持つポイントを選択
    top_solar_indices = np.argsort(flat_solar.values)[::-1][:3]
    top_solar_lats = flat_solar_lats[top_solar_indices]
    top_solar_lons = flat_solar_lons[top_solar_indices]

    # 条件を満たすポイントを抽出
    valid_points = []
    for lat, lon in zip(top_solar_lats, top_solar_lons):
        if shallow_areas[np.argmin(np.abs(etopo_lat - lat)), np.argmin(np.abs(etopo_lon - lon))]:
            valid_points.append((lat, lon))

    # CSVファイルのためのデータフレームに追加
    valid_locations = pd.DataFrame(valid_points, columns=['Latitude', 'Longitude'])
    valid_locations['Month'] = month
    valid_locations_all_months = pd.concat([valid_locations_all_months, valid_locations])

    # ヒートマップに☆印をプロット
    for lat, lon in valid_points:
        ax.scatter(lon, lat, s=100, c='magenta', marker='*', transform=ccrs.PlateCarree())

    # タイトルの設定
    plt.title(f'Surface Solar Radiation Monthly Mean Heatmap with Water Depth for Month {month}')
    plt.colorbar(mesh, orientation='vertical', pad=0.02, aspect=50, label='Surface Solar Radiation Downwards (MJ/m²)')

    # 図の保存
    plt.savefig(f"heatmap_waterdepth_solar_month_{month}.png", bbox_inches='tight', dpi=300)
    plt.close()

# CSVファイルの保存
valid_locations_all_months.to_csv('kouho_locations_all_months.csv', index=False)
```
## 候補地について
上記に挙げた条件に合致するところにピンクの★印を付けた図を月毎に作成しました。ここでは一番見やすかった8月を示します。

![heatmap_bathymetry_solar_month_8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/7c7b68ac-ef9c-f5a2-1d1f-7a13e6732d3e.png)

ピンクの★印を付けた候補地の緯度、経度、近くの海岸からの距離（google map[[2]](#参考サイト)で手作業で測定したもの）を以下の表に示します。

|No.  |緯度　|経度　|海岸からの距離|
|---|---|---|---|
|1  |  北緯25.5°|  東経142°|  北硫黄島より東へ約72km|
|2  |  北緯24.75°|  東経132°|  南大東島より南へ約142km|
|3  |  北緯25.5°|  東経142.25°|  北硫黄島より東へ約97km|


# 考察と課題
　非常にアバウトな形ですが、水深が浅くて比較的日射量が高いところは「だいたいここらへん」といった当たりをつけられたと考えます。
　ただ海岸からの距離というところはコーディングできず、google mapでの手動測定という方法になってしまったので、そこは課題として残っています。それから今回候補地と抽出したところも島から数十キロも離れたところですから、発電所を建てるなんてのは送電も考えれば現実的ではないなと思いました。

今回はここまでですが、今後は波高や潮の流れの速さなどの調査にも機会があれば取り組みたいと考えています。

👆[海上の太陽光発電所に最適なとこってどこなんだろうか？　波高調査編](https://qiita.com/bebebefu/items/19f887e7c8db56064551)の記事にて波高について調査してみました。

# 参考サイト
[1] [海上の太陽光発電所に最適なとこってどこなんだろうか？](https://qiita.com/bebebefu/items/4d2f676c1779aa2f3253)
[2] [google map](https://www.google.com/maps?authuser=0)