Open9

JAXA Earth API 技術習得

わおんわおん

とりあえず、これまでのJAXA Earth APIを使った記事をここに列挙する

JAXA Earth API for Pythonで遊んでみた

https://zenn.dev/aymaymaym/articles/c482db5fdc3ae4

APIを叩くサンプルコードとか

わおんわおん

他のデータとの違いを述べるとよさそうかも。
気象データだったら気象庁のものとかと比べるとか

わおんわおん

JAXA Earth API の生データを取得する

データ分析をしたいから,データを取得したいよ

わおんわおん

動機

公式のExampleには画像データとして取得する方法がほとんど.

一応取得データを分析するために最大値,最小値,平均値,標準偏差を取得する方法は紹介されているが,セルの値を直接知りたい時など,丸められる前のデータを取得したい場面は多い.

わおんわおん

動機続き

一応以下のように紹介はされているが,あまりにも説明が短すぎる気がする

If you would like to get raw numpy array and show it, please execute following script.

import matplotlib.pyplot as plt
plt.imshow(img.raster.img[0])
plt.show()
わおんわおん

やり方は3通りあります。結論:API自体は“画像を返す”設計ですが、内部では NumPy 配列や STAC/COG を使っているので、配列を取り出して DataFrame 化するか、COG(GeoTIFF) を直接読む形にすればOKです。


1) raster.img をそのまま DataFrame にする(最短)

get_images()ImageProcess の戻り値に 生の NumPy 配列が入っています。公式サンプルにも「生配列を取り出すには img.raster.img[0]」と明記されています。時系列集計は calc_spatial_stats()timeseries(mean, std, min, max, median)で配列取得できます。([JAXA Earth API][1])

from jaxa.earth import je
import numpy as np, pandas as pd

# 例:短波放射の1日の1枚を取得(bboxは [minlon, minlat, maxlon, maxlat])
collection = "JAXA.JASMES_Aqua.MODIS_swr.v811_global_daily"
band = "swr"
dlim = ["2021-01-15T00:00:00", "2021-01-15T23:59:59"]
bbox = [135, 34, 136, 35]
ppu  = 180  # 1度あたりの画素数(EPSG:4326)。ppiではなくPPU。:contentReference[oaicite:1]{index=1}

ic = (je.ImageCollection(collection=collection, ssl_verify=True)
        .filter_date(dlim)
        .filter_resolution(ppu)       # PPU=1度あたりのピクセル数
        .filter_bounds(bbox=bbox)
        .select(band)
        .get_images())
ip = je.ImageProcess(ic)              # 画像の容器(raster)を持つ

arr = ip.raster.img[0]                # 2DのNumPy配列(行=緯度, 列=経度):contentReference[oaicite:2]{index=2}
nrows, ncols = arr.shape
lonmin, latmin, lonmax, latmax = bbox

# セル中心の座標ベクトルを作ってテーブル化
dx = (lonmax - lonmin)/ncols
dy = (latmax - latmin)/nrows
lons = lonmin + dx*(np.arange(ncols)+0.5)
lats = latmax - dy*(np.arange(nrows)+0.5)  # 上が北なので減少方向

df = pd.DataFrame({
    "lat": np.repeat(lats, ncols),
    "lon": np.tile(lons, nrows),
    band: arr.ravel()
})

時系列の平均などをDataFrameで:

ip_ts = je.ImageProcess(ic).calc_spatial_stats()  # mean, std, min, max, medianを計算
df_ts = pd.DataFrame(ip_ts.timeseries)            # 各系列はNumPy配列で返る:contentReference[oaicite:3]{index=3}

補足:ip.raster には latlim/lonlim も入っています(bboxと同義)。必要ならそちらから座標範囲を取ってください。([JAXA Earth API][2])


2) STAC/COG から GeoTIFF を直接読み、xarray→DataFrame

JAXA Earth は COG(Cloud Optimized GeoTIFF) と STAC で配信されています。ImageCollectionstac_* プロパティに STAC の url/json が入るので、アセットの href(GeoTIFF) を取り出して rioxarray/rasterio で読むと座標付きの配列→DataFrame化が簡単です。([JAXA Earth API][3])

import requests, rioxarray as rxr, pandas as pd
# すでに ic = ImageCollection(...).filter_*().select(...) まで済んでいる前提
item_url = ic.stac_band.url                       # バンド選択後のSTACアイテムURL:contentReference[oaicite:6]{index=6}
item = requests.get(item_url).json()

# アセットからGeoTIFFのhrefをひとつ選ぶ(キー名はデータセットにより異なる)
asset = next(v for v in item["assets"].values() if "tif" in v.get("href",""))
href = asset["href"]

da = rxr.open_rasterio(href, masked=True).squeeze(drop=True)  # CRSは基本EPSG:4326
df = da.to_dataframe(name=band).reset_index()                  # (y,x)->(lat,lon) 付きの表に

STAC は階層(コレクション→date→COGレベル→経度→緯度)を持ち、日付レイヤもあるので、実際の観測日時ic.stac_date.json を辿って取得できます(DataFrameのindexに付与するなど)。([JAXA Earth API][3])


3) QGIS で一旦ラスター保存→後で pandas へ

QGIS 内で show_images_qgis() を使うと、一時フォルダにGeoTIFFが保存されます。保存しておけば、後で rasterio/rioxarray で読み込み→DataFrame 化できます。([JAXA Earth API][4])


どれを選ぶ?

  • 素早く「今表示しているもの」を表にしたい方法1(raster.img
  • 正確な座標系/メタデータ付きで扱いたい、時系列をしっかり管理したい方法2(COG直読み)
  • QGISワークフロー中心方法3

必要なら、あなたの使っているコレクション/バンド/領域に合わせて、上のコードをこちらで埋め替えて完成版を渡します。