

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Akses pengumpulan data raster Sentinel-2 dan buat pekerjaan observasi bumi untuk melakukan segmentasi lahan
<a name="geospatial-demo"></a>

Tutorial berbasis Python ini menggunakan SDK for Python (Boto3) dan notebook Amazon Studio Classic. SageMaker Untuk menyelesaikan demo ini dengan sukses, pastikan Anda memiliki izin AWS Identity and Access Management (IAM) yang diperlukan untuk menggunakan SageMaker geospasial dan Studio Classic. SageMaker geospasial mengharuskan Anda memiliki pengguna, grup, atau peran yang dapat mengakses Studio Classic. Anda juga harus memiliki peran eksekusi SageMaker AI yang menentukan prinsip layanan SageMaker geospasial, `sagemaker-geospatial.amazonaws.com` dalam kebijakan kepercayaannya. 

Untuk mempelajari lebih lanjut tentang persyaratan ini, lihat peran [IAM SageMaker geospasial](sagemaker-geospatial-roles.md).

Tutorial ini menunjukkan cara menggunakan API SageMaker geospasial untuk menyelesaikan tugas-tugas berikut:
+ Temukan koleksi data raster yang tersedia dengan`list_raster_data_collections`.
+ Cari pengumpulan data raster tertentu dengan menggunakan`search_raster_data_collection`.
+ Buat pekerjaan pengamatan bumi (EOJ) dengan menggunakan`start_earth_observation_job`.

## Menggunakan `list_raster_data_collections` untuk menemukan koleksi data yang tersedia
<a name="demo-use-list-rdc"></a>

SageMaker geospasial mendukung beberapa pengumpulan data raster. Untuk mempelajari lebih lanjut tentang pengumpulan data yang tersedia, lihat[Pengumpulan data](geospatial-data-collections.md).

Demo ini menggunakan data satelit yang dikumpulkan dari satelit [GeoTIFF yang Sentinel-2 Dioptimalkan di Cloud](https://registry.opendata.aws/sentinel-2-l2a-cogs/). Satelit-satelit ini menyediakan cakupan global permukaan bumi setiap lima hari. Selain mengumpulkan gambar permukaan Bumi, satelit Sentinel-2 juga mengumpulkan data di berbagai spektrum.

Untuk mencari area minat (AOI), Anda memerlukan ARN yang terkait dengan data satelit Sentinel-2. Untuk menemukan koleksi data yang tersedia dan yang terkait ARNs di Anda Wilayah AWS, gunakan operasi `list_raster_data_collections` API.

Karena respons dapat diberi paginasi, Anda harus menggunakan `get_paginator` operasi untuk mengembalikan semua data yang relevan:

```
import boto3
import sagemaker
import sagemaker_geospatial_map
import json 

## SageMaker Geospatial  is currently only avaialable in US-WEST-2  
session = boto3.Session(region_name='us-west-2')
execution_role = sagemaker.get_execution_role()

## Creates a SageMaker Geospatial client instance 
geospatial_client = session.client(service_name="sagemaker-geospatial")

# Creates a resusable Paginator for the list_raster_data_collections API operation 
paginator = geospatial_client.get_paginator("list_raster_data_collections")

# Create a PageIterator from the paginator class
page_iterator = paginator.paginate()

# Use the iterator to iterate throught the results of list_raster_data_collections
results = []
for page in page_iterator:
    results.append(page['RasterDataCollectionSummaries'])

print(results)
```

Ini adalah contoh respons JSON dari operasi `list_raster_data_collections` API. Itu terpotong untuk menyertakan hanya pengumpulan data (Sentinel-2) yang digunakan dalam contoh  kodenya. Untuk detail selengkapnya tentang pengumpulan data raster tertentu, gunakan`get_raster_data_collection`:

```
{
    "Arn": "arn:aws:sagemaker-geospatial:us-west-2:378778860802:raster-data-collection/public/nmqj48dcu3g7ayw8",
    "Description": "Sentinel-2a and Sentinel-2b imagery, processed to Level 2A (Surface Reflectance) and converted to Cloud-Optimized GeoTIFFs",
    "DescriptionPageUrl": "https://registry.opendata.aws/sentinel-2-l2a-cogs",
    "Name": "Sentinel 2 L2A COGs",
    "SupportedFilters": [
        {
            "Maximum": 100,
            "Minimum": 0,
            "Name": "EoCloudCover",
            "Type": "number"
        },
        {
            "Maximum": 90,
            "Minimum": 0,
            "Name": "ViewOffNadir",
            "Type": "number"
        },
        {
            "Name": "Platform",
            "Type": "string"
        }
    ],
    "Tags": {},
    "Type": "PUBLIC"
}
```

Setelah menjalankan contoh kode sebelumnya, Anda mendapatkan ARN dari pengumpulan data raster Sentinel-2,. `arn:aws:sagemaker-geospatial:us-west-2:378778860802:raster-data-collection/public/nmqj48dcu3g7ayw8` Di [bagian selanjutnya](#demo-search-raster-data), Anda dapat menanyakan pengumpulan data Sentinel-2 menggunakan API. `search_raster_data_collection`

## Mencari pengumpulan data Sentinel-2 raster menggunakan `search_raster_data_collection`
<a name="demo-search-raster-data"></a>

Di bagian sebelumnya, Anda biasa mendapatkan ARN `list_raster_data_collections` untuk pengumpulan data. Sentinel-2 Sekarang Anda dapat menggunakan ARN itu untuk mencari pengumpulan data di area minat tertentu (AOI), rentang waktu, properti, dan pita UV yang tersedia.

Untuk memanggil `search_raster_data_collection` API, Anda harus meneruskan Python dic  tionary ke `RasterDataCollectionQuery` parameter. Contoh ini menggunakan`AreaOfInterest`,`TimeRangeFilter`,`PropertyFilters`, dan`BandFilter`. Untuk memudahkan, Anda dapat menentukan kamus Python menggunakan variabel **search\$1rdc\$1query** untuk menahan parameter permintaan pencarian:

```
search_rdc_query = {
    "AreaOfInterest": {
        "AreaOfInterestGeometry": {
            "PolygonGeometry": {
                "Coordinates": [
                    [
                        # coordinates are input as longitute followed by latitude 
                        [-114.529, 36.142],
                        [-114.373, 36.142],
                        [-114.373, 36.411],
                        [-114.529, 36.411],
                        [-114.529, 36.142],
                    ]
                ]
            }
        }
    },
    "TimeRangeFilter": {
        "StartTime": "2022-01-01T00:00:00Z",
        "EndTime": "2022-07-10T23:59:59Z"
    },
    "PropertyFilters": {
        "Properties": [
            {
                "Property": {
                    "EoCloudCover": {
                        "LowerBound": 0,
                        "UpperBound": 1
                    }
                }
            }
        ],
        "LogicalOperator": "AND"
    },
    "BandFilter": [
        "visual"
    ]
}
```

Dalam contoh ini, Anda menanyakan `AreaOfInterest` yang menyertakan [Danau Mead](https://en.wikipedia.org/wiki/Lake_Mead) di Utah. Selain itu, Sentinel-2 mendukung beberapa jenis pita gambar. Untuk mengukur perubahan permukaan air, Anda hanya perlu `visual` pita.

Setelah membuat parameter kueri, Anda dapat menggunakan `search_raster_data_collection` API untuk membuat permintaan. 

Contoh kode berikut mengimplementasikan permintaan `search_raster_data_collection` API. API ini tidak mendukung pagination menggunakan `get_paginator` API. Untuk memastikan bahwa respons API lengkap telah dikumpulkan, sampel kode menggunakan `while` loop untuk memeriksa apakah `NextToken` ada. Sampel kode kemudian digunakan `.extend()` untuk menambahkan citra satelit URLs dan metadata respons lainnya ke. `items_list` 

Untuk mempelajari selengkapnya`search_raster_data_collection`, lihat [SearchRasterDataCollection](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_geospatial_SearchRasterDataCollection.html)di *Referensi Amazon SageMaker AI API*.

```
search_rdc_response = sm_geo_client.search_raster_data_collection(
    Arn='arn:aws:sagemaker-geospatial:us-west-2:378778860802:raster-data-collection/public/nmqj48dcu3g7ayw8',
    RasterDataCollectionQuery=search_rdc_query
)


## items_list is the response from the API request. 
items_list = []

## Use the python .get() method to check that the 'NextToken' exists, if null returns None breaking the while loop 
while search_rdc_response.get('NextToken'):
    items_list.extend(search_rdc_response['Items'])
    search_rdc_response = sm_geo_client.search_raster_data_collection(
        Arn='arn:aws:sagemaker-geospatial:us-west-2:378778860802:raster-data-collection/public/nmqj48dcu3g7ayw8',
        RasterDataCollectionQuery=search_rdc_query, NextToken=search_rdc_response['NextToken']
    )

## Print the number of observation return based on the query
print (len(items_list))
```

Berikut ini adalah respons JSON dari kueri Anda. Itu telah dipotong untuk kejelasan. Hanya yang **"BandFilter": ["visual"]** ditentukan dalam permintaan yang dikembalikan dalam pasangan `Assets` kunci-nilai:

```
{
    'Assets': {
        'visual': {
            'Href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/15/T/UH/2022/6/S2A_15TUH_20220623_0_L2A/TCI.tif'
        }
    },
    'DateTime': datetime.datetime(2022, 6, 23, 17, 22, 5, 926000, tzinfo = tzlocal()),
    'Geometry': {
        'Coordinates': [
            [
                [-114.529, 36.142],
                [-114.373, 36.142],
                [-114.373, 36.411],
                [-114.529, 36.411],
                [-114.529, 36.142],
            ]
        ],
        'Type': 'Polygon'
    },
    'Id': 'S2A_15TUH_20220623_0_L2A',
    'Properties': {
        'EoCloudCover': 0.046519,
        'Platform': 'sentinel-2a'
    }
}
```

Sekarang setelah Anda memiliki hasil kueri, di bagian selanjutnya Anda dapat memvisualisasikan hasilnya dengan menggunakan`matplotlib`. Ini untuk memverifikasi bahwa hasil berasal dari wilayah geografis yang benar. 

## Memvisualisasikan penggunaan Anda `search_raster_data_collection` `matplotlib`
<a name="demo-geospatial-visualize"></a>

Sebelum Anda memulai pekerjaan pengamatan bumi (EOJ), Anda dapat memvisualisasikan hasil dari pertanyaan kami dengan.  `matplotlib` Contoh kode berikut mengambil item pertama,`items_list[0]["Assets"]["visual"]["Href"]`, dari `items_list` variabel yang dibuat dalam contoh kode sebelumnya dan mencetak gambar menggunakan`matplotlib`.

```
# Visualize an example image.
import os
from urllib import request
import tifffile
import matplotlib.pyplot as plt

image_dir = "./images/lake_mead"
os.makedirs(image_dir, exist_ok=True)

image_dir = "./images/lake_mead"
os.makedirs(image_dir, exist_ok=True)

image_url = items_list[0]["Assets"]["visual"]["Href"]
img_id = image_url.split("/")[-2]
path_to_image = image_dir + "/" + img_id + "_TCI.tif"
response = request.urlretrieve(image_url, path_to_image)
print("Downloaded image: " + img_id)

tci = tifffile.imread(path_to_image)
plt.figure(figsize=(6, 6))
plt.imshow(tci)
plt.show()
```

Setelah memeriksa apakah hasilnya berada di wilayah geografis yang benar, Anda dapat memulai Earth Observation Job (EOJ) di langkah berikutnya. Anda menggunakan EOJ untuk mengidentifikasi badan air dari citra satelit dengan menggunakan proses yang disebut segmentasi tanah.

## Memulai pekerjaan observasi bumi (EOJ) yang melakukan segmentasi tanah pada serangkaian citra satelit
<a name="demo-start-eoj"></a>

SageMaker geospasial menyediakan beberapa model pra-terlatih yang dapat Anda gunakan untuk memproses data geospasial dari pengumpulan data raster. Untuk mempelajari lebih lanjut tentang model pra-terlatih yang tersedia dan operasi kustom, lihat[Jenis-jenis Operasi](geospatial-eoj-models.md).

Untuk menghitung perubahan luas permukaan air, Anda perlu mengidentifikasi piksel mana dalam gambar yang sesuai dengan air. Segmentasi tutupan lahan adalah model segmentasi semantik yang didukung oleh API. `start_earth_observation_job` Model segmentasi semantik mengaitkan label dengan setiap piksel di setiap gambar. Dalam hasilnya, setiap piksel diberi label yang didasarkan pada peta kelas untuk model. Berikut ini adalah peta kelas untuk model segmentasi lahan:

```
{
    0: "No_data",
    1: "Saturated_or_defective",
    2: "Dark_area_pixels",
    3: "Cloud_shadows",
    4: "Vegetation",
    5: "Not_vegetated",
    6: "Water",
    7: "Unclassified",
    8: "Cloud_medium_probability",
    9: "Cloud_high_probability",
    10: "Thin_cirrus",
    11: "Snow_ice"
}
```

Untuk memulai pekerjaan pengamatan bumi, gunakan `start_earth_observation_job` API. Ketika Anda mengirimkan permintaan Anda, Anda harus menentukan yang berikut:
+ `InputConfig`(*dict*) - Digunakan untuk menentukan koordinat area yang ingin Anda cari, dan metadata lain yang terkait dengan pencarian Anda.
+ `JobConfig`(*dict*) - Digunakan untuk menentukan jenis operasi EOJ yang Anda lakukan pada data. Contoh ini menggunakan **LandCoverSegmentationConfig**.
+ `ExecutionRoleArn`(*string*) — ARN dari peran eksekusi SageMaker AI dengan izin yang diperlukan untuk menjalankan pekerjaan.
+ `Name`(*string*) —Nama untuk pekerjaan pengamatan bumi.

`InputConfig`Ini adalah Python kamus. Gunakan variabel berikut **eoj\$1input\$1config** untuk menahan parameter permintaan pencarian. Gunakan variabel ini saat Anda membuat permintaan `start_earth_observation_job` API. w.

```
# Perform land cover segmentation on images returned from the Sentinel-2 dataset.
eoj_input_config = {
    "RasterDataCollectionQuery": {
        "RasterDataCollectionArn": "arn:aws:sagemaker-geospatial:us-west-2:378778860802:raster-data-collection/public/nmqj48dcu3g7ayw8",
        "AreaOfInterest": {
            "AreaOfInterestGeometry": {
                "PolygonGeometry": {
                    "Coordinates":[
                        [
                            [-114.529, 36.142],
                            [-114.373, 36.142],
                            [-114.373, 36.411],
                            [-114.529, 36.411],
                            [-114.529, 36.142],
                        ]
                    ]
                }
            }
        },
        "TimeRangeFilter": {
            "StartTime": "2021-01-01T00:00:00Z",
            "EndTime": "2022-07-10T23:59:59Z",
        },
        "PropertyFilters": {
            "Properties": [{"Property": {"EoCloudCover": {"LowerBound": 0, "UpperBound": 1}}}],
            "LogicalOperator": "AND",
        },
    }
}
```

`JobConfig`Ini adalah Python kamus yang digunakan untuk menentukan operasi EOJ yang ingin Anda lakukan pada data Anda:

```
eoj_config = {"LandCoverSegmentationConfig": {}}
```

Dengan elemen kamus yang sekarang ditentukan, Anda dapat mengirimkan permintaan `start_earth_observation_job` API Anda menggunakan contoh kode berikut:

```
# Gets the execution role arn associated with current notebook instance 
execution_role_arn = sagemaker.get_execution_role()

# Starts an earth observation job
response = sm_geo_client.start_earth_observation_job(
    Name="lake-mead-landcover",
    InputConfig=eoj_input_config,
    JobConfig=eoj_config,
    ExecutionRoleArn=execution_role_arn,
)
            
print(response)
```

Awal pekerjaan pengamatan bumi mengembalikan ARN bersama dengan metadata lainnya.

Untuk mendapatkan daftar semua pekerjaan pengamatan bumi yang sedang berlangsung dan saat ini, gunakan `list_earth_observation_jobs` API. Untuk memantau status pekerjaan pengamatan bumi tunggal, gunakan `get_earth_observation_job` API. Untuk membuat permintaan ini, gunakan ARN yang dibuat setelah mengirimkan permintaan EOJ Anda. Untuk mempelajari lebih lanjut, lihat [GetEarthObservationJob](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_geospatial_GetEarthObservationJob.html)di *Referensi Amazon SageMaker AI API*.

Untuk menemukan yang ARNs terkait dengan Anda, EOJs gunakan operasi `list_earth_observation_jobs` API. Untuk mempelajari lebih lanjut, lihat [ListEarthObservationJobs](https://docs.aws.amazon.com//sagemaker/latest/APIReference/API_geospatial_ListEarthObservationJobs.html)di *Referensi Amazon SageMaker AI API*.

```
# List all jobs in the account
sg_client.list_earth_observation_jobs()["EarthObservationJobSummaries"]
```

Berikut ini adalah contoh respon JSON:

```
{
    'Arn': 'arn:aws:sagemaker-geospatial:us-west-2:111122223333:earth-observation-job/futg3vuq935t',
    'CreationTime': datetime.datetime(2023, 10, 19, 4, 33, 54, 21481, tzinfo = tzlocal()),
    'DurationInSeconds': 3493,
    'Name': 'lake-mead-landcover',
    'OperationType': 'LAND_COVER_SEGMENTATION',
    'Status': 'COMPLETED',
    'Tags': {}
}, {
    'Arn': 'arn:aws:sagemaker-geospatial:us-west-2:111122223333:earth-observation-job/wu8j9x42zw3d',
    'CreationTime': datetime.datetime(2023, 10, 20, 0, 3, 27, 270920, tzinfo = tzlocal()),
    'DurationInSeconds': 1,
    'Name': 'mt-shasta-landcover',
    'OperationType': 'LAND_COVER_SEGMENTATION',
    'Status': 'INITIALIZING',
    'Tags': {}
}
```

Setelah status pekerjaan EOJ Anda berubah menjadi`COMPLETED`, lanjutkan ke bagian berikutnya untuk menghitung perubahan luas Mead's  permukaan Danau.

## Menghitung perubahan luas Mead permukaan Danau
<a name="demo-geospatial-calc"></a>

Untuk menghitung perubahan luas permukaan Danau Mead, pertama-tama ekspor hasil EOJ ke Amazon S3 dengan menggunakan: `export_earth_observation_job`

```
sagemaker_session = sagemaker.Session()
s3_bucket_name = sagemaker_session.default_bucket()  # Replace with your own bucket if needed
s3_bucket = session.resource("s3").Bucket(s3_bucket_name)
prefix = "export-lake-mead-eoj"  # Replace with the S3 prefix desired
export_bucket_and_key = f"s3://{s3_bucket_name}/{prefix}/"

eoj_output_config = {"S3Data": {"S3Uri": export_bucket_and_key}}
export_response = sm_geo_client.export_earth_observation_job(
    Arn="arn:aws:sagemaker-geospatial:us-west-2:111122223333:earth-observation-job/7xgwzijebynp",
    ExecutionRoleArn=execution_role_arn,
    OutputConfig=eoj_output_config,
    ExportSourceImages=False,
)
```

Untuk melihat status pekerjaan ekspor Anda, gunakan`get_earth_observation_job`:

```
export_job_details = sm_geo_client.get_earth_observation_job(Arn=export_response["Arn"])
```

Untuk menghitung perubahan ketinggian air Danau Mead, unduh masker tutupan lahan ke instance SageMaker notebook lokal dan unduh gambar sumber dari kueri kami sebelumnya. Dalam peta kelas untuk model segmentasi tanah, indeks kelas air adalah 6.

Untuk mengekstrak masker air dari Sentinel-2 gambar, ikuti langkah-langkah ini. Pertama, hitung jumlah piksel yang ditandai sebagai air (indeks kelas 6) pada gambar. Kedua, kalikan hitungan dengan area yang dicakup setiap piksel. Band dapat berbeda dalam resolusi spasialnya. Untuk model segmentasi tutupan lahan, semua pita diambil sampelnya ke resolusi spasial sebesar 60 meter.

```
import os
from glob import glob
import cv2
import numpy as np
import tifffile
import matplotlib.pyplot as plt
from urllib.parse import urlparse
from botocore import UNSIGNED
from botocore.config import Config

# Download land cover masks
mask_dir = "./masks/lake_mead"
os.makedirs(mask_dir, exist_ok=True)
image_paths = []
for s3_object in s3_bucket.objects.filter(Prefix=prefix).all():
    path, filename = os.path.split(s3_object.key)
    if "output" in path:
        mask_name = mask_dir + "/" + filename
        s3_bucket.download_file(s3_object.key, mask_name)
        print("Downloaded mask: " + mask_name)

# Download source images for visualization
for tci_url in tci_urls:
    url_parts = urlparse(tci_url)
    img_id = url_parts.path.split("/")[-2]
    tci_download_path = image_dir + "/" + img_id + "_TCI.tif"
    cogs_bucket = session.resource(
        "s3", config=Config(signature_version=UNSIGNED, region_name="us-west-2")
    ).Bucket(url_parts.hostname.split(".")[0])
    cogs_bucket.download_file(url_parts.path[1:], tci_download_path)
    print("Downloaded image: " + img_id)

print("Downloads complete.")

image_files = glob("images/lake_mead/*.tif")
mask_files = glob("masks/lake_mead/*.tif")
image_files.sort(key=lambda x: x.split("SQA_")[1])
mask_files.sort(key=lambda x: x.split("SQA_")[1])
overlay_dir = "./masks/lake_mead_overlay"
os.makedirs(overlay_dir, exist_ok=True)
lake_areas = []
mask_dates = []

for image_file, mask_file in zip(image_files, mask_files):
    image_id = image_file.split("/")[-1].split("_TCI")[0]
    mask_id = mask_file.split("/")[-1].split(".tif")[0]
    mask_date = mask_id.split("_")[2]
    mask_dates.append(mask_date)
    assert image_id == mask_id
    image = tifffile.imread(image_file)
    image_ds = cv2.resize(image, (1830, 1830), interpolation=cv2.INTER_LINEAR)
    mask = tifffile.imread(mask_file)
    water_mask = np.isin(mask, [6]).astype(np.uint8)  # water has a class index 6
    lake_mask = water_mask[1000:, :1100]
    lake_area = lake_mask.sum() * 60 * 60 / (1000 * 1000)  # calculate the surface area
    lake_areas.append(lake_area)
    contour, _ = cv2.findContours(water_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    combined = cv2.drawContours(image_ds, contour, -1, (255, 0, 0), 4)
    lake_crop = combined[1000:, :1100]
    cv2.putText(lake_crop, f"{mask_date}", (10,50), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 0), 3, cv2.LINE_AA)
    cv2.putText(lake_crop, f"{lake_area} [sq km]", (10,100), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 0), 3, cv2.LINE_AA)
    overlay_file = overlay_dir + '/' + mask_date + '.png'
    cv2.imwrite(overlay_file, cv2.cvtColor(lake_crop, cv2.COLOR_RGB2BGR))

# Plot water surface area vs. time.
plt.figure(figsize=(20,10))
plt.title('Lake Mead surface area for the 2021.02 - 2022.07 period.', fontsize=20)
plt.xticks(rotation=45)
plt.ylabel('Water surface area [sq km]', fontsize=14)
plt.plot(mask_dates, lake_areas, marker='o')
plt.grid('on')
plt.ylim(240, 320)
for i, v in enumerate(lake_areas):
    plt.text(i, v+2, "%d" %v, ha='center')
plt.show()
```

Dengan menggunakan`matplotlib`, Anda dapat memvisualisasikan hasilnya dengan grafik. Grafik menunjukkan bahwa luas permukaan Danau Mead menurun dari Januari 2021—Juli 2022.

![\[Grafik batang yang menunjukkan luas permukaan Danau Mead menurun dari Januari 2021-Juli 2022\]](http://docs.aws.amazon.com/id_id/sagemaker/latest/dg/images/lake-mead-decrease.png)
