The camera
Contents
The camera is how the user views the map. It can be centered on a location, zoomed, rotated and moved. The camera can be set programmatically but also controlled through user interaction with gestures.
The CameraPositionModule
is used for creating a custom camera for the Map view. The module only keeps one reference to a camera object. Changing the settings for the CameraPositionModule
and calling build will replace the old camera you created. Configurations for iOS and Android for creating a map camera are different between platforms. To use the camera position, refer to the next section.
import React, { useEffect, useRef, findNodeHandle } from "react"
// import NativeModules
import { Dimensions, NativeModules, PixelRatio, Platform, StyleSheet} from "react-native"
import { MapViewManager } from "./MapViewManager"
// get CameraPositionModule
const CameraPositionModule = NativeModules.CameraPositionModule;
export const ExampleView = () => {
...
const buildCamera = async () => {
if (Platform.OS === "android") {
// create location with lat lng values
await CameraPositionModule.latLng(40.609028, -97.738000);
// set the center location of map to be the newly created location above
await CameraPositionModule.target();
await CameraPositionModule.zoom(2.5);
} else if (Platform.OS === "ios") {
await CameraPositionModule.latLng(40.609028, -97.738000);
await CameraPositionModule.target();
// set the altitude(meters) of the camera
await CameraPositionModule.altitude(1e4);
}
await CameraPositionModule.build();
}
...
}
Calling native map view functions
MapViewModule
is used to manage the created map views and to call native functions to modify the map. Modifying the map requires that the map is loaded first. In order to call functions for a map, you identify which map view you are using.
Setting the map camera after MapViewInitialized event
import React, { useEffect, useRef, findNodeHandle } from "react";
import {
Dimensions,
// add NativeEventEmitter
NativeEventEmitter,
NativeModules,
PixelRatio,
Platform,
StyleSheet} from "react-native"
import { MapViewManager } from "./MapViewManager";
const CameraPositionModule = NativeModules.CameraPositionModule;
// get MapViewModule
const MapViewModule = NativeModules.MapViewModule;
export const ExampleView = () => {
const iosMapViewTag = 123; // iOS mapView tag
const ref = useRef(null);
useEffect(() => {
// tag for android
const androidMapViewTag = findNodeHandle(ref.current);
if (Platform.OS === "android") {
const eventEmitter = new NativeEventEmitter();
// listen for map loaded event for android
let eventListener = eventEmitter.addListener(
"MapViewInitialized",
(event) => {
MapViewModule.getMapAsync(() => {
// setting map camera for android
setMapCamera(androidMapViewTag);
});
}
);
}
}, []);
// callback for map loaded event for iOS
const onMapLoaded = () => {
// setting map camera for iOS
setMapCamera(iosMapViewTag);
}
const buildCamera = async () => {
...
}
const setMapCamera = async (mapViewTag) => {
// add map view with unique integer tag to the module and set it
// as the current one we are modifying
await MapViewModule.setMapView(mapViewTag);
await buildCamera(); // configure and create camera
await MapViewModule.zoomPosition(); // apply camera
// remove reference to map view in the module after modifying map
await MapViewModule.releaseMap(mapViewTag);
}
// view styles
...
return <View style={styles.container}>
<MapViewManager
ref={ref} // for android to get tag
tag={tag} // for iOS to set tag
style={Platform.OS === "android" ? styles.androidStyle : styles.iosStyle}
onMapLoaded={onMapLoaded} // set mapLoaded callback for iOS
/>
</View>
}
Alternatively, for iOS you can use the functions directly in MapViewModule
instead of building a camera.
// imports
...
export const ExampleView = () => {
const iosMapViewTag = 123; // iOS mapView tag
const ref = useRef(null);
useEffect(() => {
...
}, []);
// callback for map loaded event for iOS
const onMapLoaded = async () => {
// finds map view with Tag mapViewTag
await MapViewModule.setMapView(iosMapViewTag);
await MapViewModule.setCenterCoordinateAndZoom(
40.609028, // lat
-97.738000, // lon
13, // zoom level (0-20)
true // animated
);
await MapViewModule.releaseMap();
}
return <View style={styles.container}>
<MapViewManager
ref={ref} // for android to get tag
tag={tag} // for iOS to set tag
style={Platform.OS === "android" ? styles.androidStyle : styles.iosStyle}
onMapLoaded={onMapLoaded} // set mapLoaded callback for iOS
/>
</View>
}