首页 > 解决方案 > 如何有效地隐藏 ClusterManager 中不在 Circle 半径内的每个标记/集群?

问题描述

我正在尝试根据用户的位置过滤掉我的集群/标记,并使用预定义的圆作为半径。我希望它在该半径之外不可见集群/标记。

我尝试创建一个数组并将我的经纬度设置为: Android - 在地图中仅显示确定区域中包含的标记

还有这个: 如何仅在地图上的半径(圆圈)内显示标记?

但是,我不确定如何使用 ClusterManager 解决这个问题

在这里,我从 Firebase 获取数据并将其存储在 ClusterManager 中:

    private fun loadMarkersFromDB() {

        mCompanies.child("data/results").addListenerForSingleValueEvent(object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                if (dataSnapshot.exists()) {
                    for (s in dataSnapshot.children) {
                        var company = s.getValue(Company::class.java)
                        val infoWindow =
                            MyItem(company!!.latitude, company!!.longitude, company.name)
                        mClusterManager.setAnimation(false)
                        mClusterManager.addItem(infoWindow)

                        Log.d("onDataChange", company.toString())
                    }
                }
            }

            override fun onCancelled(databaseError: DatabaseError) {
                Log.w("MapsActivity", databaseError.toException())
            }
        })
    }

设置集群功能:

    private fun setUpCluster() {
        // Initialize the manager with the context and the map.
        // (Activity extends context, so we can pass 'this' in the constructor.)
        mClusterManager = ClusterManager(this, mMap)
        // Point the map's listeners at the listeners implemented by the cluster
        // manager.
        mMap.setOnCameraIdleListener(mClusterManager)
        mMap.setOnMarkerClickListener(mClusterManager)

        // Add cluster items (markers) to the cluster manager.
        loadMarkersFromDB()
    }

我在 onMapReady 中调用的内容:

 setUpCluster()

        mClusterManager = ClusterManager(this, mMap)
        val customRenderer = CustomClusterRenderer(this, mMap, mClusterManager, mMap.getCameraPosition().zoom, 20f)
        mClusterManager.renderer = customRenderer
        mMap.setOnCameraMoveListener(customRenderer)
        mMap.setOnCameraIdleListener(mClusterManager)
        mMap.setOnMarkerClickListener(mClusterManager)

这是我从 StackOverflow 获得的 Circle 代码:

circle = mMap.addCircle(
                    CircleOptions()
                        .center(currentLatLng)
                        .radius(400.0) //The radius of the circle, specified in meters. It should be zero or greater.
                        .strokeColor(Color.rgb(0, 136, 255))
                        .fillColor(Color.argb(20, 0, 136, 255))
                )

我的集群项目类:

class MyItem : ClusterItem {
    private val position: LatLng
    private var title: String = ""
    private var snippet: String = ""

    constructor(lat: Double, lng: Double, title: String) {
        position = LatLng(lat, lng)
        this.title = title
    }

    override fun getSnippet(): String {
        return snippet
    }

    override fun getTitle(): String {
        return title
    }

    override fun getPosition(): LatLng {
        return position
    }

}

我让集群正常工作,并且数据已按预期加载,但是,因为我有超过 3000 个位置,我试图使其尽可能优化,以便用户只能看到给定半径内的标记,但我还希望通过单击按钮取消隐藏半径之外的标记的选项。

标签: androidkotlinmaps

解决方案


我认为你真的只需要简单的条件来检查即将到来的位置是否在半径内,即:

if(company!!.longitude < useLocation.longitude + radius && company!!.longitude > useLocation.longitude - radius)
   mClusterManager.addItem(infoWindow)

注意:您可能需要对纬度执行相同操作。

我猜这个radius0.00578当然取决于你的需要。

虽然最好的方法是编写查询以仅获取您指定范围内的位置。


推荐阅读