2022-07-11 09:36:43 +03:00
|
|
|
package centre.sciprog.maps
|
2022-07-10 16:05:18 +03:00
|
|
|
|
2022-07-10 22:37:07 +03:00
|
|
|
import kotlin.math.roundToInt
|
|
|
|
|
2022-07-10 16:05:18 +03:00
|
|
|
/**
|
2022-07-10 22:37:07 +03:00
|
|
|
* Observable position on the map. Includes observation coordinate and [zoom] factor
|
2022-07-10 16:05:18 +03:00
|
|
|
*/
|
|
|
|
data class MapViewPoint(
|
|
|
|
val focus: GeodeticMapCoordinates,
|
|
|
|
val zoom: Double,
|
|
|
|
) {
|
2022-07-10 22:37:07 +03:00
|
|
|
val scaleFactor by lazy { WebMercatorProjection.scaleFactor(zoom.roundToInt()) }
|
2022-07-10 16:05:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
fun MapViewPoint.move(deltaX: Float, deltaY: Float): MapViewPoint {
|
|
|
|
val newCoordinates = GeodeticMapCoordinates.ofRadians(
|
|
|
|
(focus.latitude + deltaY / scaleFactor).coerceIn(
|
|
|
|
-MercatorProjection.MAXIMUM_LATITUDE,
|
|
|
|
MercatorProjection.MAXIMUM_LATITUDE
|
|
|
|
),
|
|
|
|
focus.longitude + deltaX / scaleFactor
|
|
|
|
)
|
|
|
|
return MapViewPoint(newCoordinates, zoom)
|
|
|
|
}
|
|
|
|
|
|
|
|
fun MapViewPoint.move(delta: GeodeticMapCoordinates): MapViewPoint {
|
|
|
|
val newCoordinates = GeodeticMapCoordinates.ofRadians(
|
|
|
|
(focus.latitude + delta.latitude).coerceIn(
|
|
|
|
-MercatorProjection.MAXIMUM_LATITUDE,
|
|
|
|
MercatorProjection.MAXIMUM_LATITUDE
|
|
|
|
),
|
|
|
|
focus.longitude + delta.longitude
|
|
|
|
)
|
|
|
|
return MapViewPoint(newCoordinates, zoom)
|
|
|
|
}
|
|
|
|
|
2022-07-10 22:37:07 +03:00
|
|
|
fun MapViewPoint.zoom(zoomDelta: Double): MapViewPoint = copy(zoom = (zoom + zoomDelta).coerceIn(2.0, 18.0))
|