Skip to main content
Version: 5.0

Camera Controls

Using Mappedin SDK for Android with your own map requires an Enterprise license. Try a demo map for free or refer to the Pricing page for more information.

To create rich experiences on top of the Mappedin Android SDK, it's useful to be able to control the map view programmatically. This guide shows how to focus the map view on targets, how to listen to camera events and how to control the camera.

A complete class that uses the code snippet in this guide can be found in the Mappedin Android Github repo: CameraControls.kt

Focus the Camera on Targets

To focus on a polygon after it has been touched, we use the onPolygonClicked() function in the MPIMapViewListener. In this case, we are targeting only the touched polygon. However, we can also give coordinates or nodes as MPIOptions.CameraTargets.

override fun onPolygonClicked(polygon: MPINavigatable.MPIPolygon) {
mapView?.cameraManager?.focusOn(MPIOptions.CameraTargets(polygons = listOf(polygon)))
}

Listening to Camera Events

We can use the onCameraChanged() function in the MPICameraListener to monitor changes to the camera position, rotation, tilt, and zoom.

First, implement the interface on your existing class and assign the listener this. For more information on how to initialize your MPIMapView, read the Getting Started guide

class MyClass : AppCompatActivity(), MPIMapViewListener, MPICameraListener {
private var mapView: MPIMapView? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ... other setup
mapView?.cameraManager?.listener = this
}
}

The interface implements the onCameraChanged() function which passes in an MPICameraTransform whenever the camera moves. We can log the values within it to track the camera.

override fun onCameraChanged(cameraTransform: MPICameraTransform) {
Log.d("Position", cameraTransform.position.toString())
Log.d("Rotation", cameraTransform.rotation.toString())
Log.d("Tilt", cameraTransform.tilt.toString())
Log.d("Zoom", cameraTransform.zoom.toString())
}

Controlling the Camera

Controlling the camera to set it to a specific tilt, rotation or zoom can be done with mapView.cameraManager.set(). It takes either MPIOptions.CameraTransformNode or MPIOptions.CameraTransformCoordinate which take either an MPINavigatable.MPINode or MPIMap.MPICoordinate respectively as the position. Tilt and rotation are set as radians, where as zoom is in the camera distance in meters from the target.

mapView?.cameraManager?.set(
MPIOptions.CameraTransformNode(
zoom = 1234.0,
tilt = 0.3,
rotation = 1.5
)
)

// or

mapView?.cameraManager?.set(
MPIOptions.CameraTransformCoordinate(
zoom = 800.0,
position = mapView.currentMap?.createCoordinate(
43.519881426957596,
-80.53906704663625
)
)
)

It is possible to limit the tilting of the camera by listening to the change event and setting it to a desired value in onCameraChanged().

override fun onCameraChanged(cameraTransform: MPICameraTransform) {
val tilt = 0.0
if (cameraTransform.tilt != tilt) {
mapView?.cameraManager?.set(MPIOptions.CameraTransformNode(tilt = tilt))
}
}

If you want to be able to zoom in closer than the default limit, use the setter mapView?.cameraManager?.setMinZoom(zoomLevel = 200.0).

Animation

The camera can also be animated to zoom, tilt and rotate to a MPINode or MPIMap.MPICoordinate. This works similar to the set methods described in the Controlling the Camera section above but instead of jumping directly to a camera position, the camera moves gradually to the new position. The MPICameraManager.animate() methods are use to accomplish this.

Animating to the node of a location:

val zoomTarget = mapView.venueData?.locations?.first {
it.name == "Sunglass Hut" }

val cameraTransform = MPIOptions.CameraTransformNode(
zoom = 50.0, tilt = 2.0,
rotation = 180.0,
position = zoomTarget?.nodes?.first())

val cameraAnimation = MPIOptions.CameraAnimation(
duration = 3000.0, easing = MPIOptions.EASING_MODE.EASE_IN)

mapView.cameraManager.animate(cameraTransform, cameraAnimation)

Animating to latitude and longitude coordinates:

val zoomCoordinate = mapView?.currentMap?.createCoordinate(
latitude = 43.86147923972817,
longitude = -78.94671703394187)

val cameraTransform = MPIOptions.CameraTransformCoordinate(
zoom = 50.0, tilt = 2.0,
rotation = 180.0,
position = zoomCoordinate)

val cameraAnimation = MPIOptions.CameraAnimation(
duration = 3000.0,
easing = MPIOptions.EASING_MODE.EASE_IN)

mapView.cameraManager.animate(cameraTransform, cameraAnimation)

Reset Camera

To reset the camera, store the initial camera position in the onFirstMapLoaded() method. Then, at a later time these values can be used to reset the camera.

// Store the default camera values when the map is loaded.
override fun onFirstMapLoaded() {
defaultTilt = mapView.cameraManager.tilt
defaultZoom = mapView.cameraManager.zoom
defaultRotation = mapView.cameraManager.rotation
defaultPosition = mapView.cameraManager.position
}

// Use the default camera values to reposition the camera.
fun resetCamera() {
mapView.cameraManager.set(MPIOptions.CameraTransformCoordinate(
zoom = defaultZoom,
tilt = defaultTilt,
rotation = defaultRotation,
position = defaultPosition))
}

A complete class that uses the code snippet in this guide can be found in the Mappedin Android Github repo: CameraControls.kt