Partilhar via


Mostrar as direções de A para B

Este artigo mostra como fazer uma solicitação de rota e mostrar a rota no mapa.

Existem duas formas de o fazer. A primeira maneira é consultar a API Get Route Directions usando o SDK REST do TypeScript @azure-rest/maps-route. A segunda maneira é usar a API Fetch para fazer uma solicitação de pesquisa para a API Get Route Directions. Ambas as abordagens são descritas neste artigo.

Consultar a rota via REST SDK

import * as atlas from "azure-maps-control";
import MapsRoute, { toColonDelimitedLatLonString } from "@azure-rest/maps-route";
import "azure-maps-control/dist/atlas.min.css";

const onload = () => {
  // Initialize a map instance.
  const map = new atlas.Map("map", {
    view: "Auto",
    // Add authentication details for connecting to Azure Maps.
    authOptions: {
      // Use Azure Active Directory authentication.
      authType: "aad",
      clientId: "<Your Azure Maps Client Id>",
      aadAppId: "<Your Azure Active Directory Client Id>",
      aadTenant: "<Your Azure Active Directory Tenant Id>"
    }
  });

  map.events.add("load", async () => {
    // Use the access token from the map and create an object that implements the TokenCredential interface.
    const credential = {
      getToken: () => {
        return {
          token: map.authentication.getToken()
        };
      }
    };

    // Create a Route client.
    const client = MapsRoute(credential, "<Your Azure Maps Client Id>");

    // Create a data source and add it to the map.
    const dataSource = new atlas.source.DataSource();
    map.sources.add(dataSource);

    // Create the GeoJSON objects which represent the start and end points of the route.
    const startPoint = new atlas.data.Feature(new atlas.data.Point([-122.130137, 47.644702]), {
      title: "Redmond",
      icon: "pin-blue"
    });

    const endPoint = new atlas.data.Feature(new atlas.data.Point([-122.3352, 47.61397]), {
      title: "Seattle",
      icon: "pin-round-blue"
    });

    // Add the data to the data source.
    dataSource.add([startPoint, endPoint]);

    // Create a layer for rendering the route line under the road labels.
    map.layers.add(
      new atlas.layer.LineLayer(dataSource, null, {
        strokeColor: "#2272B9",
        strokeWidth: 5,
        lineJoin: "round",
        lineCap: "round"
      }),
      "labels"
    );

    // Create a layer for rendering the start and end points of the route as symbols.
    map.layers.add(
      new atlas.layer.SymbolLayer(dataSource, null, {
        iconOptions: {
          image: ["get", "icon"],
          allowOverlap: true,
          ignorePlacement: true
        },
        textOptions: {
          textField: ["get", "title"],
          offset: [0, 1.2]
        },
        filter: ["any", ["==", ["geometry-type"], "Point"], ["==", ["geometry-type"], "MultiPoint"]] //Only render Point or MultiPoints in this layer.
      })
    );

    // Get the coordinates of the start and end points.
    const coordinates = [
      [startPoint.geometry.coordinates[1], startPoint.geometry.coordinates[0]],
      [endPoint.geometry.coordinates[1], endPoint.geometry.coordinates[0]]
    ];

    // Get the route directions between the start and end points.
    const response = await client.path("/route/directions/{format}", "json").get({
      queryParameters: {
        query: toColonDelimitedLatLonString(coordinates)
      }
    });

    // Get the GeoJSON feature collection of the route.
    const data = getFeatures(response.body.routes);

    // Add the route data to the data source.
    dataSource.add(data);

    // Update the map view to center over the route.
    map.setCamera({
      bounds: data.bbox,
      padding: 40
    });
  });
};

/**
 * Helper function to convert a route response into a GeoJSON FeatureCollection.
 */
const getFeatures = (routes) => {
  const bounds = [];
  const features = routes.map((route, index) => {
    const multiLineCoords = route.legs.map((leg) => {
      return leg.points.map((coord) => {
        const position = [coord.longitude, coord.latitude];
        bounds.push(position);
        return position;
      });
    });

    // Include all properties on the route object except legs.
    // Legs is used to create the MultiLineString, so we only need the summaries.
    // The legSummaries property replaces the legs property with just summary data.
    const props = {
      ...route,
      legSummaries: route.legs.map((leg) => leg.summary),
      resultIndex: index
    };
    delete props.legs;

    return {
      type: "Feature",
      geometry: {
        type: "MultiLineString",
        coordinates: multiLineCoords
      },
      properties: props
    };
  });

  return {
    type: "FeatureCollection",
    features: features,
    bbox: new atlas.data.BoundingBox.fromLatLngs(bounds)
  };
};

document.body.onload = onload;

No exemplo de código anterior, o primeiro bloco constrói um objeto map e define o mecanismo de autenticação para usar o Microsoft Entra ID. Você pode ver Criar um mapa para obter instruções.

O segundo bloco de código cria um objeto que implementa a interface TokenCredential para autenticar solicitações HTTP no Azure Maps com o token de acesso. Em seguida, ele passa o objeto de credencial para MapsRoute e cria uma instância do cliente.

O terceiro bloco de código cria e adiciona um objeto DataSource ao mapa.

O quarto bloco de código cria objetos de pontos de início e fim e os adiciona ao objeto dataSource.

Uma linha é um recurso para LineString. Um LineLayer renderiza objetos de linha encapsulados na DataSource como linhas no mapa. O quarto bloco de código cria e adiciona uma camada de linha ao mapa. Consulte as propriedades de uma camada de linha em LinestringLayerOptions.

Uma camada de símbolos usa textos ou ícones para renderizar dados baseados em pontos encapsulados no DataSource. Os textos ou os ícones são renderizados como símbolos no mapa. O quinto bloco de código cria e adiciona uma camada de símbolos ao mapa.

O sexto bloco de código consulta o serviço de roteamento do Azure Maps, que faz parte do cliente MapsRoute . Uma solicitação GET é usada para obter uma rota entre os pontos inicial e final. Uma coleção de recursos GeoJSON da resposta é então extraída usando uma getFeatures() função auxiliar e adicionada à fonte de dados. Em seguida, ele renderiza a resposta como uma rota no mapa. Para obter mais informações sobre como adicionar uma linha ao mapa, consulte Adicionar uma linha no mapa.

O último bloco de código define os limites do mapa usando a propriedade setCamera do mapa.

A consulta de rota, a fonte de dados, o símbolo, as camadas de linha e os limites da câmera são criados dentro do ouvinte de eventos. Essa estrutura de código garante que os resultados sejam exibidos somente depois que o mapa for totalmente carregado.

Consultar a rota via Fetch API

import * as atlas from "azure-maps-control";
import "azure-maps-control/dist/atlas.min.css";

const onload = () => {
  // Initialize a map instance.
  const map = new atlas.Map("map", {
    view: "Auto",
    // Add authentication details for connecting to Azure Maps.
    authOptions: {
      // Use Azure Active Directory authentication.
      authType: "aad",
      clientId: "<Your Azure Maps Client Id>",
      aadAppId: "<Your Azure Active Directory Client Id>",
      aadTenant: "<Your Azure Active Directory Tenant Id>"
    }
  });

  map.events.add("load", async () => {
    // Create a data source and add it to the map.
    const dataSource = new atlas.source.DataSource();
    map.sources.add(dataSource);

    // Create the GeoJSON objects which represent the start and end points of the route.
    const startPoint = new atlas.data.Feature(new atlas.data.Point([-122.130137, 47.644702]), {
      title: "Redmond",
      icon: "pin-blue"
    });

    const endPoint = new atlas.data.Feature(new atlas.data.Point([-122.3352, 47.61397]), {
      title: "Seattle",
      icon: "pin-round-blue"
    });

    // Add the data to the data source.
    dataSource.add([startPoint, endPoint]);

    // Create a layer for rendering the route line under the road labels.
    map.layers.add(
      new atlas.layer.LineLayer(dataSource, null, {
        strokeColor: "#2272B9",
        strokeWidth: 5,
        lineJoin: "round",
        lineCap: "round"
      }),
      "labels"
    );

    // Create a layer for rendering the start and end points of the route as symbols.
    map.layers.add(
      new atlas.layer.SymbolLayer(dataSource, null, {
        iconOptions: {
          image: ["get", "icon"],
          allowOverlap: true,
          ignorePlacement: true
        },
        textOptions: {
          textField: ["get", "title"],
          offset: [0, 1.2]
        },
        filter: ["any", ["==", ["geometry-type"], "Point"], ["==", ["geometry-type"], "MultiPoint"]] //Only render Point or MultiPoints in this layer.
      })
    );

    // Send a request to the route API
    let url = "https://atlas.microsoft.com/route/directions/json?";
    url += "&api-version=1.0";
    url +=
      "&query=" +
      startPoint.geometry.coordinates[1] +
      "," +
      startPoint.geometry.coordinates[0] +
      ":" +
      endPoint.geometry.coordinates[1] +
      "," +
      endPoint.geometry.coordinates[0];

    // Process request
    fetch(url, {
      headers: {
        Authorization: "Bearer " + map.authentication.getToken(),
        "x-ms-client-id": "<Your Azure Maps Client Id>"
      }
    })
      .then((response) => response.json())
      .then((response) => {
        const bounds = [];
        const route = response.routes[0];
        
        // Create an array to store the coordinates of each turn
        let routeCoordinates = [];
        route.legs.forEach((leg) => {
          const legCoordinates = leg.points.map((point) => {
            const position = [point.longitude, point.latitude];
            bounds.push(position);
            return position;
          });
          // Add each turn coordinate to the array
          routeCoordinates = routeCoordinates.concat(legCoordinates);
        });

        // Add route line to the dataSource
        dataSource.add(new atlas.data.Feature(new atlas.data.LineString(routeCoordinates)));

        // Update the map view to center over the route.
        map.setCamera({
          bounds: new atlas.data.BoundingBox.fromLatLngs(bounds),
          padding: 40
        });
      });
  });
};

document.body.onload = onload;

No exemplo de código anterior, o primeiro bloco de código constrói um objeto map e define o mecanismo de autenticação para usar o Microsoft Entra ID. Você pode ver Criar um mapa para obter instruções.

O segundo bloco de código cria e adiciona um objeto DataSource ao mapa.

O terceiro bloco de código cria os pontos de início e destino para a rota. Em seguida, adiciona-os à fonte de dados. Para obter mais informações, consulte Adicionar um pino no mapa.

Um LineLayer renderiza objetos de linha encapsulados na DataSource como linhas no mapa. O quarto bloco de código cria e adiciona uma camada de linha ao mapa. Consulte as propriedades de uma camada de linha em LineLayerOptions.

Uma camada de símbolos usa texto ou ícones para renderizar dados baseados em pontos quebrados na Fonte de Dados como símbolos no mapa. O quinto bloco de código cria e adiciona uma camada de símbolos ao mapa. Consulte as propriedades de uma camada de símbolo em SymbolLayerOptions.

O próximo bloco de código usa a API de busca para fazer uma solicitação de pesquisa para obter direções de rota. A resposta é então analisada. Se a resposta foi bem-sucedida, as informações de latitude e longitude são usadas para criar uma matriz de uma linha conectando esses pontos. Os dados da linha são então adicionados à fonte de dados para renderizar a rota no mapa. Para obter mais informações, consulte Adicionar uma linha no mapa.

O último bloco de código define os limites do mapa usando a propriedade setCamera do mapa.

A consulta de rota, a fonte de dados, o símbolo, as camadas de linha e os limites da câmera são criados dentro do ouvinte de eventos. Mais uma vez, queremos garantir que os resultados sejam exibidos depois que o mapa for totalmente carregado.

A imagem a seguir é uma captura de tela mostrando os resultados dos dois exemplos de código.

A screenshot of a map showing route directions between two points.

Próximos passos

Saiba mais sobre as classes e métodos usados neste artigo:

Consulte os seguintes artigos para obter exemplos de código completo: