Skip to main content

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>
}
Last updated December 21, 2023.
Contents