gpt4 book ai didi

android - 使用 android-maps-utils 在最大缩放级别禁用集群

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:34:04 24 4
gpt4 key购买 nike

我是新来的,所以欢迎任何反馈。我正在尝试使用 DefaultClusterRenderer 来显示一些自定义聚类,并且我试图让它在 map 完全放大时不聚类。所以我找到了完全相同问题的答案: Disable clustering at max zoom level with Googles android-maps-utils所以我尝试了该代码,但遇到了Not on the main thread 错误。任何帮助将不胜感激。我的构造函数中有这个

public EspecieRenderer(Context context, GoogleMap map, ClusterManager<T> clusterManager) {
super(context, map, clusterManager);
this.mMap = map;
...
}

然后我在做

@Override
protected boolean shouldRenderAsCluster(Cluster<T> cluster) {
final float currentZoom = mMap.getCameraPosition().zoom;
final float currentMaxZoom = mMap.getMaxZoomLevel();
return currentZoom < currentMaxZoom && cluster.getSize() >= 10;
}

这是我初始化集群的方式。我使用线程是因为我有近 200 个物种要加载,每个物种都有一个或多个要添加到 map 的标记

private void setUpClusterer() {
clusterManager = new ClusterManager<>(this, googleMap);
clusterManager.setRenderer(new EspecieRenderer<>(this, googleMap, clusterManager));
googleMap.setOnCameraChangeListener(clusterManager);
googleMap.setOnMarkerClickListener(clusterManager);
ArrayList<Especie> especies = (ArrayList<Especie>) Especie.list(this);
for (Especie especie : especies) {
ExecutorService queue = Executors.newSingleThreadExecutor();
queue.execute(new EspecieLoader(this, especie));
}
}

EspecieLoader所在

public class EspecieLoader implements Runnable {
private MainActivity context;
private Especie especie;

public EspecieLoader(MainActivity mainActivity, Especie especie) {
this.context = mainActivity;
this.especie = especie;
}

@Override
public void run() {
List<Foto> fotos = Foto.findAllByEspecieWithdCoords(context, especie);
String nombre = especie.getNombreCientifico();
for (Foto foto : fotos) {
LatLng latLng = new LatLng(foto.getLatitud(), foto.getLongitud());
Bitmap bitmap;
String path = "new/" + foto.getPath().replaceAll("-", "_").toLowerCase();
try {
bitmap = ResourcesHelper.getEncyclopediaAssetByName(context, path);
EspecieMarker especieMarker = new EspecieMarker(nombre, bitmap, latLng);
context.addSpeciesMarker(especieMarker);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

当我尝试运行我的应用程序时,我得到了这个:

07-16 19:18:41.402 31151-32075/com.lzm.Cajas E/AndroidRuntime: FATAL EXCEPTION: Thread-47332
Process: com.lzm.Cajas, PID: 31151
java.lang.IllegalStateException: Not on the main thread
2at maps.f.g.b(Unknown Source)
at maps.z.F.a(Unknown Source)
at maps.af.t.a(Unknown Source)
at vl.onTransact(:com.google.android.gms.DynamiteModulesB:51)
at android.os.Binder.transact(Binder.java:387)
at com.google.android.gms.maps.internal.IGoogleMapDelegate$zza$zza.getCameraPosition(Unknown Source)
at com.google.android.gms.maps.GoogleMap.getCameraPosition(Unknown Source)
at com.lzm.Cajas.map.EspecieRenderer.shouldRenderAsCluster(EspecieRenderer.java:62)
at com.google.maps.android.clustering.view.DefaultClusterRenderer$RenderTask.run(DefaultClusterRenderer.java:416)
at java.lang.Thread.run(Thread.java:818)

最佳答案

2022 更新 - 由于之前的答案有点困惑,并且谷歌地图相机事件发生了变化,这里有一个更新更优雅的解决方案:

扩展 ClusterManager 结束暴露一个属性,该属性指示是否应根据缩放级别对标记进行聚类,并在 onCameraIdle 事件中更新它。

open class ZoomClusterManager<T : ClusterItem>(
context: Context,
private val map: GoogleMap
) : ClusterManager<T>(context, map) {
companion object {
private const val CLUSTER_MAX_ZOOM_LEVEL = 9
}

private var _shouldClusterZoom: Boolean = true
val shouldClusterZoom get() = _shouldClusterZoom

override fun onCameraIdle() {
super.onCameraIdle()
_shouldClusterZoom = map.cameraPosition.zoom < CLUSTER_MAX_ZOOM_LEVEL
}
}

根据用例,您可能希望将 CLUSTER_MAX_ZOOM_LEVEL 作为构造函数中的属性,以提高类的可重用性。
然后也扩展 DefaultClusterRenderer。在构造函数中传递您的扩展版本的 ClusterManager,覆盖 shouldRenderAsCluster 并检查之前公开的属性,如下所示:

open class ZoomClusterRenderer<T : ClusterItem>(
context: Context,
map: GoogleMap,
private val clusterManager: ZoomClusterManager<T>
) : DefaultClusterRenderer<T>(context, map, clusterManager) {

override fun shouldRenderAsCluster(cluster: Cluster<T>): Boolean {
return super.shouldRenderAsCluster(cluster) && clusterManager.shouldClusterZoom
}
}

最后,在您要设置 map 的 fragment 中连接所有内容:

val clusterManager = ZoomClusterManager<ClusterItem>(requireContext(), googleMap)
clusterManager.renderer = ZoomClusterRenderer(requireContext(), googleMap, clusterManager)
googleMap.setOnCameraIdleListener(clusterManager)

旧答案 - 我今天遇到了同样的需求。这是我的解决方案:由于您不能设置 setOnCameraChangeListener 两次,因此删除

googleMap.setOnCameraChangeListener(clusterManager);

并将其替换为

googleMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
@Override
public void onCameraChange(CameraPosition cameraPosition) {
shouldCluster_zoom = cameraPosition.zoom < 9; //disables the cluster at 9 and higher zoom levels
clusterManager.onCameraChange(cameraPosition); //Replaces googleMap.setOnCameraChangeListener(clusterManager);
}
});

shouldCluster_zoom”显然是一个全局变量,static 和 boolean。现在在“shouldRenderAsCluster”方法中根据缩放检查标记是否应该聚类:

    @Override
protected boolean shouldRenderAsCluster(Cluster<T> cluster) {
return super.shouldRenderAsCluster(cluster) && Your_class_name.shouldCluster_zoom;
}

关于android - 使用 android-maps-utils 在最大缩放级别禁用集群,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38416903/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com