react-native - 如何在本机反应中使用 mapbox 标记集群?
问题描述
我正在使用 react-native-mapbox-gl。我有一组位置,我正在循环遍历以在地图上绘制标记。但是有些位置彼此非常接近,几乎看不到。我想对彼此靠近的所有位置进行聚类,这样当我单击它时,它会展开并向我显示该聚类中的所有位置。
mapbox 中有<MapboxGL.ShapeSource />
可用的,但它要求从其中加载 lat long 的 url。但我有一个数组,每个位置都有 lat long。有没有其他方法可以在 mapbox 中创建一组位置。
<Mapbox.MapView
styleURL={Mapbox.StyleURL.Dark}
zoomLevel={15}
centerCoordinate={[locations[0].longitude, locations[0].latitude]}
style={styles.container}
showUserLocation={true}>
{this.renderLocations(locations)}
</Mapbox.MapView>
渲染位置函数循环遍历位置数组并在地图上显示标记
renderLocations(locations) {
return locations.map((loc, locIndex) => {
return (
<Mapbox.PointAnnotation
key={`${locIndex}pointAnnotation`}
id={`${locIndex}pointAnnotation`}
coordinate={[loc.longitude, loc.latitude]}
title={loc.name}>
<Image source={require("../../../assets/images/marker.png")}/>
<Mapbox.Callout title={loc.name} />
</Mapbox.PointAnnotation>
);
});
解决方案
您可以像这样使用@turf/clusterDbScan:
let collection = MapboxGL.geoUtils.makeFeatureCollection();
results.forEach(result => {
const geometry = {
type: "Point",
coordinates: [result.lon, result.lat]
};
let marker = MapboxGL.geoUtils.makeFeature(geometry);
marker.id = result.id
marker.properties = {
...yourProperties
};
collection = MapboxGL.geoUtils.addToFeatureCollection(collection, marker);
});
// Let Turf do the job !
const maxDistance = 0.005;
const clustered = turf.clustersDbscan(collection, maxDistance);
// Markers have no cluster property
const markers = clustered.features
.filter( f => f.properties.cluster===undefined)
.map(f => {
return {...f.properties, coordinates: f.geometry.coordinates}
})
// Clusters have one (cluster id)
let clusters = {};
clustered.features
.filter( f => f.properties.cluster!==undefined)
.forEach( f => {
const { cluster, id} = f.properties;
const { coordinates } = f.geometry;
if (!clusters[cluster]) {
clusters[cluster] = {
id: `cluster_${cluster}`,
count: 1,
objects: [id],
coordinates: coordinates
}
console.tron.log({clusters})
}
else {
const { count } = clusters[cluster]
const [lastX, lastY] = clusters[cluster].coordinates;
const [x, y] = coordinates;
const newX = ((lastX * count) + x) / (count+1);
const newY = ((lastY * count) + y) / (count+1);
clusters[cluster] = {
...clusters[cluster],
count: count+1,
objects: [...clusters[cluster].objects, id],
coordinates: [newX, newY]
}
}
})
this.setState({ markers, clusters: _.values(clusters) });
推荐阅读
- javascript - 尝试打开具有特定用户 ID 的模式
- arduino - 如何使用 ESP8266 制作 html 页面
- snowflake-cloud-data-platform - Snowflake - 查看查询最多的表和列
- homebrew - 自制安装错误:Formula::FormulaNamespace0687b9ea3596758a5cc31a58c3aca98d::Rpm:Class 的“livecheck”
- php - 关于“IF”语句,“if”是一个函数吗?
- c - 如何将类型 char a[] 分配给 unsigned char b[]?
- python - 使用 itertools 库获取对象组合?
- c# - 为什么我的 if 语句在我的 switch 语句中不起作用?
- javascript - 如何使用猫鼬更新另一个对象内的数组内的对象
- javascript - vue-cli devServer 代理绕过