Skip to content

Commit

Permalink
Update cluster
Browse files Browse the repository at this point in the history
  • Loading branch information
qiuxiang committed Jan 18, 2018
1 parent e33d2a7 commit 1207968
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 148 deletions.
15 changes: 14 additions & 1 deletion example/src/examples/marker/clustering.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,18 @@ export default class Clustering extends Component {
static navigationOptions = { title: 'Marker clustering' }

onLoad = () => this.mapView.animateTo({ zoomLevel: 10 })
onStatusChange = status => this.cluster.update(status)

onStatusChange = status => {
this.status = status
this.cluster.update(status)
}

onPress = cluster => {
this.mapView.animateTo({
center: cluster.coordinate,
zoomLevel: this.status.zoomLevel + 1,
})
}

markers = Array(100).fill(0).map((_, i) => ({
coordinate: {
Expand All @@ -31,9 +42,11 @@ export default class Clustering extends Component {
onLoad: this.onLoad,
onStatusChange: this.onStatusChange,
}

return (
<MapView {...props}>
<MapView.Cluster
onPress={this.onPress}
ref={ref => this.cluster = ref}
markers={this.markers}
renderMarker={this.renderMarker}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"mapview",
"baidumap"
],
"version": "0.1.5",
"version": "0.1.6",
"author": "7c00 <[email protected]>",
"repository": {
"type": "git",
Expand Down
146 changes: 0 additions & 146 deletions src/map-view/cluster.js

This file was deleted.

62 changes: 62 additions & 0 deletions src/map-view/cluster/cluster-view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// @flow
import React, { PureComponent } from 'react'
import { StyleSheet, Text, TouchableWithoutFeedback, View } from 'react-native'
import Marker from '../marker'
import type { ClusterParams } from '.'

const style = StyleSheet.create({
cluster: {
borderWidth: 4,
borderColor: 'rgba(245,83,61,0.5)',
backgroundColor: 'rgba(245,83,61,0.9)',
alignItems: 'center',
justifyContent: 'center',
},
text: {
color: '#fff',
fontWeight: '600',
},
})

type Props = {
cluster: ClusterParams,
style?: View.propTypes.style,
textStyle?: View.propTypes.style,
onPress?: (cluster: ClusterParams) => {},
}

export default class ClusterView extends PureComponent<Props> {
onPress = () => {
if (this.props.onPress) {
this.props.onPress(this.props.cluster)
}
}

renderClusterView = () => {
const { count } = this.props.cluster
const size = 36 + Math.log2(count)
const clusterStyle = {
width: size,
height: size,
borderRadius: size / 2,
}
return (
<TouchableWithoutFeedback>
<View style={[style.cluster, clusterStyle, this.props.style]}>
<Text style={[style.text, this.props.textStyle]}>{count}</Text>
</View>
</TouchableWithoutFeedback>
)
}

render() {
return (
<Marker
onPress={this.onPress}
coordinate={this.props.cluster.coordinate}
view={this.renderClusterView}
flat
/>
)
}
}
114 changes: 114 additions & 0 deletions src/map-view/cluster/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/* eslint-disable camelcase */
// @flow
import React, { PureComponent } from 'react'
import type { Element } from 'react'
import { ViewPropTypes } from 'react-native'
import SuperCluster from 'supercluster'
import type { LatLng, MapStatus } from '../..'
import ClusterView from './cluster-view'

export type ClusterParams = {
id: number,
count: number,
coordinate: LatLng,
}

type Props = {
radius?: number,
clusterStyle?: ViewPropTypes.style,
clusterTextStyle?: ViewPropTypes.style,

markers: {
coordinate: LatLng,
extra?: any,
}[],

renderMarker: ({
coordinate: LatLng,
index: number,
extra?: any,
}) => Element<*>,

renderCluster?: (cluster: ClusterParams) => Element<*>,
onPress?: (cluster: ClusterParams) => {},
}

type State = {
clusters: {
geometry: {
coordinates: [number, number],
properties: any,
},
properties: {
cluster_id: number,
point_count: number,
},
}[],
}

export default class Cluster extends PureComponent<Props, State> {
static defaultProps = { radius: 500 }

state = { clusters: [] }

componentDidMount() {
this.init(this.props)
}

componentWillReceiveProps(props: Props) {
this.init(props)
}

cluster: SuperCluster

init(props: Props) {
const { radius } = props
this.cluster = SuperCluster({ radius, minZoom: 3, maxZoom: 21 })
.load(props.markers.map(marker => ({
geometry: {
coordinates: [marker.coordinate.longitude, marker.coordinate.latitude],
properties: marker.extra,
},
})))
}

update({ zoomLevel, region }: MapStatus) {
this.setState({
clusters: this.cluster.getClusters([
region.longitude - (region.longitudeDelta / 2),
region.latitude - (region.latitudeDelta / 2),
region.longitude + (region.longitudeDelta / 2),
region.latitude + (region.latitudeDelta / 2),
], Math.round(zoomLevel)),
})
}

renderCluster = (cluster: ClusterParams) => (
<ClusterView
key={cluster.id}
cluster={cluster}
onPress={this.props.onPress}
style={this.props.clusterStyle}
textStyle={this.props.clusterTextStyle}
/>
)

render() {
return this.state.clusters.map((cluster, index) => {
const { geometry, properties } = cluster
const { renderCluster, renderMarker } = this.props
const coordinate = {
latitude: geometry.coordinates[1],
longitude: geometry.coordinates[0],
}

if (properties) {
const { cluster_id, point_count } = cluster.properties
const render = renderCluster || this.renderCluster
return render({ coordinate, id: cluster_id, count: point_count })
}

return renderMarker({ index, coordinate, extra: geometry.properties })
})
}
}
1 change: 1 addition & 0 deletions src/map-view/marker.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export default class Marker extends Component<Props> {
selected: PropTypes.bool,
}


componentDidUpdate() {
if (this.props.view && Platform.OS === 'android') {
this.update()
Expand Down

0 comments on commit 1207968

Please sign in to comment.