An open API service indexing awesome lists of open source software.

https://github.com/yoshidan/react-native-map-cluster

8xplorer or cmapper like Smooth map clustering library for react-native
https://github.com/yoshidan/react-native-map-cluster

react-native react-native-maps typescript

Last synced: 19 days ago
JSON representation

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

Awesome Lists containing this project

README

          

# react-native-map-cluster

[cmapper](https://apps.apple.com/jp/app/cmapper/id935586290) or [8xplorer](https://apps.apple.com/app/apple-store/id1460433285?mt=8&l=ja) like smooth map clustering library for both iOS and Android.

iOS
![demo](/image/anim.gif)

Android
![demo](/image/anim_android.gif)

## Installation

1. install dependency
```
yarn add react-native-maps
yarn add supercluster
yarn add @mapbox/geo-viewport
```

2. install library

```
yarn add https://github.com/yoshidan/react-native-map-cluster
```

## Usage

Complete examples is [Here](/example/sampleProject)

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 {

// render map
public render() {

const { initialRegion } = this.props;

// here is the property that the HoC injects.
const {animatedMarkers, onRegionChanged} = this.props;

return (


// render markers
{animatedMarkers.map(this.renderMarker)}


);
}
}
```

* Use wrapped component with required props `markers` and `initialRegion`

```
const App = () => {
return (






);
};
```

## 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 (
markersInClusterCount && this.map.animateToRegion(currentCluster.userExtension.getCenterPosition()}>
<...>

);
}

```