Skip to main content
Guides

DrawingManager в Google Maps и устаревшие API: руководство по миграции 2026

Drawing Library и Heatmap Layer удалены из Maps JavaScript API. DirectionsService и DistanceMatrixService получили статус Legacy и объявлены устаревшими. Текущий статус, даты и замены.

Brent van der HeidenПоследнее обновление 12 min read
#Google Maps API#миграция API#DrawingManager#DirectionsService#маршрутизация#руководство для разработчиков
DrawingManager в Google Maps и устаревшие API: руководство по миграции 2026

За последние полтора года Google объявил устаревшими четыре широко используемые части Maps JavaScript API. Две из них, Heatmap Layer и Drawing Library, недоступны с мая 2026 года. Две другие, DirectionsService и DistanceMatrixService, имеют статус Legacy и считаются устаревшими, но продолжают работать, и даты отключения у них нет.

В руководстве собран текущий статус каждой функции со ссылками на страницы Google и показано, чем их заменить. Там, где замену даёт MapAtlas, код использует наши реальные эндпоинты и форматы ответов.

Что устарело и что ещё работает

СервисСтатусКлючевые датыЗамена от Google
Heatmap LayerУдалёнУстарел 27 мая 2025 года, выведен из эксплуатации в версии 3.65.1c (20 мая 2026 года)Сторонние библиотеки, например deck.gl
Drawing Library (DrawingManager)УдаленаУстарела в августе 2025 года, недоступна с мая 2026 года (подтверждено в версии 3.65.3b, 4 июня 2026 года)Сторонние библиотеки, например Terra Draw
DirectionsServiceLegacy, устарелLegacy с 1 марта 2025 года, устарел с 25 февраля 2026 года (версия 3.64.2b), даты отключения нетКласс Route в библиотеке Routes
DistanceMatrixServiceLegacy, устарелLegacy с 1 марта 2025 года, устарел с 25 февраля 2026 года (версия 3.64.2b), даты отключения нетКласс RouteMatrix в библиотеке Routes

Источники: страница устаревших функций Google Maps Platform, примечания к выпускам Maps JavaScript API и страница продуктов Legacy.

У статуса Legacy есть точное значение. По словам Google, сервис Legacy больше не получает новых функций и не включается в новых проектах Cloud, но в существующих проектах поддержка сохраняется. Google обещает предупреждать минимум за 12 месяцев до вывода такого сервиса из эксплуатации. В примечании к выпуску, где DirectionsService и DistanceMatrixService объявлены устаревшими, сказано, что их отключение не запланировано и серьёзные регрессии будут исправляться. Тот же переход в Legacy 1 марта 2025 года затронул веб-сервисы Directions API и Distance Matrix API, а также Places API и JavaScript Places Service.

Что ломается

Этот код уже не работает в актуальных версиях Maps JavaScript API:

// Removed in 2026: these constructors no longer work
const heatmap = new google.maps.visualization.HeatmapLayer({ data: points });
const drawingManager = new google.maps.drawing.DrawingManager();

Этот код по-прежнему работает в существующих проектах, но устарел и не заработает в новом проекте Cloud:

// Legacy and deprecated, no shutdown date yet
const directionsService = new google.maps.DirectionsService();
const distanceMatrixService = new google.maps.DistanceMatrixService();

Если тепловая карта или инструмент рисования на вашем сайте перестали работать в мае 2026 года, причина в этом. Исправьте их в первую очередь. Затем спланируйте миграцию маршрутизации, пока Google не объявил дату.

Замены от Google

Для маршрутизации Google предлагает два пути, и ни один не заставляет переносить логику на сервер:

  • В браузере: библиотека Routes в Maps JavaScript API. Класс Route заменяет DirectionsService, а класс RouteMatrix заменяет DistanceMatrixService.
  • На сервере: Routes API, REST-сервис с методами Compute Routes и Compute Route Matrix.

Для визуализации у Google больше нет собственного решения. Страница о тепловой карте отсылает к deck.gl, а страница устаревших функций называет Terra Draw для рисования.

Чек-лист миграции

1. Проверьте кодовую базу

Найдите затронутые классы:

# Find all files using deprecated Google Maps services
grep -rn "DirectionsService\|DistanceMatrixService\|DirectionsRenderer\|HeatmapLayer\|DrawingManager" \
  --include="*.js" --include="*.ts" --include="*.tsx" --include="*.jsx" src/

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

2. Опишите, как используется каждый сервис

Для каждого случая зафиксируйте:

  • Способы передвижения (автомобиль, пешком, велосипед, общественный транспорт)
  • Промежуточные точки (простой маршрут из A в B или маршрут с несколькими остановками)
  • Поля ответа, которые вы читаете (расстояние, время, полилиния, шаги, стоимость проезда)
  • Объём (запросы в день и в месяц, для оценки затрат)
  • Требования к задержке (ответ пользователю в реальном времени или пакетная обработка)

3. Выберите цель

Вариант A: остаться в Google. Перейдите на классы Route и RouteMatrix или на Routes API. Сверьте используемые поля с руководствами по миграции, потому что форматы ответов отличаются от классов Legacy.

Вариант B: сменить поставщика. Интеграцию всё равно придётся переписать, поэтому сравните поставщиков по требованиям из шага 2.

4. Запустите старую и новую версии параллельно

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

5. Обновите обработку ошибок

Классы Legacy сообщали об ошибках через значение статуса в колбэке. REST-замены возвращают HTTP-коды и тело ошибки, поэтому обработку ошибок нужно изменить.

Замена каждого сервиса на MapAtlas

Эндпоинты маршрутизации MapAtlas работают как REST-сервисы на gateway.mapmetrics-atlas.net и описаны в документации API MapAtlas. Они принимают токен как параметр запроса, поэтому вызывайте их с бэкенда.

С DirectionsService на Directions API от MapAtlas

До (Google, Legacy):

const directionsService = new google.maps.DirectionsService();

directionsService.route(
  {
    origin: { lat: 52.52, lng: 13.405 },
    destination: { lat: 48.8566, lng: 2.3522 },
    travelMode: google.maps.TravelMode.DRIVING,
    waypoints: [
      { location: { lat: 50.9375, lng: 6.9603 }, stopover: true }
    ],
  },
  (result, status) => {
    if (status === "OK") {
      const route = result.routes[0];
      console.log("Distance:", route.legs[0].distance.text);
      console.log("Duration:", route.legs[0].duration.text);
    }
  }
);

После (Directions API от MapAtlas):

const response = await fetch(
  `https://gateway.mapmetrics-atlas.net/directions/?token=${process.env.MAPATLAS_API_KEY}`,
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      // Ordered stops: origin, waypoints, destination
      locations: [
        { lat: 52.52, lon: 13.405 },
        { lat: 50.9375, lon: 6.9603 },
        { lat: 48.8566, lon: 2.3522 },
      ],
      costing: "auto", // auto, bicycle, pedestrian, bus, truck, taxi, motor_scooter
      units: "kilometers",
    }),
  }
);

const { trip } = await response.json();
console.log("Distance (km):", trip.summary.length);
console.log("Duration (s):", trip.summary.time);
// Each leg carries its geometry as an encoded polyline (precision 6)
const shapes = trip.legs.map((leg) => leg.shape);

Основные отличия:

  • REST-вызов вместо класса JavaScript, выполняется с вашего бэкенда.
  • Промежуточные точки задаются средними элементами locations.
  • Другая структура ответа. Итоги находятся в trip.summary, а у каждого участка есть закодированная полилиния в shape. Декодируйте её перед отрисовкой маршрута (см. пример бэкенда ниже).

С DistanceMatrixService на Matrix API от MapAtlas

Matrix API от MapAtlas возвращает время в пути и расстояние для каждой пары точки отправления и назначения за один вызов. Наш эндпоинт ограничивает каждую пару 400 км по маршруту, поэтому в примере используются места вокруг Берлина.

До (Google, Legacy):

const service = new google.maps.DistanceMatrixService();

service.getDistanceMatrix(
  {
    origins: [
      { lat: 52.52, lng: 13.405 },
      { lat: 52.3906, lng: 13.0645 },
    ],
    destinations: [
      { lat: 51.3397, lng: 12.3731 },
      { lat: 51.0504, lng: 13.7373 },
    ],
    travelMode: google.maps.TravelMode.DRIVING,
  },
  (response, status) => {
    if (status === "OK") {
      response.rows.forEach((row, i) => {
        row.elements.forEach((element, j) => {
          console.log(`Origin ${i} -> Dest ${j}:`,
            element.distance.text, element.duration.text);
        });
      });
    }
  }
);

После (Matrix API от MapAtlas):

const response = await fetch(
  `https://gateway.mapmetrics-atlas.net/matrix/?token=${process.env.MAPATLAS_API_KEY}`,
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      sources: [
        { lat: 52.52, lon: 13.405 },
        { lat: 52.3906, lon: 13.0645 },
      ],
      targets: [
        { lat: 51.3397, lon: 12.3731 },
        { lat: 51.0504, lon: 13.7373 },
      ],
      costing: "auto",
      units: "kilometers",
    }),
  }
);

const data = await response.json();

// One row per source, one cell per target
data.sources_to_targets.forEach((row: any[], i: number) => {
  row.forEach((cell, j) => {
    console.log(`Origin ${i} -> Dest ${j}:`, cell.distance, "km", cell.time, "s");
  });
});

Сетка соответствует rows и elements у Google. Расстояния приходят числами в запрошенных единицах, а время в секундах, так что форматирование остаётся за вами.

Замена Heatmap Layer

Вариант 1: слой тепловой карты в MapLibre GL JS (open source)

import maplibregl from "maplibre-gl";

const map = new maplibregl.Map({
  container: "map",
  style: "https://gateway.mapmetrics-atlas.net/styles/?fileName=YOUR_ACCOUNT_ID/mapstyle.json&token=YOUR_API_KEY",
  center: [13.405, 52.52],
  zoom: 10,
});

map.on("load", () => {
  map.addSource("heat-data", {
    type: "geojson",
    data: {
      type: "FeatureCollection",
      features: heatmapPoints.map((point) => ({
        type: "Feature",
        geometry: { type: "Point", coordinates: [point.lng, point.lat] },
        properties: { weight: point.weight },
      })),
    },
  });

  map.addLayer({
    id: "heatmap-layer",
    type: "heatmap",
    source: "heat-data",
    paint: {
      "heatmap-weight": ["get", "weight"],
      "heatmap-intensity": 1,
      "heatmap-radius": 20,
      "heatmap-opacity": 0.7,
    },
  });
});

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

Вариант 2: HeatmapLayer из deck.gl, который предлагает документация Google:

import { HeatmapLayer } from "@deck.gl/aggregation-layers";

const heatmapLayer = new HeatmapLayer({
  data: heatmapPoints,
  getPosition: (d) => [d.lng, d.lat],
  getWeight: (d) => d.weight,
  radiusPixels: 30,
});

Оба варианта работают. MapLibre GL JS напрямую читает стили MapAtlas, а deck.gl можно наложить на любую базовую карту.

Замена Drawing Library

DrawingManager позволял пользователям рисовать на карте маркеры, линии, круги и полигоны. Terra Draw, библиотека, которую называет страница устаревших функций Google, поддерживает те же режимы и имеет адаптеры для нескольких картографических библиотек, включая Google Maps и MapLibre GL JS. Фигуры возвращаются в формате GeoJSON, который можно сохранить или без изменений отправить в сервис геозон или изохрон.

Сравнение затрат

Прайс-лист Google одинаков для Legacy-SKU маршрутизации и для Essentials-SKU их замен. Все цены ниже взяты со страницы цен Google Maps Platform и страницы цен MapAtlas, обе проверены 26 сентября 2026 года.

СервисGoogle, бесплатно в месяцGoogle, за 1 000 сверх лимита (первая ступень)MapAtlas, бесплатно в месяцMapAtlas, за 1 000 сверх лимита (первая ступень)
Directions (Legacy) или Compute Routes Essentials10 0005,00 $100 000 навигационных запросов1,53 €
Directions Advanced (Legacy) или Compute Routes Pro5 00010,00 $Та же навигационная ступень1,53 €
Distance Matrix (Legacy) или Compute Route Matrix Essentials10 000 элементов5,00 $См. страницу ценСм. страницу цен
Geocoding10 0005,00 $25 0003,90 €

Google выставляет счета в долларах США, а MapAtlas в евро, поэтому перед сравнением пересчитайте валюту. Оба снижают тарифы при росте объёма. Пример расчёта для 500 000 запросов маршрута в месяц:

  • Google Compute Routes Essentials: 10 000 бесплатно, 90 000 по 5,00 $ и 400 000 по 4,00 $, итого 2 050 $.
  • Навигация MapAtlas: 100 000 бесплатно и 400 000 по 1,53 €, итого около 610 €.

Полный пример: маршрут на бэкенде и карта

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

Маршрут API на бэкенде (Next.js)

// app/api/directions/route.ts
import { NextRequest, NextResponse } from "next/server";

// Decode an encoded polyline with precision 6 into [lon, lat] pairs
function decodePolyline6(str: string): [number, number][] {
  const coords: [number, number][] = [];
  let index = 0, lat = 0, lng = 0;
  while (index < str.length) {
    for (const axis of [0, 1]) {
      let result = 0, shift = 0, byte: number;
      do {
        byte = str.charCodeAt(index++) - 63;
        result |= (byte & 0x1f) << shift;
        shift += 5;
      } while (byte >= 0x20);
      const delta = result & 1 ? ~(result >> 1) : result >> 1;
      if (axis === 0) lat += delta; else lng += delta;
    }
    coords.push([lng / 1e6, lat / 1e6]);
  }
  return coords;
}

export async function GET(request: NextRequest) {
  const { searchParams } = new URL(request.url);
  const [oLat, oLon] = searchParams.get("origin")!.split(",").map(Number);
  const [dLat, dLon] = searchParams.get("destination")!.split(",").map(Number);

  const response = await fetch(
    `https://gateway.mapmetrics-atlas.net/directions/?token=${process.env.MAPATLAS_API_KEY}`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        locations: [{ lat: oLat, lon: oLon }, { lat: dLat, lon: dLon }],
        costing: "auto",
        units: "kilometers",
      }),
    }
  );
  if (!response.ok) {
    return NextResponse.json({ error: "routing failed" }, { status: 502 });
  }

  const { trip } = await response.json();
  const coordinates = trip.legs.flatMap((leg: { shape: string }) => decodePolyline6(leg.shape));
  return NextResponse.json({
    coordinates,
    distanceKm: trip.summary.length,
    durationS: trip.summary.time,
  });
}

Компонент карты (React и MapLibre GL JS)

import { useEffect, useRef } from "react";
import maplibregl from "maplibre-gl";

function DirectionsMap({ origin, destination }: {
  origin: { lat: number; lng: number };
  destination: { lat: number; lng: number };
}) {
  const mapRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const map = new maplibregl.Map({
      container: mapRef.current!,
      style: "https://gateway.mapmetrics-atlas.net/styles/?fileName=YOUR_ACCOUNT_ID/mapstyle.json&token=YOUR_API_KEY",
      center: [origin.lng, origin.lat],
      zoom: 7,
    });

    map.on("load", async () => {
      const res = await fetch(
        "/api/directions?" +
          new URLSearchParams({
            origin: `${origin.lat},${origin.lng}`,
            destination: `${destination.lat},${destination.lng}`,
          })
      );
      if (!res.ok) return;
      const { coordinates } = await res.json();

      map.addSource("route", {
        type: "geojson",
        data: {
          type: "Feature",
          geometry: { type: "LineString", coordinates },
          properties: {},
        },
      });

      map.addLayer({
        id: "route-line",
        type: "line",
        source: "route",
        paint: { "line-color": "#4A90D9", "line-width": 5 },
      });

      const bounds = coordinates.reduce(
        (b: maplibregl.LngLatBounds, coord: [number, number]) => b.extend(coord),
        new maplibregl.LngLatBounds(coordinates[0], coordinates[0])
      );
      map.fitBounds(bounds, { padding: 50 });
    });

    return () => map.remove();
  }, [origin, destination]);

  return <div ref={mapRef} style={{ width: "100%", height: "400px" }} />;
}

Как протестировать миграцию

Шаг 1: сравните обе реализации

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

Шаг 2: используйте feature flag

Спрячьте выбор поставщика за флагом, чтобы откатиться без деплоя:

const useMapAtlasDirections = process.env.FEATURE_MAPATLAS_DIRECTIONS === "true";

const directions = useMapAtlasDirections
  ? await fetchMapAtlasDirections(origin, destination)
  : await fetchGoogleDirections(origin, destination);

Шаг 3: следите за долей ошибок

После переключения отслеживайте:

  • Долю ответов HTTP 4xx и 5xx от нового API
  • Изменения задержки
  • Отсутствующие поля, которые читает ваш интерфейс
  • Расхождения маршрутов в пограничных случаях: паромы, платные дороги, зоны с ограниченным доступом

Шаг 4: нагрузочный тест перед запуском

Если у вас бывают пики трафика, например при утренней диспетчеризации на логистической платформе, проведите нагрузочный тест нового API на удвоенном пиковом объёме, прежде чем на него полагаться.

Что делать сейчас

  1. Если вы всё ещё загружаете Heatmap Layer или Drawing Library: замените их в первую очередь. В актуальных версиях Maps JavaScript API они больше не работают.
  2. Проверьте код маршрутизации: найдите каждый вызов DirectionsService, DirectionsRenderer и DistanceMatrixService.
  3. Выберите замену: классы Route и RouteMatrix, Routes API или другого поставщика.
  4. Мигрируйте по одному сервису, за feature flag, и сравнивайте результаты перед переключением.
  5. Следите за страницей устаревших функций Google, чтобы не пропустить дату отключения. Для сервисов Legacy Google обещает предупреждение минимум за 12 месяцев.

Чтобы попробовать API маршрутизации MapAtlas, создайте бесплатный аккаунт и изучите документацию API. За помощью с миграцией обращайтесь через страницу контактов.

Часто задаваемые вопросы

Доступна ли ещё Drawing Library в Google Maps?

Нет. Google объявил Drawing Library, включая DrawingManager, устаревшей в августе 2025 года, и на странице устаревших функций она значится недоступной с мая 2026 года. Примечания к версии 3.65.3b Maps JavaScript API (4 июня 2026 года) подтверждают, что DrawingManager больше не доступен. В качестве альтернативы Google называет Terra Draw.

Доступен ли ещё Heatmap Layer?

Нет. Google объявил Heatmap Layer устаревшим 27 мая 2025 года, а в версии 3.65.1c от 20 мая 2026 года он выведен из эксплуатации. Вместо него Google предлагает сторонние библиотеки, например HeatmapLayer из deck.gl.

Когда перестанут работать DirectionsService и DistanceMatrixService?

Google не назвал дату. Оба сервиса имеют статус Legacy с 1 марта 2025 года и считаются устаревшими с 25 февраля 2026 года. Согласно примечаниям к выпуску, отключение не запланировано, серьёзные регрессии продолжат исправлять, а о прекращении поддержки предупредят минимум за 12 месяцев. Сервисы Legacy недоступны в новых проектах Cloud, поэтому новому проекту нужны классы Route и RouteMatrix или другой поставщик.

Можно ли мигрировать постепенно или нужно менять всё сразу?

Мигрировать можно по одному сервису. Каждый устаревший класс независим. Сначала замените уже удалённые Drawing Library и Heatmap Layer, потому что они не работают, а затем DirectionsService и DistanceMatrixService в удобные для вас сроки.

Поддерживает ли MapAtlas промежуточные точки и разные способы передвижения?

Да. Directions API от MapAtlas принимает упорядоченный список точек, так что каждая точка между первой и последней служит промежуточной. Поддерживаются модели стоимости auto, bicycle, pedestrian, bus, truck, taxi и motor_scooter. Это REST-эндпоинт, поэтому вызывайте его с бэкенда, чтобы ключ API не попадал к клиенту.

Оказалось полезным? Поделитесь.

Об авторе

Brent van der Heiden

Автор

Brent van der Heiden

Co-Founder & CEO at MapAtlas

Brent built MapAtlas out of a conviction that developers deserve location APIs with fair pricing and genuine end-user privacy. Before that he co-founded MapMetrics, a community mapping and navigation app. He writes about geospatial infrastructure, map data, AI search visibility, and how location data powers the products people rely on every day.

Все статьи →
Вернуться в блог