Location and tracking
Contents
Request runtime permission
Declare location permissions in Getting started, then request runtime permission before rendering <UserLocation> or enabling trackUserLocation. Without granted permission, the map loads but the location puck does not appear.
On Android, request permission explicitly:
import { PermissionsAndroid, Platform } from "react-native";
async function requestLocationPermission(): Promise<boolean> {
if (Platform.OS !== "android") {
return true;
}
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
);
return granted === PermissionsAndroid.RESULTS.GRANTED;
}
On iOS, add the Info.plist usage-description keys from getting started. The system permission dialog appears when location is first accessed.
User location and follow-me
Add <UserLocation> as a child of <Map> to show the device location puck. Combine with <Camera trackUserLocation> to follow the user as they move:
import {
Camera,
Map,
TrimbleMaps,
UserLocation,
} from "@trimblemaps/maps-react-native";
import { useEffect, useState } from "react";
function FollowMe() {
const [locationReady, setLocationReady] = useState(false);
useEffect(() => {
requestLocationPermission().then(setLocationReady);
}, []);
if (!locationReady) {
return null;
}
return (
<Map mapStyle={TrimbleMaps.StyleURL.MobileDay} style={{ flex: 1 }}>
<Camera trackUserLocation="default" zoom={16} />
<UserLocation accuracy heading />
</Map>
);
}
Map press events
Handle taps on the map with the onPress prop. The event provides the tapped coordinate in GeoJSON order [longitude, latitude]:
import { Map, TrimbleMaps, type PressEvent } from "@trimblemaps/maps-react-native";
import { useState } from "react";
function ClickableMap() {
const [press, setPress] = useState<PressEvent | null>(null);
return (
<Map
mapStyle={TrimbleMaps.StyleURL.MobileDay}
style={{ flex: 1 }}
onPress={(event) => setPress(event.nativeEvent)}
/>
);
}
Access the coordinate with press.lngLat[0] (longitude) and press.lngLat[1] (latitude).
Cycling between locations
Use a Camera ref with flyTo to animate between preset locations:
const LOCATIONS = [
{ name: "Princeton", center: [-74.6672, 40.3573] as [number, number] },
{ name: "Richmond", center: [-77.436, 37.5407] as [number, number] },
];
cameraRef.current?.flyTo({
center: LOCATIONS[index].center,
zoom: 12,
duration: 600,
});