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