rs-react-native-map-clustering
Version:
React Native Map Clustering both for Android and iOS with TypeScript support
299 lines (254 loc) • 11.3 kB
Markdown
# React Native Map Clustering



A powerful React Native module that elegantly handles map clustering with full TypeScript support.
Works seamlessly with **Expo** and **react-native-cli** 🚀
> This is a maintained fork of [react-native-map-clustering](https://github.com/venits/react-native-map-clustering) with SuperCluster v8.0.1 and complete TypeScript typings.
## 📋 Table of Contents
- [React Native Map Clustering](#react-native-map-clustering)
- [📋 Table of Contents](#-table-of-contents)
- [✨ Features](#-features)
- [📦 Installation](#-installation)
- [🚀 Quick Start](#-quick-start)
- [🔍 TypeScript Support](#-typescript-support)
- [⚙️ Props](#️-props)
- [📱 Examples](#-examples)
- [Animate Map to Region](#animate-map-to-region)
- [Custom Cluster Rendering](#custom-cluster-rendering)
- [🤝 Support](#-support)
- [Happy Coding! 💖🚀](#happy-coding-)
## ✨ Features
- **Fully typed** with comprehensive TypeScript declarations
- **High performance** clustering using SuperCluster v8.0.1
- **Customizable** markers, clusters, and animations
- **Spider mode** for elegant handling of overlapping markers
- **Optimized rendering** with minimal re-renders for smooth performance
- **Compatible** with both Expo and React Native CLI
- **Cross-platform** with full iOS and Android support
## 📦 Installation
```bash
# Using npm
npm install rs-react-native-map-clustering react-native-maps --save
# Using yarn
yarn add rs-react-native-map-clustering react-native-maps
# Using pnpm
pnpm add rs-react-native-map-clustering react-native-maps
```
## 🚀 Quick Start
```jsx
import React from 'react';
import { StyleSheet, View } from 'react-native';
import MapView from 'rs-react-native-map-clustering';
import { Marker } from 'react-native-maps';
export default function App() {
return (
<View style={styles.container}>
<MapView
style={styles.map}
initialRegion={{
latitude: 52.5,
longitude: 19.2,
latitudeDelta: 8.5,
longitudeDelta: 8.5,
}}
>
<Marker coordinate={{ latitude: 52.4, longitude: 18.7 }} />
<Marker coordinate={{ latitude: 52.1, longitude: 18.4 }} />
<Marker coordinate={{ latitude: 52.6, longitude: 18.3 }} />
<Marker coordinate={{ latitude: 51.6, longitude: 18.0 }} />
<Marker coordinate={{ latitude: 53.1, longitude: 18.8 }} />
</MapView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
map: {
flex: 1,
},
});
```
## 🔍 TypeScript Support
The library comes with full TypeScript support and exports helpful types for your development.
```tsx
import React, { useRef } from 'react';
import { View, StyleSheet } from 'react-native';
import MapView, { ClusteredMapProps } from 'rs-react-native-map-clustering';
import { Marker } from 'react-native-maps';
const INITIAL_REGION = {
latitude: 52.5,
longitude: 19.2,
latitudeDelta: 8.5,
longitudeDelta: 8.5,
};
const App = () => {
const mapRef = useRef<MapView>(null);
// Access to exported types
const clusteringOptions: Partial<ClusteredMapProps> = {
clusterColor: '#FF0000',
spiralEnabled: true,
tracksViewChanges: false
};
return (
<View style={styles.container}>
<MapView
ref={mapRef}
initialRegion={INITIAL_REGION}
style={styles.map}
{...clusteringOptions}
>
<Marker coordinate={{ latitude: 52.4, longitude: 18.7 }} />
<Marker coordinate={{ latitude: 52.1, longitude: 18.4 }} />
<Marker coordinate={{ latitude: 52.6, longitude: 18.3 }} />
<Marker coordinate={{ latitude: 51.6, longitude: 18.0 }} />
<Marker coordinate={{ latitude: 53.1, longitude: 18.8 }} />
</MapView>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
map: {
flex: 1,
},
});
export default App;
```
## ⚙️ Props
| Name | Type | Default | Description |
| ------------------------------------------- | --------------------- | -------------------------------------------- | ------------------------------------------------------------------------ |
| **clusterColor** | String | #00B386 | Background color of clusters |
| **clusterTextColor** | String | #FFFFFF | Color of text in clusters |
| **clusterFontFamily** | String | undefined | Font family of text in clusters |
| **onClusterPress(cluster, markers)** | Function | () => {} | Handles cluster click events with cluster data and its markers |
| **tracksViewChanges** | Boolean | false | Controls whether cluster markers track view changes |
| **radius** | Number | window.width * 6% | [SuperCluster radius](https://github.com/mapbox/supercluster#options) |
| **extent** | Number | 512 | [SuperCluster extent](https://github.com/mapbox/supercluster#options) |
| **minZoom** | Number | 1 | [SuperCluster minZoom](https://github.com/mapbox/supercluster#options) |
| **maxZoom** | Number | 20 | [SuperCluster maxZoom](https://github.com/mapbox/supercluster#options) |
| **minPoints** | Number | 2 | [SuperCluster minPoints](https://github.com/mapbox/supercluster#options) |
| **preserveClusterPressBehavior** | Boolean | false | If true, disables auto-zooming when clicking on a cluster |
| **edgePadding** | Object | { top: 50, left: 50, bottom: 50, right: 50 } | Padding for `fitToCoordinates` when focusing on clusters |
| **animationEnabled** | Boolean | true | Enables animations for clusters (iOS only) |
| **layoutAnimationConf** | LayoutAnimationConfig | LayoutAnimation.Presets.spring | Animation configuration for clusters (iOS only) |
| **onRegionChangeComplete(region, markers)** | Function | () => {} | Called when map region finishes changing |
| **onMarkersChange(markers)** | Function | () => {} | Called when markers data changes |
| **superClusterRef** | MutableRefObject | {} | Provides direct access to the SuperCluster instance |
| **clusteringEnabled** | Boolean | true | Enables/disables clustering functionality |
| **spiralEnabled** | Boolean | true | Controls spiral view for overlapping markers |
| **renderCluster** | Function | undefined | Custom rendering function for clusters |
| **spiderLineColor** | String | #FF0000 | Color of lines connecting markers in spider mode |
## 📱 Examples
### Animate Map to Region
```jsx
import React, { useRef } from "react";
import { Button, View, StyleSheet } from "react-native";
import MapView from "rs-react-native-map-clustering";
import { Marker } from "react-native-maps";
const App = () => {
const mapRef = useRef(null);
const animateToRegion = () => {
mapRef.current?.animateToRegion({
latitude: 42.5,
longitude: 15.2,
latitudeDelta: 7.5,
longitudeDelta: 7.5,
}, 2000);
};
return (
<View style={styles.container}>
<MapView
ref={mapRef}
style={styles.map}
initialRegion={{
latitude: 52.5,
longitude: 19.2,
latitudeDelta: 8.5,
longitudeDelta: 8.5,
}}
/>
<Button onPress={animateToRegion} title="Animate to Italy" />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
map: {
flex: 1,
},
});
export default App;
```
### Custom Cluster Rendering
```jsx
import React from "react";
import { View, Text, StyleSheet } from "react-native";
import MapView from "rs-react-native-map-clustering";
import { Marker } from "react-native-maps";
const CustomClusterMarker = ({ onPress, geometry, properties }) => {
const { point_count } = properties;
return (
<Marker
coordinate={{
latitude: geometry.coordinates[1],
longitude: geometry.coordinates[0],
}}
onPress={onPress}
>
<View style={styles.customCluster}>
<Text style={styles.customClusterText}>{point_count}</Text>
</View>
</Marker>
);
};
const App = () => {
return (
<View style={styles.container}>
<MapView
style={styles.map}
initialRegion={{
latitude: 52.5,
longitude: 19.2,
latitudeDelta: 8.5,
longitudeDelta: 8.5,
}}
renderCluster={CustomClusterMarker}
>
{/* Add your markers here */}
</MapView>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
map: {
flex: 1,
},
customCluster: {
backgroundColor: "purple",
borderRadius: 25,
padding: 10,
width: 50,
height: 50,
justifyContent: "center",
alignItems: "center",
},
customClusterText: {
color: "#FFFFFF",
fontWeight: "bold",
},
});
export default App;
```
## 🤝 Support
Feel free to create issues and pull requests on the [GitHub repository](https://github.com/rsoubrane/react-native-map-clustering). We welcome contributions and feedback to make this library even better.
### Happy Coding! 💖🚀