Камера и область просмотра

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

Maps SDK для iOS позволяет изменять пользовательскую точку обзора, изменяя положение камеры для карты.

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

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

Точка обзора карты

В Maps SDK для iOS используется проекция Меркатора.

Позиция камеры

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

Схема свойств карты

Цель камеры (местоположение)

Цель камеры – это местоположение, которое должно быть в центре карты. Оно задается широтой и долготой.

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

Азимут (ориентация)

Азимут камеры указывается как направление по компасу, измеряемое в градусах отклонения от географического севера, который соответствует верхнему краю карты. Если нарисовать вертикальную линию от центра карты до ее верхнего края, азимут соответствует отклонению камеры в градусах от этой линии.

Нулевой азимут означает, что верхний край карты соответствует географическому северу. Значение 90 означает, что верхний край карты соответствует востоку (90 градусов на компасе), а 180 – югу.

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

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

Угол наклона определяется положением камеры на дуге над центром карты. Он измеряется в градусах относительно надира – направления, указывающего строго вниз от камеры. Нулевое значение соответствует камере, направленной вертикально вниз. Значения больше нуля соответствуют наклону камеры по направлению к линии горизонта на указанное количество градусов. При изменении угла наклона применяется эффект перспективы, т. е. близкие объекты выглядят крупнее, а далекие – мельче. Этот эффект проиллюстрирован ниже.

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

Скриншот карты с углом обзора 0 градусов и уровнем масштабирования 18
Вид карты под углом обзора по умолчанию
Схема, показывающая положение камеры по умолчанию (с углом наклона 0°).
Угол наклона камеры по умолчанию

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

Скриншот карты с углом обзора 45 градусов и уровнем масштабирования 18
Вид карты с углом обзора 45 градусов
Схема, показывающая положение камеры под углом 45 градусов с уровнем масштабирования 18
Угол наклона камеры – 45 градусов

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

Масштаб

Уровень масштабирования камеры определяет масштаб карты. Чем он выше, тем больше деталей можно рассмотреть, зато при уменьшении масштаба на экране умещается большая территория. При уровне масштабирования 0 вся карта мира имеет ширину около 256 точек.

Увеличение уровня масштабирования на единицу удваивает ширину карты на экране. Таким образом, на уровне масштабирования N ширина мира составляет примерно 256 * 2N точек. Например, на уровне масштабирования 2 ширина карты составляет приблизительно 1024 точки.

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

  • 1: мир;
  • 5: континент;
  • 10: город;
  • 15: улицы;
  • 20: здания.
На следующих изображениях представлены различные уровни масштабирования:
Скриншот карты с уровнем масштабирования 5
Карта с уровнем масштабирования 5
Скриншот карты с уровнем масштабирования 15
Карта с уровнем масштабирования 15
Скриншот карты с уровнем масштабирования 20
Карта с уровнем масштабирования 20

Как задать начальное положение камеры

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

Чтобы задать начальное положение камеры, создайте объект GMSMapViewOptions и присвойте свойству camera значение GMSCameraPosition. Затем передайте параметры в конструктор GMSMapView.

Swift

let options = GMSMapViewOptions()
options.camera = GMSCameraPosition.camera(withLatitude: -33.8683, longitude: 151.2086, zoom: 16)
let mapView = GMSMapView(options:options)

Objective-C

GMSMapViewOptions *options = [[GMSMapViewOptions alloc] init];
options.camera = [GMSCameraPosition cameraWithLatitude:-33.8683
                                                        longitude:151.2086
                                                             zoom:16];
GMSMapView *mapView = [[GMSMapView alloc] initWithOptions:options];

Вы также можете создать объект GMSMapView, используя метод инициализации UIView по умолчанию. В этом случае камера сначала будет находиться в положении по умолчанию, а затем вы сможете его изменить.

Swift

let options = GMSMapViewOptions()
options.frame = self.view.bounds
let mapView = GMSMapView(options:options)

Objective-C

GMSMapViewOptions *options = [[GMSMapViewOptions alloc] init];
options.frame = self.view.bounds;
GMSMapView *mapView = [[GMSMapView alloc] initWithOptions:options];

Как изменить положение камеры

Вы можете программно изменить положение камеры, чтобы задать местоположение, направление, наклон и масштаб. В классе GMSMapView есть несколько методов, позволяющих изменить положение камеры. Обычно используются методы GMSCameraPosition и GMSCameraUpdate.

  • Класс GMSCameraPosition содержит свойства и методы, позволяющие изменять все параметры положения камеры: цель, азимут, наклон и масштаб.

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

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

Текущие и новые значения атрибутов камеры интерполируются. Длительность анимации можно настроить с помощью Core Animation.

Использовать помощника (GMSCameraPosition)

Чтобы изменить камеру с помощью GMSCameraPosition, создайте новый объект или скопируйте существующий, а затем задайте его в объекте GMSMapView. Используйте объект GMSCameraPosition, чтобы переместить камеру в новое местоположение с анимацией или без нее.

Используйте объект GMSCameraPosition, чтобы настроить свойства камеры, такие как широта, долгота, масштаб, азимут и угол обзора. Затем вы используете этот объект, чтобы задать свойство camera для GMSMapView.

Swift

let fancy = GMSCameraPosition(
  latitude: -33,
  longitude: 151,
  zoom: 6,
  bearing: 270,
  viewingAngle: 45
)
mapView.camera = fancy
      

Objective-C

GMSCameraPosition *fancy = [GMSCameraPosition cameraWithLatitude:-33.8683
                                                       longitude:151.2086
                                                            zoom:6
                                                         bearing:30
                                                    viewingAngle:45];
[mapView setCamera:fancy];
      

Если вы хотите использовать значение по умолчанию, не указывайте свойство GMSCameraPosition.

Чтобы анимировать перемещение, используйте метод animateToCameraPosition: вместо свойства camera.

Использовать помощника (GMSCameraUpdate)

GMSCameraUpdate позволяет обновить положение камеры и выбрать, как она будет перемещаться в новое положение – мгновенно или с анимацией. Преимущество GMSCameraUpdate – удобство. Для выполнения тех же задач, что и с помощью GMSCameraUpdate, можно использовать GMSCameraPosition, но в GMSCameraUpdate есть дополнительные вспомогательные методы, упрощающие управление камерой.

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

Также можно создать объект GMSCameraUpdate с помощью метода zoomIn:. Затем обновите камеру, передав объект GMSCameraUpdate в метод GMSMapView animateWithCameraUpdate:.

Swift

// Zoom in one zoom level
let zoomCamera = GMSCameraUpdate.zoomIn()
mapView.animate(with: zoomCamera)
      

Objective-C

// Zoom in one zoom level
GMSCameraUpdate *zoomCamera = [GMSCameraUpdate zoomIn];
[mapView animateWithCameraUpdate:zoomCamera];
      

Вместо этого используйте метод GMSMapView moveCamera:, чтобы переместить камеру в новое положение.

В следующем примере метод GMSCameraUpdate используется для анимации перемещения камеры, чтобы центрировать ее на Ванкувере.

Swift

// Center the camera on Vancouver, Canada
let vancouver = CLLocationCoordinate2D(latitude: 49.26, longitude: -123.11)
let vancouverCam = GMSCameraUpdate.setTarget(vancouver)
mapView.animate(with: vancouverCam)
      

Objective-C

// Center the camera on Vancouver, Canada
CLLocationCoordinate2D vancouver = CLLocationCoordinate2DMake(49.26, -123.11);
GMSCameraUpdate *vancouverCam = [GMSCameraUpdate setTarget:vancouver];
[mapView animateWithCameraUpdate:vancouverCam];
      

Создайте объект GMSCameraUpdate.

Создайте объект GMSCameraUpdate, используя один из его методов.

zoomIn: и zoomOut:
Изменить уровень масштабирования на 1,0, оставив все остальные свойства без изменений.
zoomTo:
Задает уровень масштабирования, равный указанной величине, и оставляет все остальные свойства без изменений.
zoomBy:
Повышает уровень масштабирования на указанное значение (или понижает, если значение отрицательное).
zoomBy:atPoint:
Повышает уровень масштабирования на указанное значение (или понижает, если значение отрицательное), сохраняя положение заданной точки на экране.
setTarget:
Изменяет широту и долготу, оставляя все прочие свойства прежними.
setTarget:zoom:
Изменяет широту, долготу и уровень масштабирования, оставляя все прочие свойства прежними.
setCamera:
Задает новое значение GMSCameraPosition.
scrollByX:Y:
Изменяет широту и долготу положения камеры так, что камера передвигается на указанное количество точек. При положительном значении X камера смещается вправо (т. е. карта смещается влево). При положительном значении Y камера смещается вниз (т. е. карта смещается вверх). Панорамирование выполняется с учетом текущего азимута камеры. (например, если угол ориентации – 90 градусов, то восток находится вверху).
fitBounds:
Перемещает камеру так, чтобы указанные границы выравнивались по центру экрана с максимально возможным уровнем масштабирования. Применяет к границам отступ по умолчанию, равный 64 точкам.
fitBounds:withPadding:
Перемещает камеру так, чтобы указанные границы выравнивались по центру экрана с максимально возможным уровнем масштабирования. Этот метод позволяет задать одинаковые отступы в пунктах для всех сторон ограничивающей рамки.
fitBounds:withEdgeInsets:
Перемещает камеру так, чтобы указанные границы выравнивались по центру экрана с максимально возможным уровнем масштабирования. С помощью UIEdgeInsets можно задать отступы для каждой стороны граничной рамки по отдельности.

Используйте GMSMapView, чтобы изменить одно свойство

Класс GMSMapView предоставляет несколько методов, позволяющих перемещать камеру без использования объектов GMSCameraPosition или GMSCameraUpdate. С помощью таких методов, как animateToLocation: или animateToZoom:, можно анимировать изменение одного свойства камеры.

Например, используйте метод toViewingAngle:, чтобы анимировать изменение наклона камеры.

Swift

mapView.animate(toViewingAngle: 45)
      

Objective-C

[mapView animateToViewingAngle:45];
      

Задать цель (местоположение)

Местоположение определяет центр карты. Местоположения задаются с помощью широты и долготы и программно представлены объектом CLLocationCoordinate2D, созданным с помощью CLLocationCoordinate2DMake.

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

Swift

let target = CLLocationCoordinate2D(latitude: -33.868, longitude: 151.208)
mapView.camera = GMSCameraPosition(target: target, zoom: 6)
      

Objective-C

CLLocationCoordinate2D target =
    CLLocationCoordinate2DMake(-33.868, 151.208);
mapView.camera = [GMSCameraPosition cameraWithTarget:target zoom:6];
      

Чтобы анимировать изменение и панорамировать карту в новое местоположение, можно использовать метод animateToCameraPosition: вместо настройки свойства camera. Или используйте метод animateToLocation: для GMSMapView.

Swift

mapView.animate(toLocation: CLLocationCoordinate2D(latitude: -33.868, longitude: 151.208))
      

Objective-C

[mapView animateToLocation:CLLocationCoordinate2DMake(-33.868, 151.208)];
      

Вы также можете создать объект GMSCameraUpdate, чтобы переместить камеру. Используйте встроенный метод scrollByX:Y:, чтобы указать количество точек, на которое нужно переместить камеру по осям X и Y. В этом примере камера перемещается на 200 точек вправо и на 100 точек вниз.

Swift

// Move the camera 200 points to the right, and 100 points downwards
let downwards = GMSCameraUpdate.scrollBy(x: 200, y: 100)
mapView.animate(with: downwards)
      

Objective-C

// Move the camera 200 points to the right, and 100 points downwards
GMSCameraUpdate *downwards = [GMSCameraUpdate scrollByX:200.0 Y:100.0];
[mapView animateWithCameraUpdate:downwards];
      

Как задать азимут (ориентацию)

Азимут – это направление по компасу, измеряемое в градусах отклонения от географического севера, который соответствует верхнему краю карты. Например, если азимут равен 90 градусам, верхний край карты будет указывать на восток.

Задайте азимут программно с помощью GMSCameraPosition или GMSCameraUpdate или с помощью метода animateToBearing: класса GMSMapView.

Swift

mapView.animate(toBearing: 0)
      

Objective-C

[mapView animateToBearing:0];
      

Как задать наклон (угол обзора)

Угол обзора определяется положением камеры на дуге, соединяющей точку над центром карты с земной поверхностью. Он измеряется в градусах относительно надира – направления, указывающего строго вниз от камеры. При изменении угла наклона применяется эффект перспективы, т. е. близкие объекты выглядят крупнее, а далекие – мельче.

Угол обзора может варьироваться от 0 (камера направлена строго вниз) до максимального значения, которое зависит от уровня масштабирования. Для уровня масштабирования 16 или выше максимальный угол составляет 65 градусов. Для уровня масштабирования 10 или ниже максимальный угол составляет 30 градусов.

Задайте угол обзора программно с помощью GMSCameraPosition или GMSCameraUpdate или метода animateToViewingAngle: класса GMSMapView.

Swift

mapView.animate(toViewingAngle: 45)
      

Objective-C

[mapView animateToViewingAngle:45];
      

Задать масштаб

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

Задайте масштаб программно с помощью GMSCameraPosition или GMSCameraUpdate или с помощью метода animateToZoom: класса GMSMapView.

Swift

mapView.animate(toZoom: 12)
      

Objective-C

[mapView animateToZoom:12];
      

В приведенном ниже примере метод zoomIn: используется для создания объекта GMSCameraUpdate, который анимирует увеличение масштаба на один уровень по сравнению с текущим.

Swift

// Zoom in one zoom level
let zoomCamera = GMSCameraUpdate.zoomIn()
mapView.animate(with: zoomCamera)
      

Objective-C

// Zoom in one zoom level
GMSCameraUpdate *zoomCamera = [GMSCameraUpdate zoomIn];
[mapView animateWithCameraUpdate:zoomCamera];
      

Устанавливать рамки кампании

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

  1. Вычислите границы GMSCoordinateBounds для области, которую вы хотите отобразить на экране.
  2. Используйте метод cameraForBounds:insets: объекта GMSMapView, чтобы вернуть новый объект GMSCameraPosition.

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

В следующем примере показано, как изменить камеру, чтобы в одном представлении отображались города Ванкувер и Калгари.

Swift

let vancouver = CLLocationCoordinate2D(latitude: 49.26, longitude: -123.11)
let calgary = CLLocationCoordinate2D(latitude: 51.05,longitude: -114.05)
let bounds = GMSCoordinateBounds(coordinate: vancouver, coordinate: calgary)
let camera = mapView.camera(for: bounds, insets: UIEdgeInsets())!
mapView.camera = camera
      

Objective-C

CLLocationCoordinate2D vancouver = CLLocationCoordinate2DMake(49.26, -123.11);
CLLocationCoordinate2D calgary = CLLocationCoordinate2DMake(51.05, -114.05);
GMSCoordinateBounds *bounds =
    [[GMSCoordinateBounds alloc] initWithCoordinate:vancouver coordinate:calgary];
GMSCameraPosition *camera = [mapView cameraForBounds:bounds insets:UIEdgeInsetsZero];
mapView.camera = camera;
      

Ограничение области, в которой пользователь может сдвигать карту

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

Например, если вы разрабатываете приложение для торгового центра или аэропорта, то карту можно ограничить окрестностями этого объекта.

Чтобы ограничить панорамирование определенными границами, задайте для свойства cameraTargetBounds объекта GMSMapView объект GMSCoordinateBounds, определяющий нужные границы. Чтобы снять ограничение, задайте для cameraTargetBounds значение nil.

Swift

mapView.cameraTargetBounds = bounds
      

Objective-C

mapView.cameraTargetBounds = bounds;
      

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

Диаграмма, показывающая границы камеры, которые больше области просмотра.

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

Схема, на которой цель камеры находится в правом нижнем углу области LatLngBounds.

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

Диаграмма, показывающая границы камеры, которые меньше области просмотра.

Установка минимального или максимального масштаба

Глобальные константы kGMSMinZoomLevel и kGMSMaxZoomLevel определяют минимальное и максимальное значения масштабирования. По умолчанию свойства minZoom и maxZoom объекта GMSMapView задаются этими константами.

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

Swift

let camera = GMSCameraPosition(
  latitude: 41.887,
  longitude: -87.622,
  zoom: 12
)
let options = GMSMapViewOptions()
options.camera = camera
let mapView = GMSMapView(options: options)
mapView.setMinZoom(10, maxZoom: 15)
      

Objective-C

GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:41.887
                                                       longitude:-87.622
                                                             zoom:12];
GMSMapViewOptions *options = [[GMSMapViewOptions alloc] init];
options.camera = camera;
GMSMapView *mapView = [[GMSMapView alloc] initWithOptions:options];
[mapView setMinZoom:10 maxZoom:15];
      

Диапазон масштабирования задается с помощью метода setMinZoom:maxZoom:, а текущие значения можно получить с помощью свойств minZoom и maxZoom. Этот подход полезен, когда нужно ограничить только одно из значений. В следующем примере кода изменяется только минимальный уровень масштабирования.

Swift

mapView.setMinZoom(12, maxZoom: mapView.maxZoom)
      

Objective-C

[mapView setMinZoom:12 maxZoom:mapView.maxZoom];
      

Если после обновления минимального и максимального масштаба уровень масштабирования камеры выходит за пределы нового диапазона, текущий масштаб автоматически обновляется, чтобы отобразить ближайшее допустимое значение. Например, в приведенном ниже коде исходный масштаб определен как 4. Если затем диапазон масштабирования будет изменен на 10–15, текущий масштаб станет равен 10.

Swift

// Sets the zoom level to 4.
let camera2 = GMSCameraPosition(
  latitude: 41.887,
  longitude: -87.622,
  zoom: 4
)
let options2 = GMSMapViewOptions()
options2.camera = camera2
let mapView2 = GMSMapView(options: options2)

// The current zoom, 4, is outside of the range. The zoom will change to 10.
mapView2.setMinZoom(10, maxZoom: 15)
      

Objective-C

// Sets the zoom level to 4.
GMSCameraPosition *camera2 = [GMSCameraPosition cameraWithLatitude:41.887
                                                         longitude:-87.622
                                                              zoom:4];
GMSMapViewOptions *options2 = [[GMSMapViewOptions alloc] init];
options2.camera = camera2;
GMSMapView *mapView2 = [[GMSMapView alloc] initWithOptions:options2];
// The current zoom, 4, is outside of the range. The zoom will change to 10.
[mapView setMinZoom:10 maxZoom:15];