Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clipping MapView to Circle (MapLibre Android) #3076

Open
EllisGlaeser opened this issue Dec 10, 2024 · 0 comments
Open

Clipping MapView to Circle (MapLibre Android) #3076

EllisGlaeser opened this issue Dec 10, 2024 · 0 comments
Labels

Comments

@EllisGlaeser
Copy link

Use Case: I want to provide a "magnifier" for when the user is selecting a coordinate on the map, or drawing a route on the map. This way they can see what is under their finger. This is a second MapView displayed on top of the main map.

Problem: This is all possible, except that I want to clip this second, smaller map view to a circle to look like a magnifier. I have tried all of the standard ways to clip a View, but none of them actually clip the map — it is still displayed as a rectangle.

Here's what I've tried:

  1. Compose Modifier on AndroidView
AndroidView(
    modifier = Modifier
         .clip(CircleShape)
         .size(200.dp),
    factory = {
         GPMapLibreManager.instance.magnifierView()
    }
)

From what I've read, it seems that the compose modifier isn't actually able to modify the view's outline, although the size modifier works.

  1. Provide an Outline object:
class GPMagnifierView(context: Context): MapView(context) {
    
    init {
        outlineProvider = object : ViewOutlineProvider() {
            override fun getOutline(view: View, outline: Outline) {
                // Create a circular outline
                val size = view.width.coerceAtMost(view.height)
                outline.setOval(0, 0, size, size)
            }
        }
        clipToOutline = true
    }
}
  1. Add a circular background via drawable resource:
    Doing this gets me a white circle on top of the map, but the map remains a square.
init {
        this.clipToOutline = true
        setBackgroundResource(R.drawable.circle_background)

        this.renderView.apply {
            setBackgroundResource(R.drawable.circle_background)
            clipToOutline = true
        }
    }
  1. Override the draw function in a MapView subclass:
override fun draw(canvas: Canvas) {
        val path = Path().apply {
            val radius = 400
            val centerX = width / 2
            val centerY = height / 2

            val left = (centerX - radius).toFloat()
            val top = (centerY - radius).toFloat()
            val right = (centerX + radius).toFloat()
            val bottom = (centerY + radius).toFloat()

            addOval(left, top, right, bottom, Path.Direction.CW)
        }
        canvas.clipPath(path)
        super.draw(canvas)
}

Am I missing something, or is this not currently possible with a MapView?
If not, is this something that could be added? It could also be applicable to something like a minimap, which could also be useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants