[WIP] bounding boxes
This commit is contained in:
parent
bebd33f859
commit
1541fb4f39
@ -43,6 +43,8 @@ public class GeodeticMapCoordinates private constructor(public val latitude: Dou
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal typealias Gmc = GeodeticMapCoordinates
|
||||||
|
|
||||||
|
|
||||||
//public interface GeoToScreenConversion {
|
//public interface GeoToScreenConversion {
|
||||||
// public fun getScreenX(gmc: GeodeticMapCoordinates): Double
|
// public fun getScreenX(gmc: GeodeticMapCoordinates): Double
|
||||||
|
35
src/commonMain/kotlin/centre/sciprog/maps/GmcBox.kt
Normal file
35
src/commonMain/kotlin/centre/sciprog/maps/GmcBox.kt
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package centre.sciprog.maps
|
||||||
|
|
||||||
|
import kotlin.math.max
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
|
class GmcBox(val a: GeodeticMapCoordinates, val b: GeodeticMapCoordinates)
|
||||||
|
|
||||||
|
fun GmcBox(latitudes: ClosedFloatingPointRange<Double>, longitudes: ClosedFloatingPointRange<Double>) = GmcBox(
|
||||||
|
Gmc.ofRadians(latitudes.start, longitudes.start),
|
||||||
|
Gmc.ofRadians(latitudes.endInclusive, longitudes.endInclusive)
|
||||||
|
)
|
||||||
|
|
||||||
|
val GmcBox.center
|
||||||
|
get() = GeodeticMapCoordinates.ofRadians(
|
||||||
|
(a.latitude + b.latitude) / 2,
|
||||||
|
(a.longitude + b.longitude) / 2
|
||||||
|
)
|
||||||
|
|
||||||
|
val GmcBox.left get() = min(a.longitude, b.longitude)
|
||||||
|
val GmcBox.right get() = max(a.longitude, b.longitude)
|
||||||
|
|
||||||
|
val GmcBox.top get() = max(a.latitude, b.latitude)
|
||||||
|
val GmcBox.bottom get() = min(a.latitude, b.latitude)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute a minimal bounding box including all given boxes
|
||||||
|
*/
|
||||||
|
fun Iterable<GmcBox>.wrapAll(): GmcBox {
|
||||||
|
//TODO optimize computation
|
||||||
|
val minLat = minOf { it.bottom }
|
||||||
|
val maxLat = maxOf { it.top }
|
||||||
|
val minLong = minOf { it.left }
|
||||||
|
val maxLong = maxOf { it.right }
|
||||||
|
return GmcBox(maxLat..maxLat, minLong..maxLong)
|
||||||
|
}
|
@ -9,9 +9,15 @@ import androidx.compose.ui.graphics.vector.VectorPainter
|
|||||||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||||
import androidx.compose.ui.unit.IntSize
|
import androidx.compose.ui.unit.IntSize
|
||||||
import centre.sciprog.maps.GeodeticMapCoordinates
|
import centre.sciprog.maps.GeodeticMapCoordinates
|
||||||
|
import centre.sciprog.maps.GmcBox
|
||||||
|
import centre.sciprog.maps.wrapAll
|
||||||
|
|
||||||
//TODO replace zoom range with zoom-based representation change
|
//TODO replace zoom range with zoom-based representation change
|
||||||
sealed class MapFeature(val zoomRange: IntRange)
|
sealed class MapFeature(val zoomRange: IntRange) {
|
||||||
|
abstract fun getBoundingBox(zoom: Int): GmcBox
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Iterable<MapFeature>.computeBoundingBox(zoom: Int): GmcBox = map { it.getBoundingBox(zoom) }.wrapAll()
|
||||||
|
|
||||||
internal fun Pair<Double, Double>.toCoordinates() = GeodeticMapCoordinates.ofDegrees(first, second)
|
internal fun Pair<Double, Double>.toCoordinates() = GeodeticMapCoordinates.ofDegrees(first, second)
|
||||||
|
|
||||||
@ -20,35 +26,46 @@ internal val defaultZoomRange = 1..18
|
|||||||
/**
|
/**
|
||||||
* A feature that decides what to show depending on the zoom value (it could change size of shape)
|
* A feature that decides what to show depending on the zoom value (it could change size of shape)
|
||||||
*/
|
*/
|
||||||
class MapFeatureSelector(val selector: (zoom: Int) -> MapFeature) : MapFeature(defaultZoomRange)
|
class MapFeatureSelector(val selector: (zoom: Int) -> MapFeature) : MapFeature(defaultZoomRange) {
|
||||||
|
override fun getBoundingBox(zoom: Int): GmcBox = selector(zoom).getBoundingBox(zoom)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
class MapCircleFeature(
|
class MapCircleFeature(
|
||||||
val center: GeodeticMapCoordinates,
|
val center: GeodeticMapCoordinates,
|
||||||
zoomRange: IntRange = defaultZoomRange,
|
zoomRange: IntRange = defaultZoomRange,
|
||||||
val size: Float = 5f,
|
val size: Float = 5f,
|
||||||
val color: Color = Color.Red,
|
val color: Color = Color.Red,
|
||||||
) : MapFeature(zoomRange)
|
) : MapFeature(zoomRange) {
|
||||||
|
override fun getBoundingBox(zoom: Int): GmcBox = GmcBox(center, center)
|
||||||
|
}
|
||||||
|
|
||||||
class MapLineFeature(
|
class MapLineFeature(
|
||||||
val a: GeodeticMapCoordinates,
|
val a: GeodeticMapCoordinates,
|
||||||
val b: GeodeticMapCoordinates,
|
val b: GeodeticMapCoordinates,
|
||||||
zoomRange: IntRange = defaultZoomRange,
|
zoomRange: IntRange = defaultZoomRange,
|
||||||
val color: Color = Color.Red,
|
val color: Color = Color.Red,
|
||||||
) : MapFeature(zoomRange)
|
) : MapFeature(zoomRange) {
|
||||||
|
override fun getBoundingBox(zoom: Int): GmcBox = GmcBox(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
class MapTextFeature(
|
class MapTextFeature(
|
||||||
val position: GeodeticMapCoordinates,
|
val position: GeodeticMapCoordinates,
|
||||||
val text: String,
|
val text: String,
|
||||||
zoomRange: IntRange = defaultZoomRange,
|
zoomRange: IntRange = defaultZoomRange,
|
||||||
val color: Color = Color.Red,
|
val color: Color = Color.Red,
|
||||||
) : MapFeature(zoomRange)
|
) : MapFeature(zoomRange) {
|
||||||
|
override fun getBoundingBox(zoom: Int): GmcBox = GmcBox(position, position)
|
||||||
|
}
|
||||||
|
|
||||||
class MapBitmapImageFeature(
|
class MapBitmapImageFeature(
|
||||||
val position: GeodeticMapCoordinates,
|
val position: GeodeticMapCoordinates,
|
||||||
val image: ImageBitmap,
|
val image: ImageBitmap,
|
||||||
val size: IntSize = IntSize(15, 15),
|
val size: IntSize = IntSize(15, 15),
|
||||||
zoomRange: IntRange = defaultZoomRange,
|
zoomRange: IntRange = defaultZoomRange,
|
||||||
) : MapFeature(zoomRange)
|
) : MapFeature(zoomRange) {
|
||||||
|
override fun getBoundingBox(zoom: Int): GmcBox = GmcBox(position, position)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class MapVectorImageFeature internal constructor(
|
class MapVectorImageFeature internal constructor(
|
||||||
@ -56,7 +73,9 @@ class MapVectorImageFeature internal constructor(
|
|||||||
val painter: VectorPainter,
|
val painter: VectorPainter,
|
||||||
val size: Size,
|
val size: Size,
|
||||||
zoomRange: IntRange = defaultZoomRange,
|
zoomRange: IntRange = defaultZoomRange,
|
||||||
) : MapFeature(zoomRange)
|
) : MapFeature(zoomRange) {
|
||||||
|
override fun getBoundingBox(zoom: Int): GmcBox = GmcBox(position, position)
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MapVectorImageFeature(
|
fun MapVectorImageFeature(
|
||||||
|
Loading…
Reference in New Issue
Block a user