Pythonで人工衛星画像を扱う：Sentinel Hub APIのコードを作成して、衛星画像をダウンロードしましょう

# イントロ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/999291/cf994436-c3dc-91b7-2296-1f6ffe3ebd53.png)
今回の記事には、SentinalというのESA(欧州宇宙機関)の人工衛星の画像を取得して、イギリスのKeyGardens(キューガーデン)を表示してみます。すべてのコードはcolabとgithubでアップしましたので、ぜひ使ってください
([Colabのリンク](https://colab.research.google.com/drive/1a1dU4hRnfp5JG8jAvgLVUdmvp1wbpWwT?usp=sharing) [Githubのリンク](https://github.com/JarvisSan22/Jinlabs_learn_python_Notebooks))
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/999291/6c32df1b-1c81-e8e6-98ee-5b5ccfa41343.png)

# APIの鍵を取得
最初は、API鍵を取得することは必要です。このために、[SenteinelHub](https://www.sentinel-hub.com/)でアカウントを作れなければなりません。メールよるアカウント確認が必要なので、したメールボックスをチェックしてください。アカウント確認した後、無料のトライアルが始められます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/999291/6825d9f2-e6be-6b64-2ebb-5f09923a2081.png)
ログインして、AuthClientのボタンをして、APIが鍵を作れます。作成した後で、IDと鍵のコードをメモしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/999291/b050489e-cd77-36fe-0067-4c0ad114300d.png)

# PythonでSentinelhubをセットアップする 
SentinelhubはPythonのモジュールがあります。インストールした後で、Sentinelの人工衛星画像を取得できます。
```python
pip3 install sentinelhub 
```
次、PythonでSentinelhubをセットアップしましょう。最初にSHConfigという関数をインポートして、前に取得したAPI画像の情報を記入しまます

```python
from sentinelhub import SHConfig
config = SHConfig()
config.sh_client_id="{OAuth ID }"
config.sh_client_secret="{OAuth secret key}"
if not config.sh_client_id or not config.sh_client_secret:
    print("Warning! To use Process API, please provide the credentials (OAuth client ID and client secret).")
```
### API鍵を安全に扱い
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/999291/9e7b6f41-3e43-2993-44cb-d52ee8a8cb55.png)

.envというファイルを作成して、IDとSecretという変数では、APIのIDと鍵のコードを記入してください
```
ID=”"{OAuth ID }"
Secret="{OAuth secret key}"
```

次は、Pythonで「python-dotenv」というモジュールを利用して、このファイルは読み込めんで、変数は環境変数に設定してみます。
```
!pip3 install python-dotenv
```
```python 
from dotenv import load_dotenv
import os 
load_dotenv(".env")
```

そして、前にコードを同じようなSHconfigではAPI鍵を設定します。しかし、今回、os.environを利用して、鍵はコード内で表示しません。

```python
from sentinelhub import SHConfig
config = SHConfig()
config.sh_client_id=os.environ["ID"]  
config.sh_client_secret=os.environ["Secret"] 
if not config.sh_client_id or not config.sh_client_secret:
    print("Warning! To use Process API, please provide the credentials (OAuth client ID and client secret).")
```

# 人工衛星画像をダウンロードする
## 対象範囲

人工衛星画像をダウンロードするために、最初にステップは何の座標範囲で画像を取得したいですか？緯度経度の座標が必要ですこそのために、[Geojson.io](https://geojson.io/#map=2/0/20)というサイトはとても役に立っています。下記にロンドンのKeyGardens(キューガーデン)の範囲を調べました。二つの点を設定して、緯度経度をメモしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/999291/3f422249-8376-3536-e402-a86e631ec8a2.png)
次はこの緯度経度はSentinalhubで利用できる形式に変換します。sentinelhubのモジュールからBBoxとCRS(座標系）という関数をインポートして、target_bbox(対象範囲)という変数を作ります。次は、対象範囲はピクセルサイズに変換します。このために、解像度が必要です。今回 2m解像度を設定して、 bbox_to_dimensionsの関数に入り込み、ピクセルサイズを変換できます。

```python
from sentinelhub import  CRS,BBox, bbox_to_dimensions
target_coords = [  
                 -0.3273582458496094,
          51.45892724311225, 
       -0.2847862243652344,
          51.48801054716568
        ] #WGS84
res=2
target_bbox= BBox(bbox=target_coords,crs=CRS.WGS84)
target_size= bbox_to_dimensions(target_bbox,resolution=res)

print(f'Image shape at {res} m resolution: {target_size} pixels')
#$Image shape at 2 m resolution: (1418, 1671) pixels
```

## データのダウンロード

Sentinelhubからダウンロードするために、最初にデータの要求(sentinelHubRequest)を作れなければなりません。これは、evalscriptというjavaで書いていた人工衛星のバンドの情報を取り込んで、人工衛星の名前と時間時期と対象範囲の情報を記入した後で、データが存在している場合はダウンロードできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/999291/b9c1b92f-1a89-43c9-67ef-9d5de70c51e7.png)

evalscriptはJavaで書かれていますが、バンド情報を表現する簡単な関数です。人工衛星画像は、RGBだけではなくて、いろいろな波長のデータを含めれます。今回　Sentinel-2 L1CのRGBのバンドを取得したいです。実はこの人工衛星は13バンドがあり、もっと情報を調べてみたい場合は、この[リンク](https://docs.sentinel-hub.com/api/latest/data/sentinel-2-l1c/)を確認してください。

```python
evalscript_true_color="""
 //VERSION=3

    function setup() {
        return {
            input: [{
                bands: ["B02", "B03", "B04"]
            }],
            output: {
                bands: 3
            }
        };
    }

    function evaluatePixel(sample) {
        return [sample.B04, sample.B03, sample.B02];
    }
"""
```

次は、SentinelHubRequestを作りました。最初に上記のevalscriptを入り込み、人工衛星の入力データを設定します。SentinelHubRequest.input_data内で、data_collectionでは、希望の人工衛星を記入して、次は希望の時間時期(time_interval)を設定しています。最後にmosaicking_orderを設定しています。この設定は、leastCCを設定すると、なるべく雲量が少ない画像を作ります。入力のデータを設定した後で、希望のファイル式はresponsesで設定しています。今回普通のRBGの画像が欲しいので、PNGの式を設定します。最後に、前に設定した対象範囲とAPI鍵の変数を記入します。

```Python
from sentinelhub import  MimeType,SentinelHubRequest, SentinelHubDownloadClient, \
    DataCollection, DownloadRequest

request_true_color = SentinelHubRequest(
    
    evalscript=evalscript_true_color,
    
    input_data=[
        SentinelHubRequest.input_data(
            data_collection=DataCollection.SENTINEL2_L1C,
            time_interval=('2020-12-1', '2020-12-30'),
            mosaicking_order='leastCC', #mostRecent leastRecent 
        )
    ],
 
    responses=[
        SentinelHubRequest.output_response('default', MimeType.PNG)
    ],

    bbox=target_bbox, #Target area 対象範囲
    size=target_size, #Resolution 解像度
    config=config 

)
```

そして、次はこの要求で、「.get_data()」を加えると、画像をダウンロードします。
```Python
rue_color_imgs = request_true_color.get_data()
```

## 画像を表示
データをダウンロードした後で、pythonで表示しましょう。また、データを正規化し、より見やすくするために明るくしました。
```python
import matplotlib.pyplot as plt
plt.imshow(true_color_imgs[0]*3.5/255)
plt.axis(False)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/999291/605b85eb-8c57-cfbd-2d79-d1d0c9ad9b52.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/999291/a399b66e-16b6-003d-68a2-e1b29b1581e4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/999291/dab2b4f8-246c-508e-c25d-5d16c6c72a2d.png)
自分の画像をダウンロードしましたか？

ツイッターで結果を発表してください （[@jarvissan22](https://twitter.com/JarvisSan22)）