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 with
easy gestures, 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. The bearing, tilt, location and
zoom level of the map can be controlled programmatically via the
Changes to the camera will not make any changes to markers, polylines, or other graphics you've added, although you may want to change your additions to fit better with the new view.
The rest of this topic describes how to use the camera to make changes that impact the zoom level, viewport or perspective of the map.
The map's view
Like Google Maps on the web, 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 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: latitude/longitude location, zoom, bearing and viewing angle.
The initial camera position is set when you create the
GMSMapView object via
its convenience constructor.
let camera = GMSCameraPosition.camera( withLatitude: -33.8683, longitude: 151.2086, zoom: 16 ) mapView = GMSMapView.map(withFrame: self.view.bounds, camera: camera)
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.8683 longitude:151.2086 zoom:16]; mapView = [GMSMapView mapWithFrame:self.view.bounds camera:camera];
You may also create the
GMSMapView with the default
UIView init method. In
this case, the camera position will start at a default location, and can be
explicitly modified after creation.
mapView = GMSMapView(frame: self.view.bounds)
mapView = [[GMSMapView alloc] initWithFrame:self.view.bounds];
Moving the camera
When you've created the
GMSMapView, and it has either a configured or
default camera, you can change it in one of several ways. When you change the
camera, you have the option of animating the resulting camera movement. The
animation interpolates between the current camera attributes and the new
camera attributes. You can also control the duration of the animation using
You can modify the
GMSCameraPosition object, and set it on the
This will snap the camera to the new location with no animation. The
GMSCameraPosition may be created to configure either latitude, longitude
and zoom, or to configure those properties plus bearing and viewing angle.
let sydney = GMSCameraPosition.camera( withLatitude: -33.8683, longitude: 151.2086, zoom: 6 ) mapView.camera = sydney
GMSCameraPosition *sydney = [GMSCameraPosition cameraWithLatitude:-33.8683 longitude:151.2086 zoom:6]; [mapView setCamera:sydney];
GMSCameraPosition may also be created with explicit bearing and viewing
let fancy = GMSCameraPosition.camera( withLatitude: -33, longitude: 151, zoom: 6, bearing: 270, viewingAngle: 45 ) mapView.camera = fancy
GMSCameraPosition *fancy = [GMSCameraPosition cameraWithLatitude:-33.8683 longitude:151.2086 zoom:6 bearing:30 viewingAngle:45]; [mapView setCamera:fancy];
If you prefer to animate the transition, you can call one of several methods that allow you to animate the camera moving to a new location. You can control the duration of the animation with Core Animation.
GMSCameraUpdate object allows you to specify a new view for the
camera, and choose whether to snap-to or animate-to that view. You can update
the view by passing a new
GMSCameraUpdate object to
moveCamera method. This can be useful when you want to modify the camera to
fit predefined bounds.
let northEast = CLLocationCoordinate2D(latitude: -33.8683, longitude: 151.2086) let southWest = CLLocationCoordinate2D(latitude: -33.994065, longitude: 151.251859) let bounds = GMSCoordinateBounds(coordinate: northEast, coordinate: southWest) let update = GMSCameraUpdate.fit(bounds, withPadding: 50.0) mapView.moveCamera(update)
CLLocationCoordinate2D northEast = CLLocationCoordinate2DMake(-33.8683, 151.2086); CLLocationCoordinate2D southWest = CLLocationCoordinate2DMake(-33.994065, 151.251859); GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] initWithCoordinate:northEast coordinate:southWest]; GMSCameraUpdate *update = [GMSCameraUpdate fitBounds:bounds withPadding:50.0f]; [mapView moveCamera:update];
The sections below describe each camera property, and how to modify the values after the map has been created.
The location determines the center of the map. Locations are specified by
latitude and longitude, and represented programmatically by a
CLLocationCoordinate2D, created with
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.
Users are able to change the location by panning the map. You can
set the location programmatically with
mapView.animate(toLocation: CLLocationCoordinate2D(latitude: -33.868, longitude: 151.208))
[mapView animateToLocation:CLLocationCoordinate2DMake(-33.868, 151.208)];
Alternately, you can set the camera directly, without animating the change.
let target = CLLocationCoordinate2D(latitude: -33.868, longitude: 151.208) mapView.camera = GMSCameraPosition.camera(withTarget: target, zoom: 6)
CLLocationCoordinate2D target = CLLocationCoordinate2DMake(-33.868, 151.208); mapView.camera = [GMSCameraPosition cameraWithTarget:target zoom:6];
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, i.e., at zoom level 2, the whole world is approximately 1024 points wide. Note that the zoom level need not be an integer. The range of zoom levels permitted by the map depends on a number of factors including location, map type and screen size. 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
Users are able to change the zoom level by using a two-finger pinch. You can
set the zoom programmatically with
Set a minimum or maximum zoom
You can restrict the range of zoom available to the map by setting a min and max zoom level. The below code restricts the zoom level between 10 and 15.
let camera = GMSCameraPosition.camera( withLatitude: 41.887, longitude: -87.622, zoom: 12 ) let mapView = GMSMapView.map(withFrame: .zero, camera: camera) mapView.setMinZoom(10, maxZoom: 15)
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 the
values can be read individually using the
This is helpful when restricting only one of the values. The below code
changes only the minimum zoom level.
mapView.setMinZoom(12, maxZoom: mapView.maxZoom)
[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.
// Sets the zoom level to 4. let camera2 = GMSCameraPosition.camera( withLatitude: 41.887, longitude: -87.622, zoom: 4 ) let mapView2 = GMSMapView.map(withFrame: .zero, camera: camera) // The current zoom, 4, is outside of the range. The zoom will change to 10. mapView.setMinZoom(10, maxZoom: 15)
// 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];
maxZoom are set to the values defined by the
The bearing is the direction in which a vertical line on the map points, measured in degrees clockwise from north. 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. The Maps SDK for iOS lets you change a map's alignment or bearing. For example, a bearing of 90 degrees results in a map where the upwards direction points due east.
Users are able to change the bearing by using a two-finger gesture to rotate
the orientation of the map. You can set the bearing programmatically with
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 dependent maximum. The maximum angle is defined as a series of line segments as a function of zoom, rather than a step function. For zoom 16 and above, the maximum angle is 65 degrees. For zoom 10 and below, the maximum angle is 30 degrees.
Users are able to change the viewing angle by using a two-finger swipe.
You can set the viewing angle programmatically with
Build a GMSCameraPosition
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.
To do this, first calculate the
GMSCoordinateBounds that you want to be
visible on the screen. Then use the
cameraForBounds:insets: method on
GMSMapView to return a new
GMSCameraPosition. This ensures that
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.
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
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;
Updating the Camera View
Instead of directly modifying the camera view with various methods of
GMSMapView, you can create an operation to update the map in a predefined
way, called a
GMSCameraUpdate, and apply it to the map with
moveCamera: method. You can also animate the update to the camera with the
GMSCameraUpdate should only be constructed using one of its factory methods.
- Change the current zoom level by 1.0, while keeping all other properties the same.
- Changes the zoom level to the given value, while keeping all other properties the same.
- Increases (or decreases, if the value is negative) the zoom level by the given value.
- 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.
- Changes the camera's latitude and longitude, while preserving all other properties.
- Changes the camera's latitude, longitude and zoom, while preserving all other properties.
- Lets you specify a new
- 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 orientation. For example, if the camera has a bearing of 90 degrees, then east is "up".
- 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.
- 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.
- Transforms the camera such that the specified bounds are centered on
screen at the greatest possible zoom level. Allows you to specify custom
UIEdgeInsets, for the bounding box. Use this method when you want to set the padding on each edge independently.
To update the camera view with a
- Create an initial
- Create a
GMSCameraUpdateobject with one of the supplied factory methods, described above.
- Apply the camera update to the
GMSMapViewwith either the
The following code snippets illustrate some of the common ways to move the
// Zoom in one zoom level let zoomCamera = GMSCameraUpdate.zoomIn() mapView.animate(with: zoomCamera) // Center the camera on Vancouver, Canada let vancouver = CLLocationCoordinate2D(latitude: 49.26, longitude: -123.11) let vancouverCam = GMSCameraUpdate.setTarget(vancouver) mapView.animate(with: vancouverCam) // Move the camera 100 points down, and 200 points to the right. let downwards = GMSCameraUpdate.scrollBy(x: 100, y: 200) mapView.animate(with: downwards)
// Zoom in one zoom level GMSCameraUpdate *zoomCamera = [GMSCameraUpdate zoomIn]; [mapView animateWithCameraUpdate:zoomCamera]; // Center the camera on Vancouver, Canada CLLocationCoordinate2D vancouver = CLLocationCoordinate2DMake(49.26, -123.11); GMSCameraUpdate *vancouverCam = [GMSCameraUpdate setTarget:vancouver]; [mapView animateWithCameraUpdate:vancouverCam]; // Move the camera 100 points down, and 200 points to the right. GMSCameraUpdate *downwards = [GMSCameraUpdate scrollByX:100.0 Y:200.0]; [mapView animateWithCameraUpdate:downwards];