Last active
March 26, 2019 14:43
-
-
Save p-fischer/163057034807c76766eef80cb3eda989 to your computer and use it in GitHub Desktop.
Mapbox dragging
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fun MapboxMap.resolveSymbolId(location: LatLng) = resolveAnnotationId(location, SymbolManager.ID_GEOJSON_LAYER) | |
fun MapboxMap.resolveSymbolId(screenLocation: PointF) = resolveAnnotationId(screenLocation, SymbolManager.ID_GEOJSON_LAYER) | |
/** | |
* Check if an annotation is located at a given coordinate. | |
* | |
* @param location click location in real world coordinates | |
* | |
* @return annotation ID if an annotation exists, null otherwise | |
*/ | |
private fun MapboxMap.resolveAnnotationId(location: LatLng, vararg layerIds: String): Long? = | |
resolveAnnotationId(projection.toScreenLocation(location), *layerIds) | |
/** | |
* Check if an annotation is located at a given coordinate. | |
* | |
* @param screenLocation click location in device coordinates | |
* | |
* @return annotation ID if an annotation exists, null otherwise | |
*/ | |
private fun MapboxMap.resolveAnnotationId(screenLocation: PointF, vararg layerIds: String): Long? | |
{ | |
val features = queryRenderedFeatures(screenLocation, *layerIds) | |
if (features.isNotEmpty()) | |
{ | |
return features[0].getProperty("id").asLong | |
} | |
return null | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.graphics.PointF | |
import android.view.MotionEvent | |
import android.view.View | |
import com.anfema.pingonaut.utils.Log | |
import com.anfema.pingonaut.utils.resolveSymbolId | |
import com.mapbox.mapboxsdk.maps.MapboxMap | |
import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener | |
import com.mapbox.mapboxsdk.plugins.annotation.Symbol | |
import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager | |
/** | |
* Make a single symbol draggable. | |
* | |
* @param onSymbolDragListener optional interface to receive dragging callback events | |
*/ | |
class SymbolDraggingHandler(private val mapBox: MapboxMap, private val symbolManager: SymbolManager, private val onSymbolDragListener: OnSymbolDragListener?) : View.OnTouchListener | |
{ | |
var symbol: Symbol? = null | |
private var touchDelta = PointF() // initial distance of touch event to anchor of symbol icon | |
private var isDragged: Boolean = false | |
override fun onTouch(v: View?, event: MotionEvent): Boolean | |
{ | |
val symbol = symbol ?: return false | |
val action = event.actionMasked | |
if (action == MotionEvent.ACTION_DOWN) | |
{ | |
if (isSymbolTouched(event, symbol)) | |
{ | |
isDragged = true | |
val initialScreenLocation = mapBox.projection.toScreenLocation(symbol.latLng) | |
touchDelta.apply { | |
x = initialScreenLocation.x - event.x | |
y = initialScreenLocation.y - event.y | |
} | |
} | |
} | |
if (isDragged) | |
{ | |
if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) | |
{ | |
isDragged = false | |
onSymbolDragListener?.onAnnotationDragFinished(symbol) | |
} | |
else | |
{ | |
val latLng = mapBox.projection.fromScreenLocation(PointF(event.x + touchDelta.x, event.y + touchDelta.y)) | |
symbol.latLng = latLng | |
symbolManager.update(symbol) | |
Log.d("Marker", "position $latLng") | |
onSymbolDragListener?.onAnnotationDrag(symbol) | |
} | |
return true | |
} | |
else | |
{ | |
return false | |
} | |
} | |
private fun isSymbolTouched(event: MotionEvent, symbol: Symbol) = mapBox.resolveSymbolId(PointF(event.x, event.y)) == symbol.id | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment