Add js support for features
This commit is contained in:
parent
8969b2b094
commit
33cadb1d15
@ -4,5 +4,6 @@ compose.version=1.2.2
|
|||||||
|
|
||||||
agp.version=4.2.2
|
agp.version=4.2.2
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
|
org.jetbrains.compose.experimental.jscanvas.enabled=true
|
||||||
|
|
||||||
toolsVersion=0.13.3-kotlin-1.7.20
|
toolsVersion=0.13.3-kotlin-1.7.20
|
@ -9,36 +9,35 @@ import androidx.compose.ui.unit.DpSize
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import center.sciprog.maps.coordinates.*
|
import center.sciprog.maps.coordinates.*
|
||||||
import center.sciprog.maps.features.*
|
import center.sciprog.maps.features.*
|
||||||
import center.sciprog.maps.features.Feature.Companion.defaultZoomRange
|
|
||||||
|
|
||||||
|
|
||||||
internal fun FeatureCollection<Gmc>.coordinatesOf(pair: Pair<Number, Number>) =
|
internal fun FeatureBuilder<Gmc>.coordinatesOf(pair: Pair<Number, Number>) =
|
||||||
GeodeticMapCoordinates.ofDegrees(pair.first.toDouble(), pair.second.toDouble())
|
GeodeticMapCoordinates.ofDegrees(pair.first.toDouble(), pair.second.toDouble())
|
||||||
|
|
||||||
public typealias MapFeature = Feature<Gmc>
|
public typealias MapFeature = Feature<Gmc>
|
||||||
|
|
||||||
public fun FeatureCollection<Gmc>.circle(
|
public fun FeatureBuilder<Gmc>.circle(
|
||||||
centerCoordinates: Pair<Number, Number>,
|
centerCoordinates: Pair<Number, Number>,
|
||||||
zoomRange: DoubleRange = defaultZoomRange,
|
zoomRange: DoubleRange = defaultZoomRange,
|
||||||
size: Dp = 5.dp,
|
size: Dp = 5.dp,
|
||||||
color: Color = Color.Red,
|
color: Color = defaultColor,
|
||||||
id: String? = null,
|
id: String? = null,
|
||||||
): FeatureId<CircleFeature<Gmc>> = feature(
|
): FeatureId<CircleFeature<Gmc>> = feature(
|
||||||
id, CircleFeature(coordinateSpace, coordinatesOf(centerCoordinates), zoomRange, size, color)
|
id, CircleFeature(coordinateSpace, coordinatesOf(centerCoordinates), zoomRange, size, color)
|
||||||
)
|
)
|
||||||
|
|
||||||
public fun FeatureCollection<Gmc>.rectangle(
|
public fun FeatureBuilder<Gmc>.rectangle(
|
||||||
centerCoordinates: Pair<Number, Number>,
|
centerCoordinates: Pair<Number, Number>,
|
||||||
zoomRange: DoubleRange = defaultZoomRange,
|
zoomRange: DoubleRange = defaultZoomRange,
|
||||||
size: DpSize = DpSize(5.dp, 5.dp),
|
size: DpSize = DpSize(5.dp, 5.dp),
|
||||||
color: Color = Color.Red,
|
color: Color = defaultColor,
|
||||||
id: String? = null,
|
id: String? = null,
|
||||||
): FeatureId<RectangleFeature<Gmc>> = feature(
|
): FeatureId<RectangleFeature<Gmc>> = feature(
|
||||||
id, RectangleFeature(coordinateSpace, coordinatesOf(centerCoordinates), zoomRange, size, color)
|
id, RectangleFeature(coordinateSpace, coordinatesOf(centerCoordinates), zoomRange, size, color)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
public fun FeatureCollection<Gmc>.draw(
|
public fun FeatureBuilder<Gmc>.draw(
|
||||||
position: Pair<Number, Number>,
|
position: Pair<Number, Number>,
|
||||||
zoomRange: DoubleRange = defaultZoomRange,
|
zoomRange: DoubleRange = defaultZoomRange,
|
||||||
id: String? = null,
|
id: String? = null,
|
||||||
@ -49,10 +48,10 @@ public fun FeatureCollection<Gmc>.draw(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
public fun FeatureCollection<Gmc>.line(
|
public fun FeatureBuilder<Gmc>.line(
|
||||||
curve: GmcCurve,
|
curve: GmcCurve,
|
||||||
zoomRange: DoubleRange = defaultZoomRange,
|
zoomRange: DoubleRange = defaultZoomRange,
|
||||||
color: Color = Color.Red,
|
color: Color = defaultColor,
|
||||||
id: String? = null,
|
id: String? = null,
|
||||||
): FeatureId<LineFeature<Gmc>> = feature(
|
): FeatureId<LineFeature<Gmc>> = feature(
|
||||||
id,
|
id,
|
||||||
@ -60,11 +59,11 @@ public fun FeatureCollection<Gmc>.line(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
public fun FeatureCollection<Gmc>.line(
|
public fun FeatureBuilder<Gmc>.line(
|
||||||
aCoordinates: Pair<Double, Double>,
|
aCoordinates: Pair<Double, Double>,
|
||||||
bCoordinates: Pair<Double, Double>,
|
bCoordinates: Pair<Double, Double>,
|
||||||
zoomRange: DoubleRange = defaultZoomRange,
|
zoomRange: DoubleRange = defaultZoomRange,
|
||||||
color: Color = Color.Red,
|
color: Color = defaultColor,
|
||||||
id: String? = null,
|
id: String? = null,
|
||||||
): FeatureId<LineFeature<Gmc>> = feature(
|
): FeatureId<LineFeature<Gmc>> = feature(
|
||||||
id,
|
id,
|
||||||
@ -72,19 +71,19 @@ public fun FeatureCollection<Gmc>.line(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
public fun FeatureCollection<Gmc>.arc(
|
public fun FeatureBuilder<Gmc>.arc(
|
||||||
center: Pair<Double, Double>,
|
center: Pair<Double, Double>,
|
||||||
radius: Distance,
|
radius: Distance,
|
||||||
startAngle: Angle,
|
startAngle: Angle,
|
||||||
arcLength: Angle,
|
arcLength: Angle,
|
||||||
zoomRange: DoubleRange = defaultZoomRange,
|
zoomRange: DoubleRange = defaultZoomRange,
|
||||||
color: Color = Color.Red,
|
color: Color = defaultColor,
|
||||||
id: String? = null,
|
id: String? = null,
|
||||||
): FeatureId<ArcFeature<Gmc>> = feature(
|
): FeatureId<ArcFeature<Gmc>> = feature(
|
||||||
id,
|
id,
|
||||||
ArcFeature(
|
ArcFeature(
|
||||||
coordinateSpace,
|
coordinateSpace,
|
||||||
oval = Rectangle(coordinatesOf(center), radius, radius),
|
oval = coordinateSpace.Rectangle(coordinatesOf(center), radius, radius),
|
||||||
startAngle = startAngle.radians.toFloat(),
|
startAngle = startAngle.radians.toFloat(),
|
||||||
arcLength = arcLength.radians.toFloat(),
|
arcLength = arcLength.radians.toFloat(),
|
||||||
zoomRange = zoomRange,
|
zoomRange = zoomRange,
|
||||||
@ -92,17 +91,17 @@ public fun FeatureCollection<Gmc>.arc(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
public fun FeatureCollection<Gmc>.points(
|
public fun FeatureBuilder<Gmc>.points(
|
||||||
points: List<Pair<Double, Double>>,
|
points: List<Pair<Double, Double>>,
|
||||||
zoomRange: DoubleRange = defaultZoomRange,
|
zoomRange: DoubleRange = defaultZoomRange,
|
||||||
stroke: Float = 2f,
|
stroke: Float = 2f,
|
||||||
color: Color = Color.Red,
|
color: Color = defaultColor,
|
||||||
pointMode: PointMode = PointMode.Points,
|
pointMode: PointMode = PointMode.Points,
|
||||||
id: String? = null,
|
id: String? = null,
|
||||||
): FeatureId<PointsFeature<Gmc>> =
|
): FeatureId<PointsFeature<Gmc>> =
|
||||||
feature(id, PointsFeature(coordinateSpace, points.map(::coordinatesOf), zoomRange, stroke, color, pointMode))
|
feature(id, PointsFeature(coordinateSpace, points.map(::coordinatesOf), zoomRange, stroke, color, pointMode))
|
||||||
|
|
||||||
public fun FeatureCollection<Gmc>.image(
|
public fun FeatureBuilder<Gmc>.image(
|
||||||
position: Pair<Double, Double>,
|
position: Pair<Double, Double>,
|
||||||
image: ImageVector,
|
image: ImageVector,
|
||||||
size: DpSize = DpSize(20.dp, 20.dp),
|
size: DpSize = DpSize(20.dp, 20.dp),
|
||||||
@ -119,11 +118,11 @@ public fun FeatureCollection<Gmc>.image(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
public fun FeatureCollection<Gmc>.text(
|
public fun FeatureBuilder<Gmc>.text(
|
||||||
position: Pair<Double, Double>,
|
position: Pair<Double, Double>,
|
||||||
text: String,
|
text: String,
|
||||||
zoomRange: DoubleRange = defaultZoomRange,
|
zoomRange: DoubleRange = defaultZoomRange,
|
||||||
color: Color = Color.Red,
|
color: Color = defaultColor,
|
||||||
font: FeatureFont.() -> Unit = { size = 16f },
|
font: FeatureFont.() -> Unit = { size = 16f },
|
||||||
id: String? = null,
|
id: String? = null,
|
||||||
): FeatureId<TextFeature<Gmc>> = feature(
|
): FeatureId<TextFeature<Gmc>> = feature(
|
||||||
|
@ -98,7 +98,7 @@ public actual fun MapView(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val painterCache: Map<PainterFeature<Gmc>, Painter> = key(featuresState) {
|
val painterCache: Map<PainterFeature<Gmc>, Painter> = key(featuresState) {
|
||||||
featuresState.features.values.filterIsInstance<PainterFeature<Gmc>>().associateWith { it.painter() }
|
featuresState.features.values.filterIsInstance<PainterFeature<Gmc>>().associateWith { it.getPainter() }
|
||||||
}
|
}
|
||||||
|
|
||||||
Canvas(modifier = modifier.mapControls(state).fillMaxSize()) {
|
Canvas(modifier = modifier.mapControls(state).fillMaxSize()) {
|
||||||
|
@ -6,6 +6,7 @@ package center.sciprog.maps.coordinates
|
|||||||
public class GeodeticMapCoordinates(
|
public class GeodeticMapCoordinates(
|
||||||
public val latitude: Angle,
|
public val latitude: Angle,
|
||||||
longitude: Angle,
|
longitude: Angle,
|
||||||
|
public val elevation: Distance = 0.kilometers
|
||||||
) {
|
) {
|
||||||
public val longitude: Angle = longitude.normalized(Angle.zero)
|
public val longitude: Angle = longitude.normalized(Angle.zero)
|
||||||
|
|
||||||
|
@ -1,39 +1,15 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("multiplatform")
|
id("space.kscience.gradle.mpp")
|
||||||
id("org.jetbrains.compose")
|
id("org.jetbrains.compose")
|
||||||
`maven-publish`
|
`maven-publish`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
explicitApi = org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode.Warning
|
|
||||||
jvm {
|
|
||||||
compilations.all {
|
|
||||||
kotlinOptions.jvmTarget = space.kscience.gradle.KScienceVersions.JVM_TARGET.toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
commonMain {
|
commonMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
api(compose.foundation)
|
api(compose.foundation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val jvmMain by getting{
|
|
||||||
|
|
||||||
}
|
|
||||||
val jvmTest by getting {
|
|
||||||
dependencies {
|
|
||||||
implementation(kotlin("test-junit5"))
|
|
||||||
implementation("org.junit.jupiter:junit-jupiter:5.8.2")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
targetCompatibility = space.kscience.gradle.KScienceVersions.JVM_TARGET
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.withType<Test> {
|
|
||||||
useJUnitPlatform()
|
|
||||||
}
|
}
|
@ -30,7 +30,7 @@ public class AttributeMap {
|
|||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (javaClass != other?.javaClass) return false
|
if (other == null || this::class != other::class) return false
|
||||||
|
|
||||||
other as AttributeMap
|
other as AttributeMap
|
||||||
|
|
||||||
|
@ -13,7 +13,6 @@ import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
|||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.DpSize
|
import androidx.compose.ui.unit.DpSize
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import center.sciprog.maps.features.Feature.Companion.defaultZoomRange
|
|
||||||
|
|
||||||
public typealias DoubleRange = FloatRange
|
public typealias DoubleRange = FloatRange
|
||||||
public typealias FloatRange = ClosedFloatingPointRange<Float>
|
public typealias FloatRange = ClosedFloatingPointRange<Float>
|
||||||
@ -28,15 +27,11 @@ public interface Feature<T : Any> {
|
|||||||
public var attributes: AttributeMap
|
public var attributes: AttributeMap
|
||||||
|
|
||||||
public fun getBoundingBox(zoom: Float): Rectangle<T>?
|
public fun getBoundingBox(zoom: Float): Rectangle<T>?
|
||||||
|
|
||||||
public companion object {
|
|
||||||
public val defaultZoomRange: FloatRange = 0f..Float.POSITIVE_INFINITY
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface PainterFeature<T:Any>: Feature<T> {
|
public interface PainterFeature<T:Any>: Feature<T> {
|
||||||
@Composable
|
@Composable
|
||||||
public fun painter(): Painter
|
public fun getPainter(): Painter
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface SelectableFeature<T : Any> : Feature<T> {
|
public interface SelectableFeature<T : Any> : Feature<T> {
|
||||||
@ -72,10 +67,11 @@ public fun <T : Any> Iterable<Feature<T>>.computeBoundingBox(
|
|||||||
*/
|
*/
|
||||||
public class FeatureSelector<T : Any>(
|
public class FeatureSelector<T : Any>(
|
||||||
override val space: CoordinateSpace<T>,
|
override val space: CoordinateSpace<T>,
|
||||||
|
override val zoomRange: FloatRange,
|
||||||
override var attributes: AttributeMap = AttributeMap(),
|
override var attributes: AttributeMap = AttributeMap(),
|
||||||
public val selector: (zoom: Float) -> Feature<T>,
|
public val selector: (zoom: Float) -> Feature<T>,
|
||||||
) : Feature<T> {
|
) : Feature<T> {
|
||||||
override val zoomRange: FloatRange get() = defaultZoomRange
|
|
||||||
|
|
||||||
override fun getBoundingBox(zoom: Float): Rectangle<T>? = selector(zoom).getBoundingBox(zoom)
|
override fun getBoundingBox(zoom: Float): Rectangle<T>? = selector(zoom).getBoundingBox(zoom)
|
||||||
}
|
}
|
||||||
@ -85,9 +81,9 @@ public class PathFeature<T : Any>(
|
|||||||
public val rectangle: Rectangle<T>,
|
public val rectangle: Rectangle<T>,
|
||||||
public val path: Path,
|
public val path: Path,
|
||||||
public val brush: Brush,
|
public val brush: Brush,
|
||||||
|
override val zoomRange: FloatRange,
|
||||||
public val style: DrawStyle = Fill,
|
public val style: DrawStyle = Fill,
|
||||||
public val targetRect: Rect = path.getBounds(),
|
public val targetRect: Rect = path.getBounds(),
|
||||||
override val zoomRange: FloatRange = defaultZoomRange,
|
|
||||||
override var attributes: AttributeMap = AttributeMap(),
|
override var attributes: AttributeMap = AttributeMap(),
|
||||||
) : DraggableFeature<T> {
|
) : DraggableFeature<T> {
|
||||||
override fun withCoordinates(newCoordinates: T): Feature<T> = with(space) {
|
override fun withCoordinates(newCoordinates: T): Feature<T> = with(space) {
|
||||||
@ -109,7 +105,7 @@ public class PathFeature<T : Any>(
|
|||||||
public class PointsFeature<T : Any>(
|
public class PointsFeature<T : Any>(
|
||||||
override val space: CoordinateSpace<T>,
|
override val space: CoordinateSpace<T>,
|
||||||
public val points: List<T>,
|
public val points: List<T>,
|
||||||
override val zoomRange: FloatRange = defaultZoomRange,
|
override val zoomRange: FloatRange,
|
||||||
public val stroke: Float = 2f,
|
public val stroke: Float = 2f,
|
||||||
public val color: Color = Color.Red,
|
public val color: Color = Color.Red,
|
||||||
public val pointMode: PointMode = PointMode.Points,
|
public val pointMode: PointMode = PointMode.Points,
|
||||||
@ -123,7 +119,7 @@ public class PointsFeature<T : Any>(
|
|||||||
public data class CircleFeature<T : Any>(
|
public data class CircleFeature<T : Any>(
|
||||||
override val space: CoordinateSpace<T>,
|
override val space: CoordinateSpace<T>,
|
||||||
override val center: T,
|
override val center: T,
|
||||||
override val zoomRange: FloatRange = defaultZoomRange,
|
override val zoomRange: FloatRange,
|
||||||
public val size: Dp = 5.dp,
|
public val size: Dp = 5.dp,
|
||||||
public val color: Color = Color.Red,
|
public val color: Color = Color.Red,
|
||||||
override var attributes: AttributeMap = AttributeMap(),
|
override var attributes: AttributeMap = AttributeMap(),
|
||||||
@ -138,7 +134,7 @@ public data class CircleFeature<T : Any>(
|
|||||||
public class RectangleFeature<T : Any>(
|
public class RectangleFeature<T : Any>(
|
||||||
override val space: CoordinateSpace<T>,
|
override val space: CoordinateSpace<T>,
|
||||||
override val center: T,
|
override val center: T,
|
||||||
override val zoomRange: FloatRange = defaultZoomRange,
|
override val zoomRange: FloatRange,
|
||||||
public val size: DpSize = DpSize(5.dp, 5.dp),
|
public val size: DpSize = DpSize(5.dp, 5.dp),
|
||||||
public val color: Color = Color.Red,
|
public val color: Color = Color.Red,
|
||||||
override var attributes: AttributeMap = AttributeMap(),
|
override var attributes: AttributeMap = AttributeMap(),
|
||||||
@ -154,7 +150,7 @@ public class LineFeature<T : Any>(
|
|||||||
override val space: CoordinateSpace<T>,
|
override val space: CoordinateSpace<T>,
|
||||||
public val a: T,
|
public val a: T,
|
||||||
public val b: T,
|
public val b: T,
|
||||||
override val zoomRange: FloatRange = defaultZoomRange,
|
override val zoomRange: FloatRange,
|
||||||
public val color: Color = Color.Red,
|
public val color: Color = Color.Red,
|
||||||
override var attributes: AttributeMap = AttributeMap(),
|
override var attributes: AttributeMap = AttributeMap(),
|
||||||
) : SelectableFeature<T> {
|
) : SelectableFeature<T> {
|
||||||
@ -175,7 +171,7 @@ public class ArcFeature<T : Any>(
|
|||||||
public val oval: Rectangle<T>,
|
public val oval: Rectangle<T>,
|
||||||
public val startAngle: Float,
|
public val startAngle: Float,
|
||||||
public val arcLength: Float,
|
public val arcLength: Float,
|
||||||
override val zoomRange: FloatRange = defaultZoomRange,
|
override val zoomRange: FloatRange,
|
||||||
public val color: Color = Color.Red,
|
public val color: Color = Color.Red,
|
||||||
override var attributes: AttributeMap = AttributeMap(),
|
override var attributes: AttributeMap = AttributeMap(),
|
||||||
) : DraggableFeature<T> {
|
) : DraggableFeature<T> {
|
||||||
@ -189,7 +185,7 @@ public class ArcFeature<T : Any>(
|
|||||||
public data class DrawFeature<T : Any>(
|
public data class DrawFeature<T : Any>(
|
||||||
override val space: CoordinateSpace<T>,
|
override val space: CoordinateSpace<T>,
|
||||||
public val position: T,
|
public val position: T,
|
||||||
override val zoomRange: FloatRange = defaultZoomRange,
|
override val zoomRange: FloatRange,
|
||||||
override var attributes: AttributeMap = AttributeMap(),
|
override var attributes: AttributeMap = AttributeMap(),
|
||||||
public val drawFeature: DrawScope.() -> Unit,
|
public val drawFeature: DrawScope.() -> Unit,
|
||||||
) : DraggableFeature<T> {
|
) : DraggableFeature<T> {
|
||||||
@ -203,7 +199,7 @@ public data class BitmapImageFeature<T : Any>(
|
|||||||
override val center: T,
|
override val center: T,
|
||||||
public val size: DpSize,
|
public val size: DpSize,
|
||||||
public val image: ImageBitmap,
|
public val image: ImageBitmap,
|
||||||
override val zoomRange: FloatRange = defaultZoomRange,
|
override val zoomRange: FloatRange,
|
||||||
override var attributes: AttributeMap = AttributeMap(),
|
override var attributes: AttributeMap = AttributeMap(),
|
||||||
) : MarkerFeature<T> {
|
) : MarkerFeature<T> {
|
||||||
override fun getBoundingBox(zoom: Float): Rectangle<T> = space.Rectangle(center, zoom, size)
|
override fun getBoundingBox(zoom: Float): Rectangle<T> = space.Rectangle(center, zoom, size)
|
||||||
@ -216,7 +212,7 @@ public data class VectorImageFeature<T : Any>(
|
|||||||
override val center: T,
|
override val center: T,
|
||||||
public val size: DpSize,
|
public val size: DpSize,
|
||||||
public val image: ImageVector,
|
public val image: ImageVector,
|
||||||
override val zoomRange: FloatRange = defaultZoomRange,
|
override val zoomRange: FloatRange,
|
||||||
override var attributes: AttributeMap = AttributeMap(),
|
override var attributes: AttributeMap = AttributeMap(),
|
||||||
) : MarkerFeature<T>, PainterFeature<T> {
|
) : MarkerFeature<T>, PainterFeature<T> {
|
||||||
override fun getBoundingBox(zoom: Float): Rectangle<T> = space.Rectangle(center, zoom, size)
|
override fun getBoundingBox(zoom: Float): Rectangle<T> = space.Rectangle(center, zoom, size)
|
||||||
@ -224,7 +220,7 @@ public data class VectorImageFeature<T : Any>(
|
|||||||
override fun withCoordinates(newCoordinates: T): Feature<T> = copy(center = newCoordinates)
|
override fun withCoordinates(newCoordinates: T): Feature<T> = copy(center = newCoordinates)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun painter(): VectorPainter = rememberVectorPainter(image)
|
override fun getPainter(): VectorPainter = rememberVectorPainter(image)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -235,12 +231,12 @@ public data class VectorImageFeature<T : Any>(
|
|||||||
public class ScalableImageFeature<T: Any>(
|
public class ScalableImageFeature<T: Any>(
|
||||||
override val space: CoordinateSpace<T>,
|
override val space: CoordinateSpace<T>,
|
||||||
public val rectangle: Rectangle<T>,
|
public val rectangle: Rectangle<T>,
|
||||||
override val zoomRange: FloatRange = defaultZoomRange,
|
override val zoomRange: FloatRange,
|
||||||
override var attributes: AttributeMap = AttributeMap(),
|
override var attributes: AttributeMap = AttributeMap(),
|
||||||
public val painter: @Composable () -> Painter,
|
public val painter: @Composable () -> Painter,
|
||||||
) : Feature<T>, PainterFeature<T>{
|
) : Feature<T>, PainterFeature<T>{
|
||||||
@Composable
|
@Composable
|
||||||
override fun painter(): Painter = painter.invoke()
|
override fun getPainter(): Painter = painter.invoke()
|
||||||
|
|
||||||
override fun getBoundingBox(zoom: Float): Rectangle<T> =rectangle
|
override fun getBoundingBox(zoom: Float): Rectangle<T> =rectangle
|
||||||
}
|
}
|
||||||
@ -252,7 +248,7 @@ public class ScalableImageFeature<T: Any>(
|
|||||||
public class FeatureGroup<T : Any>(
|
public class FeatureGroup<T : Any>(
|
||||||
override val space: CoordinateSpace<T>,
|
override val space: CoordinateSpace<T>,
|
||||||
public val children: Map<FeatureId<*>, Feature<T>>,
|
public val children: Map<FeatureId<*>, Feature<T>>,
|
||||||
override val zoomRange: FloatRange = defaultZoomRange,
|
override val zoomRange: FloatRange,
|
||||||
override var attributes: AttributeMap = AttributeMap(),
|
override var attributes: AttributeMap = AttributeMap(),
|
||||||
) : Feature<T> {
|
) : Feature<T> {
|
||||||
override fun getBoundingBox(zoom: Float): Rectangle<T>? = with(space) {
|
override fun getBoundingBox(zoom: Float): Rectangle<T>? = with(space) {
|
||||||
@ -264,7 +260,7 @@ public class TextFeature<T : Any>(
|
|||||||
override val space: CoordinateSpace<T>,
|
override val space: CoordinateSpace<T>,
|
||||||
public val position: T,
|
public val position: T,
|
||||||
public val text: String,
|
public val text: String,
|
||||||
override val zoomRange: FloatRange = defaultZoomRange,
|
override val zoomRange: FloatRange,
|
||||||
public val color: Color = Color.Black,
|
public val color: Color = Color.Black,
|
||||||
override var attributes: AttributeMap = AttributeMap(),
|
override var attributes: AttributeMap = AttributeMap(),
|
||||||
public val fontConfig: FeatureFont.() -> Unit,
|
public val fontConfig: FeatureFont.() -> Unit,
|
||||||
|
@ -11,11 +11,11 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
|||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.DpSize
|
import androidx.compose.ui.unit.DpSize
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import center.sciprog.maps.features.Feature.Companion.defaultZoomRange
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.isActive
|
import kotlinx.coroutines.isActive
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlin.jvm.JvmInline
|
||||||
|
|
||||||
@JvmInline
|
@JvmInline
|
||||||
public value class FeatureId<out F : Feature<*>>(public val id: String)
|
public value class FeatureId<out F : Feature<*>>(public val id: String)
|
||||||
@ -29,6 +29,8 @@ public interface FeatureBuilder<T : Any> {
|
|||||||
public fun <F : Feature<T>, V> setAttribute(id: FeatureId<F>, key: Feature.Attribute<V>, value: V?)
|
public fun <F : Feature<T>, V> setAttribute(id: FeatureId<F>, key: Feature.Attribute<V>, value: V?)
|
||||||
|
|
||||||
public val defaultColor: Color get() = Color.Red
|
public val defaultColor: Color get() = Color.Red
|
||||||
|
|
||||||
|
public val defaultZoomRange: FloatRange get() = 0f..Float.POSITIVE_INFINITY
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun <T : Any, F : Feature<T>> FeatureBuilder<T>.feature(id: FeatureId<F>, feature: F): FeatureId<F> =
|
public fun <T : Any, F : Feature<T>> FeatureBuilder<T>.feature(id: FeatureId<F>, feature: F): FeatureId<F> =
|
||||||
|
@ -6,7 +6,7 @@ import androidx.compose.ui.graphics.Color
|
|||||||
public fun <T : Any> FeatureCollection<T>.draggableLine(
|
public fun <T : Any> FeatureCollection<T>.draggableLine(
|
||||||
aId: FeatureId<MarkerFeature<T>>,
|
aId: FeatureId<MarkerFeature<T>>,
|
||||||
bId: FeatureId<MarkerFeature<T>>,
|
bId: FeatureId<MarkerFeature<T>>,
|
||||||
zoomRange: FloatRange = Feature.defaultZoomRange,
|
zoomRange: FloatRange = defaultZoomRange,
|
||||||
color: Color = Color.Red,
|
color: Color = Color.Red,
|
||||||
id: String? = null,
|
id: String? = null,
|
||||||
): FeatureId<LineFeature<T>> {
|
): FeatureId<LineFeature<T>> {
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
package center.sciprog.maps.features
|
||||||
|
|
||||||
|
public actual class FeatureFont {
|
||||||
|
public actual var size: Float = 16f
|
||||||
|
}
|
@ -12,7 +12,7 @@ import center.sciprog.maps.features.*
|
|||||||
|
|
||||||
internal fun Pair<Number, Number>.toCoordinates(): XY = XY(first.toFloat(), second.toFloat())
|
internal fun Pair<Number, Number>.toCoordinates(): XY = XY(first.toFloat(), second.toFloat())
|
||||||
|
|
||||||
fun FeatureCollection<XY>.background(
|
fun FeatureBuilder<XY>.background(
|
||||||
width: Float,
|
width: Float,
|
||||||
height: Float,
|
height: Float,
|
||||||
offset: XY = XY(0f, 0f),
|
offset: XY = XY(0f, 0f),
|
||||||
@ -25,42 +25,42 @@ fun FeatureCollection<XY>.background(
|
|||||||
)
|
)
|
||||||
return feature(
|
return feature(
|
||||||
id,
|
id,
|
||||||
ScalableImageFeature(coordinateSpace, box, painter = painter).apply {
|
ScalableImageFeature(coordinateSpace, box, zoomRange = defaultZoomRange, painter = painter).apply {
|
||||||
z = -100f
|
z = -100f
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FeatureCollection<XY>.circle(
|
fun FeatureBuilder<XY>.circle(
|
||||||
centerCoordinates: Pair<Number, Number>,
|
centerCoordinates: Pair<Number, Number>,
|
||||||
zoomRange: FloatRange = Feature.defaultZoomRange,
|
zoomRange: FloatRange = defaultZoomRange,
|
||||||
size: Dp = 5.dp,
|
size: Dp = 5.dp,
|
||||||
color: Color = Color.Red,
|
color: Color = Color.Red,
|
||||||
id: String? = null,
|
id: String? = null,
|
||||||
): FeatureId<CircleFeature<XY>> = circle(centerCoordinates.toCoordinates(), zoomRange, size, color, id = id)
|
): FeatureId<CircleFeature<XY>> = circle(centerCoordinates.toCoordinates(), zoomRange, size, color, id = id)
|
||||||
|
|
||||||
fun FeatureCollection<XY>.draw(
|
fun FeatureBuilder<XY>.draw(
|
||||||
position: Pair<Number, Number>,
|
position: Pair<Number, Number>,
|
||||||
zoomRange: FloatRange = Feature.defaultZoomRange,
|
zoomRange: FloatRange = defaultZoomRange,
|
||||||
id: String? = null,
|
id: String? = null,
|
||||||
draw: DrawScope.() -> Unit,
|
draw: DrawScope.() -> Unit,
|
||||||
): FeatureId<DrawFeature<XY>> = draw(position.toCoordinates(), zoomRange = zoomRange, id = id, draw = draw)
|
): FeatureId<DrawFeature<XY>> = draw(position.toCoordinates(), zoomRange = zoomRange, id = id, draw = draw)
|
||||||
|
|
||||||
fun FeatureCollection<XY>.line(
|
fun FeatureBuilder<XY>.line(
|
||||||
aCoordinates: Pair<Number, Number>,
|
aCoordinates: Pair<Number, Number>,
|
||||||
bCoordinates: Pair<Number, Number>,
|
bCoordinates: Pair<Number, Number>,
|
||||||
scaleRange: FloatRange = Feature.defaultZoomRange,
|
scaleRange: FloatRange = defaultZoomRange,
|
||||||
color: Color = Color.Red,
|
color: Color = Color.Red,
|
||||||
id: String? = null,
|
id: String? = null,
|
||||||
): FeatureId<LineFeature<XY>> = line(aCoordinates.toCoordinates(), bCoordinates.toCoordinates(), scaleRange, color, id)
|
): FeatureId<LineFeature<XY>> = line(aCoordinates.toCoordinates(), bCoordinates.toCoordinates(), scaleRange, color, id)
|
||||||
|
|
||||||
|
|
||||||
public fun FeatureCollection<XY>.arc(
|
public fun FeatureBuilder<XY>.arc(
|
||||||
center: Pair<Double, Double>,
|
center: Pair<Double, Double>,
|
||||||
radius: Float,
|
radius: Float,
|
||||||
startAngle: Float,
|
startAngle: Float,
|
||||||
arcLength: Float,
|
arcLength: Float,
|
||||||
zoomRange: FloatRange = Feature.defaultZoomRange,
|
zoomRange: FloatRange = defaultZoomRange,
|
||||||
color: Color = Color.Red,
|
color: Color = Color.Red,
|
||||||
id: String? = null,
|
id: String? = null,
|
||||||
): FeatureId<ArcFeature<XY>> = arc(
|
): FeatureId<ArcFeature<XY>> = arc(
|
||||||
@ -71,19 +71,19 @@ public fun FeatureCollection<XY>.arc(
|
|||||||
color = color
|
color = color
|
||||||
)
|
)
|
||||||
|
|
||||||
fun FeatureCollection<XY>.image(
|
fun FeatureBuilder<XY>.image(
|
||||||
position: Pair<Number, Number>,
|
position: Pair<Number, Number>,
|
||||||
image: ImageVector,
|
image: ImageVector,
|
||||||
size: DpSize = DpSize(image.defaultWidth, image.defaultHeight),
|
size: DpSize = DpSize(image.defaultWidth, image.defaultHeight),
|
||||||
zoomRange: FloatRange = Feature.defaultZoomRange,
|
zoomRange: FloatRange = defaultZoomRange,
|
||||||
id: String? = null,
|
id: String? = null,
|
||||||
): FeatureId<VectorImageFeature<XY>> =
|
): FeatureId<VectorImageFeature<XY>> =
|
||||||
image(position.toCoordinates(), image, size = size, zoomRange = zoomRange, id = id)
|
image(position.toCoordinates(), image, size = size, zoomRange = zoomRange, id = id)
|
||||||
|
|
||||||
fun FeatureCollection<XY>.text(
|
fun FeatureBuilder<XY>.text(
|
||||||
position: Pair<Number, Number>,
|
position: Pair<Number, Number>,
|
||||||
text: String,
|
text: String,
|
||||||
zoomRange: FloatRange = Feature.defaultZoomRange,
|
zoomRange: FloatRange = defaultZoomRange,
|
||||||
color: Color = Color.Red,
|
color: Color = Color.Red,
|
||||||
id: String? = null,
|
id: String? = null,
|
||||||
): FeatureId<TextFeature<XY>> = text(position.toCoordinates(), text, zoomRange, color, id = id)
|
): FeatureId<TextFeature<XY>> = text(position.toCoordinates(), text, zoomRange, color, id = id)
|
||||||
|
@ -37,7 +37,7 @@ public fun SchemeView(
|
|||||||
}
|
}
|
||||||
with(state) {
|
with(state) {
|
||||||
val painterCache: Map<PainterFeature<XY>, Painter> = key(featuresState) {
|
val painterCache: Map<PainterFeature<XY>, Painter> = key(featuresState) {
|
||||||
featuresState.features.values.filterIsInstance<PainterFeature<XY>>().associateWith { it.painter() }
|
featuresState.features.values.filterIsInstance<PainterFeature<XY>>().associateWith { it.getPainter() }
|
||||||
}
|
}
|
||||||
|
|
||||||
Canvas(modifier = modifier.mapControls(state).fillMaxSize()) {
|
Canvas(modifier = modifier.mapControls(state).fillMaxSize()) {
|
||||||
|
@ -24,7 +24,7 @@ class FeatureStateSnapshot<T : Any>(
|
|||||||
@Composable
|
@Composable
|
||||||
fun <T: Any> FeatureCollection<T>.snapshot(): FeatureStateSnapshot<T> = FeatureStateSnapshot(
|
fun <T: Any> FeatureCollection<T>.snapshot(): FeatureStateSnapshot<T> = FeatureStateSnapshot(
|
||||||
features,
|
features,
|
||||||
features.values.filterIsInstance<PainterFeature<T>>().associateWith { it.painter() }
|
features.values.filterIsInstance<PainterFeature<T>>().associateWith { it.getPainter() }
|
||||||
)
|
)
|
||||||
|
|
||||||
fun FeatureStateSnapshot<XY>.generateSvg(
|
fun FeatureStateSnapshot<XY>.generateSvg(
|
||||||
|
Loading…
Reference in New Issue
Block a user