Skip to main content

Adjust the map view

|

The Maps SDK for C++ provides multiple ways to modify the map view, center on coordinates or areas, including MapView functionality for exploring different perspectives.

The SDK enables a range of features, including zooming in and out, tilting the camera, centering on specific locations, and more, all through the MapView object.

  • Use getViewport getter to return the current viewport of the map view.
  • Center on specific coordinates with centerOnCoordinates which takes extra parameters for centering preferences such as zoom level, screen position, map angle, animation and more.
  • Center on a specific geographic area represented by a rectangle with coordinates as corners with centerOnArea.
  • Align map according to the north direction by using alignNorthUp.
  • Adjust the current zoom level using setZoomLevel, where lower values result in a more zoomed-out view.
  • Perform a scrolling behavior based on horizontal and vertical scroll offsets with scroll method.
  • MapCamera class provides further functionality such as manipulating orientation, position, and state.

Map viewport

The map viewport refers to the area displayed by the MapView object. Getting the current viewport provides a Rect object which consists of xy (left and top) screen coordinates and width and height on MapView.

The top left coordinate of the screen is represented by [0, 0] and bottom right [viewport.width, viewport.height].

auto currentViewport =  mapView->getViewport();

This viewport can be useful when you need to use methods such as centerOnCoordinates. When Xy object is provided the values must be inside the viewport boundaries.

Map centering

Map centering can be achieved using the centerOnCoordinates, centerOnArea, centerOnRoute, centerOnRouteInstruction, centerOnRouteTrafficEvent methods.

Map centering on coordinates

In order to center the WGS coordinates on the viewport coordinates you can use the centerOnCoordinates method like so:

mapView->centerOnCoordinates( { 48.86130, 2.33387 } );

A linear animation can be incorporated while centering, as demonstrated below:

mapView>centerOnCoordinates(
{ 52.14569, 1.0615 },
gem::Animation(gem::Animation::AnimationLinear, 2000));
tip

You can call the skipAnimation() method of MapView to bypass the animation. To check if an animation is in progress the isAnimationInProgress getter can be used. To check if the camera is moving (as a consequence of an animation or not), the isCameraMoving getter can be used.

In order to convert a screen position to WGS coordinates, the mapView->transformScreenToWgs() method is used:

Coordinates coordsToCenter = mapController->transformScreenToWgs(gem::Xy(pos.x, pos.y));

mapView->centerOnCoordinates(coordsToCenter, 70 /* zoom level */);
note

If the applied style includes elevation and terrain data is loaded, the transformScreenToWgs method returns Coordinates objects that include altitude. You can check for terrain support using the hasTerrainTopography getter on MapView.

To convert WGS coordinates to screen coordinates, the mapView->transformWgsToScreen():

Coordinates wgsCoordinates = Coordinates( { 8, 25 } );

Xy screenPosition = mapView->transformWgsToScreen(wgsCoordinates);
tip

You can also convert a Rect to a RectangleGeographicArea using the transformScreenToWgs method.

This centers the view precisely on the specified coordinates, positioning them at position of the cursor (which by default is in the center of the screen).

Map centering on coordinates at given screen position

To center on a different area of the viewport (not the position of the cursor), provide a Xy parameter. Note that x coordinate should be in [0, viewport.width] and y coordinate between [0, viewport.height].

The following example demonstrates how to center the map at one-third of its height:

auto widthPixels = mapView->getViewport().width;
auto heightPixels = mapView->getViewport().height;

mapView->centerOnCoordinates(
{ 52.48209, -2.48888 },
40,
{ widthPixels / 2, heightPixels / 3 }
);
Centered at one-third of map height
tip

More parameters such as animation, mapAngle, viewAngle and zoomLevel can be passed to the method in order to achieve a higher level of control.

Map centering on area

Centering can be done on a specific RectangleGeographicArea which consists of top left and bottom right coordinates.

auto topLeftCoords = Coordinates(44.93343, 25.09946);
auto bottomRightCoords = Coordinates(44.93324, 25.09987);
auto area = RectangleGeographicArea(topLeftCoords, bottomRightCoords);

mapView->centerOnArea(area);

This will center the view on the geographic area ensuring the RectangleGeographicArea covers most of the viewport. For centering the geographic area on a particular coordinate of the viewport, the xy parameter should be provided.

Alternatively, to center the RectangleGeographicArea method on a specific region of the viewport, you can use the specializedcenterOnArea method. This requires passing the viewRc parameter, represented as a RectType<int>, which defines the targeted region of the screen. The Rect passed to the viewRc parameter determines the positioning of the centered area relative to the top-left coordinates. Consequently, the top-right corner will be at left + Rectangle's width.

info

As the width and height of Rectangle decrease, the centering will result in a more zoomed-out view. For a more zoomed-in perspective, use larger values within the range [1, viewport.width - x] and [1, viewport.height - y].

tip

Use the getOptimalRoutesCenterViewport and getOptimalHighlightCenterViewport methods to compute the viewport region that best fits given routes and highlights.

Map centering on area with padding

Centering on an area using padding can be done with by altering the screen coordinates (in physical pixels) by adding/subtracting the padding value. Then a new RectangleGeographicArea object needs to be instantiated with the padded screen coordinates transformed into wgs coordinates using MapView::transformScreenToWgs(point).

The following code exemplifies the process:

// Getting the RectangleGeographicArea in which the route belongs
auto routeArea = route.getGeographicArea();
const auto paddingPixels = 200;

// Getting the top left point screen coordinates in physical pixels
auto routeAreaTopLeftPoint = mapView->transformWgsToScreen(routeArea.getTopLeft());

// Adding padding by shifting point in the top left
auto topLeftPadded = Xy(
routeAreaTopLeftPoint.x - paddingPixels,
routeAreaTopLeftPoint.y - paddingPixels
);

auto routeAreaBottomRightPoint = mapView->transformWgsToScreen(routeArea.getBottomRight());

// Adding padding by shifting point downwards three times the padding
auto bottomRightPadded = Xy(
routeAreaBottomRightPoint.x + paddingPixels,
routeAreaBottomRightPoint.y + 3 * paddingPixels
);

// Converting points with padding to wgs coordinates
auto paddedTopLeftCoordinate = mapView->transformScreenToWgs(topLeftPadded);
auto paddedBottomRightCoordinate = mapView->transformScreenToWgs(bottomRightPadded);

mapView->centerOnArea(RectangleGeographicArea(
paddedTopLeftCoordinate,
paddedBottomRightCoordinate
));
Route without padding
Route with center padding

Map zoom

This is done throughout setZoomLevel method of MapView class in the following way:

mapView->setZoomLevel(50);

To get the current zoom level use the getZoomLevel getter. A bigger value means the camera is closer to the terrain.

The maximum and minimum allowed zoom levels can be accessed via the getMaxZoomLevel and getMinZoomLevel getters from the MapView class. This class also provides setters for these limits. In order to check if a particular zoom level can be applied, use the canZoom method.

Map rotation angle

This is done throughout setRotationAngle setter of MapViewPreferences inside of MapView like so:

mapView->preferences().setRotationAngle( 45 );

The provided value needs to be between 0 and 360. By default, the camera has a rotation angle value of 0 degrees corresponding to the north-up alignment. Note that the rotation axis is always perpendicular to the ground and passes through the camera, regardless of the current camera orientation.

Map view angle

The camera can transform the flat 2D map into a 3D perspective, allowing you to view features like distant roads appearing on the horizon. By default, the camera has a top-down perspective (viewAngle = 90°).

In addition to adjusting the camera's view angle, you can modify its tilt angle. The tiltAngle is defined as the complement of the viewAngle, calculated as tiltAngle = 90-viewAngle

In order to change the view angle of camera you need to access the preferences field of MapView like so:

mapView->preferences().setViewAngle( 60 );
Map with a view angle of 60 degrees
Map with a view angle of 0 degrees

To adjust the camera's perspective dynamically, you can utilize both the setTiltAngle and setViewAngle properties.

The difference between the different types of angles is shown below:

Tilt angle & view angle
Rotation angle

Note

Keep in mind that adjusting the rotation value produces different outcomes depending on the camera's tilt. When the camera is tilted, changing the rotation will shift the target location, whereas with no tilt, the target location remains fixed.

Map perspective

Map perspective can be either two dimensional or three dimensional and can also be set by using MapViewPreferences method setMapViewPerspective:

mapView->preferences().setMapViewPerspective(EMapViewPerspective::MVP_3D);

By default, the map perspective is two-dimensional.

Map with a two-dimensional perspective
Map with a three-dimensional perspective

A three-dimensional perspective gives buildings a realistic, 3D appearance, while a two-dimensional perspective makes them appear as flat shapes.

note

To ensure three-dimensional buildings are visible, the camera angle should not be perpendicular to the map. Instead, the view angle must be less than 90 degrees.

The same effect can be implemented more precisely using the setTiltAngle/setViewAngle setters.

Buildings visibility

Buildings visibility can be controlled using the buildingsVisibility getter/setter from the MapViewPreferences class:

  • BV_Default: Uses the default visibility defined in the map style.
  • BV_Hide: Hides all buildings.
  • BV_2D: Displays buildings as flat 2D polygons without height.
  • BV_3D: Displays buildings as 3D polygons with height.
mapView->preferences().setBuildingsVisibility( EBuildingsVisibility::BV_2D );

Buildings become visible when the camera is zoomed in close to the ground. The 3D effect is most noticeable when viewed from a tilted angle. Note that the 3D buildings do not reflect realistic or accurate heights.

Store and restore a view

The map camera object has getters and setters for position and orientation ensuring a high level of control over the map view.

For storing a particular view the cameraState getter can be used. This member returns a DataBuffer object and depending on the usecase this can be stored inside a variable or serialized in a file.

auto state = mapView->getCamera()->getCameraState();

Restoring a saved view can be done easily using the cameraState setter:

mapView->getCamera()->setCameraState( state );

Alternatively the position and orientation can be stored and restored separately using the provided getters and setters.

Note

Please note that cameraState does not contain information about the current style.

Download individual map tiles

A map tile is a small, rectangular image or data chunk that represents a specific geographic area at a particular zoom level on a MapView object. Tiles are usually downloaded when panning or zooming in on a map, and they are used to render the map's visual content. However, you can also download tiles that are not currently visible on the screen, using the MapDownloaderService class.

Configuring the MapDownloaderService

The service can be configured by setting specific maximum area size in square kilometers to download by using the setMaxSquareKm setter:

auto service = MapDownloaderService::produce();

// Set a new value
service->setMaxSquareKm( 100 );

// Verify the new value
int updatedMaxSquareKm = service->getMaxSquareKm();

The larger the area, the more tiles can be downloaded, which can lead to increased memory usage. The default value is 1000 square kilometers.

warning

If the RectangleGeographicArea surface exceeds the MaxSquareKm, the MapDownloaderService will return error::KOutOfRange.

Downloading tiles is done by calling the startDownload method of MapDownloaderService like so:

auto service = MapDownloaderService::produce();
ProgressListener yourProgressListenerImpl;

service->setMaxSquareKm( 300 );

service->startDownload(
{
// Area in which the tiles will be downloaded that is under 300 square kilometers
RectangleGeographicArea(
Coordinates(67.69866, 24.81115),
Coordinates(67.58326, 25.36093))
},
yourProgressListenerImpl );

When tiles are downloaded, the notifyComplete callback of the supplied progress listener implementation is invoked with a gem::error parameter indicating the success or failure of the operation. If the download is successful, the error will be gem::KNoError. Downloaded tiles are stored in the cache and can be used later for features such as viewing map content, searchAlongRoute, searchAroundPosition, searchInArea without requiring an internet connection.

Downloaded tiles centered in the middle, top and bottom tiles are not available
Note

SearchService().search method will return error::KInvalidInput when trying to search in a downloaded tiles area as it requires indexing, which is not available for downloaded tiles.

Download can be canceled by calling the cancelDownload method of MapDownloaderService and the notifyComplete callback will be invoked with error::KCancel.

tip

Trying to download previously downloaded tiles will not result in a error::KUpToDate, as downloaded tiles are present inside the Data/Temporary/Tiles folder of your application folder as .dat1 files.

You can access detailed download statistics for map tiles using the getTransferStatistics method.

warning

Downloaded map tiles via MapDownloaderService do not support operations such as free-text search, routing, or turn-by-turn navigation while offline. They are primarily intended for caching map data for visual display purposes only.

For full offline functionality, including search and navigation, refer to the Manage Offline Content Guide to learn how to download roadmap data designed for full offline use.

Change map settings while following the current position

The FollowPositionPreferences class provides more customization while the camera in the follow position mode. To retrieve an instance, use the snippet below:

auto preferences = mapView->preferences().followPositionPreferences();

See the customize follow position settings guide for more details.