The HERE SDK provides a number of ways to change the view on a map. While you can use map styles to change the look of the map, you can use a camera to view the map from different perspectives.
For example, the HERE SDK allows you to set a target location, tilt the camera, zoom in and out, or set a bearing angle.
At a glance
- Use the
mapView.camerato manipulate the view of the map.
- Set a new target location by calling
camera.lookAt(point: GeoCoordinates(latitude: 52.530932, longitude: 13.384915)).
- Zoom the map by setting a distance in meters:
camera.lookAt(point: GeoCoordinates(latitude: 52.530932, longitude: 13.384915), distanceInMeters: 1000 * 2). Get the current distance from the camera's
- Set a
MapCamera.OrientationUpdate()to specify the tilt angle and bearing angle of the camera.
- Set a transform center with
MapCamera.principalPointto change the default pivot point that is centered on the map view.
- Get the bounds of the currently displayed area from
- Set the bounds of an area to display by calling
camera.lookAt(area: geoBox, orientation: MapCamera.OrientationUpdate()).
- Run basic animations from A to B with the Camera's flyTo()-method. Customize animations by setting
By default, the camera is located centered above the map. From a bird's eye view looking straight-down, the map is oriented North-up. This means that on your device, the top edge is pointing to the north of the map.
With the camera, you cannot rotate the map directly, but change the camera's orientation instead. By changing the
bearing parameter of the
MapCamera.OrientationUpdate(), you will have the same effect as when rotating the map.
The orientation of the map is usually specified by a bearing angle. 'Bearing' is a navigational term, counted in degrees, from the North in a clockwise direction.
By default, the camera has a bearing value of 0° degrees. By setting a bearing angle of 45°, as visualized in the illustration above, the map appears to the camera's eye as it rotates counter-clockwise and the direction of the bearing becomes the new upward direction on your map, pointing to the top edge of your device. This is similar to holding and rotating a paper map while hiking in a certain direction. Apparently, it is easier to orient yourself if the map's top edge points in the direction in which you want to go. However, this will not always be the true North direction (bearing = 0°).
Note that the bearing axis is always perpendicular to the ground and passes through the camera, regardless of the current camera orientation.
The following code rotates the camera by 90°:
let orientation = MapCamera.OrientationUpdate(bearing: 90, tilt: 0) mapView.camera.lookAt(point: GeoCoordinates(latitude: 52.373556, longitude: 13.114358), orientation: orientation, distanceInMeters: 1000 * 7)
Effectively, for the viewer this lets the map appear rotated by 90° to the left.
The camera can also be used to transform the flat 2D map surface to a 3D perspective to see, for example, roads at a greater distance that may appear towards the horizon. By default, the camera is not tilted (tilt = 0°).
In addition to the tilt value of the camera, the camera's bearing angle (see above) can be manipulated. Here we show the effect of changing the tilt value. Look at the illustration below to see the available camera axes.
A tilt value of 0° means that the camera's optical axis is perpendicular to the ground. The tilt angle is always calculated from this perpendicular axis. The tilt angle relates to the optical axis of the camera.
As visualized in the illustration, tilting the camera by 45° will change the bird's eye view of the camera to a 3D perspective. Use the code below to change only the tilt value of the camera:
let orientation = MapCamera.OrientationUpdate(bearing: 0, tilt: 45) mapView.camera.lookAt(point: GeoCoordinates(latitude: 52.373556, longitude: 13.114358), orientation: orientation, distanceInMeters: 1000 * 7)
Any subsequent tilt value will always be applied from the camera's default location. This is the same for the tilt angle and the bearing angle of the camera. Some values will be clamped when they are out of range.
All axes can be manipulated at the same time. Changing the bearing value will give different results when the camera is tilted.
By setting a new camera target, you can change the camera's location and effectively change the location that is shown at the center of the map view. The
lookAt() method is available in different overloads. Just a few examples:
// Change only the location. camera.lookAt(point: GeoCoordinates(latitude: 52.530932, longitude: 13.384915)) // Change zoom and location. camera.lookAt(point: GeoCoordinates(latitude: 52.530932, longitude: 13.384915), distanceInMeters: 1000 * 2) // Change location area and orientation. let geoBox = GeoBox(southWestCorner: GeoCoordinates(latitude: 52.373556, longitude: 13.114358), northEastCorner: GeoCoordinates(latitude: 52.611022, longitude: 13.479493)) let orientation = MapCamera.OrientationUpdate(bearing: 0, tilt: 45) camera.lookAt(area: geoBox, orientation: orientation)
Note that changing the orientation (bearing, tilt) of the camera does not change the location of the map.
The HERE SDK also supports dedicated zoom levels in the range [0,22] to provide a quick way to achieve the desired level of detail. Call the camera's
zoomBy() method to set the zoom level and access the current zoom level from the camera's
State property. Important: The zoom level is set as
Double, be sure to not mix it with the
distanceInMeters parameter that is also of type
By changing the camera, you can only programmatically change the perspective of the map view, but you do not have direct control of the map view itself - like when performing gestures to zoom the map or to rotate or to tilt the map. See the Gestures section for an overview of the available gestures to manipulate the map directly.
By default, the map's pivot point - or principal point - is centered on the map view. It determines the point where the target coordinates are placed within the map view. Setting a new principal point instantly moves the map to render the current target coordinates at the new principal point. It is set in pixels relative to the map view's origin top-left (0, 0).
The principal point affects all programmatical map transformations (rotate, orbit, tilt and zoom) and the two-finger-pan gesture to tilt the map. Other gestures, like pinch-rotate, are not affected.
Usually, you want to set the principal point only once, for example to lower the transform center a bit during turn-by-turn navigation - so the user can see more of the road ahead. To achieve this, you need to get the pixel dimensions of your map view (based on your layout and the device's screen dimensions) and then lower the height by 3/4, that is multiply
mapViewHeightInPixels by 0.75. See the following example:
// Repositions principal point 3/4 lower than default. let scaleFactor = UIScreen.main.scale let mapViewWidthInPixels = Double(mapView.bounds.width * scaleFactor) let mapViewHeightInPixels = Double(mapView.bounds.height * scaleFactor) let newTransformCenter = Point2D(x: mapViewWidthInPixels / 2, y: mapViewHeightInPixels * 0.75) camera.principalPoint = newTransformCenter // Reposition a circle view on screen to indicate the new target. cameraTargetView.center = CGPoint(x: newTransformCenter.x / Double(scaleFactor), y: newTransformCenter.y / Double(scaleFactor)) print("New transform center: \(newTransformCenter.x), \(newTransformCenter.y)")
The code snippet above sets a new principal point that will instantly move the current map center down by 3/4 of the visible map area on screen. Once set, all further map manipulations will be pivoted around this new principal point. For example, when you programatically rotate the map, the map will always rotate around the principal point.
In the example above, we show also how to render a custom
cameraTargetView centered on the principal point, the full code for this can be seen in the Camera example app.