Bad performance when Cluster Styling added
Closed this issue · 1 comments
ezzcodeezzlife commented
Im loading some Markers from the Overpass API (OpenStreetMaps). When showing Markers and Clusters as default red markers the performance is really good:
import React, { Component } from 'react'
import {
Text,
View,
Image,
StyleSheet,
SafeAreaView,
TouchableOpacity,
} from 'react-native'
import { Marker, Callout } from 'react-native-maps'
import ClusteredMapView from 'react-native-maps-super-cluster'
export const getBoundByRegion = (region, scale = 1) => {
/*
* Latitude : max/min +90 to -90
* Longitude : max/min +180 to -180
*/
// Of course we can do it mo compact but it wait is more obvious
const calcMinLatByOffset = (lng, offset) => {
const factValue = lng - offset;
if (factValue < -90) {
return (90 + offset) * -1;
}
return factValue;
};
const calcMaxLatByOffset = (lng, offset) => {
const factValue = lng + offset;
if (90 < factValue) {
return (90 - offset) * -1;
}
return factValue;
};
const calcMinLngByOffset = (lng, offset) => {
const factValue = lng - offset;
if (factValue < -180) {
return (180 + offset) * -1;
}
return factValue;
};
const calcMaxLngByOffset = (lng, offset) => {
const factValue = lng + offset;
if (180 < factValue) {
return (180 - offset) * -1;
}
return factValue;
};
const latOffset = region.latitudeDelta / 2 * scale;
const lngD = (region.longitudeDelta < -180) ? 360 + region.longitudeDelta : region.longitudeDelta;
const lngOffset = lngD / 2 * scale;
return {
minLng: calcMinLngByOffset(region.longitude, lngOffset), // westLng - min lng
minLat: calcMinLatByOffset(region.latitude, latOffset), // southLat - min lat
maxLng: calcMaxLngByOffset(region.longitude, lngOffset), // eastLng - max lng
maxLat: calcMaxLatByOffset(region.latitude, latOffset),// northLat - max lat
}
}
export default class MyClusteredMapView extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
isLoading: true,
region: {
latitude: 50.551085251254634,
latitudeDelta: 0.005160252144293054,
longitude: 9.676355849951506,
longitudeDelta: 0.003820471465587616,
}
};
}
onRegionChange(region) {
this.setState({
region: region
});
//console.log(region)
}
async getNewBenches(bounds) {
try {
const response = await fetch("https://overpass.openstreetmap.fr/api/interpreter?data=[out:json];node[%27amenity%27=%27bench%27](" + bounds.minLat +"," + bounds.minLng + "," + bounds.maxLat + "," + bounds.maxLng + ");out%20body;");
const json = await response.json();
var markers = []
for(var i = 0; i < json.elements.length; i++) {
//console.log(json.elements[i])
var mymarker = {
id: json.elements[i].id ,
location: { latitude : json.elements[i].lat , longitude : json.elements[i].lon },
tags: json.elements[i].tags,
}
markers.push(mymarker)
}
console.log(markers)
this.setState({ data: markers });
} catch (error) {
console.error(error);
} finally {
}
}
renderCluster = (cluster, onPress) => {
const pointCount = cluster.pointCount,
coordinate = cluster.coordinate,
clusterId = cluster.clusterId
// use pointCount to calculate cluster size scaling
// and apply it to "style" prop below
// eventually get clustered points by using
// underlying SuperCluster instance
// Methods ref: https://github.com/mapbox/supercluster
const clusteringEngine = this.map.getClusteringEngine(),
clusteredPoints = clusteringEngine.getLeaves(clusterId, 100)
return (
<Marker coordinate={coordinate} onPress={onPress}>
{
/*
Eventually use <Callout /> to
show clustered point thumbs, i.e.:
<Callout>
<ScrollView>
{
clusteredPoints.map(p => (
<Image source={p.image}>
))
}
</ScrollView>
</Callout>
IMPORTANT: be aware that Marker's onPress event isn't really consistent when using Callout.
*/
}
</Marker>
)
}
renderMarker = (data) => <Marker key={data.id || Math.random()} coordinate={data.location} />
render() {
return (
<ClusteredMapView
style={{flex: 1}}
data={this.state.data}
initialRegion={{
latitude: 50.551085251254634,
latitudeDelta: 0.005160252144293054,
longitude: 9.676355849951506,
longitudeDelta: 0.003820471465587616,
}}
onRegionChangeComplete={ (region) => {
this.onRegionChange(region);
this.getNewBenches(getBoundByRegion(region));
}
}
ref={(r) => { this.map = r }}
renderMarker={this.renderMarker}
renderCluster={this.renderCluster} />
)
}
}
but when adding custom styles the performance is slow.
import React, { Component } from 'react'
import {
Text,
View,
Image,
StyleSheet,
SafeAreaView,
TouchableOpacity,
} from 'react-native'
import { Marker, Callout } from 'react-native-maps'
import ClusteredMapView from 'react-native-maps-super-cluster'
export const getBoundByRegion = (region, scale = 1) => {
/*
* Latitude : max/min +90 to -90
* Longitude : max/min +180 to -180
*/
// Of course we can do it mo compact but it wait is more obvious
const calcMinLatByOffset = (lng, offset) => {
const factValue = lng - offset;
if (factValue < -90) {
return (90 + offset) * -1;
}
return factValue;
};
const calcMaxLatByOffset = (lng, offset) => {
const factValue = lng + offset;
if (90 < factValue) {
return (90 - offset) * -1;
}
return factValue;
};
const calcMinLngByOffset = (lng, offset) => {
const factValue = lng - offset;
if (factValue < -180) {
return (180 + offset) * -1;
}
return factValue;
};
const calcMaxLngByOffset = (lng, offset) => {
const factValue = lng + offset;
if (180 < factValue) {
return (180 - offset) * -1;
}
return factValue;
};
const latOffset = region.latitudeDelta / 2 * scale;
const lngD = (region.longitudeDelta < -180) ? 360 + region.longitudeDelta : region.longitudeDelta;
const lngOffset = lngD / 2 * scale;
return {
minLng: calcMinLngByOffset(region.longitude, lngOffset), // westLng - min lng
minLat: calcMinLatByOffset(region.latitude, latOffset), // southLat - min lat
maxLng: calcMaxLngByOffset(region.longitude, lngOffset), // eastLng - max lng
maxLat: calcMaxLatByOffset(region.latitude, latOffset),// northLat - max lat
}
}
export default class MyClusteredMapView extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
isLoading: true,
region: {
latitude: 50.551085251254634,
latitudeDelta: 0.005160252144293054,
longitude: 9.676355849951506,
longitudeDelta: 0.003820471465587616,
}
};
}
onRegionChange(region) {
this.setState({
region: region
});
//console.log(region)
}
async getNewBenches(bounds) {
try {
const response = await fetch("https://overpass.openstreetmap.fr/api/interpreter?data=[out:json];node[%27amenity%27=%27bench%27](" + bounds.minLat +"," + bounds.minLng + "," + bounds.maxLat + "," + bounds.maxLng + ");out%20body;");
const json = await response.json();
var markers = []
for(var i = 0; i < json.elements.length; i++) {
//console.log(json.elements[i])
var mymarker = {
id: json.elements[i].id ,
location: { latitude : json.elements[i].lat , longitude : json.elements[i].lon },
tags: json.elements[i].tags,
}
markers.push(mymarker)
}
console.log(markers)
this.setState({ data: markers });
} catch (error) {
console.error(error);
} finally {
}
}
renderCluster = (cluster, onPress) => {
const pointCount = cluster.pointCount,
coordinate = cluster.coordinate,
clusterId = cluster.clusterId
// use pointCount to calculate cluster size scaling
// and apply it to "style" prop below
// eventually get clustered points by using
// underlying SuperCluster instance
// Methods ref: https://github.com/mapbox/supercluster
const clusteringEngine = this.map.getClusteringEngine(),
clusteredPoints = clusteringEngine.getLeaves(clusterId, 100)
return (
<Marker coordinate={coordinate} onPress={onPress}>
<View style={styles.clusterContainer}>
<Text style={styles.clusterText}>
{pointCount}
</Text>
</View>
{
/*
Eventually use <Callout /> to
show clustered point thumbs, i.e.:
<Callout>
<ScrollView>
{
clusteredPoints.map(p => (
<Image source={p.image}>
))
}
</ScrollView>
</Callout>
IMPORTANT: be aware that Marker's onPress event isn't really consistent when using Callout.
*/
}
</Marker>
)
}
renderMarker = (data) => <Marker key={data.id || Math.random()} coordinate={data.location} />
render() {
return (
<ClusteredMapView
style={{flex: 1}}
data={this.state.data}
initialRegion={{
latitude: 50.551085251254634,
latitudeDelta: 0.005160252144293054,
longitude: 9.676355849951506,
longitudeDelta: 0.003820471465587616,
}}
onRegionChangeComplete={ (region) => {
this.onRegionChange(region);
this.getNewBenches(getBoundByRegion(region));
}
}
ref={(r) => { this.map = r }}
renderMarker={this.renderMarker}
renderCluster={this.renderCluster} />
)
}
}
const styles = StyleSheet.create({
clusterContainer: {
width: 30,
height: 30,
padding: 6,
borderWidth: 1,
borderRadius: 15,
alignItems: 'center',
borderColor: '#65bc46',
justifyContent: 'center',
backgroundColor: 'white',
},
clusterText: {
fontSize: 13,
color: '#65bc46',
fontWeight: '500',
textAlign: 'center',
}
})
maybe this is a know issue and someone can provide help
ezzcodeezzlife commented
this issue still exists