Skip to main content
The CustomLocationProvider component allows you to override the native location services and provide custom location data to the map. This is useful for testing, simulation, or using alternative location sources.

Basic Usage

import { MapView, CustomLocationProvider, LocationPuck } from '@rnmapbox/maps';

<MapView>
  <CustomLocationProvider 
    coordinate={[-122.4194, 37.7749]}
    heading={45}
  >
    <LocationPuck visible={true} />
  </CustomLocationProvider>
</MapView>

Props

coordinate
Position
Longitude and latitude coordinates to use for the custom location provider. This position will be applied to any LocationPuck component within the provider.Format: [longitude, latitude]
<CustomLocationProvider 
  coordinate={[-122.4194, 37.7749]}
/>
heading
number
Heading/bearing value (in degrees) to use for the custom location provider. This will be applied to the LocationPuck component.Range: 0-360 degrees, where:
  • 0° = North
  • 90° = East
  • 180° = South
  • 270° = West
<CustomLocationProvider 
  coordinate={[-122.4194, 37.7749]}
  heading={45}  // Northeast
/>

Types

Position

type Position = [longitude: number, latitude: number]
A tuple containing longitude and latitude coordinates.
longitude
number
required
The longitude coordinate (first element in the array).Range: -180 to 180
latitude
number
required
The latitude coordinate (second element in the array).Range: -90 to 90

Examples

Basic Custom Location

import { MapView, CustomLocationProvider, LocationPuck } from '@rnmapbox/maps';

function MyMap() {
  return (
    <MapView>
      <CustomLocationProvider 
        coordinate={[-122.4194, 37.7749]}  // San Francisco
      >
        <LocationPuck visible={true} />
      </CustomLocationProvider>
    </MapView>
  );
}

With Heading

import { MapView, CustomLocationProvider, LocationPuck } from '@rnmapbox/maps';

function MyMap() {
  return (
    <MapView>
      <CustomLocationProvider 
        coordinate={[-73.9857, 40.7484]}  // New York
        heading={90}  // Facing East
      >
        <LocationPuck 
          puckBearing="heading"
          puckBearingEnabled={true}
        />
      </CustomLocationProvider>
    </MapView>
  );
}

Animated Location Updates

import { MapView, CustomLocationProvider, LocationPuck } from '@rnmapbox/maps';
import { useState, useEffect } from 'react';

function MyMap() {
  const [position, setPosition] = useState<[number, number]>([
    -122.4194, 37.7749
  ]);
  const [heading, setHeading] = useState(0);
  
  useEffect(() => {
    const interval = setInterval(() => {
      // Simulate movement
      setPosition(([lng, lat]) => [
        lng + 0.001,
        lat + 0.001
      ]);
      
      // Rotate heading
      setHeading((prev) => (prev + 10) % 360);
    }, 1000);
    
    return () => clearInterval(interval);
  }, []);
  
  return (
    <MapView>
      <CustomLocationProvider 
        coordinate={position}
        heading={heading}
      >
        <LocationPuck 
          puckBearing="heading"
          puckBearingEnabled={true}
        />
      </CustomLocationProvider>
    </MapView>
  );
}

Route Playback

import { MapView, CustomLocationProvider, LocationPuck } from '@rnmapbox/maps';
import { useState, useEffect } from 'react';

const route = [
  [-122.4194, 37.7749],
  [-122.4184, 37.7759],
  [-122.4174, 37.7769],
  // ... more coordinates
];

function RoutePlayback() {
  const [currentIndex, setCurrentIndex] = useState(0);
  
  useEffect(() => {
    const interval = setInterval(() => {
      setCurrentIndex((prev) => (prev + 1) % route.length);
    }, 1000);
    
    return () => clearInterval(interval);
  }, []);
  
  return (
    <MapView>
      <CustomLocationProvider 
        coordinate={route[currentIndex]}
      >
        <LocationPuck visible={true} />
      </CustomLocationProvider>
    </MapView>
  );
}

Testing Location Features

import { MapView, CustomLocationProvider, LocationPuck } from '@rnmapbox/maps';
import { useState } from 'react';

function LocationTest() {
  const [testLocation, setTestLocation] = useState<[number, number]>([
    -122.4194, 37.7749
  ]);
  
  const testLocations = {
    sanFrancisco: [-122.4194, 37.7749],
    newYork: [-73.9857, 40.7484],
    london: [-0.1278, 51.5074],
    tokyo: [139.6917, 35.6895],
  };
  
  return (
    <>
      <MapView>
        <CustomLocationProvider coordinate={testLocation}>
          <LocationPuck visible={true} />
        </CustomLocationProvider>
      </MapView>
      
      <View>
        <Button 
          title="San Francisco" 
          onPress={() => setTestLocation(testLocations.sanFrancisco)}
        />
        <Button 
          title="New York" 
          onPress={() => setTestLocation(testLocations.newYork)}
        />
        <Button 
          title="London" 
          onPress={() => setTestLocation(testLocations.london)}
        />
        <Button 
          title="Tokyo" 
          onPress={() => setTestLocation(testLocations.tokyo)}
        />
      </View>
    </>
  );
}

With Camera Following

import { MapView, Camera, CustomLocationProvider, LocationPuck } from '@rnmapbox/maps';
import { useState } from 'react';

function MyMap() {
  const [location, setLocation] = useState<[number, number]>([
    -122.4194, 37.7749
  ]);
  
  return (
    <MapView>
      <Camera 
        centerCoordinate={location}
        zoomLevel={14}
        animationMode="flyTo"
        animationDuration={1000}
      />
      
      <CustomLocationProvider coordinate={location}>
        <LocationPuck visible={true} />
      </CustomLocationProvider>
    </MapView>
  );
}

Use Cases

Testing

Use CustomLocationProvider to test location-based features without requiring actual device movement:
if (__DEV__) {
  return (
    <CustomLocationProvider coordinate={testCoordinate}>
      <LocationPuck />
    </CustomLocationProvider>
  );
}

Simulation

Simulate GPS tracks or routes for demonstrations:
// Play back recorded GPS data
<CustomLocationProvider 
  coordinate={recordedTrack[currentIndex]}
  heading={recordedHeading[currentIndex]}
/>

Alternative Location Sources

Integrate with custom positioning systems (indoor positioning, etc.):
const indoorPosition = useIndoorPositioning();

<CustomLocationProvider 
  coordinate={[indoorPosition.lng, indoorPosition.lat]}
/>

Notes

  • The CustomLocationProvider overrides native location services only for components within its scope
  • You can use it in conjunction with UserLocation component, but LocationPuck is recommended
  • The provider does not emit location update events - it simply provides a static or controlled location
  • For real device location, use LocationPuck or UserLocation without a CustomLocationProvider

See Also

Build docs developers (and LLMs) love