Поделиться через


Отображение направлений от точки А до точки Б

В этой статье объясняется, как выполнить запрос маршрута и отобразить маршрут на карте.

Это можно сделать двумя способами. Первым способом является запрос API направления маршрута с помощью пакета SDK REST TypeScript @azure-rest/maps-route. Второй способ — использовать API получения для выполнения поискового запроса к API получения маршрутов . Оба подхода описаны в этой статье.

Запрос маршрута с помощью пакета SDK REST

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;

В предыдущем примере кода первый блок создает объект карты и задает механизм проверки подлинности для использования идентификатора Microsoft Entra. Инструкции см. в статье "Создание карты ".

Второй блок кода создает объект, реализующий интерфейс TokenCredential для проверки подлинности HTTP-запросов в Azure Карты с помощью маркера доступа. Затем он передает объект учетных данных в Карты Route и создает экземпляр клиента.

Третий блок кода создает и добавляет на карту объект DataSource.

Четвертый блок кода создает начальную и конечную точки и добавляет их в объект dataSource.

Линия — это функция для LineString. LineLayer отвечает за отображение линейных объектов в оболочке DataSource в качестве линий на карте. Четвертый блок кода позволяет создать и добавить на карту слой линий. Ознакомьтесь со свойствами слоя линий в разделе о классе LinestringLayerOptions.

Слой символов использует тексты или значки для отображения точечных данных, завернутых в источник данных . Текст или значки отображаются в виде символов на карте. Пятый блок кода позволяет создать и добавить на карту слой символов.

Шестой блок кода запрашивает службу маршрутизации azure Карты, которая является частью клиента Карты Route. Запрос GET используется для получения маршрута между начальной и конечной точками. Затем коллекция функций GeoJSON из ответа извлекается с помощью вспомогательной getFeatures() функции и добавляется в источник данных. После этого ответ отображается в виде маршрута на карте. Дополнительные сведения о добавлении строки в карту см. в разделе "Добавление строки" на карте.

Последний блок кода устанавливает границы карты, используя свойство setCamera карты.

Запрос маршрута, источник данных, символ, линейные слои и границы камеры создаются внутри прослушивателя событий. Эта структура кода гарантирует, что результаты будут отображаться только после полной загрузки схемы.

Отправка запроса через API FETCH

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;

В предыдущем примере кода первый блок кода создает объект карты и задает механизм проверки подлинности для использования идентификатора Microsoft Entra. Инструкции см. в статье "Создание карты ".

Второй блок кода создает и добавляет на карту объект DataSource.

Третий блок кода создает начальную и конечную точку маршрута. Затем он добавляет их в источник данных. Дополнительные сведения см. в разделе "Добавление пин-кода на карте".

LineLayer отвечает за отображение линейных объектов в оболочке DataSource в качестве линий на карте. Четвертый блок кода позволяет создать и добавить на карту слой линий. Ознакомьтесь со свойствами слоя линий в разделе о классе LineLayerOptions.

В слое символов данные на основе точек в оболочке DataSource преобразовываются для просмотра в качестве символов на карте с помощью текста или значков. Пятый блок кода позволяет создать и добавить на карту слой символов. Сведения о свойствах слоя символов см. в разделе SymbolLayerOptions.

Следующий блок кода использует API получения для выполнения поискового запроса на получение маршрутов. Затем выполняется синтаксический анализ ответа. Если ответ был успешным, сведения широты и долготы используются для создания массива с линией, соединяющей эти точки. Затем данные строки добавляются в источник данных для отрисовки маршрута на карте. Дополнительные сведения см. в разделе "Добавление строки на карте".

Последний блок кода устанавливает границы карты, используя свойство setCamera карты.

Запрос маршрута, источник данных, символ, линейные слои и границы камеры создаются внутри прослушивателя событий. Мы хотим убедиться, что результаты отображаются после полной загрузки карты.

На следующем рисунке показан снимок экрана, показывающий результаты двух примеров кода.

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

Следующие шаги

Дополнительные сведения о классах и методах, которые используются в этой статье:

Map

Полные примеры кода см. в следующих статьях: