SLATS(つばめ)の衛星画像を取得する

Tag

はじめに

SLATS(超低高度衛星技術試験機「つばめ」)は小型高分解能光学センサ(SHIROP)を搭載し、超低空度(200mから300m)からの観測によって地上分解能を向上することができることを技術実証するために打ち上げられました。つばめによって得られる画像は、解像度1m以下のモノクロ画像になります。TellusのAPIによりTSUBAMEの光学画像を取得することができます。

APIの使い方は商品情報のAPIリファレンスにまとめられています。

※画像を利用する際は、利用ポリシーを確認して、規約を違反しないように注意してください。

https://gisapi.tellusxdp.com/tsubame/{scene_id}_AS1/{z}/{x}/{y}.png
Name Input Description
X-Data-Version 任意 データセットバージョン(X.Y) リリース履歴 2.0: 2019/10/23 1.0: 2019/05/15 未指定、無効な値の場合は最新バージョンが返されます。 ※提供元での処理方法が変更された場合、メジャーバージョン(X)がアップデートされます。 ※Tellusでの処理方法が変更された場合、マイナーバージョン(Y)がアップデートされます。
min_lat 必須 最小緯度(-90~90)
min_lon 必須 最小経度(-180~180)
max_lat 必須 最大緯度(-90~90)
max_lon 必須 最大経度(-180~180)

「つばめ」(SLATS)はJAXAの技術試験衛星で、解像度1m以下の高解像度モノクロ画像をTellusで見ることができます。この衛星の最大の特徴は、2019年の4月からおよそ1ヶ月間、ほぼ毎日東京の決まった地点を観測し続けたことです。

シーンデータを取得する

SLATSのシーンデータを取得するためには、最小緯度・経度、最大緯度・経度を入力する必要があります。まずは、シーンデータを取得するための関数を定義しましょう。

import os, json, requests, math
import numpy as np
import dateutil.parser
from datetime import datetime
from datetime import timezone
from skimage import io
from io import BytesIO
import matplotlib.pyplot as plt
%matplotlib inline
TOKEN = "ここに自分のトークンを貼り付ける"
def get_tsubame_scene(min_lat, min_lon, max_lat, max_lon):
    url = "https://gisapi.tellusxdp.com/api/v1/tsubame/scene" \
        + "?min_lat={}&min_lon={}&max_lat={}&max_lon={}".format(min_lat, min_lon, max_lat, max_lon)
    headers = {
        "Authorization": "Bearer " + TOKEN
    }
    r = requests.get(url, headers=headers)
    return r.json()

東京周辺のシーンを検索します。

tsubame_scenes = get_tsubame_scene(35.524375, 139.585347, 35.724375, 140.005347)
len(tsubame_scenes)

43個のデータが取得できました。その中から皇居周辺のデータを用います。

# 皇居周辺
io.imshow(io.imread(tsubame_scenes[-1]["thumbs_url"]))

devSlats_api1_20200220_3.png

Credit:Original data provided by JAXA

このシーンから、地図タイル画像を取得してみましょう。地図タイル画像を探すためには、シーンid、ズーム率、タイルのXY座標を把握しておく必要があります。

地図タイル画像を取得する

https://gisapi.tellusxdp.com/tsubame/{scene_id}/{x}/{y}/{z}.png
Name Input Description
scene_id 必須 scene_id ※シーン検索APIで取得したシーンIDで呼び出すことが可能です。 scene_idは「Time0197277583_Num01_SCENE57_RSVLAT2」のように示されます。
z 必須 Zoom Level 9-18
x 必須 X座標
y 必須 Y座標
def get_tsubame_image(scene_id, zoom, xtile, ytile):
    url = " https://gisapi.tellusxdp.com/tsubame/{}/{}/{}/{}.png".format(scene_id, zoom, xtile, ytile)
    headers = {
        "Authorization": "Bearer " + TOKEN
    }
    r = requests.get(url, headers=headers)
    return io.imread(BytesIO(r.content))
# 新国立競技場
io.imshow(get_tsubame_image(tsubame_scenes[-1]["entityId"], 18, 232808, 103228))

関数を定義し、新国立競技場を含むタイル番号で画像を切り出してみます。

devSlats_api1_20200220_1.png

Credit:Original data provided by JAXA

高倍率画像であるため全てを捉えることはできません。取得した地図タイルを複数結合して、新国立競技場の全体を映し出してみましょう。

def get_slat_series_image(scene_id, zoom, topleft_x, topleft_y, size_x=1, size_y=1):
    """切り出したタイル画像を結合する"""
    img = []
    for y in range(size_y):
        row = []
        for x in range(size_x):
            row.append(get_tsubame_image(scene_id, zoom, topleft_x + x, topleft_y + y))
        img.append(np.hstack(row))
    return  np.vstack(img)
# 近傍の4つの画像を結合して表示
io.imshow(get_slat_series_image(tsubame_scenes[-1]["entityId"], 18, 232807, 103226, 4, 4))

devSlats_api1_20200220_2.png

Credit:Original data provided by JAXA

全体を捉えることができました。

SLATSは2019年の10月1日に運用を終了しています。短い期間ですが2019年の4月から10月までの東京周辺の変化を明瞭に捉えることができます。変化する東京の景色を観察するためには、衛星のシーンデータから撮影日(acquisitionDate)を選択することで任意期間のデータを取得できます。

また、SLATSは東京だけでなく世界各地も観測していました。その中でもワイキキ、クウェート、ニース(フランス)の4地点は定期的に観測が行われていました。東京以外の景色の変化も、SLATSを利用して探してみてください。

今回使用したスクリプトです。

import os, json, requests, math
import numpy as np
import dateutil.parser
from datetime import datetime
from datetime import timezone
from skimage import io
from io import BytesIO
import matplotlib.pyplot as plt
%matplotlib inline
TOKEN = "ここに自分のトークンを貼り付ける"
def get_tsubame_scene(min_lat, min_lon, max_lat, max_lon):
    url = "https://gisapi.tellusxdp.com/api/v1/tsubame/scene" \
        + "?min_lat={}&min_lon={}&max_lat={}&max_lon={}".format(min_lat, min_lon, max_lat, max_lon)
    headers = {
        "Authorization": "Bearer " + TOKEN
    }
    r = requests.get(url, headers=headers)
    return r.json()
tsubame_scenes = get_tsubame_scene(35.524375, 139.585347, 35.724375, 140.005347)
len(tsubame_scenes)
# 皇居周辺
io.imshow(io.imread(tsubame_scenes[-1]["thumbs_url"]))
def get_tsubame_image(scene_id, zoom, xtile, ytile):
    url = " https://gisapi.tellusxdp.com/tsubame/{}/{}/{}/{}.png".format(scene_id, zoom, xtile, ytile)
    headers = {
        "Authorization": "Bearer " + TOKEN
    }
    r = requests.get(url, headers=headers)
    return io.imread(BytesIO(r.content))
# 新国立競技場
io.imshow(get_tsubame_image(tsubame_scenes[-1]["entityId"], 18, 232808, 103228))
def get_slat_series_image(scene_id, zoom, topleft_x, topleft_y, size_x=1, size_y=1):
    """切り出したタイル画像を結合する"""
    img = []
    for y in range(size_y):
        row = []
        for x in range(size_x):
            row.append(get_tsubame_image(scene_id, zoom, topleft_x + x, topleft_y + y))
        img.append(np.hstack(row))
    return  np.vstack(img)
# 近傍の4つの画像を結合して表示
io.imshow(get_slat_series_image(tsubame_scenes[-1]["entityId"], 18, 232807, 103226, 4, 4))