Skip to main content
Миграция с Google Maps API до мая 2026 года: чек-лист
Guides

Миграция с Google Maps API до мая 2026 года: чек-лист

DirectionsService, DistanceMatrixService, Heatmap Layer и Drawing Library удаляются из Maps JavaScript API в мае 2026 года.

Brent van der Heiden12 min read
#Google Maps API#API Migration#Geocoding#Routing#Developer Guide

Google планомерно ужесточает требования своей Maps Platform на протяжении нескольких лет, но волна устареваний мая 2026 года оказывается наиболее разрушительной из всех предшествующих. Из Maps JavaScript API удаляются четыре широко используемые возможности: Heatmap Layer, Drawing Library, DirectionsService и DistanceMatrixService. Если приложение опирается на любую из них, времени на миграцию осталось совсем немного.

Речь не о мягком устаревании, при котором старые endpoints продолжают работать годами. Google установил жёсткие даты удаления, и консоль разработчика уже отображает соответствующие предупреждения. Данное руководство охватывает конкретные изменения, их причины и способы миграции каждого сервиса с рабочими примерами кода. Для тех, кто ищет готовую замену, здесь показано, как API MapAtlas соответствует каждому устаревшему сервису Google.

Что и когда устаревает

Полная хронология затронутых сервисов:

СервисОбъявлен устаревшимДата удаленияЗамена (Google)
Heatmap Layer (Maps JS API)Август 2025Май 2026Maps Datasets API + deck.gl
Drawing Library (Maps JS API)Май 2025Май 2026Extended Component Library
DirectionsService (Maps JS API)25 февраля 2026Май 2026Routes API (REST)
DistanceMatrixService (Maps JS API)25 февраля 2026Май 2026Routes API (REST)

Принципиальный момент: Google не устраняет маршрутизацию и расчёт расстояний как таковые. Удаляются JavaScript-классы на стороне клиента, которыми разработчики пользуются более десяти лет, а взамен предлагается миграция на новый Routes API — серверный REST-endpoint. Это не банальная смена версии, а архитектурное изменение, перемещающее логику маршрутизации из браузера в бэкенд.

Что перестанет работать

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

// All of these will stop working in May 2026
const directionsService = new google.maps.DirectionsService();
const distanceMatrixService = new google.maps.DistanceMatrixService();
const heatmap = new google.maps.visualization.HeatmapLayer({ data: points });
const drawingManager = new google.maps.drawing.DrawingManager();

После удаления эти конструкторы будут генерировать исключения. Никакого fallback-поведения, никакой плавной деградации. Карта загрузится, однако любая функциональность, зависящая от этих классов, полностью перестанет работать.

Почему Google вводит эти изменения принудительно

Официальная позиция Google — производительность и модернизация. Routes API, пришедший на смену DirectionsService и DistanceMatrixService, поддерживает новые возможности: экологичную маршрутизацию, маршрутизацию для двухколёсных транспортных средств и расчёт стоимости платных дорог, которые устаревшие JavaScript-классы не могут обеспечить.

Реальным движущим фактором является ценовой контроль. Перенос маршрутизации на серверный REST API даёт Google более детальный биллинг и точное отслеживание использования. JavaScript-вариант DirectionsService позволял реализовывать клиентские паттерны пакетной обработки, которые Google сложнее было точно тарифицировать. Routes API гарантирует, что каждый запрос проходит через измеряемый endpoint.

В случае Heatmap Layer и Drawing Library Google подталкивает разработчиков к собственной Extended Component Library и сторонним инструментам визуализации, в частности deck.gl. Это проявление более широкой тенденции: Google сохраняет за собой рендеринг тайлов карты, а всё остальное передаёт экосистеме.

Практические последствия для разработчиков: бо́льшая серверная инфраструктура, больше API-ключей под управлением и, как правило, более высокая стоимость запросов на новых ценовых уровнях.

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

Прежде чем писать какой-либо код миграции, следует проработать этот чек-лист:

1. Проведите аудит кодовой базы

Выполните поиск по всей кодовой базе на предмет обращений к устаревшим классам:

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

Задокументируйте каждый файл и компонент, использующий эти сервисы. Зафиксируйте, происходят ли вызовы на стороне клиента (браузер) или в серверном контексте (например, API routes в Next.js).

2. Определите паттерны использования

Для каждого случая использования задокументируйте:

  • Применяемые режимы передвижения (driving, walking, cycling, transit)
  • Поддержка waypoints (простой маршрут A-B или многоточечные маршруты)
  • Используемые поля ответа (расстояние, время, polyline, шаги, тариф)
  • Объём (запросы в день/месяц, для оценки стоимости)
  • Требования к задержке (real-time для конечного пользователя или пакетная обработка)

3. Выберите целевой вариант миграции

Доступны два варианта:

Вариант A: Остаться с Google. Перейти с устаревших JavaScript-классов на новый Google Routes API (REST). Это потребует изменений на бэкенде, новых прав доступа для API-ключа и обновления биллинга.

Вариант B: Сменить провайдера. Перейти на сторонний routing API. Поскольку код интеграции всё равно придётся переписывать, это подходящий момент для оценки альтернатив.

4. Настройте параллельную среду

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

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

Устаревшие сервисы передавали ошибки через callback-функции. Замены на REST API возвращают HTTP-коды статуса. Логика обработки ошибок должна быть обновлена соответствующим образом.

Пошаговое руководство по замене API

DirectionsService на MapAtlas Directions API

До (Google, устаревший):

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);
    }
  }
);

После (MapAtlas Directions API):

const response = await fetch(
  "https://api.mapatlas.com/v1/directions?" +
    new URLSearchParams({
      origin: "52.52,13.405",
      destination: "48.8566,2.3522",
      waypoints: "50.9375,6.9603",
      mode: "driving",
      key: process.env.MAPATLAS_API_KEY!,
    })
);

const data = await response.json();

if (data.status === "OK") {
  const leg = data.routes[0].legs[0];
  console.log("Distance:", leg.distance.text);
  console.log("Duration:", leg.duration.text);
  // Polyline for map rendering
  const polyline = data.routes[0].overview_polyline;
}

Ключевые отличия:

  • REST endpoint вместо класса JavaScript. Вызовы идут с бэкенда, а не из браузера.
  • Упрощённая аутентификация. Один API-ключ в строке запроса или заголовке.
  • Та же структура ответа. Routes, legs, distance, duration и polyline — всё присутствует.

DistanceMatrixService на MapAtlas Matrix API

До (Google, устаревший):

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

service.getDistanceMatrix(
  {
    origins: [
      { lat: 52.52, lng: 13.405 },
      { lat: 48.1351, lng: 11.582 },
    ],
    destinations: [
      { lat: 48.8566, lng: 2.3522 },
      { lat: 51.5074, lng: -0.1278 },
    ],
    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);
        });
      });
    }
  }
);

После (MapAtlas Matrix API):

const response = await fetch("https://api.mapatlas.com/v1/matrix", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${process.env.MAPATLAS_API_KEY}`,
  },
  body: JSON.stringify({
    origins: [
      { lat: 52.52, lng: 13.405 },
      { lat: 48.1351, lng: 11.582 },
    ],
    destinations: [
      { lat: 48.8566, lng: 2.3522 },
      { lat: 51.5074, lng: -0.1278 },
    ],
    mode: "driving",
  }),
});

const data = await response.json();

data.rows.forEach((row: any, i: number) => {
  row.elements.forEach((element: any, j: number) => {
    console.log(`Origin ${i} -> Dest ${j}:`,
      element.distance.text, element.duration.text);
  });
});

Структура ответа практически идентична. Главное изменение — переход с callback-ориентированного браузерного API на promise-ориентированный серверный API.

Замена Heatmap Layer

Путь миграции для визуализации тепловых карт зависит от конкретных требований:

Вариант 1: MapLibre GL JS с heatmap layer (open source)

import maplibregl from "maplibre-gl";

const map = new maplibregl.Map({
  container: "map",
  style: "https://api.mapatlas.com/v1/styles/streets?key=YOUR_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,
    },
  });
});

Это обеспечивает полный контроль над рендерингом тепловой карты без зависимости от тайловых серверов Google.

Вариант 2: deck.gl HeatmapLayer (собственная рекомендация Google)

import { Deck } from "@deck.gl/core";
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 может накладываться поверх любой базовой карты.

Сравнение стоимости: Google Routes API и MapAtlas

Переход на собственный Routes API Google — это не только изменение кода. Он влечёт за собой новое ценообразование:

СервисGoogle (legacy, за 1 000)Google Routes API (за 1 000)MapAtlas (за 1 000)
Directions (базовый)$5,00$5,00$1,50
Directions (расширенный, waypoints/пробки)$10,00$10,00$2,50
Distance Matrix (за элемент)$5,00$5,00$1,00
Distance Matrix (расширенный)$10,00$10,00$2,00
Geocoding$5,00$5,00$1,50

При 100 000 запросов маршрутизации в месяц:

  • Google Routes API: около $500-$1 000 (в зависимости от используемых функций)
  • MapAtlas Directions API: около $150-$250

Экономия быстро накапливается для приложений, сочетающих маршрутизацию с геокодированием и расчётом расстояний. Логистическая платформа, обрабатывающая 500 000 элементов матрицы в месяц, заплатит у Google порядка $2 500 против $500 в MapAtlas.

Подробная информация о ценах приведена в разделе ценообразование MapAtlas.

Примеры миграции кода: полное сравнение до и после

Ниже приведён полный пример миграции для React-компонента, отображающего маршруты на карте.

До: Google Maps DirectionsService в React

import { useEffect, useRef } from "react";

function DirectionsMap({ origin, destination }: {
  origin: google.maps.LatLngLiteral;
  destination: google.maps.LatLngLiteral;
}) {
  const mapRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const map = new google.maps.Map(mapRef.current!, {
      center: origin,
      zoom: 7,
    });

    const directionsRenderer = new google.maps.DirectionsRenderer();
    directionsRenderer.setMap(map);

    const directionsService = new google.maps.DirectionsService();
    directionsService.route(
      {
        origin,
        destination,
        travelMode: google.maps.TravelMode.DRIVING,
      },
      (result, status) => {
        if (status === "OK" && result) {
          directionsRenderer.setDirections(result);
        }
      }
    );
  }, [origin, destination]);

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

После: MapAtlas Directions API с 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://api.mapatlas.com/v1/styles/streets?key=YOUR_KEY",
      center: [origin.lng, origin.lat],
      zoom: 7,
    });

    map.on("load", async () => {
      // Fetch directions from your backend (or directly if CORS allows)
      const res = await fetch(
        `/api/directions?` +
          new URLSearchParams({
            origin: `${origin.lat},${origin.lng}`,
            destination: `${destination.lat},${destination.lng}`,
            mode: "driving",
          })
      );
      const data = await res.json();

      if (data.routes?.[0]) {
        const coordinates = data.routes[0].geometry.coordinates;

        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,
          },
        });

        // Fit map to route bounds
        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" }} />;
}

Backend API Route (Next.js)

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

export async function GET(request: NextRequest) {
  const { searchParams } = new URL(request.url);
  const origin = searchParams.get("origin");
  const destination = searchParams.get("destination");
  const mode = searchParams.get("mode") || "driving";

  const response = await fetch(
    `https://api.mapatlas.com/v1/directions?` +
      new URLSearchParams({
        origin: origin!,
        destination: destination!,
        mode,
        key: process.env.MAPATLAS_API_KEY!,
      })
  );

  const data = await response.json();
  return NextResponse.json(data);
}

Данный паттерн сохраняет API-ключ на сервере и передаёт клиенту только геометрию маршрута.

Тестирование миграции до наступления крайнего срока

Шаг 1: Запуск обоих API параллельно

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

async function getDirectionsWithComparison(
  origin: string,
  destination: string
) {
  const [googleResult, mapatResult] = await Promise.all([
    fetchGoogleDirections(origin, destination),
    fetchMapAtlasDirections(origin, destination),
  ]);

  // Compare key metrics
  const distanceDelta = Math.abs(
    googleResult.distance - mapatResult.distance
  );
  const durationDelta = Math.abs(
    googleResult.duration - mapatResult.duration
  );

  console.log({
    route: `${origin} -> ${destination}`,
    googleDistance: googleResult.distance,
    mapatDistance: mapatResult.distance,
    distanceDeltaPercent: ((distanceDelta / googleResult.distance) * 100).toFixed(1),
    googleDuration: googleResult.duration,
    mapatDuration: mapatResult.duration,
    durationDeltaPercent: ((durationDelta / googleResult.duration) * 100).toFixed(1),
  });

  // Use MapAtlas result in production, Google as validation
  return mapatResult;
}

Шаг 2: Настройка feature flags

Управляйте выбором API с помощью 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 при двукратном пиковом объёме. MapAtlas предоставляет среду sandbox для нагрузочного тестирования без биллинга в боевом режиме.

Хронология: что делать на этой неделе

Если миграция ещё не начата, следует придерживаться следующего порядка приоритетов:

  1. Эта неделя: Аудит кодовой базы. Выявите каждое обращение к четырём устаревшим сервисам.
  2. Неделя 2: Зарегистрируйтесь в MapAtlas и получите API-ключи. Бесплатный уровень включает 10 000 запросов для тестирования.
  3. Неделя 3: Реализуйте замену для наиболее критичного сервиса, как правило DirectionsService.
  4. Неделя 4: Перенесите оставшиеся сервисы и проведите параллельное тестирование.
  5. До майского дедлайна: Переключитесь окончательно, устраните зависимости от Google API, обновите биллинг.

Миграция не является опциональной. После мая 2026 года устаревшие классы будут удалены из Maps JavaScript API, и любой код, обращающийся к ним, будет генерировать ошибки во время выполнения. Начните сейчас — и у вас будет время на полноценное тестирование. Дотяните до последней недели — и придётся вносить исправления в продакшн под давлением.

По вопросам сопровождения миграции MapAtlas предоставляет прямую техническую поддержку разработчикам. Обратитесь через страницу контактов или начните изучение с документации API, чтобы оценить замещающие API применительно к вашим требованиям.

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

Когда именно будут удалены DirectionsService и DistanceMatrixService из Google Maps API?

Heatmap Layer и Drawing Library признаны устаревшими в августе и мае 2025 года соответственно, удаление запланировано на май 2026 года. DirectionsService и DistanceMatrixService устарели 25 февраля 2026 года с той же целевой датой удаления. После удаления вызовы к этим сервисам будут возвращать ошибки без какого-либо запасного поведения.

Будет ли работать мой API-ключ Google Maps JavaScript после мая 2026 года?

API-ключ продолжит работать для неустаревших сервисов. Любой код, обращающийся к DirectionsService, DistanceMatrixService, Heatmap Layer или Drawing Library через Maps JavaScript API, перестанет функционировать после даты удаления. Эти конкретные вызовы необходимо перенести на замещающие API до наступления крайнего срока.

Какова наиболее экономичная альтернатива Google Maps Directions API?

MapAtlas предлагает Directions API примерно на 70% дешевле, чем эквивалент Google. Бесплатный уровень включает 10 000 запросов в месяц, чего достаточно для разработки и тестирования миграции. Формат запросов/ответов максимально близок к Google, что существенно снижает трудозатраты на миграцию.

Можно ли мигрировать поэтапно или необходимо переключиться сразу?

Поэтапная миграция не только возможна, но и рекомендуется. Каждый устаревший сервис независим: сначала заменяется DirectionsService, затем DistanceMatrixService, после чего — библиотеки визуализации. Такой подход позволяет тестировать каждую замену в изоляции перед переходом к следующему шагу.

Поддерживает ли MapAtlas те же waypoints и режимы передвижения, что и Google DirectionsService?

Да. MapAtlas Directions API поддерживает режимы driving, walking и cycling, а также промежуточные waypoints. Формат запроса отличается (RESTful endpoint вместо класса JavaScript), однако основная функциональность, многоточечная маршрутизация с выбором режима передвижения, полностью эквивалентна.

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

Об авторе

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. He writes about geospatial infrastructure, AI search visibility, and how location data powers the products people rely on every day.

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