Working with Maps and Location
1. Integrating React Native Maps
Example: Basic Map Integration
import React from 'react';
import { StyleSheet, View } from 'react-native';
import MapView from 'react-native-maps';
const MapScreen = () => {
return (
<View style={styles.container}>
<MapView
style={styles.map}
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
map: {
flex: 1,
},
});
export default MapScreen;
| Property | Description | Default |
|---|---|---|
| initialRegion | Initial map region to display | null |
| showsUserLocation | Whether to show the user's location | false |
| showsMyLocationButton | Whether to show the "My Location" button | true |
| mapType | Map style (standard, satellite, hybrid) | standard |
Note: You need to install
react-native-maps and configure it for your platform (iOS/Android) before using it.
2. Displaying User Location
| Property | Description | Example |
|---|---|---|
| latitude | Latitude coordinate of the user's location | 37.7749 |
| longitude | Longitude coordinate of the user's location | -122.4194 |
| accuracy | Accuracy of the location in meters | 5.0 |
| timestamp | Time when the location was acquired | 1678886400000 |
Example: Displaying User Location on a Map
import React, { useState, useEffect } from 'react';
import { MapView } from 'react-native-maps';
const UserLocationMap = () => {
const [userLocation, setUserLocation] = useState(null);
useEffect(() => {
navigator.geolocation.getCurrentPosition(
(position) => {
setUserLocation({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
});
},
(error) => console.log(error),
{ enableHighAccuracy: true, timeout: 15000, maximumAge: 60000 }
);
}, []);
return (
<MapView
style={{ flex: 1 }}
initialRegion={{
latitude: userLocation?.latitude || 37.7749,
longitude: userLocation?.longitude || -122.4194,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
>
{userLocation && (
<MapView.Marker
coordinate={userLocation}
title="Your Location"
/>
)}
</MapView>
);
};
export default UserLocationMap;
Note: Ensure that you have added the necessary permissions in your app's configuration to access location services.
3. Adding Map Markers
Example: Basic Marker with Title
import { Marker } from 'react-native-maps';
<MapView style={styles.map}>
<Marker
coordinate={{ latitude: 37.78825, longitude: -122.4324 }}
title="Golden Gate Bridge"
description="San Francisco landmark"
/>
</MapView>
| Property | Values | Description |
|---|---|---|
| coordinate | { latitude: number, longitude: number } |
Position of the marker on the map |
| title | string |
Marker title (shown on tap) |
| description | string |
Additional description text (optional) |
| pinColor | string |
Custom color for the marker pin (e.g., "#FF0000") |
| calloutOffset | { x: number, y: number } |
Offset of the callout bubble |
Note: The
coordinate property is required for all markers.Example: Custom Marker Icon
import { Marker } from 'react-native-maps';
<Marker
coordinate={{ latitude: 37.78825, longitude: -122.4324 }}
image={require('./assets/custom-marker.png')}
anchor={{ x: 0.5, y: 1 }}
/>
| Property | Values | Description |
|---|---|---|
| image | ImageSourcePropType |
Custom image to use as marker icon |
| anchor | { x: number, y: number } |
Adjusts the anchor point of the marker (default is center) |
| flat | boolean |
If true, marker is not affected by 3D perspective |
4. Drawing Polylines and Polygons
Example: Drawing a Polyline on a Map
import { Polyline } from 'react-native-maps';
<MapView style={styles.map}>
<Polyline
coordinates={[
{ latitude: 37.78825, longitude: -122.4324 },
{ latitude: 37.7885, longitude: -122.4326 },
{ latitude: 37.78875, longitude: -122.4328 },
]}
strokeColor="#000"
strokeWidth={6}
/>
</MapView>
| Property | Description | Default | Notes |
|---|---|---|---|
| coordinates | List of latitude/longitude points | Required | Array of objects with latitude and longitude |
| strokeColor | Color of the polyline | #000 |
Supports hex, rgb, rgba |
| strokeWidth | Thickness of the line in pixels | 1 |
Minimum is 1px |
| lineCap | End cap style of the line | butt |
Options: butt, round, square |
| lineJoin | Join style of the line | miter |
Options: miter, round, bevel |
| geodesic | Draws a geodesic line (true curvature) | false |
Use for accurate long-distance lines |
Example: Drawing a Polygon
import { Polygon } from 'react-native-maps';
<MapView style={styles.map}>
<Polygon
coordinates={[
{ latitude: 37.78825, longitude: -122.4324 },
{ latitude: 37.7885, longitude: -122.4326 },
{ latitude: 37.78875, longitude: -122.4328 },
{ latitude: 37.7885, longitude: -122.433 },
]}
strokeColor="#000"
strokeWidth={2}
fillColor="rgba(255,0,0,0.3)"
/>
</MapView>
| Property | Description | Default | Notes |
|---|---|---|---|
| coordinates | List of latitude/longitude points | Required | Array of objects with latitude and longitude |
| strokeColor | Outline color of the polygon | #000 |
Supports hex, rgb, rgba |
| strokeWidth | Thickness of the outline in pixels | 1 |
Minimum is 1px |
| fillColor | Fill color of the polygon | transparent |
Supports hex, rgb, rgba |
| editable | Allows editing of polygon points (iOS only) | false |
Requires editable to be true |
Note: Polygons and polylines are drawn using the MapView component. They do not support touch events or interaction directly.
5. Implementing Geofencing
Example: Setting up a Geofence
import { Geolocation } from 'react-native';
const region = {
latitude: 37.7849,
longitude: -122.409,
latitudeDelta: 0.01,
longitudeDelta: 0.01,
};
const geofence = {
latitude: 37.7849,
longitude: -122.409,
radius: 500, // meters
};
const watchId = Geolocation.watchPosition(
(position) => {
const { latitude, longitude } = position.coords;
const distance = calculateDistance(
latitude,
longitude,
geofence.latitude,
geofence.longitude
);
if (distance <= geofence.radius) {
console.log("Entered geofenced area");
} else {
console.log("Exited geofenced area");
}
},
(error) => console.log("Geofence error:", error),
{ enableHighAccuracy: true, distanceFilter: 10 }
);
function calculateDistance(lat1, lon1, lat2, lon2) {
const R = 6371e3; // Earth radius in meters
const φ1 = lat1 * Math.PI/180;
const φ2 = lat2 * Math.PI/180;
const Δφ = (lat2-lat1) * Math.PI/180;
const Δλ = (lon2-lon1) * Math.PI/180;
const a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +
Math.cos(φ1) * Math.cos(φ2) *
Math.sin(Δλ/2) * Math.sin(Δλ/2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c;
}
| Property | Description | Values | Notes |
|---|---|---|---|
| latitude | Latitude of the center point | number |
Required |
| longitude | Longitude of the center point | number |
Required |
| radius | Radius of the geofence in meters | number |
Required |
| watchId | ID returned by watchPosition |
number |
Used to stop watching |
Note: Geofencing requires location permissions and may have accuracy limitations depending on device hardware.
Warning: Frequent position updates can drain battery life. Consider using
distanceFilter to limit how often position changes are reported.
Geofencing Workflow
- Define a circular region with center coordinates and radius
- Use
Geolocation.watchPositionto monitor location changes - Calculate distance between current position and geofence center
- Trigger actions when the device enters or exits the region
6. Calculating Distance Between Coordinates
| Method | Description | Parameters | Notes |
|---|---|---|---|
| getDistanceFromLatLonInKm | Calculates the distance between two sets of latitude and longitude coordinates in kilometers. | lat1, lon1, lat2, lon2 |
Uses the Haversine formula for accurate calculation. |
| getDistanceFromLatLonInMiles | Calculates the distance between two sets of latitude and longitude coordinates in miles. | lat1, lon1, lat2, lon2 |
Uses the Haversine formula for accurate calculation. |
Example: Calculating Distance in Kilometers
const getDistanceFromLatLonInKm = (lat1, lon1, lat2, lon2) => {
const R = 6371; // Earth radius in km
const dLat = deg2rad(lat2 - lat1);
const dLon = deg2rad(lon2 - lon1);
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
const d = R * c;
return d;
};
const deg2rad = (deg) => {
return deg * (Math.PI / 180);
};
// Example usage:
const distance = getDistanceFromLatLonInKm(51.5074, -0.1278, 40.7128, -74.0060);
console.log(distance); // Distance between London and New York in km
Example: Calculating Distance in Miles
const getDistanceFromLatLonInMiles = (lat1, lon1, lat2, lon2) => {
const R = 3959; // Earth radius in miles
const dLat = deg2rad(lat2 - lat1);
const dLon = deg2rad(lon2 - lon1);
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
const d = R * c;
return d;
};
const deg2rad = (deg) => {
return deg * (Math.PI / 180);
};
// Example usage:
const distance = getDistanceFromLatLonInMiles(51.5074, -0.1278, 40.7128, -74.0060);
console.log(distance); // Distance between London and New York in miles
7. Geocoding Addresses
| Property | Description | Example |
|---|---|---|
| address | Full address string to geocode | "1600 Amphitheatre Parkway, Mountain View, CA" |
| latitude | Latitude coordinate returned from geocoding | 37.4223 |
| longitude | Longitude coordinate returned from geocoding | -122.0856 |
Example: Geocoding an Address
import Geocoder from 'react-native-geocoder';
const address = '1600 Amphitheatre Parkway, Mountain View, CA';
Geocoder.geocodeAddress(address)
.then(res => {
const { latitude, longitude } = res[0].position;
console.log(`Latitude: ${latitude}, Longitude: ${longitude}`);
})
.catch(err => console.log(err));
Note: Geocoding requires an internet connection and a valid API key for services like Google Maps.
8. Reverse Geocoding
| Property | Description | Example |
|---|---|---|
| latitude | Latitude coordinate of the location | 37.7749 |
| longitude | Longitude coordinate of the location | -122.4194 |
Example: Using Geocoder Library
import Geocoder from 'react-native-geocoder';
const location = {
latitude: 37.7749,
longitude: -122.4194
};
Geocoder.reverseGeocodePosition(location)
.then(results => {
console.log(results[0].formattedAddress);
})
.catch(error => {
console.error('Geocoding error:', error);
});
Note: Reverse geocoding requires internet access and may have rate limits depending on the service used.
9. Handling Location Updates
| Property | Description | Example |
|---|---|---|
| watchPosition() | Continuously monitors the device's location | watchPosition(successCallback, errorCallback, options) |
| clearWatch() | Stops monitoring location updates | clearWatch(watchId) |
Example: Watching Location Updates
import { Geolocation } from 'react-native';
const watchId = Geolocation.watchPosition(
(position) => {
console.log('Current position:', position);
},
(error) => {
console.log('Error watching position:', error);
},
{
enableHighAccuracy: true,
distanceFilter: 10,
interval: 5000,
}
);
// To stop watching:
// Geolocation.clearWatch(watchId);
Note: The
watchPosition method returns a watchId which is used to clear the watch later.
Warning: Continuous location tracking can drain the battery quickly. Always use
distanceFilter and interval to optimize performance.
10. Implementing Location-based Features
Example: Requesting Location Permissions
import { PermissionsAndroid, Platform } from 'react-native';
const requestLocationPermission = async () => {
if (Platform.OS === 'android') {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: 'Location Permission',
message: 'This app needs access to your location.',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK'
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('Location permission granted');
} else {
console.log('Location permission denied');
}
} catch (err) {
console.warn(err);
}
}
};
| Permission | Android | iOS | Description |
|---|---|---|---|
| ACCESS_FINE_LOCATION | true |
false |
Allows access to precise location data |
| ACCESS_COARSE_LOCATION | true |
false |
Allows access to approximate location |
Example: Getting Current Location
import { Geolocation } from 'react-native';
const getCurrentLocation = () => {
Geolocation.getCurrentPosition(
(position) => {
console.log('Current position:', position);
},
(error) => {
console.log('Error getting location:', error);
},
{ enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 }
);
};
| Option | Values | Description |
|---|---|---|
| enableHighAccuracy | true, false |
Use GPS or other high-accuracy methods |
| timeout | number |
Maximum time (ms) to wait for location |
| maximumAge | number |
Maximum age (ms) of cached location to use |
Example: Watching Position Changes
import { Geolocation } from 'react-native';
const watchPosition = () => {
const watchId = Geolocation.watchPosition(
(position) => {
console.log('Updated position:', position);
},
(error) => {
console.log('Error watching position:', error);
},
{ distanceFilter: 10, interval: 5000 }
);
return watchId; // Used to stop watching
};
| Option | Values | Description |
|---|---|---|
| distanceFilter | number |
Minimum distance (m) to trigger update |
| interval | number |
Minimum time (ms) between updates |
Note: On iOS, location permissions require adding
NSLocationWhenInUseUsageDescription or NSLocationAlwaysAndWhenInUseUsageDescription to Info.plist.
Warning: Frequent location updates can drain battery quickly. Always stop watching position when no longer needed.