vasyas / react-native-map-cluster

8xplorer or cmapper like Smooth map clustering library for react-native

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

react-native-map-cluster

cmapper or 8xplorer like smooth map clustering library for both iOS and Android.

iOS
demo

Android
demo

Installation

  1. install dependency
yarn add react-native-maps
yarn add supercluster
yarn add @mapbox/geo-viewport
  1. install library
yarn add https://github.com/yoshidan/react-native-map-cluster

Usage

Complete examples is Here

There are only keypoint in this README.

  • use withAnimatedCluster
  • use onRegionChanged for MapView#onRegionChangeComplete
import React, {Fragment} from 'react';
import {Dimensions,Image,SafeAreaView,StatusBar,StyleSheet,Text,View } from 'react-native';
import { AnimatedMarker, withAnimatedCluster } from '@yoshidan/react-native-map-cluster';
import MapView, {MarkerAnimated} from 'react-native-maps';
import Supercluster from 'supercluster';

const {width, height} = Dimensions.get('window');
const Component = withAnimatedCluster({
  moveSpeed: 600, 
  deltaOffset: 1.3,
  width,
  height,
  superClusterProvider: () =>new Supercluster(),
})(class Map extends React.Component<Props, State> {

  // render map 
  public render() {
 
      const { initialRegion } = this.props;
      
      // here is the property that the HoC injects.
      const {animatedMarkers, onRegionChanged} = this.props;
      
      return (
        <MapView 
        
          // recreate cluster when the region changes
          onRegionChangeComplete={onRegionChanged}
          
          initialRegion={initialRegion}
          style={styles.map}>
          
          // render markers 
          {animatedMarkers.map(this.renderMarker)}
          
        </MapView>
      );
    }
} 
  • Use wrapped component with required props markers and initialRegion
const App = () => {
  return (
    <Fragment>
      <StatusBar barStyle="dark-content" />
      <SafeAreaView style={{flex: 1}}>
        <Component
        
          // {id , coorinates: { latitude, longitude}} is required for each markers
          markers={markers}
          
          initialRegion={{
            ...markers[0].coordinate,
            latitudeDelta: 0,
            longitudeDelta: 0,
          }}
        />
      </SafeAreaView>
    </Fragment>
  );
};

Props

withAnimatedCluster

Arguments

Name Type Default Note
moveSpeed number 600 the animating speed of split or synthesize cluster
deltaOffset number 1.3 the value to suppress marker spreading to the outside of the window when splitting cluster. Set smaller value if the icon is small or bigger value if the icon is big.
width number null dimension width of map
height number null dimension height of map
superClusterProvider () => Supercluster null the function to create the Supercluster

Required props to use wrapped component

Name Type Note
markers Marker[] Markers to display on the MapView
initialRegion Region initial region of MapView
type Marker = {
  coordinate: Region;
  id: number | string
}

Injected props

Name Type Note
animatedMarkers AnimatedMarkers[] Converted to markers to animate. render this markers
region Region Current region
clusters Cluster[] Current clusters
onRegionChanged (region:Region) => void function to cluster markers with current region. Set as MapView#onRegionChangeCompleted
type AnimatedMarkers = {
  coordinate: AnimatedRegion;
  id: number | string;
  getCluster: (clusters: Cluster[]) => Cluster | undefined;
}
type Clusters = {  
  properties: {
      point_count: number // count of markers in this cluster 
  },  
  userExtension: {
    getCenterPosition: () => Region;
  }
}

getCenterPosition is required for splitting cluster on marker pressed

renderMarker(marker: AnimatedMarker) {

    const {clusters, region} = this.props;

    const currentCluster = marker.getCluster(clusters);
    const markersInClusterCount = currentCluster ? currentCluster.properties.point_count : 0;
      
    return (
       <MarkerAnimated
         key={marker.id}
         coordinate={marker.coordinate}
          
         // split clster when markers is pressed.
         onPress={() => markersInClusterCount && this.map.animateToRegion(currentCluster.userExtension.getCenterPosition()}>
         <...>
       </MarkerAnimated>
    );
}

About

8xplorer or cmapper like Smooth map clustering library for react-native

License:MIT License


Languages

Language:TypeScript 61.9%Language:Objective-C 15.1%Language:Ruby 8.1%Language:JavaScript 6.4%Language:Java 6.3%Language:Python 2.2%