

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Acesse a coleta de dados raster do Sentinel-2 e crie um trabalho de observação da terra para realizar a segmentação da terra
<a name="geospatial-demo"></a>

Este tutorial baseado em Python usa o SDK para Python (Boto3) e um notebook Amazon Studio Classic. SageMaker Para concluir esta demonstração com sucesso, verifique se você tem as permissões AWS Identity and Access Management (IAM) necessárias para usar SageMaker geospatial e o Studio Classic. SageMaker geospatial exige que você tenha um usuário, grupo ou função que possa acessar o Studio Classic. Você também deve ter uma função de execução de SageMaker IA que especifique o principal do serviço SageMaker geoespacial `sagemaker-geospatial.amazonaws.com` em sua política de confiança. 

Para saber mais sobre esses requisitos, consulte as [funções SageMaker geoespaciais do IAM](sagemaker-geospatial-roles.md).

Este tutorial mostra como usar a API SageMaker geoespacial para concluir as seguintes tarefas:
+ Encontre as coleções de dados raster disponíveis com `list_raster_data_collections`.
+ Pesquise uma coleção de dados raster especificada usando `search_raster_data_collection`.
+ Crie um trabalho de observação da terra (EOJ) usando o `start_earth_observation_job`.

## Usando `list_raster_data_collections` para encontrar coleções de dados disponíveis
<a name="demo-use-list-rdc"></a>

SageMaker geospatial suporta várias coleções de dados raster. Para saber mais sobre as coleções de dados disponíveis, consulte [Coleções de dados](geospatial-data-collections.md).

Esta demonstração usa dados de satélite coletados de satélites [GeoTIFF Sentinel-2 otimizados para nuvem](https://registry.opendata.aws/sentinel-2-l2a-cogs/). Esses satélites fornecem cobertura global da superfície terrestre da terra a cada cinco dias. Além de coletar imagens da superfície da terra, os satélites Sentinel-2 também coletam dados em uma variedade de bandas espectrais.

Para pesquisar uma área de interesse (AOI), você precisa do ARN associado aos dados do satélite Sentinel-2. Para encontrar as coleções de dados disponíveis e as associadas às ARNs suas Região da AWS, use a operação da `list_raster_data_collections` API.

Como a resposta pode ser paginada, você deve usar a operação `get_paginator` para retornar todos os dados relevantes:

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

Este é um exemplo de resposta JSON da operação de API `list_raster_data_collections`. É truncado para incluir somente a coleta de dados (Sentinel-2) usada neste exemplo de código. Para obter mais detalhes sobre uma coleta de dados raster específica, use `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"
}
```

Depois de executar a amostra de código anterior, você obtém o ARN da coleção de dados raster do Sentinel-2, `arn:aws:sagemaker-geospatial:us-west-2:378778860802:raster-data-collection/public/nmqj48dcu3g7ayw8`. Na [próxima seção](#demo-search-raster-data), você pode consultar a coleta de dados do Sentinel-2 usando a API `search_raster_data_collection`.

## Pesquisando a coleta de dados Sentinel-2 raster usando `search_raster_data_collection`
<a name="demo-search-raster-data"></a>

Na seção anterior, você costumava obter o ARN `list_raster_data_collections` para Sentinel-2 a coleta de dados. Agora você pode usar esse ARN para pesquisar a coleta de dados em uma determinada área de interesse (AOI), intervalo de tempo, propriedades e as bandas UV disponíveis.

Para chamar a API `search_raster_data_collection`, você deve passar um Python dicionário para o parâmetro `RasterDataCollectionQuery`. Este exemplo usa `AreaOfInterest`, `TimeRangeFilter`, `PropertyFilters` e `BandFilter`. Para facilitar, você pode especificar o dicionário Python usando a variável **search\$1rdc\$1query** para armazenar os parâmetros de consulta de pesquisa:

```
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"
    ]
}
```

Neste exemplo, você consulta um `AreaOfInterest` que inclui [Lake Mead](https://en.wikipedia.org/wiki/Lake_Mead), em Utah. Além disso, o Sentinel-2 é compatível com vários tipos de bandas de imagem. Para medir a mudança na superfície da água, você só precisa da faixa `visual`.

Depois de criar os parâmetros de consulta, você pode usar a API `search_raster_data_collection` para fazer a solicitação. 

O exemplo de código a seguir implementa uma solicitação de API `search_raster_data_collection`. Essa API não oferece apoio à paginação usando a API `get_paginator`. Para garantir que a resposta completa da API tenha sido coletada, a amostra de código usa um loop `while` para verificar se `NextToken` existe. Em seguida, a amostra de código é usada `.extend()` para anexar a imagem de satélite URLs e outros metadados de resposta ao. `items_list` 

Para saber mais sobre o`search_raster_data_collection`, consulte [SearchRasterDataCollection](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_geospatial_SearchRasterDataCollection.html)a *Amazon SageMaker AI API Reference*.

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

O exemplo a seguir é a resposta JSON parcial da sua consulta. Foi truncado para maior clareza. Somente o **"BandFilter": ["visual"]** especificado na solicitação é retornado no par de valores-chave `Assets`:

```
{
    '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'
    }
}
```

Agora que você tem os resultados da consulta, na próxima seção, você pode visualizar os resultados usando o `matplotlib`. Isso serve para verificar se os resultados são da região geográfica correta. 

## Visualizando seu `search_raster_data_collection` usando `matplotlib`
<a name="demo-geospatial-visualize"></a>

Antes de começar o trabalho de observação da terra (EOJ), você pode visualizar um resultado de nossa consulta com  `matplotlib`. A amostra de código a seguir pega o primeiro item, `items_list[0]["Assets"]["visual"]["Href"]`, da variável `items_list` criada na amostra de código anterior e imprime uma imagem usando `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()
```

Depois de verificar se os resultados estão na região geográfica correta, você pode iniciar o trabalho de observação da terra (EOJ) na próxima etapa. Você usa o EOJ para identificar os corpos d'água a partir das imagens de satélite usando um processo chamado segmentação terrestre.

## Iniciando um trabalho de observação da terra (EOJ) que realiza a segmentação da terra em uma série de imagens de satélite
<a name="demo-start-eoj"></a>

SageMaker geospatial fornece vários modelos pré-treinados que você pode usar para processar dados geoespaciais de coleções de dados raster. Para saber mais sobre os modelos pré-treinados disponíveis e as operações personalizadas, consulte [Tipos de operações](geospatial-eoj-models.md).

Para calcular a mudança na área da superfície da água, você precisa identificar quais pixels nas imagens correspondem à água. A segmentação da cobertura da terra é um modelo de segmentação semântica compatível com a API `start_earth_observation_job`. Os modelos de segmentação semântica associam um rótulo a cada pixel em cada imagem. Nos resultados, cada pixel recebe um rótulo baseado no mapa de classes do modelo. A seguir está o mapa de classes para o modelo de segmentação de terras:

```
{
    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"
}
```

Para iniciar um trabalho de observação da terra, use a API `start_earth_observation_job`. Ao enviar sua solicitação, você deve especificar o seguinte:
+ `InputConfig` (*dict*): Usado para especificar as coordenadas da área que você deseja pesquisar e outros metadados associados à sua pesquisa.
+ `JobConfig` (*dict*): Usado para especificar o tipo de operação EOJ que você executou nos dados. Este exemplo usa **LandCoverSegmentationConfig**.
+ `ExecutionRoleArn`(*string*) — O ARN da função de execução da SageMaker IA com as permissões necessárias para executar o trabalho.
+ `Name` (*string*): Um nome para o trabalho de observação da terra.

O `InputConfig` é um dicionário Python. Use a variável **eoj\$1input\$1config** a seguir para manter os parâmetros de consulta de pesquisa. Use essa variável ao fazer a solicitação de API `start_earth_observation_job`. 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",
        },
    }
}
```

O `JobConfig` é um dicionário Python usado para especificar a operação EOJ que você deseja realizar em seus dados:

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

Com os elementos do dicionário agora especificados, você pode enviar sua solicitação de API `start_earth_observation_job` usando o seguinte exemplo de código:

```
# 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)
```

O início de um trabalho de observação da terra retorna um ARN junto com outros metadados.

Para obter uma lista de todos os trabalhos de observação da terra em andamento e atuais, use a API `list_earth_observation_jobs`. Para monitorar o status de um único trabalho de observação da Terra, use a API `get_earth_observation_job`. Para fazer essa solicitação, use o ARN criado após enviar sua solicitação de EOJ. Para saber mais, consulte [GetEarthObservationJob](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_geospatial_GetEarthObservationJob.html)a *Amazon SageMaker AI API Reference*.

Para encontrar o ARNs associado ao seu, EOJs use a operação `list_earth_observation_jobs` da API. Para saber mais, consulte [ListEarthObservationJobs](https://docs.aws.amazon.com//sagemaker/latest/APIReference/API_geospatial_ListEarthObservationJobs.html)a *Amazon SageMaker AI API Reference*.

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

O seguinte é um exemplo de resposta 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': {}
}
```

Depois que o status de seu trabalho no EOJ mudar para `COMPLETED`, vá para a próxima seção para calcular a mudança na área da superfície do lago Mead's .

## Cálculo da mudança na área da superfície do Lago Mead
<a name="demo-geospatial-calc"></a>

Para calcular a mudança na área de superfície do Lago Mead, primeiro exporte os resultados do EOJ para o Amazon S3 usando `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,
)
```

Para ver o status da exportação, use `get_earth_observation_job`:

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

Para calcular as mudanças no nível da água do Lago Mead, baixe as máscaras de cobertura da terra para a instância local do SageMaker notebook e baixe as imagens de origem da nossa consulta anterior. No mapa de classes do modelo de segmentação de terras, o índice de classes da água é 6.

Para extrair a máscara de água de uma imagem Sentinel-2, siga estas etapas. Primeiro, conte o número de pixels marcados como água (índice de classe 6) na imagem. Segundo, multiplique a contagem pela área que cada pixel cobre. As bandas podem diferir em sua resolução espacial. Para o modelo de segmentação da cobertura do solo, todas as faixas são obtidas como amostra para uma resolução espacial igual a 60 metros.

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

Usando `matplotlib`, você pode visualizar os resultados com um gráfico. O gráfico mostra que a área da superfície do Lago Mead diminuiu de janeiro de 2021 a julho de 2022.

![\[Um gráfico de barras mostrando a área da superfície do Lago Mead diminuiu de janeiro de 2021 a julho de 2022\]](http://docs.aws.amazon.com/pt_br/sagemaker/latest/dg/images/lake-mead-decrease.png)
