Skip to main content

Overview

The camera attached to the MapScene defines the section of the map that is rendered when a frame is drawn. It controls the viewport, handles user interactions, and provides methods for programmatic navigation.
The camera is your primary tool for controlling what users see on the map.

Camera Concepts

The camera system in Open Mobile Maps SDK supports both 2D orthographic projection and 3D perspective projection:
  • 2D Camera: Simple orthographic view moving in the x/y plane
  • 3D Camera: Perspective view with pitch and rotation capabilities

MapCameraInterface

The MapCameraInterface provides the core camera functionality:
class MapCameraInterface {
public:
    // Creation
    static std::shared_ptr<MapCameraInterface> create(
        const std::shared_ptr<MapInterface> & mapInterface,
        float screenDensityPpi,
        bool is3D
    );
    
    // Position and movement
    virtual void moveToCenterPosition(const Coord & centerPosition, bool animated);
    virtual void moveToCenterPositionZoom(const Coord & centerPosition, 
                                          double zoom, bool animated);
    virtual void moveToBoundingBox(const RectCoord & boundingBox, 
                                   float paddingPc, bool animated,
                                   std::optional<double> minZoom,
                                   std::optional<double> maxZoom);
    
    virtual Coord getCenterPosition();
    
    // Zoom
    virtual void setZoom(double zoom, bool animated);
    virtual double getZoom();
    virtual void setMinZoom(double minZoom);
    virtual void setMaxZoom(double maxZoom);
    
    // Rotation
    virtual void setRotation(float angle, bool animated);
    virtual float getRotation();
    
    // Bounds
    virtual void setBounds(const RectCoord & bounds);
    virtual RectCoord getBounds();
    virtual RectCoord getVisibleRect();
    
    // ...
};

Creating a Camera

// Create a 2D camera
auto camera = MapCameraInterface::create(
    mapInterface,
    screenDensityPpi,
    false  // is3D
);

mapInterface->setCamera(camera);
// Create a 3D camera
auto camera = MapCameraInterface::create(
    mapInterface,
    screenDensityPpi,
    true  // is3D
);

mapInterface->setCamera(camera);

Camera Movement

Move to Position

Move the camera to a specific coordinate:
// Move to Zurich, Switzerland (EPSG:4326)
Coord zurich(
    CoordinateSystemIdentifiers::EPSG4326(),
    8.5417,  // longitude
    47.3769, // latitude
    0.0
);

// Move without animation
camera->moveToCenterPosition(zurich, false);

// Move with animation
camera->moveToCenterPosition(zurich, true);

Move to Position with Zoom

// Move to position and set zoom level simultaneously
camera->moveToCenterPositionZoom(zurich, 14.0, true);

Fit Bounding Box

Move the camera to fit a bounding box in view:
RectCoord boundingBox(
    Coord(systemId, minX, minY, 0.0),
    Coord(systemId, maxX, maxY, 0.0)
);

// Fit with 10% padding
camera->moveToBoundingBox(
    boundingBox,
    0.1f,          // paddingPc (10%)
    true,          // animated
    std::nullopt,  // minZoom (optional)
    std::nullopt   // maxZoom (optional)
);
The paddingPc parameter adds padding as a percentage, where 1.0 = half of the viewport width/height.

Zoom Control

Setting Zoom

// Set zoom level
camera->setZoom(12.0, true);  // animated

// Get current zoom
double currentZoom = camera->getZoom();

Zoom Constraints

// Set minimum zoom level
camera->setMinZoom(5.0);

// Set maximum zoom level
camera->setMaxZoom(18.0);

// Get constraints
double minZoom = camera->getMinZoom();
double maxZoom = camera->getMaxZoom();
Zoom levels typically range from 0 (world view) to 20+ (street level), matching standard web map zoom conventions.

Rotation

// Rotate map (angle in radians)
camera->setRotation(M_PI / 4, true);  // 45 degrees, animated

// Get current rotation
float rotation = camera->getRotation();

// Enable/disable rotation by user
camera->setRotationEnabled(true);

// Enable snap to north (auto-rotate to 0 when close)
camera->setSnapToNorthEnabled(true);

Camera Bounds

Setting Bounds

Restrict where the camera can move:
// Define bounds in map coordinates
RectCoord mapBounds(
    Coord(systemId, minX, minY, 0.0),
    Coord(systemId, maxX, maxY, 0.0)
);

camera->setBounds(mapBounds);

// Get current bounds
RectCoord bounds = camera->getBounds();

// Check if coordinate is in bounds
bool inBounds = camera->isInBounds(someCoord);

Visible Rectangle

// Get currently visible area
RectCoord visibleRect = camera->getVisibleRect();

// Get visible area adjusted for padding
RectCoord paddedRect = camera->getPaddingAdjustedVisibleRect();

Camera Padding

Add padding to camera edges (useful for UI overlays):
// Add padding (in pixels)
camera->setPaddingLeft(50.0f);
camera->setPaddingRight(50.0f);
camera->setPaddingTop(100.0f);
camera->setPaddingBottom(80.0f);
Padding shifts the effective center of the camera, ensuring important content isn’t hidden under UI elements.

Coordinate Conversion

Convert between screen positions and map coordinates:
// Convert screen position to map coordinate
Vec2F screenPos(100.0f, 200.0f);
Coord mapCoord = camera->coordFromScreenPosition(screenPos);

// Convert at specific zoom level
Coord mapCoordAtZoom = camera->coordFromScreenPositionZoom(screenPos, 15.0);

// Convert map coordinate to screen position
Vec2F screenPosition = camera->screenPosFromCoord(mapCoord);

// Convert at specific zoom level
Vec2F screenPosAtZoom = camera->screenPosFromCoordZoom(mapCoord, 15.0);

Distance Conversion

// Convert pixel distance to map units
double mapUnits = camera->mapUnitsFromPixels(100.0);  // 100 pixels

// Get current scaling factor
double scalingFactor = camera->getScalingFactor();

Visibility Testing

// Check if coordinate is visible on screen
bool isVisible = camera->coordIsVisibleOnScreen(
    coordinate,
    0.1f  // paddingPc (10% padding)
);

MapCamera3dInterface

For 3D cameras, additional configuration is available:
auto camera3d = camera->asMapCamera3d();
if (camera3d) {
    // Get current 3D configuration
    Camera3dConfig config = camera3d->getCameraConfig();
    
    // Set new configuration
    Camera3dConfig newConfig;
    newConfig.key = "aerial";
    newConfig.allowUserInteraction = true;
    newConfig.minZoom = 10.0f;
    newConfig.maxZoom = 18.0f;
    newConfig.animationDurationMs = 500;
    
    camera3d->setCameraConfig(
        newConfig,
        std::optional<float>(1.0f),      // duration in seconds
        std::optional<float>(15.0f),     // target zoom
        std::optional<Coord>(targetPos)  // target coordinate
    );
}

Camera3dConfig

struct Camera3dConfig {
    std::string key;
    bool allowUserInteraction;
    std::optional<float> rotationSpeed;
    int32_t animationDurationMs;
    float minZoom;
    float maxZoom;
    CameraInterpolation pitchInterpolationValues;
    CameraInterpolation verticalDisplacementInterpolationValues;
};
pitchInterpolationValues
CameraInterpolation
Controls camera tilt based on zoom level
verticalDisplacementInterpolationValues
CameraInterpolation
Vertical camera displacement in the viewport, range [-1.0, 1.0]

Camera Listeners

Listen to camera changes:
class MyCameraListener : public MapCameraListenerInterface {
public:
    void onCameraChanged() override {
        // Camera position or zoom changed
    }
    
    void onBoundsChanged() override {
        // Camera bounds changed
    }
};

auto listener = std::make_shared<MyCameraListener>();
camera->addListener(listener);

// Remove listener when done
camera->removeListener(listener);

Touch Interaction

The camera integrates with the touch handler for gesture recognition:
// The camera interprets touch events passed by the TouchHandler
// Default gestures include:
// - Pan: Move the camera
// - Pinch: Zoom in/out
// - Rotate: Rotate the map (if enabled)
// - Double-tap: Zoom in
The Maps Core includes a DefaultTouchHandler that recognizes standard gestures.

Freeze Camera

Temporarily disable camera updates:
// Freeze camera (ignores all movement commands)
camera->freeze(true);

// Unfreeze
camera->freeze(false);
When frozen, the camera ignores all movement commands, including programmatic ones.

Advanced: View Projection Matrix

Access the camera’s view-projection matrix:
// Get VP matrix (double precision)
auto vpMatrixD = camera->getLastVpMatrixD();

// Get VP matrix (float precision)
auto vpMatrix = camera->getLastVpMatrix();

// Get inverse VP matrix
auto inverseVpMatrix = camera->getLastInverseVpMatrix();

// Get view bounds from last VP matrix
auto viewBounds = camera->getLastVpMatrixViewBounds();

// Get rotation from last VP matrix
auto rotation = camera->getLastVpMatrixRotation();

// Get zoom from last VP matrix
auto zoom = camera->getLastVpMatrixZoom();

Best Practices

Use animated movements for better user experience. Set animated to true for position, zoom, and rotation changes.
Set appropriate bounds to prevent users from panning to empty areas. Use setBoundsRestrictWholeVisibleRect(true) to keep the entire visible area within bounds.
Configure min/max zoom based on your data. Prevent zooming too far in (where there’s no data) or too far out (where content is too small).
Cache coordinate conversions when possible. Converting coordinates repeatedly in update loops can impact performance.

Platform Examples

// Create and configure camera
val camera = MapCameraInterface.create(
    mapInterface,
    resources.displayMetrics.densityDpi.toFloat(),
    false
)

mapInterface.camera = camera

// Move to location with zoom
val zurich = Coord(
    CoordinateSystemIdentifiers.EPSG4326(),
    8.5417,
    47.3769,
    0.0
)

camera.moveToCenterPositionZoom(zurich, 14.0, true)

// Set zoom limits
camera.minZoom = 5.0
camera.maxZoom = 18.0

// Add padding for UI
camera.setPaddingTop(100f)
camera.setPaddingBottom(80f)

Architecture

Understand the SDK structure

Coordinate Systems

Learn about coordinate systems

Layers

Control layer visibility with the camera

Build docs developers (and LLMs) love