UNPKG

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
# React Native Map Clustering ![npm version](https://img.shields.io/npm/v/rs-react-native-map-clustering.svg) ![license](https://img.shields.io/npm/l/rs-react-native-map-clustering.svg) ![downloads](https://img.shields.io/npm/dt/rs-react-native-map-clustering.svg) 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! 💖🚀