Функции векторной карты

Выберите платформу: Android iOS JavaScript

Посмотреть образец

JavaScript API Карт предлагает две различные реализации карты: растровую и векторную. Растровая карта загружается как сетка из фрагментов пиксельных растровых изображений, которые генерируются серверной частью платформы Google Карт и затем передаются в ваше веб-приложение. Векторная карта состоит из векторных фрагментов, которые отрисовываются во время загрузки на стороне клиента с помощью WebGL — веб-технологии, которая позволяет браузеру получать доступ к графическому процессору на устройстве пользователя для рендеринга 2D- и 3D-графики.

Векторная карта — это та же карта Google, с которой ваши пользователи знакомы, и обладает рядом преимуществ по сравнению с растровой картой по умолчанию, в частности, чёткостью векторных изображений и добавлением 3D-зданий при небольшом увеличении. Векторная карта поддерживает следующие функции:

Начните работу с векторными картами

Наклон и вращение

Вы можете задать наклон и поворот (направление) векторной карты , включив свойства heading и tilt при инициализации карты и вызвав методы setTilt и setHeading . В следующем примере на карту добавляются кнопки, которые программно регулируют наклон и направление с шагом 20 градусов.

Машинопись

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      center: {
        lat: 37.7893719,
        lng: -122.3942,
      },
      zoom: 16,
      heading: 320,
      tilt: 47.5,
      mapId: "90f87356969d889c",
    }
  );

  const buttons: [string, string, number, google.maps.ControlPosition][] = [
    ["Rotate Left", "rotate", 20, google.maps.ControlPosition.LEFT_CENTER],
    ["Rotate Right", "rotate", -20, google.maps.ControlPosition.RIGHT_CENTER],
    ["Tilt Down", "tilt", 20, google.maps.ControlPosition.TOP_CENTER],
    ["Tilt Up", "tilt", -20, google.maps.ControlPosition.BOTTOM_CENTER],
  ];

  buttons.forEach(([text, mode, amount, position]) => {
    const controlDiv = document.createElement("div");
    const controlUI = document.createElement("button");

    controlUI.classList.add("ui-button");
    controlUI.innerText = `${text}`;
    controlUI.addEventListener("click", () => {
      adjustMap(mode, amount);
    });
    controlDiv.appendChild(controlUI);
    map.controls[position].push(controlDiv);
  });

  const adjustMap = function (mode: string, amount: number) {
    switch (mode) {
      case "tilt":
        map.setTilt(map.getTilt()! + amount);
        break;
      case "rotate":
        map.setHeading(map.getHeading()! + amount);
        break;
      default:
        break;
    }
  };
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: {
      lat: 37.7893719,
      lng: -122.3942,
    },
    zoom: 16,
    heading: 320,
    tilt: 47.5,
    mapId: "90f87356969d889c",
  });
  const buttons = [
    ["Rotate Left", "rotate", 20, google.maps.ControlPosition.LEFT_CENTER],
    ["Rotate Right", "rotate", -20, google.maps.ControlPosition.RIGHT_CENTER],
    ["Tilt Down", "tilt", 20, google.maps.ControlPosition.TOP_CENTER],
    ["Tilt Up", "tilt", -20, google.maps.ControlPosition.BOTTOM_CENTER],
  ];

  buttons.forEach(([text, mode, amount, position]) => {
    const controlDiv = document.createElement("div");
    const controlUI = document.createElement("button");

    controlUI.classList.add("ui-button");
    controlUI.innerText = `${text}`;
    controlUI.addEventListener("click", () => {
      adjustMap(mode, amount);
    });
    controlDiv.appendChild(controlUI);
    map.controls[position].push(controlDiv);
  });

  const adjustMap = function (mode, amount) {
    switch (mode) {
      case "tilt":
        map.setTilt(map.getTilt() + amount);
        break;
      case "rotate":
        map.setHeading(map.getHeading() + amount);
        break;
      default:
        break;
    }
  };
}

window.initMap = initMap;

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.ui-button {
  background-color: #fff;
  border: 0;
  border-radius: 2px;
  box-shadow: 0 1px 4px -1px rgba(0, 0, 0, 0.3);
  margin: 10px;
  padding: 0 0.5em;
  font: 400 18px Roboto, Arial, sans-serif;
  overflow: hidden;
  height: 40px;
  cursor: pointer;
}
.ui-button:hover {
  background: rgb(235, 235, 235);
}

HTML

<html>
  <head>
    <title>Tilt and Rotation</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="map"></div>

    <!-- 
      The `defer` attribute causes the script to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
      defer
    ></script>
  </body>
</html>

Попробуйте образец

Используйте жесты мыши и клавиатуры

Если включены пользовательские взаимодействия с наклоном и поворотом (направлением) (программно или в консоли Google Cloud Console), то пользователи могут регулировать наклон и поворот с помощью мыши и клавиатуры:

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

Программная регулировка наклона и направления

Используйте методы setTilt() и setHeading() для программной настройки наклона и направления на векторной карте. Направление — это направление, в градусах по часовой стрелке, начиная с севера, поэтому map.setHeading(90) повернёт карту так, чтобы восток был сверху. Угол наклона измеряется от зенита, поэтому map.setTilt(0) смотрит прямо вниз, а map.setTilt(45) создаст наклонную проекцию.

  • Вызовите setTilt() чтобы задать угол наклона карты. Используйте getTilt() чтобы получить текущее значение наклона.
  • Вызовите setHeading() чтобы задать направление карты. Используйте getHeading() , чтобы получить текущее значение направления.

Чтобы изменить центр карты, сохранив наклон и направление, используйте map.setCenter() или map.panBy() .

Обратите внимание, что диапазон доступных углов зависит от текущего уровня масштабирования. Значения вне этого диапазона ограничиваются допустимым диапазоном.

Вы также можете использовать метод moveCamera для программного изменения направления, наклона, центрирования и масштабирования. Подробнее .

Влияние на другие методы

При наклоне или повороте карты изменяется поведение других методов JavaScript API Карт:

  • map.getBounds() всегда возвращает наименьший ограничивающий прямоугольник, включающий видимую область; при применении наклона возвращаемые границы могут представлять большую область, чем видимая область области просмотра карты.
  • map.fitBounds() сбросит наклон и направление на ноль перед подгонкой границ.
  • map.panToBounds() сбросит наклон и направление на ноль перед панорамированием границ.
  • map.setTilt() принимает любое значение, но ограничивает максимальный наклон на основе текущего уровня масштабирования карты.
  • map.setHeading() принимает любое значение и изменяет его так, чтобы оно вписывалось в диапазон [0, 360] .

Управляйте камерой

Используйте функцию map.moveCamera() для одновременного обновления любой комбинации свойств камеры. Функция map.moveCamera() принимает один параметр, содержащий все свойства камеры для обновления. В следующем примере показан вызов map.moveCamera() для одновременной установки center , zoom , heading и tilt :

map.moveCamera({
  center: new google.maps.LatLng(37.7893719, -122.3942),
  zoom: 16,
  heading: 320,
  tilt: 47.5
});

Вы можете анимировать свойства камеры, вызвав map.moveCamera() с циклом анимации, как показано здесь:

const degreesPerSecond = 3;

function animateCamera(time) {
  // Update the heading, leave everything else as-is.
  map.moveCamera({
    heading: (time / 1000) * degreesPerSecond
  });

  requestAnimationFrame(animateCamera);
}

// Start the animation.
requestAnimationFrame(animateCamera);

Положение камеры

Вид карты моделируется камерой , направленной вниз на плоскую плоскость. Положение камеры (и, следовательно, рендеринг карты) определяется следующими свойствами: цель (местоположение по широте/долготе) , направление , наклон и масштаб .

Диаграмма свойств камеры

Цель (местоположение)

Целью камеры является местоположение центра карты, указанное в виде координат широты и долготы.

Широта может находиться в диапазоне от -85 до 85 градусов включительно. Значения выше или ниже этого диапазона будут ограничены ближайшим значением в пределах этого диапазона. Например, при указании широты 100 значение будет равно 85. Долгота находится в диапазоне от -180 до 180 градусов включительно. Значения выше или ниже этого диапазона будут сжаты таким образом, чтобы попасть в диапазон (-180, 180). Например, значения 480, 840 и 1200 будут сжаты до 120 градусов.

Подшипник (ориентация)

Пеленг камеры определяет направление по компасу, измеряемое в градусах от истинного севера, соответствующего верхнему краю карты. Если провести вертикальную линию от центра карты до её верхнего края, пеленг будет соответствовать направлению камеры (измеряемому в градусах) относительно истинного севера.

Азимут 0 означает, что верхняя часть карты указывает на истинный север. Азимут 90 означает, что верхняя часть карты указывает на восток (90 градусов по компасу). Азимут 180 означает, что верхняя часть карты указывает на юг.

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

Наклон (угол обзора)

Наклон определяет положение камеры на дуге, описывающей центр карты, измеряемое в градусах от надира (направления, указывающего прямо под камеру). Значение 0 соответствует камере, направленной строго вниз. Значения больше 0 соответствуют камере, наклоненной к горизонту на указанное количество градусов. При изменении угла обзора карта отображается в перспективе: удалённые объекты кажутся меньше, а близлежащие — больше. Это показано на следующих иллюстрациях.

На изображениях ниже угол обзора составляет 0 градусов. На первом изображении показана схема: позиция 1 — это положение камеры, а позиция 2 — текущее положение карты. Итоговая карта показана ниже.

Скриншот карты с камерой, расположенной под углом обзора 0 градусов, при уровне масштабирования 18.
Карта отображается с углом обзора камеры по умолчанию.
Диаграмма, показывающая положение камеры по умолчанию — прямо над позицией карты, под углом 0 градусов.
Угол обзора камеры по умолчанию.

На изображениях ниже угол обзора составляет 45 градусов. Обратите внимание, что камера перемещается на полпути по дуге между прямой линией над головой (0 градусов) и землёй (90 градусов), попадая в точку 3. Камера по-прежнему направлена ​​на центр карты, но область, представленная линией в точке 4, теперь видна.

Скриншот карты с камерой, расположенной под углом обзора 45 градусов, при уровне масштабирования 18.
Карта отображается под углом обзора 45 градусов.
Диаграмма, показывающая угол обзора камеры, установленный на 45 градусов, при этом уровень масштабирования по-прежнему установлен на 18.
Угол обзора камеры 45 градусов.

Карта на этом скриншоте по-прежнему центрирована на той же точке, что и на исходной карте, но в верхней части карты появилось больше объектов. При увеличении угла более 45 градусов объекты между камерой и картой кажутся пропорционально крупнее, а объекты за пределами карты — пропорционально крупнее, создавая трёхмерный эффект.

Увеличить

Масштаб карты определяется уровнем масштабирования камеры. При большем масштабе на экране можно увидеть больше деталей, а при меньшем — больше деталей мира.

Уровень масштабирования не обязательно должен быть целым числом. Диапазон уровней масштабирования, допустимых для карты, зависит от ряда факторов, включая целевой объект, тип карты и размер экрана. Любое число, выходящее за пределы диапазона, будет преобразовано в ближайшее допустимое значение, которое может быть как минимальным, так и максимальным уровнем масштабирования. В следующем списке показан примерный уровень детализации, который можно ожидать на каждом уровне масштабирования:

  • 1: Мир
  • 5: Суша/континент
  • 10: Город
  • 15: Улицы
  • 20: Здания
На следующих изображениях показан визуальный вид различных уровней масштабирования:
Скриншот карты с уровнем масштабирования 5
Карта с уровнем масштабирования 5.
Скриншот карты с уровнем масштабирования 15
Карта с уровнем масштабирования 15.
Скриншот карты с уровнем масштабирования 20
Карта с коэффициентом масштабирования 20.

Дробный зум

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

В следующем примере показано включение дробного масштабирования при инициализации карты:

map = new google.maps.Map(document.getElementById('map'), {
  center: {lat: -34.397, lng: 150.644},
  zoom: 8,
  isFractionalZoomEnabled: true
});

Вы также можете включать и выключать дробное масштабирование, установив параметр карты isFractionalZoomEnabled , как показано здесь:

// Using map.set
map.set('isFractionalZoomEnabled', true);

// Using map.setOptions
map.setOptions({isFractionalZoomEnabled: true});

Вы можете настроить прослушиватель для определения, включено ли дробное масштабирование; это особенно полезно, если вы явно не установили значение isFractionalZoomEnabled в true или false . Следующий пример кода проверяет, включено ли дробное масштабирование:

map.addListener('isfractionalzoomenabled_changed', () => {
  const isFractionalZoomEnabled = map.get('isFractionalZoomEnabled');
  if (isFractionalZoomEnabled === false) {
    console.log('not using fractional zoom');
  } else if (isFractionalZoomEnabled === true) {
    console.log('using fractional zoom');
  } else {
    console.log('map not done initializing yet');
  }
});