Camera and view

Select platform: Android iOS JavaScript

The Maps SDK for iOS allows you to change the user's viewpoint of the map by modifying the map's camera.

Maps added with the Maps SDK for iOS can be tilted and rotated, giving users the ability to adjust the map with an orientation that makes sense for them. At any zoom level, you can pan the map, or change its perspective with very little latency.

Changes to the camera will not make any changes to markers, polylines, or other graphics you've added, although you might want to change your additions to fit better with the new view.

The map's view

The Maps SDK for iOS represents the world's surface (a sphere) on your device's screen (a flat plane) using the Mercator projection. In the east and west direction, the map is repeated infinitely as the world seamlessly wraps around on itself. In the north and south direction the map is limited to approximately 85 degrees north and 85 degrees south.

The camera position

The map view is modeled as a camera looking down on a flat plane. The position of the camera (and hence the rendering of the map) is specified by the following properties: target (latitude/longitude location), bearing, tilt, and zoom.

Camera properties diagram

Target (location)

The camera target is the location of the center of the map, specified as latitude and longitude coordinates.

The latitude can be between -85 and 85 degrees, inclusive. Values above or below this range will be clamped to the nearest value within this range. For example, specifying a latitude of 100 will set the value to 85. Longitude ranges between -180 and 180 degrees, inclusive. Values above or below this range will be wrapped such that they fall within the range (-180, 180). For example, 480, 840 and 1200 will all be wrapped to 120 degrees.

Bearing (orientation)

The camera bearing specifies the compass direction, measured in degrees from true north, corresponding to the top edge of the map. If you draw a vertical line from the center of the map to the top edge of the map, the bearing corresponds to the heading of the camera (measured in degrees) relative to true north.

A bearing of 0 means that the top of the map points to true north. A bearing value 90 means the top of the map points due east (90 degrees on a compass). A value 180 means the top of the map points due south.

The Maps API lets you change a map's bearing. For example, someone driving a car often turns a road map to align it with their direction of travel, while hikers using a map and compass usually orient the map so that a vertical line is pointing north.

Tilt (viewing angle)

The tilt defines the camera's position on an arc directly over the map's center position, measured in degrees from the nadir (the direction pointing directly below the camera). A value of 0 corresponds to a camera pointed straight down. Values greater than 0 correspond to a camera that is pitched toward the horizon by the specified number of degrees. When you change the viewing angle, the map appears in perspective, with far-away features appearing smaller, and nearby features appearing larger. The following illustrations demonstrate this.

In the images below, the viewing angle is 0 degrees. The first image shows a schematic of this; position 1 is the camera position, and position 2 is the current map position. The resulting map is shown below it.

Screenshot of a map with a camera positioned at 0 degrees viewing angle, at a zoom level of 18.
The map displayed with the camera's default viewing angle.
Diagram that shows the default position of the camera, directly over the map position, at an angle of 0 degrees.
The default viewing angle of the camera.

In the images below, the viewing angle is 45 degrees. Notice that the camera moves halfway along an arc between straight overhead (0 degrees) and the ground (90 degrees), to position 3. The camera is still pointing at the map's center point, but the area represented by the line at position 4 is now visible.

Screenshot of a map with a camera positioned at 45 degrees viewing angle, at a zoom level of 18.
The map displayed with a viewing angle of 45 degrees.
Diagram that shows the camera's viewing angle set to 45 degrees, with the zoom level still set to 18.
A camera viewing angle of 45 degrees.

The map in this screenshot is still centered on the same point as in the original map, but more features have appeared at the top of the map. As you increase the angle beyond 45 degrees, features between the camera and the map position appear proportionally larger, while features beyond the map position appear proportionally smaller, yielding a three-dimensional effect.

Zoom

The zoom level of the camera determines the scale of the map. At larger zoom levels more detail can be seen on the screen, while at smaller zoom levels more of the world can be seen on the screen. At zoom level 0, the scale of the map is such that the entire world has a width of approximately 256 points.

Increasing the zoom level by 1 doubles the width of the world on the screen. Hence at zoom level N, the width of the world is approximately 256 * 2N points. For example, at zoom level 2, the whole world is approximately 1024 points wide.

The zoom level need not be an integer. The range of zoom levels permitted by the map depends on a number of factors including target, map type and screen size. Any number out of the range will be converted to the next closest valid value, which can be either the minimum zoom level or the maximum zoom level. The following list shows the approximate level of detail you can expect to see at each zoom level:

  • 1: World
  • 5: Landmass/continent
  • 10: City
  • 15: Streets
  • 20: Buildings
The following images show the visual appearance of different zoom levels:
Screenshot of a map at a zoom level of 5
A map at zoom level 5.
Screenshot of a map at a zoom level of 15
A map at zoom level 15.
Screenshot of a map at zoom level 20
A map at zoom level 20.

Set the initial camera position

The camera position is represented by a GMSCameraPosition object. Create a GMSCameraPosition object to set the latitude and longitude of the target, as well as to set bearing, tilt, and zoom.

To set the initial camera position, create a GMSCameraPosition object and then pass that object to the GMSMapView convenience constructor.

Swift

let camera = GMSCameraPosition(
  latitude: -33.8683,
  longitude: 151.2086,
  zoom: 16
)
mapView = GMSMapView(frame: self.view.bounds, camera: camera)
      

Objective-C

GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.8683
                                                        longitude:151.2086
                                                             zoom:16];
mapView = [GMSMapView mapWithFrame:self.view.bounds camera:camera];
      

You can also create the GMSMapView object using the default UIView init method. In this case, the camera position starts at the default location and you can modify it after creation.

Swift

mapView = GMSMapView(frame: self.view.bounds)
      

Objective-C

mapView = [[GMSMapView alloc] initWithFrame:self.view.bounds];
      

Modify the camera position

You can programmatically modify the camera position to set the location, bearing, tilt, and zoom. While GMSMapView provides several methods that you can use to modify the camera position, you typically use GMSCameraPosition or GMSCameraUpdate:

  • GMSCameraPosition contains properties and methods that let you modify all the camera position parameters, including target, bearing, tilt and zoom.

  • GMSCameraUpdate lets you modify target, bearing, tilt and zoom and also contains additional convenience methods to support scrolling, advanced zooming, centering the camera within predefined boundaries, and more.

When you move the camera, you can choose to "snap" the camera to the new position, meaning there is no animation, or animate the move. For example, if you animate a change to the camera's target location, the animation pans from the old location to the new one.

The animation interpolates between the current camera attributes and the new camera attributes. You can control the duration of the animation using Core Animation.

Use GMSCameraPosition

To modify the camera by using GMSCameraPosition, you create a new object or copy an existing object and then set it on the GMSMapView object. Use the GMSCameraPosition object to snap the camera to the new location with no animation or to animate the move.

Use a GMSCameraPosition object to configure any camera properties such as latitude, longitude, zoom, bearing, and viewing angle. You then use that object to set the camera property of 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];
      

Omit any GMSCameraPosition property that you want to set to its default value.

To animate the move, use the animateToCameraPosition: method instead of setting the camera property.

Use GMSCameraUpdate

GMSCameraUpdate lets you update the camera position, and choose whether to snap-to or animate-to that new position. The advantage of GMSCameraUpdate is convenience. You can use GMSCameraPosition to perform the same tasks as GMSCameraUpdate, but GMSCameraUpdate provides additional helper methods to make it easier to manipulate the camera.

For example, to use GMSCameraPosition to increment the current zoom level, you have to first determine the current zoom level, then create a GMSCameraPosition object where you set the zoom to a value one greater than the current zoom.

Alternatively, construct a GMSCameraUpdate object by using the zoomIn: factory method. Then update the camera by passing the GMSCameraUpdate object to the GMSMapView animateWithCameraUpdate: method.

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];
      

Use the GMSMapView moveCamera: method to snap the camera to the new position instead.

In the next example, you use GMSCameraUpdate to animate a move of the camera to center it on Vancouver.

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];
      

Construct a GMSCameraUpdate object

Construct a GMSCameraUpdate object by using one of its factory methods.

zoomIn: and zoomOut:
Change the current zoom level by 1.0, while keeping all other properties the same.
zoomTo:
Changes the zoom level to the given value, while keeping all other properties the same.
zoomBy:
Increases (or decreases, if the value is negative) the zoom level by the given value.
zoomBy:atPoint:
Increases (or decreases, if the value is negative) the zoom level by the given value, while retaining the specified point's position on the screen.
setTarget:
Changes the camera's latitude and longitude, while preserving all other properties.
setTarget:zoom:
Changes the camera's latitude, longitude and zoom, while preserving all other properties.
setCamera:
Lets you specify a new GMSCameraPosition.
scrollByX:Y:
Change the camera's latitude and longitude such that the map moves by the specified number of points. A positive x value causes the camera to move to the right, so that the map appears to have moved to the left. A positive y value causes the camera to move down, so that the map appears to have moved up. The scrolling is relative to the camera's current bearing. For example, if the camera has a bearing of 90 degrees, then east is "up".
fitBounds:
Transforms the camera such that the specified bounds are centered on screen at the greatest possible zoom level. Applies a default padding to the bounds of 64 points.
fitBounds:withPadding:
Transforms the camera such that the specified bounds are centered on screen at the greatest possible zoom level. Allows you to specify custom padding, in points, for the bounding box. Use this method when you'd like to have the same amount of padding on all sides.
fitBounds:withEdgeInsets:
Transforms the camera such that the specified bounds are centered on screen at the greatest possible zoom level. Allows you to specify custom padding, as UIEdgeInsets, for the bounding box. Use this method when you want to set the padding on each edge independently.

Use GMSMapView to modify a single property

GMSMapView provides several methods that let you move the camera without the use of a GMSCameraPosition object or GMSCameraUpdate object. These methods, such as animateToLocation: or animateToZoom: let you animate a change to a single camera property.

For example, use the toViewingAngle: method to animate a change to the camera tilt.

Swift

mapView.animate(toViewingAngle: 45)
      

Objective-C

[mapView animateToViewingAngle:45];
      

Set target (location)

The location determines the center of the map. Locations are specified by latitude and longitude, and represented programmatically by a CLLocationCoordinate2D, created with CLLocationCoordinate2DMake.

Use GMSCameraPosition to change the location. In this example, the map snaps to the new location.

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];
      

To animate the change, and pan the map to the new location, you can use the animateToCameraPosition: method instead of setting the camera property. Or, use the animateToLocation: method on GMSMapView.

Swift

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

Objective-C

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

You can also create a GMSCameraUpdate object to move the camera. Among its factory methods is the scrollByX:Y: method that lets you scroll the camera by specifying the number of points to move the camera in the X and Y directions. In the next example, you scroll the camera 200 points to the right, and 100 points down:

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];
      

Set bearing (orientation)

The bearing is the compass direction, measured in degrees from true north, corresponding to the top edge of the map. For example, a bearing of 90 degrees results in a map where the top edge points due east.

Set the bearing programmatically with GMSCameraPosition or GMSCameraUpdate or by using the animateToBearing: method of GMSMapView.

Swift

mapView.animate(toBearing: 0)
      

Objective-C

[mapView animateToBearing:0];
      

Set tilt (viewing angle)

The viewing angle is the camera's position on an arc between directly over the map's center position and the surface of the Earth, measured in degrees from the nadir (the direction pointing directly below the camera). When you change the viewing angle, the map appears in perspective, with features between the camera and the map position appearing proportionally larger, and features beyond the map position appear proportionally smaller, yielding a three-dimensional effect.

The viewing angle can range between 0 (pointing straight down at the map), and up to a zoom-level dependent maximum. For zoom level 16 and above, the maximum angle is 65 degrees. For zoom level 10 and below, the maximum angle is 30 degrees.

Set the viewing angle programmatically using GMSCameraPosition or GMSCameraUpdate or with the animateToViewingAngle: method of GMSMapView.

Swift

mapView.animate(toViewingAngle: 45)
      

Objective-C

[mapView animateToViewingAngle:45];
      

Set zoom

The zoom level of the camera determines the scale of the map. At larger zoom levels more detail can be seen on the screen, while at smaller zoom levels more of the world can be seen on the screen.

Set the zoom programmatically with GMSCameraPosition or GMSCameraUpdate or by using the animateToZoom: method of GMSMapView.

Swift

mapView.animate(toZoom: 12)
      

Objective-C

[mapView animateToZoom:12];
      

The following example uses the zoomIn: factory method to construct a GMSCameraUpdate object to animate a zoom in by one level from the current level.

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];
      

Set boundaries

It's sometimes useful to move the camera such that an entire area of interest is visible at the greatest possible zoom level. For example, if you're displaying all of the gas stations within five miles of the user's current position, you may want to move the camera such that they are all visible on the screen.

First calculate the GMSCoordinateBounds that you want to be visible on the screen. Then use the cameraForBounds:insets: method of GMSMapView to return a new GMSCameraPosition. This ensures that the given GMSCoordinateBounds fits entirely within the current map's size. Note that the tilt and bearing of the map will both be set to 0.

The below example demonstrates how to change the camera such that both the cites of Vancouver and Calgary appear in the same view.

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;
      

Restrict the user's panning to a given area

In the above scenarios, you set the bounds of the map but the user can then scroll or pan outside of these bounds. Instead, you may want to constrain the lat/lng center bounds of the focal point of the map (the camera target) so that users can only scroll and pan within these bounds.

For example, a retail app for a shopping center or airport may want to constrain the map to a particular bounds, allowing users to scroll and pan within those bounds.

To restrict panning to a specific bounds, set the cameraTargetBounds property of GMSMapView to a GMSCoordinateBounds object that defines the required bounds. To later remove the restriction, set cameraTargetBounds to nil.

Swift

mapView.cameraTargetBounds = bounds
      

Objective-C

mapView.cameraTargetBounds = bounds;
      

The following diagram illustrates a scenario when the camera target is constrained to an area that is slightly larger than the viewport. The user can scroll and pan, provided the camera target remains within the bounded area. The cross represents the camera target:

Diagram showing a camera bounds that is larger than the
      viewport.

The map always fills the viewport, even if that results in the viewport showing areas that are outside the defined bounds. For example, if you position the camera target at a corner of the bounded area, the area beyond the corner is visible in the viewport but users cannot scroll further into that area. The following diagram illustrates this scenario. The cross represents the camera target:

Diagram showing the camera target positioned at bottom right corner of
      the camera bounds.

In the following diagram, the camera target has very restricted bounds, offering the user very little opportunity to scroll or pan the map. The cross represents the camera target:

Diagram showing a camera bounds that is smaller than the
      viewport.

Set a minimum or maximum zoom

The global constants kGMSMinZoomLevel and kGMSMaxZoomLevel define the minimum or maximum zoom values. By default, the minZoom and maxZoom properties of GMSMapView are set to these constants.

You can restrict the range of zoom levels available to the map by setting a min and max zoom level. The below code restricts the zoom level between 10 and 15.

Swift

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

Objective-C

GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:41.887
                                                       longitude:-87.622
                                                             zoom:12];
GMSMapView *mapView = [GMSMapView mapWithFrame:CGRectZero
                                        camera:camera];
[mapView setMinZoom:10 maxZoom:15];
      

The zoom range must be set using the setMinZoom:maxZoom: method, however you can read the current values using the minZoom and maxZoom properties. This is helpful when restricting only one of the values. The below code changes only the minimum zoom level.

Swift

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

Objective-C

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

If, after updating the min and max zoom, the camera's zoom level is set to a value outside of the new range, the current zoom will automatically update to display the nearest valid value. For example, in the code below, the original zoom is defined as 4. When the zoom range is later set to 10-15, the current zoom is updated to 10.

Swift

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

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

Objective-C

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