Guia de desenvolvedores do SDK REST para C#

O SDK do C# do Azure Mapas dá suporte à funcionalidade disponível na API REST do Azure Mapas, como pesquisar um endereço, rotear entre coordenadas diferentes e obter a localização geográfica de um endereço IP específico. Este artigo apresenta o SDK REST do C# com exemplos para ajudá-lo a começar a criar aplicativos com reconhecimento de localização em C# que incorporam o poder do Azure Mapas.

Observação

O SDK do C# do Azure Mapas dá suporte a qualquer versão do .NET compatível com a versão 2.0 ou superior do .NET Standard. Para obter uma tabela interativa, consulte Versões do .NET Standard.

Pré-requisitos

Dica

Você pode criar uma conta Azure Mapas programaticamente. Aqui está um exemplo usando a CLI do Azure:

az maps account create --kind "Gen2" --account-name "myMapAccountName" --resource-group "<resource group>" --sku "G2"

Criar um projeto .NET

O snippet de código do PowerShell a seguir demonstra como usar o PowerShell para criar um programa MapsDemo de console com o .NET 7.0. Você pode usar qualquer versão compatível com o .NET Standard 2.0 como a estrutura.

dotnet new console -lang C# -n MapsDemo -f net7.0 
cd MapsDemo 

Instalar os pacotes necessários

Para usar o SDK do C# do Azure Mapas, precisamos instalar os pacotes necessários. Cada um dos serviços do Azure Mapas, incluindo pesquisa, roteamento, renderização e geolocalização, estão cada um no próprio pacote. Como o SDK do C# do Azure Mapas está em versão prévia pública, você precisa adicionar o sinalizador --prerelease:

dotnet add package Azure.Maps.Rendering --prerelease
dotnet add package Azure.Maps.Routing --prerelease
dotnet add package Azure.Maps.Search --prerelease
dotnet add package Azure.Maps.Geolocation --prerelease

Serviços do Azure Mapas

Nome do serviço Pacote NuGet Exemplos
Pesquisa Azure.Maps.Search exemplos de pesquisas
Roteamento Azure.Maps.Routing  exemplos de roteamentos
Renderização Azure.Maps.Rendering exemplo de renderização
Geolocalização Azure.Maps.Geolocation exemplo de geolocalização

Criar e autenticar um MapsSearchClient

O objeto cliente usado para acessar as APIs de Pesquisa do Azure Mapas exige que um objeto AzureKeyCredential seja autenticado ao usar uma chave de assinatura do Azure Mapas ou um objeto TokenCredential com a ID do cliente do Azure Mapas ao autenticar usando o Microsoft Entra ID. Para obter mais informações sobre autenticação, confira Autenticação no Azure Mapas.

Como usar uma credencial do Microsoft Entra

Você pode autenticar com o Microsoft Entra ID usando a biblioteca de Identidade do Azure. Para usar o provedor DefaultAzureCredential, você precisará instalar a biblioteca de clientes da Identidade do Azure para .NET:

dotnet add package Azure.Identity 

Você precisará registrar o novo aplicativo do Microsoft Entra e permitir acesso ao Azure Mapas atribuindo a função necessária à entidade de serviço. Para obter mais informações, confira Hospedar um daemon em recursos que não são do Azure. A ID do aplicativo (cliente), uma ID de diretório (locatário) e um segredo do cliente são retornados. Copie esses valores e armazene-os em um local seguro. Você precisará deles nas etapas a seguir.

Defina os valores da ID do aplicativo (cliente), da ID do diretório (locatário) e do segredo do cliente do aplicativo do Microsoft Entra e a ID do cliente do recurso de mapa como variáveis de ambiente:

Variável de ambiente Descrição
AZURE_CLIENT_ID ID do aplicativo (cliente) no aplicativo registrado
AZURE_CLIENT_SECRET O valor do segredo do cliente no aplicativo registrado
AZURE_TENANT_ID ID do diretório (locatário) no aplicativo registrado
MAPS_CLIENT_ID A ID do cliente no recurso de Mapeamento do Azure

Agora você pode criar variáveis de ambiente no PowerShell para armazenar esses valores:

$Env:AZURE_CLIENT_ID="Application (client) ID"
$Env:AZURE_CLIENT_SECRET="your client secret"
$Env:AZURE_TENANT_ID="your Directory (tenant) ID"
$Env:MAPS_CLIENT_ID="your Azure Maps client ID"

Depois de configurar as variáveis de ambiente, você pode usá-las em seu programa para instanciar o cliente AzureMapsSearch:

using System;
using Azure.Identity; 
using Azure.Maps.Search; 

var credential = new DefaultAzureCredential(); 
var clientId = Environment.GetEnvironmentVariable("MAPS_CLIENT_ID"); 
var client = new MapsSearchClient(credential, clientId); 

Importante

As outras variáveis de ambiente criadas no snippet de código anterior, embora não sejam usadas no exemplo de código, são exigidas pela DefaultAzureCredential(). Se você não definir essas variáveis de ambiente corretamente, usando as mesmas convenções de nomenclatura, receberá erros em tempo de execução. Por exemplo, se o AZURE_CLIENT_ID for ignorado ou inválido, você receberá um erro InvalidAuthenticationTokenTenant.

Usando uma credencial de chave de assinatura

Você pode autenticar com sua chave de assinatura do Azure Mapas. Sua chave de assinatura pode ser encontrada na seção Autenticação na conta do Azure Mapas, conforme mostrado na seguinte captura de tela:

Screenshot showing your Azure Maps subscription key in the Azure portal.

Agora você pode criar variáveis de ambiente no PowerShell para armazenar a chave de assinatura:

$Env:SUBSCRIPTION_KEY="your subscription key"

Depois que a variável de ambiente for criada, você poderá acessá-la em seu código:

using System;
using Azure; 
using Azure.Maps.Search; 

// Use Azure Maps subscription key authentication 
var subscriptionKey = Environment.GetEnvironmentVariable("SUBSCRIPTION_KEY") ?? string.Empty;
var credential = new AzureKeyCredential(subscriptionKey);
var client = new MapsSearchClient(credential); 

Pesquisar difusamente uma entidade

O snippet de código a seguir demonstra como, em um aplicativo de console simples, importar o pacote Azure.Maps.Search e realizar uma pesquisa difusa de "Starbucks" perto de Seattle. Em Program.cs:

using System;
using Azure; 
using Azure.Core.GeoJson; 
using Azure.Maps.Search; 
using Azure.Maps.Search.Models; 

// Use Azure Maps subscription key authentication 
var subscriptionKey = Environment.GetEnvironmentVariable("SUBSCRIPTION_KEY") ?? string.Empty;
var credential = new AzureKeyCredential(subscriptionKey);
var client = new MapsSearchClient(credential); 

SearchAddressResult searchResult = client.FuzzySearch( 
    "Starbucks", new FuzzySearchOptions 
    { 
        Coordinates = new GeoPosition(-122.34255, 47.61010), 
        Language = SearchLanguage.EnglishUsa 
    }); 


// Print the search results 
foreach (var result in searchResult.Results) 
{ 
    Console.WriteLine($""" 
        * {result.Address.StreetNumber} {result.Address.StreetName} 
          {result.Address.Municipality} {result.Address.CountryCode} {result.Address.PostalCode} 
          Coordinate: ({result.Position.Latitude:F4}, {result.Position.Longitude:F4}) 
        """); 
} 

O snippet de código acima demonstra como criar um objeto MapsSearchClient usando suas credenciais do Azure e usa o método FuzzySearch passando o nome do POI (ponto de interesse) "Starbucks" e as coordenadas GeoPosition(-122.31, 47.61). O SDK empacota e envia os resultados para os pontos de extremidade REST do Azure Mapas. Quando os resultados da pesquisa são retornados, eles são gravados na tela usando Console.WriteLine.

As seguintes bibliotecas são usadas:

  1. Azure.Maps.Search é necessário para a classe MapsSearchClient.
  2. Azure.Maps.Search.Models é necessário para a classe SearchAddressResult.
  3. Azure.Core.GeoJson é necessário para o struct GeoPosition usado pela classe FuzzySearchOptions.

Para executar seu aplicativo, acesse a pasta do projeto e execute dotnet run no PowerShell:

dotnet run 

Você deve ver uma lista de resultados de endereços e coordenadas da Starbucks:

* 1912 Pike Place 
  Seattle US 98101 
  Coordinate: 47.61016, -122.34248 
* 2118 Westlake Avenue 
  Seattle US 98121 
  Coordinate: 47.61731, -122.33782 
* 2601 Elliott Avenue 
  Seattle US 98121 
  Coordinate: 47.61426, -122.35261 
* 1730 Howell Street 
  Seattle US 98101 
  Coordinate: 47.61716, -122.3298 
* 220 1st Avenue South 
  Seattle US 98104 
  Coordinate: 47.60027, -122.3338 
* 400 Occidental Avenue South 
  Seattle US 98104 
  Coordinate: 47.5991, -122.33278 
* 1600 East Olive Way 
  Seattle US 98102 
  Coordinate: 47.61948, -122.32505 
* 500 Mercer Street 
  Seattle US 98109 
  Coordinate: 47.62501, -122.34687 
* 505 5Th Ave S 
  Seattle US 98104 
  Coordinate: 47.59768, -122.32849 
* 425 Queen Anne Avenue North 
  Seattle US 98109 
  Coordinate: 47.62301, -122.3571 

Pesquisar um endereço

Chame o método SearchAddress para obter a coordenada de um endereço. Modifique o programa Principal do exemplo da seguinte maneira:

// Use Azure Maps subscription key authentication 
var subscriptionKey = Environment.GetEnvironmentVariable("SUBSCRIPTION_KEY") ?? string.Empty;
var credential = new AzureKeyCredential(subscriptionKey);
var client = new MapsSearchClient(credential); 

SearchAddressResult searchResult = client.SearchAddress(
    "1301 Alaskan Way, Seattle, WA 98101, US");

if (searchResult.Results.Count > 0) 
{
    SearchAddressResultItem result = searchResult.Results.First(); 
    Console.WriteLine($"The Coordinate: ({result.Position.Latitude:F4}, {result.Position.Longitude:F4})"); 
}

O método SearchAddress retorna os resultados segundo a ordem da pontuação de confiança e, como searchResult.Results.First() é usado, imprime as coordenadas do primeiro resultado.

A Pesquisa do Azure Mapas também fornece alguns métodos de consulta em lote. Esses métodos retornarão objetos LRO (operações de execução prolongada). As solicitações podem não retornar todos os resultados imediatamente, portanto, os usuários podem optar por aguardar até a conclusão ou consultar o resultado periodicamente. Os exemplos abaixo demonstram como chamar os métodos de pesquisa reversa em lote:

var queries = new List<ReverseSearchAddressQuery>() 
{ 
    new ReverseSearchAddressQuery(new ReverseSearchOptions() 
    { 
        Coordinates = new GeoPosition(2.294911, 48.858561) 
    }), 
    new ReverseSearchAddressQuery(new ReverseSearchOptions() 
    { 
        Coordinates = new GeoPosition(-122.127896, 47.639765), 
        RadiusInMeters = 5000 
    }) 
};

No exemplo acima, duas consultas são passadas para a solicitação de pesquisa inversa em lote. Para obter os resultados de LRO, você tem poucas opções. A primeira opção é passar WaitUntil.Completed para o método. A solicitação aguardará até que todas as solicitações sejam concluídas e retornará os resultados:

// Wait until the LRO return batch results 
Response<ReverseSearchAddressBatchOperation> waitUntilCompletedResults = client.ReverseSearchAddressBatch(WaitUntil.Completed, queries); 

// Print the result addresses 
printReverseBatchAddresses(waitUntilCompletedResults.Value); 

Outra opção é passar WaitUntil.Started. A solicitação retornará os resultados imediatamente e você precisará sondá-los manualmente:

// Manual polling the batch results 
Response<ReverseSearchAddressBatchOperation> manualPollingOperation = client.ReverseSearchAddressBatch(WaitUntil.Started, queries);

// Keep polling until we get the results
while (true)
{
    manualPollingOperation.Value.UpdateStatus();
    if (manualPollingOperation.Value.HasCompleted) break;
    Task.Delay(1000);
}
printReverseBatchAddresses(manualPollingOperation);

Também podemos chamar WaitUntilCompletion() para aguardar explicitamente o resultado:

Response<ReverseSearchAddressBatchOperation> manualPollingResult = manualPollingResults.WaitUntilCompleted();

printReverseBatchAddresses(manualPollingResult.Value);

O terceiro método requer a ID da operação para obter os resultados, que serão armazenados em cache no lado do servidor por 14 dias:

  ReverseSearchAddressBatchOperation longRunningOperation = client.ReverseSearchAddressBatch(WaitUntil.Started, queries);

  // Get batch results by ID 
  string operationId = longRunningOperation.Value.Id;

  // After the LRO completes, create a new operation
  // to get the results from the server
  ReverseSearchAddressBatchOperation newOperation = new ReverseSearchAddressBatchOperation(client, operationId);
  Response<ReverseSearchAddressBatchOperation> newOperationResult = newOperation.WaitForCompletion();

printReverseBatchAddresses(newOperationResult);

O código completo para pesquisa em lote de endereço reverso com a ID da operação:

using system;
using Azure;
using Azure.Core.GeoJson;
using Azure.Maps.Search;
using Azure.Maps.Search.Models;

// Use Azure Maps subscription key authentication 
var subscriptionKey = Environment.GetEnvironmentVariable("SUBSCRIPTION_KEY") ?? string.Empty;
var credential = new AzureKeyCredential(subscriptionKey);
var client = new MapsSearchClient(credential); 

var queries = new List<ReverseSearchAddressQuery>()
{
    new ReverseSearchAddressQuery(new ReverseSearchOptions()
    {
        Coordinates = new GeoPosition(2.294911, 48.858561)
    }),
    new ReverseSearchAddressQuery(new ReverseSearchOptions()
    {
        Coordinates = new GeoPosition(-122.127896, 47.639765),
        RadiusInMeters = 5000
    })
};

// Manual polling the batch results
ReverseSearchAddressBatchOperation longRunningOperation = client.ReverseSearchAddressBatch(WaitUntil.Started, queries);

// Get batch results by ID
string operationId = longRunningOperation.Id;

// A few days later, create a new operation and get the result from server
ReverseSearchAddressBatchOperation newOperation = new ReverseSearchAddressBatchOperation(client, operationId);
Response<ReverseSearchAddressBatchResult> newOperationResult = newOperation.WaitForCompletion();
printReverseBatchAddresses(newOperationResult.Value);
void printReverseBatchAddresses(ReverseSearchAddressBatchResult batchResult)
{
    // Print the search results
    for (int i = 0; i < batchResult.Results.Count; i++)
    {
        Console.WriteLine($"Possible addresses for query {i}:");
        var result = batchResult.Results[i];
        foreach (var address in result.Addresses)
        {
            Console.WriteLine($"{address.Address.FreeformAddress}");
        }
    }
}

Informações adicionais

O Namespace do Azure.Mapas na documentação do .NET.