Show map markers within Circle radius hide markers outside of radius iterator issue

319 Views Asked by At

I'm needing to show markers within my circle radius. I'm using Kotlin. I have the circle radius updating with every onCameraIdleListener. The issue I'm having is that I don't understand how to use the for method correctly. My end goal is to have the markers hidden when they are outside of the radius of the circle. so here is the code I have that creates the markers. This is where I store the location key/value:

private var test = mapOf(
        "TESTLOCATION" to LatLng(34.695779, -110.344185),
)

this is the code I have that adds the marker to the map:

private fun addTestLocationToMap(){
    val placeDetailsMap = mutableMapOf(

            "TESTLOCATION" to PlaceDetails(
                    position = test.getValue("TESTLOCATION"), title = "Test Location", icon = (BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_YELLOW)), snippet = "Test Location"
            ),

    )
    placeDetailsMap.keys.map{
        with(placeDetailsMap.getValue(it)){
            mMap.addMarker(MarkerOptions()
                    .position(position)
                    .title(title)
                    .snippet(snippet)
                    .icon(icon)
                    .infoWindowAnchor(infoWindowAnchorX, infoWindowAnchorY)
                    .draggable(draggable)
                    .zIndex(zIndex)
                    .visible(isVisible)
            )

        }
    }
}

Here is the Class I'm using for the addTestLocationToMap:

class PlaceDetails(
    val position: LatLng,
    val title: String = "Marker",
    val snippet: String? = null,
    val icon: BitmapDescriptor = BitmapDescriptorFactory.defaultMarker(),
    val infoWindowAnchorX: Float = 0.5F,
    val infoWindowAnchorY: Float = 0F,
    val draggable: Boolean = false,
    val zIndex: Float = 0F,
    val isVisible: Boolean = true,
    val setVisible: Boolean = true)

Here is the Class I have for the Circle:

class Circle(
    val center: LatLng,
    val radius: Double,
    val strokeColor: Int,
    val fillColor: Int,
    val draggable: Boolean = false)

Here is how I'm adding the circle to the map:

private fun addCircle() {

val newCircle = mutableMapOf(
        "CIRCLE" to Circle(
                center = mMap.cameraPosition.target,
                radius = 241402.0,
                strokeColor = Color.RED,
                fillColor = 0x00000000
        )


)

newCircle.keys.map {
    with(newCircle.getValue(it)) {
        mMap.addCircle(CircleOptions()
                .center(center)
                .radius(radius)
                .strokeColor(strokeColor)
                .fillColor(fillColor)
                    .draggable(draggable)
        )

    }
}

}

Here are the private var at the top of the code that updates the lat/lng for the camera:

private var cameraLat: Double = 0.0
private var cameraLng: Double = 0.0

Here is the map of for the Circle:

private var circle = mapOf(


        "CIRCLE" to LatLng(cameraLat, cameraLng),)

This is how I'm updating the camera's

 mMap.setOnCameraIdleListener {
        var cameraLatUpdate = mMap.cameraPosition.target.latitude
        var cameraLngUpdate = mMap.cameraPosition.target.longitude
        cameraLatLng = mMap.cameraPosition.target
        cameraLat = cameraLatUpdate
        cameraLng = cameraLngUpdate}

This is how I'm trying to show/hide markers in the radius. Here is:

private lateinit var marker: Marker

This is the code for the radius:

fun addCircleToMap() {

for (marker : LatLng in circle.getValue("CIRCLE") ){ if (SphericalUtil.computeDistanceBetween(circle.getValue("CIRCLE"), test.getValue("TESTLOCATION") ) < 241402.0){ marker.isVisible = true}

This is the error I'm getting "For-loop range must have an 'iterator()' method" This is where I'm stuck at. I have tried to look into iterator but I'm not understanding it. Does my code seem right? Am I doing something wrong with the code? I got the general idea from this comment on another similar question. this code was in java I do believe. I've done my best to try and keep it similar. but I'm not sure on how I can iterator this for loop? Thank you for all your help!

2

There are 2 best solutions below

2
On

When you call for statement it should be for an iterable collection, but you are calling one unique value, which is circle.getValue("CIRCLE"), I think you should directly assing the value to the marker

val marker = circle.getValue("CIRCLE") 
0
On

So with some code changes and I was able to successfully hide the markers outside of the circle radius with this code.

    private lateinit var testMarkers:MutableList<Marker>




fun testMarkersForLoops(): MutableList<Marker> {

    val testMarkers = mutableListOf(
            mMap.addMarker(MarkerOptions().position(LatLng(34.695779, -87.634612)).title("testMarker").icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_YELLOW)).visible(false))).toMutableList() return testMarkers

// just make sure to have the visible set to false in order to hide them until their in circle radius

}

fun loopForMarkers(){

    val circle = mMap.addCircle(CircleOptions().center(mMap.cameraPosition.target).radius(241402.0).strokeColor(Color.RED).fillColor(0x00000000))
    for (marker: Marker in testMarkers ){
        if (SphericalUtil.computeDistanceBetween(circle.center, marker.position) < 241402.0){
            marker.isVisible = true
            Log.i(TAG,"Supposed to set Loves markers within the radius to true testing to see if this runs.")
        }
    }

   
}

then adding this within the onMapReady:

mMap.setOnCameraIdleListener {
        var cameraLatUpdate = mMap.cameraPosition.target.latitude
        var cameraLngUpdate = mMap.cameraPosition.target.longitude
        cameraLatLng = mMap.cameraPosition.target
        cameraLat = cameraLatUpdate
        cameraLng = cameraLngUpdate
        
        mMap.clear()
        testMarkers = testMarkersForLoops()

        addCircleToMap()
        loopForMarkers()
    }

you have to call the location list function after the .clear() I was having the .clear() in the wrong spot. Instead of creating the mapOf then using the class PlaceDetails to assign each locations info I just did it with the mutableListOf(). in the for loop just call the mutableListOf name you assigned for it. The radius is in Meters, you can change it to the radius you want. this is roughly 150 mile raidus.

I use the circle.center for the latlng of the center of the circle, having the:

.center(mMap.cameraPosition.target)

Once you place this in the onCameraIdle, this will update the center LatLng with every camera idle.