3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Pythonで衛星画像を触ってみる その1

Posted at

はじめに

Tellusという日本発の衛星データプラットフォームをご存知でしょうか。こちらのプラットフォームを通して国内外の機関・企業が運営している衛星データに触れることができます。今回はTellusを利用して衛星データを取得・操作してみたので、その備忘録を記しておきたいと思います。

やりたいこと

  1. 人工衛星が撮影したデータを取得する
  2. 取得したデータに対して何かしら操作してみる

参考サイト

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から取得する流れは基本的に以下のイメージです。

  1. 取得したいデータセットIDを決める。
  2. データセットから条件を指定して検索し、シーンIDを取得する。
  3. シーンIDからファイルIDを取得する。
  4. データセット、シーンID、ファイルIDを指定してダウンロードURLを生成する。
  5. ダウンロードURLを利用してファイルを書き出す(ダウンロードする)。

ではやっていきましょう。

取得したいデータの検索

まずは必要なライブラリをインポートします。

# 必要なライブラリをインポートします。
import os
import requests
import json

次に、特定の場所(例えば北海道の○○市周辺とか)のデータを検索する関数を作成します。
以下に設定されているTOKENTellusにて作成します。
DATA_SETTellus Travelerから使いたいデータセットのIDを確認できます。
image.png

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())

上記を実行すると、以下のようなレスポンスが返ってきます。
image.png

この中から、今回は以下のシーン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)

こんな感じのレスポンスが返ってきます。
image.png

画像のダウンロード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()

無事にファイルの書き出しができました!
image.png

その2へ続く

その2ではダウンロードした画像を使って、衛星画像の操作を少しやってみたいと思います。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?