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

can you support Marker Drag? #36

Closed
Huangkaiping opened this issue Feb 28, 2022 · 4 comments
Closed

can you support Marker Drag? #36

Huangkaiping opened this issue Feb 28, 2022 · 4 comments

Comments

@Huangkaiping
Copy link

I like to use your library, I need to make a function, but Marked points cannot be moved by fingers。I want the marker point to move with my finger, as the func 'enableMarkerDrag' in your Mycompose library. can you support it ?

@p-lr
Copy link
Owner

p-lr commented Mar 2, 2022

It's possible to drag markers, but it's definitely less straightforward than with MapCompose. I'll look for an example and post it here.

@Huangkaiping
Copy link
Author

Thank you very much. You are a selfless and handsome man

@p-lr
Copy link
Owner

p-lr commented Mar 7, 2022

Here it is:

import android.view.GestureDetector
import android.view.GestureDetector.SimpleOnGestureListener
import android.view.MotionEvent
import android.view.View
import android.view.View.OnTouchListener
import ovh.plrapps.mapview.MapView
import ovh.plrapps.mapview.ReferentialData
import ovh.plrapps.mapview.ReferentialListener
import ovh.plrapps.mapview.api.getConstrainedX
import ovh.plrapps.mapview.api.getConstrainedY
import ovh.plrapps.mapview.core.CoordinateTranslater
import kotlin.math.cos
import kotlin.math.sin

/**
 * A touch listener that enables touch-moves of a view (also called marker) on a [MapView].
 * The logic of moving the marker is delegated to the provided [MarkerMoveAgent].
 * It can also react to single-tap event. To be notified, provide a [ClickCallback] to
 * the overloaded constructor.
 *
 * Example of usage :
 * ```
 * MarkerMoveAgent agent = new ClassImplementsMoveAgent();
 * TouchMoveListener markerTouchListener = new TouchMoveListener(mapView, agent);
 * View marker = new CustomMarker(context);
 * marker.setOnTouchListener(markerTouchListener);
 * mapView.addMarker(marker, ...);
 * ```
 */
class TouchMoveListener @JvmOverloads constructor(private val mapView: MapView,
                                                  private val markerClickCallback: ClickCallback? = null,
                                                  private val markerMarkerMoveAgent: MarkerMoveAgent) : SimpleOnGestureListener(), OnTouchListener, ReferentialListener {
    private val mGestureDetector = GestureDetector(mapView.context, this)
    private var deltaX = 0f
    private var deltaY = 0f
    private var referentialData: ReferentialData? = null

    override fun onReferentialChanged(refData: ReferentialData) {
        this.referentialData = refData
    }

    override fun onTouch(view: View, event: MotionEvent): Boolean {
        if (mGestureDetector.onTouchEvent(event)) {
            return true
        }
        val rd = referentialData
        var angle = 0.0
        if (rd != null) {
            angle = -Math.toRadians(rd.angle.toDouble())
        }
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                deltaX = event.x
                deltaY = event.y
            }
            MotionEvent.ACTION_MOVE -> {
                val dX: Float
                val dY: Float
                if (rd != null && rd.rotationEnabled) {
                    dX = ((event.x - deltaX) * cos(angle) - (event.y - deltaY) * sin(angle)).toFloat()
                    dY = ((event.x - deltaX) * sin(angle) + (event.y - deltaY) * cos(angle)).toFloat()
                } else {
                    dX = event.x - deltaX
                    dY = event.y - deltaY
                }
                val X: Double
                val Y: Double
                val ct = mapView.coordinateTranslater ?: return true
                if (rd != null && rd.rotationEnabled) {
                    val Xorig = ct.reverseRotationX(rd, view.x + (view.width shr 1), view.y + (view.height shr 1))
                    val Yorig = ct.reverseRotationY(rd, view.x + (view.width shr 1), view.y + (view.height shr 1))
                    X = getRelativeX(ct, Xorig.toFloat() + dX)
                    Y = getRelativeY(ct, Yorig.toFloat() + dY)
                } else {
                    X = getRelativeX(ct, view.x + dX + (view.width shr 1))
                    Y = getRelativeY(ct, view.y + dY + (view.height shr 1))
                }

                markerMarkerMoveAgent.onMarkerMove(mapView, view, getConstrainedX(X)
                        ?: return true, getConstrainedY(Y) ?: return true)
            }
            else -> return false
        }
        return true
    }

    override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
        markerClickCallback?.onMarkerClick()
        return true
    }

    private fun getRelativeX(ct: CoordinateTranslater, x: Float): Double {
        return ct.translateAndScaleAbsoluteToRelativeX(x.toInt(), mapView.scale)
    }

    private fun getRelativeY(ct: CoordinateTranslater, y: Float): Double {
        return ct.translateAndScaleAbsoluteToRelativeY(y.toInt(), mapView.scale)
    }

    private fun getConstrainedX(x: Double): Double? {
        return mapView.getConstrainedX(x)
    }

    private fun getConstrainedY(y: Double): Double? {
        return mapView.getConstrainedY(y)
    }

    /**
     * A [MarkerMoveAgent] is given the "relative coordinates" of the view added to the [MapView].
     * Most of the time, the callee sets the given coordinates of the view on the [MapView].
     */
    fun interface MarkerMoveAgent {
        fun onMarkerMove(mapView: MapView, view: View, x: Double, y: Double)
    }

    fun interface ClickCallback {
        fun onMarkerClick()
    }
}

@Huangkaiping
Copy link
Author

fix

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

No branches or pull requests

2 participants