OnDragg functionality added #7
@ -12,6 +12,7 @@ import androidx.compose.ui.window.application
|
|||||||
import centre.sciprog.maps.GeodeticMapCoordinates
|
import centre.sciprog.maps.GeodeticMapCoordinates
|
||||||
import centre.sciprog.maps.MapViewPoint
|
import centre.sciprog.maps.MapViewPoint
|
||||||
import centre.sciprog.maps.compose.*
|
import centre.sciprog.maps.compose.*
|
||||||
|
import centre.sciprog.maps.toDegrees
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.client.engine.cio.CIO
|
import io.ktor.client.engine.cio.CIO
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
@ -47,18 +48,27 @@ fun App() {
|
|||||||
|
|
||||||
var centerCoordinates by remember { mutableStateOf<GeodeticMapCoordinates?>(null) }
|
var centerCoordinates by remember { mutableStateOf<GeodeticMapCoordinates?>(null) }
|
||||||
|
|
||||||
|
val pointOne = 55.568548 to 37.568604
|
||||||
|
var pointTwo by remember { mutableStateOf(55.929444 to 37.518434) }
|
||||||
|
val pointThree = 60.929444 to 37.518434
|
||||||
|
|
||||||
MapView(
|
MapView(
|
||||||
mapTileProvider = mapTileProvider,
|
mapTileProvider = mapTileProvider,
|
||||||
initialViewPoint = viewPoint,
|
initialViewPoint = viewPoint,
|
||||||
config = MapViewConfig(
|
config = MapViewConfig(
|
||||||
inferViewBoxFromFeatures = true,
|
inferViewBoxFromFeatures = true,
|
||||||
onViewChange = { centerCoordinates = focus }
|
onViewChange = { centerCoordinates = focus },
|
||||||
|
onDrag = { start, end ->
|
||||||
|
if (start.focus.latitude.toDegrees() in (pointTwo.first - 0.05)..(pointTwo.first + 0.05) &&
|
||||||
|
start.focus.longitude.toDegrees() in (pointTwo.second - 0.05)..(pointTwo.second + 0.05)
|
||||||
|
) {
|
||||||
|
pointTwo = pointTwo.first + (end.focus.latitude - start.focus.latitude).toDegrees() to
|
||||||
|
pointTwo.second + (end.focus.longitude - start.focus.longitude).toDegrees()
|
||||||
|
false
|
||||||
|
} else true
|
||||||
|
}
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
val pointOne = 55.568548 to 37.568604
|
|
||||||
val pointTwo = 55.929444 to 37.518434
|
|
||||||
val pointThree = 60.929444 to 37.518434
|
|
||||||
|
|
||||||
image(pointOne, Icons.Filled.Home)
|
image(pointOne, Icons.Filled.Home)
|
||||||
|
|
||||||
@ -75,7 +85,7 @@ fun App() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
line(pointOne, pointTwo)
|
line(pointOne, pointTwo, id = "Line")
|
||||||
text(pointOne, "Home")
|
text(pointOne, "Home")
|
||||||
|
|
||||||
centerCoordinates?.let {
|
centerCoordinates?.let {
|
||||||
|
@ -17,6 +17,7 @@ data class MapViewConfig(
|
|||||||
val onClick: MapViewPoint.() -> Unit = {},
|
val onClick: MapViewPoint.() -> Unit = {},
|
||||||
val onViewChange: MapViewPoint.() -> Unit = {},
|
val onViewChange: MapViewPoint.() -> Unit = {},
|
||||||
val onSelect: (GmcBox) -> Unit = {},
|
val onSelect: (GmcBox) -> Unit = {},
|
||||||
|
val onDrag: (MapViewPoint, MapViewPoint) -> Boolean = { _, _ -> true },
|
||||||
|
|||||||
val zoomOnSelect: Boolean = true
|
val zoomOnSelect: Boolean = true
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -49,7 +50,8 @@ fun MapView(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun GmcBox.getComputeViewPoint(mapTileProvider: MapTileProvider): (canvasSize: DpSize) -> MapViewPoint = { canvasSize ->
|
internal fun GmcBox.getComputeViewPoint(mapTileProvider: MapTileProvider): (canvasSize: DpSize) -> MapViewPoint =
|
||||||
|
{ canvasSize ->
|
||||||
val zoom = log2(
|
val zoom = log2(
|
||||||
min(
|
min(
|
||||||
canvasSize.width.value / width,
|
canvasSize.width.value / width,
|
||||||
@ -57,7 +59,7 @@ internal fun GmcBox.getComputeViewPoint(mapTileProvider: MapTileProvider): (canv
|
|||||||
) * PI / mapTileProvider.tileSize
|
) * PI / mapTileProvider.tileSize
|
||||||
)
|
)
|
||||||
MapViewPoint(center, zoom)
|
MapViewPoint(center, zoom)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MapView(
|
fun MapView(
|
||||||
|
@ -131,7 +131,7 @@ actual fun MapView(
|
|||||||
rect.bottomRight.toDpOffset().toGeodetic()
|
rect.bottomRight.toDpOffset().toGeodetic()
|
||||||
)
|
)
|
||||||
config.onSelect(gmcBox)
|
config.onSelect(gmcBox)
|
||||||
if(config.zoomOnSelect) {
|
if (config.zoomOnSelect) {
|
||||||
val newViewPoint = gmcBox.getComputeViewPoint(mapTileProvider).invoke(canvasSize)
|
val newViewPoint = gmcBox.getComputeViewPoint(mapTileProvider).invoke(canvasSize)
|
||||||
|
|
||||||
config.onViewChange(newViewPoint)
|
config.onViewChange(newViewPoint)
|
||||||
@ -144,6 +144,14 @@ actual fun MapView(
|
|||||||
val dpPos = DpOffset(dragStart.x.toDp(), dragStart.y.toDp())
|
val dpPos = DpOffset(dragStart.x.toDp(), dragStart.y.toDp())
|
||||||
config.onClick(MapViewPoint(dpPos.toGeodetic(), viewPoint.zoom))
|
config.onClick(MapViewPoint(dpPos.toGeodetic(), viewPoint.zoom))
|
||||||
drag(change.id) { dragChange ->
|
drag(change.id) { dragChange ->
|
||||||
|
val dpStartPos =
|
||||||
|
DpOffset(dragChange.previousPosition.x.toDp(), dragChange.previousPosition.y.toDp())
|
||||||
|
val dpEndPos = DpOffset(dragChange.position.x.toDp(), dragChange.position.y.toDp())
|
||||||
|
if (!config.onDrag(
|
||||||
|
MapViewPoint(dpStartPos.toGeodetic(), viewPoint.zoom),
|
||||||
|
MapViewPoint(dpEndPos.toGeodetic(), viewPoint.zoom)
|
||||||
|
)
|
||||||
|
) return@drag
|
||||||
val dragAmount = dragChange.position - dragChange.previousPosition
|
val dragAmount = dragChange.position - dragChange.previousPosition
|
||||||
val newViewPoint = viewPoint.move(
|
val newViewPoint = viewPoint.move(
|
||||||
-dragAmount.x.toDp().value / tileScale,
|
-dragAmount.x.toDp().value / tileScale,
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
package centre.sciprog.maps
|
||||||
|
|
||||||
|
import kotlin.math.PI
|
||||||
|
|
||||||
|
fun Double.toDegrees() = this * 180 / PI
|
||||||
This polutes the global name space. Sadly it is not acceptable for the library. Move to demo. In order to introduce something like this, we need to limit it to a scope, or introduce value classes for radians or degrees. This polutes the global name space. Sadly it is not acceptable for the library. Move to demo. In order to introduce something like this, we need to limit it to a scope, or introduce value classes for radians or degrees.
|
|||||||
|
|
||||||
|
fun Double.toRadians() = this * PI / 180
|
Loading…
Reference in New Issue
Block a user
It is not clear, how it works, needs to be documented