[WIP] bounding boxes

This commit is contained in:
Alexander Nozik 2022-07-14 10:36:16 +03:00
parent bebd33f859
commit 1541fb4f39
No known key found for this signature in database
GPG Key ID: F7FCF2DD25C71357
3 changed files with 63 additions and 7 deletions

View File

@ -43,6 +43,8 @@ public class GeodeticMapCoordinates private constructor(public val latitude: Dou
}
}
internal typealias Gmc = GeodeticMapCoordinates
//public interface GeoToScreenConversion {
// public fun getScreenX(gmc: GeodeticMapCoordinates): Double

View 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)
}

View File

@ -9,9 +9,15 @@ import androidx.compose.ui.graphics.vector.VectorPainter
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.unit.IntSize
import centre.sciprog.maps.GeodeticMapCoordinates
import centre.sciprog.maps.GmcBox
import centre.sciprog.maps.wrapAll
//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)
@ -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)
*/
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(
val center: GeodeticMapCoordinates,
zoomRange: IntRange = defaultZoomRange,
val size: Float = 5f,
val color: Color = Color.Red,
) : MapFeature(zoomRange)
) : MapFeature(zoomRange) {
override fun getBoundingBox(zoom: Int): GmcBox = GmcBox(center, center)
}
class MapLineFeature(
val a: GeodeticMapCoordinates,
val b: GeodeticMapCoordinates,
zoomRange: IntRange = defaultZoomRange,
val color: Color = Color.Red,
) : MapFeature(zoomRange)
) : MapFeature(zoomRange) {
override fun getBoundingBox(zoom: Int): GmcBox = GmcBox(a, b)
}
class MapTextFeature(
val position: GeodeticMapCoordinates,
val text: String,
zoomRange: IntRange = defaultZoomRange,
val color: Color = Color.Red,
) : MapFeature(zoomRange)
) : MapFeature(zoomRange) {
override fun getBoundingBox(zoom: Int): GmcBox = GmcBox(position, position)
}
class MapBitmapImageFeature(
val position: GeodeticMapCoordinates,
val image: ImageBitmap,
val size: IntSize = IntSize(15, 15),
zoomRange: IntRange = defaultZoomRange,
) : MapFeature(zoomRange)
) : MapFeature(zoomRange) {
override fun getBoundingBox(zoom: Int): GmcBox = GmcBox(position, position)
}
class MapVectorImageFeature internal constructor(
@ -56,7 +73,9 @@ class MapVectorImageFeature internal constructor(
val painter: VectorPainter,
val size: Size,
zoomRange: IntRange = defaultZoomRange,
) : MapFeature(zoomRange)
) : MapFeature(zoomRange) {
override fun getBoundingBox(zoom: Int): GmcBox = GmcBox(position, position)
}
@Composable
fun MapVectorImageFeature(