如何有效地隐藏ClusterManager中不在圆半径范围内的每个标记/簇?

时间:2019-03-25 06:30:40

标签: android kotlin maps

我正在尝试根据用户的位置使用半径为预定义的Circle的方法来过滤出群集/标记。我想要这样,以便在该半径之外不可见聚类/标记。

我尝试创建一个数组,并放置如下所示的经纬度: Android - display in the map only the markers included in a determinate area

How to show markers only inside of radius (circle) on maps?

但是,我不确定如何使用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多个位置,因此我试图使其尽可能优化,以便用户只能看到给定Radius内的标记,但我还希望通过单击按钮来取消隐藏半径外的标记。

1 个答案:

答案 0 :(得分:-1)

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

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

注意:您可能需要对纬度进行同样的操作。

我想radius值将等于0.00578,这当然取决于您的需求。

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