はじめに
Tellusという日本発の衛星データプラットフォームをご存知でしょうか。こちらのプラットフォームを通して国内外の機関・企業が運営している衛星データに触れることができます。今回はTellusを利用して衛星データを取得・操作してみたので、その備忘録を記しておきたいと思います。
やりたいこと
- 人工衛星が撮影したデータを取得する
- 取得したデータに対して何かしら操作してみる
参考サイト
Tellusトップページ:https://www.tellusxdp.com/ja/
Tellus API :https://www.tellusxdp.com/docs/travelers/
やりたいこと内容 :https://sorabatake.jp/25931/
(→こちらのサイトで利用されているTellus APIは古いVersionです)
実施環境
- Tellus開発環境 (さくらVPS Ubuntu)
→Tellus APIはTellusから提供される開発環境のみで利用可能です。 - Jupyter Notebook (or Jupyter Lab)
やってみる
本「その1」の記事では取得したいデータを検索し、ローカル環境にダウンロードする部分までを記したいと思います。
流れの確認
衛星データをTellusから取得する流れは基本的に以下のイメージです。
- 取得したいデータセットIDを決める。
- データセットから条件を指定して検索し、シーンIDを取得する。
- シーンIDからファイルIDを取得する。
- データセット、シーンID、ファイルIDを指定してダウンロードURLを生成する。
- ダウンロードURLを利用してファイルを書き出す(ダウンロードする)。
ではやっていきましょう。
取得したいデータの検索
まずは必要なライブラリをインポートします。
# 必要なライブラリをインポートします。
import os
import requests
import json
次に、特定の場所(例えば北海道の○○市周辺とか)のデータを検索する関数を作成します。
以下に設定されているTOKEN
はTellusにて作成します。
DATA_SET
はTellus Travelerから使いたいデータセットのIDを確認できます。
TOKEN = "所得したトークン"
DATA_SET = "10402ffd-fb70-4625-9b46-63cec87cd5a9" ##ASNARO-2のデータセットIDをセット
#所定の場所のデータ検索をする関数
# Specify dataset and search. Using /datasets/{dataset_id}/data-search/ API.
def scene_search(dataset_id, intersects=None, query={}, sortby=None, paginate=None):
url = 'https://www.tellusxdp.com/api/traveler/v1/datasets/{}/data-search/'.format(dataset_id)
headers = {
"Authorization": "Bearer " + TOKEN,
'Content-Type': 'application/json'
}
payloads = {}
if intersects is not None:
payloads['intersects'] = intersects
if query is not None:
payloads['query'] = query
if isinstance(sortby, list):
payloads['sortby'] = sortby
if paginate is not None:
payloads['paginate'] = paginate
r = requests.post(url, headers=headers, data=json.dumps(payloads))
print(r.status_code)
if r.status_code != 200:
print(r.content)
raise ValueError('status error({}).'.format(r.status_code))
return r.json()
上記の関数を呼び出し、今回は緯度経度を指定してデータを検索します。
# 検索条件を指定してデータを検索する関数(AOIを指定)
def get_request():
ret = scene_search(
DATA_SET,
intersects={
'type':'Polygon','coordinates':[
[
[141.84938200356842,42.75105653576509],
[141.83924706503996,42.71645449666897],
[141.89461385885272,42.69893933684679],
[141.96255548380265,42.72252158826697],
[141.95711264644478,42.761943222877846],
[141.89968132811697,42.76359672954325],
[141.84938200356842,42.75105653576509]
]
]
},
)
return ret
print(get_request())
この中から、今回は以下のシーンIDを使っていきます。
# idが「7d47301d-9533-4be2-a010-31a86912e865」の2020-09-05に撮影されたデータと、
# id「2c9ccde2-3a8c-4cd2-aac5-4f0c3b33a4a4」で2018-09-08に撮影されたデータを使用する。
SCENE_ID1 = '7d47301d-9533-4be2-a010-31a86912e865'
SCENE_ID2 = '2c9ccde2-3a8c-4cd2-aac5-4f0c3b33a4a4'
次に、シーンIDを用いてファイルIDを取得する関数を定義し、実行します。
# ファイルID等を取得する関数
def get_files_list(dataset_id, data_id):
url = 'https://www.tellusxdp.com/api/traveler/v1/datasets/{}/data/{}/files/'.format(dataset_id, data_id)
headers = {
"Authorization": "Bearer " + TOKEN,
'content-type': 'application/json'
}
r = requests.get(url, headers=headers)
assert r.status_code == 200
return r.json()
print(get_files_list(DATA_SET, SCENE_ID1))
print(get_files_list(DATA_SET, SCENE_ID2))
上記を実行すると、レスポンスとして沢山のファイルIDが返却されます。この中から今回は以下のファイルIDを使いたいと思います。
# 上記関数で取得したファイルID
FILE_ID1 = '4'
FILE_ID2 = '3'
以下部分の実行はオプションですが、ファイルIDを指定すれば使わない他のファイルの情報は含まれない、指定したファイルIDのみの情報が取得できるAPIがあるので、そちらのAPIを実行して見やすいレスポンスを取得します。
# ファイルIDで指定したファイルのみの情報を抽出
def get_file_info(dataset_id, data_id, file_id):
url = 'https://www.tellusxdp.com/api/traveler/v1/datasets/{}/data/{}/files/{}/'.format(dataset_id, data_id, file_id)
headers = {
"Authorization": "Bearer " + TOKEN,
'content-type': 'application/json'
}
r = requests.get(url, headers=headers)
return r.json()
FILE_INFO1 = get_file_info(DATA_SET, SCENE_ID1, FILE_ID1)
FILE_INFO2 = get_file_info(DATA_SET, SCENE_ID2, FILE_ID2)
print(FILE_INFO1)
print(FILE_INFO2)
画像のダウンロードURLの作成とダウンロード
上記までで取得した情報(シーンID、ファイルID)を利用してダウンロードURLを生成します。
# Create download URL
def get_download_url(dataset_id, data_id, file_id):
url = 'https://www.tellusxdp.com/api/traveler/v1/datasets/{}/data/{}/files/{}/download-url/'.format(dataset_id, data_id, file_id)
headers = {
"Authorization": "Bearer " + TOKEN,
'Content-Type': 'application/json',
}
r = requests.post(url, headers=headers)
assert r.status_code == 200
return json.loads(r.content)
DOWNLOAD_URL1 = get_download_url(DATA_SET, SCENE_ID1, FILE_ID1)
DOWNLOAD_URL2 = get_download_url(DATA_SET, SCENE_ID2, FILE_ID2)
print(DOWNLOAD_URL1)
print(DOWNLOAD_URL2)
あとは上記で作成されたダウンロードURLから必要な部分を切り出し、ファイルとしてローカルに書き出す処理を実行すればファイルがダウンロードされます。(以下は1つめの画像のみ記載してますが、2つめの画像も同様に実施します)
#取得した情報から必要な情報を取り出す 1つ目の画像
URL1 = DOWNLOAD_URL1['download_url']
FILE_NAME1 = FILE_INFO1['name']
SIZE_BYTES1 = FILE_INFO1['size_bytes']
print('File Name: ' + FILE_NAME1)
print('File Size; ' + str(SIZE_BYTES1))
#ファイルを作成して取得したファイル内容を書き出す。1つ目の画像
response = requests.get(URL1)
with open(FILE_NAME1, "wb") as f:
for chunk in response.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
f.flush()
その2へ続く
その2ではダウンロードした画像を使って、衛星画像の操作を少しやってみたいと思います。