Added function to draw custom markers with Kotlin DSL Canvas API. FeatureId can be extended to hold info about a feature??? I added unused onFeatureClick, which can be latter implemented with pointer input, where it will check coordinates with offset? Features need to hold info about their coordinates?
This commit is contained in:
parent
1ebde3a7a6
commit
b520d2f93a
@ -3,9 +3,12 @@ package centre.sciprog.maps.compose
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateMapOf
|
||||
import androidx.compose.runtime.snapshots.SnapshotStateMap
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.drawscope.DrawScope
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import centre.sciprog.maps.GmcBox
|
||||
|
||||
typealias FeatureId = String
|
||||
|
||||
@ -15,7 +18,7 @@ interface FeatureBuilder {
|
||||
fun build(): SnapshotStateMap<FeatureId, MapFeature>
|
||||
}
|
||||
|
||||
internal class MapFeatureBuilder(initialFeatures: Map<FeatureId,MapFeature>) : FeatureBuilder {
|
||||
internal class MapFeatureBuilder(initialFeatures: Map<FeatureId, MapFeature>) : FeatureBuilder {
|
||||
|
||||
private val content: SnapshotStateMap<FeatureId, MapFeature> = mutableStateMapOf<FeatureId, MapFeature>().apply {
|
||||
putAll(initialFeatures)
|
||||
@ -41,6 +44,21 @@ fun FeatureBuilder.circle(
|
||||
id, MapCircleFeature(centerCoordinates.toCoordinates(), zoomRange, size, color)
|
||||
)
|
||||
|
||||
fun FeatureBuilder.custom(
|
||||
position: Pair<Double, Double>,
|
||||
id: FeatureId? = null,
|
||||
customFeatureBuilder: DrawScope.(Offset) -> Unit,
|
||||
) = addFeature(id, object : MapCustomFeature(position = position.toCoordinates()) {
|
||||
override fun drawFeature(drawScope: DrawScope, offset: Offset) {
|
||||
customFeatureBuilder(drawScope, offset)
|
||||
}
|
||||
|
||||
override fun getBoundingBox(zoom: Int): GmcBox {
|
||||
return GmcBox(position.toCoordinates(), position.toCoordinates())
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
fun FeatureBuilder.line(
|
||||
aCoordinates: Pair<Double, Double>,
|
||||
bCoordinates: Pair<Double, Double>,
|
||||
|
@ -1,9 +1,11 @@
|
||||
package centre.sciprog.maps.compose
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.ImageBitmap
|
||||
import androidx.compose.ui.graphics.drawscope.DrawScope
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||
@ -31,6 +33,13 @@ class MapFeatureSelector(val selector: (zoom: Int) -> MapFeature) : MapFeature(d
|
||||
|
||||
}
|
||||
|
||||
abstract class MapCustomFeature(
|
||||
zoomRange: IntRange = defaultZoomRange,
|
||||
val position: GeodeticMapCoordinates
|
||||
) : MapFeature(zoomRange) {
|
||||
abstract fun drawFeature(drawScope: DrawScope, offset: Offset)
|
||||
}
|
||||
|
||||
class MapCircleFeature(
|
||||
val center: GeodeticMapCoordinates,
|
||||
zoomRange: IntRange = defaultZoomRange,
|
||||
@ -68,7 +77,7 @@ class MapBitmapImageFeature(
|
||||
}
|
||||
|
||||
|
||||
class MapVectorImageFeature (
|
||||
class MapVectorImageFeature(
|
||||
val position: GeodeticMapCoordinates,
|
||||
val painter: Painter,
|
||||
val size: Size,
|
||||
|
@ -21,6 +21,7 @@ expect fun MapView(
|
||||
computeViewPoint: (canvasSize: DpSize) -> MapViewPoint,
|
||||
features: Map<FeatureId, MapFeature>,
|
||||
onClick: MapViewPoint.() -> Unit = {},
|
||||
onFeatureClick: (FeatureId) -> Unit = {},
|
||||
//TODO consider replacing by modifier
|
||||
config: MapViewConfig = MapViewConfig(),
|
||||
modifier: Modifier = Modifier.fillMaxSize(),
|
||||
@ -32,13 +33,14 @@ fun MapView(
|
||||
initialViewPoint: MapViewPoint,
|
||||
features: Map<FeatureId, MapFeature> = emptyMap(),
|
||||
onClick: MapViewPoint.() -> Unit = {},
|
||||
onFeatureClick: (FeatureId) -> Unit = {},
|
||||
config: MapViewConfig = MapViewConfig(),
|
||||
modifier: Modifier = Modifier.fillMaxSize(),
|
||||
buildFeatures: @Composable (FeatureBuilder.() -> Unit) = {},
|
||||
) {
|
||||
val featuresBuilder = MapFeatureBuilder(features)
|
||||
featuresBuilder.buildFeatures()
|
||||
MapView(mapTileProvider, { initialViewPoint }, featuresBuilder.build(), onClick, config, modifier)
|
||||
MapView(mapTileProvider, { initialViewPoint }, featuresBuilder.build(), onClick, onFeatureClick, config, modifier)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@ -47,6 +49,7 @@ fun MapView(
|
||||
box: GmcBox,
|
||||
features: Map<FeatureId, MapFeature> = emptyMap(),
|
||||
onClick: MapViewPoint.() -> Unit = {},
|
||||
onFeatureClick: (FeatureId) -> Unit = {},
|
||||
config: MapViewConfig = MapViewConfig(),
|
||||
modifier: Modifier = Modifier.fillMaxSize(),
|
||||
buildFeatures: @Composable (FeatureBuilder.() -> Unit) = {},
|
||||
@ -62,5 +65,5 @@ fun MapView(
|
||||
)
|
||||
MapViewPoint(box.center, zoom)
|
||||
}
|
||||
MapView(mapTileProvider, computeViewPoint, featuresBuilder.build(), onClick, config, modifier)
|
||||
MapView(mapTileProvider, computeViewPoint, featuresBuilder.build(), onClick, onFeatureClick, config, modifier)
|
||||
}
|
@ -6,14 +6,15 @@ import androidx.compose.material.Text
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Home
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
import centre.sciprog.maps.GeodeticMapCoordinates
|
||||
import centre.sciprog.maps.MapViewPoint
|
||||
import centre.sciprog.maps.compose.*
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.engine.cio.CIO
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.engine.cio.*
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
@ -44,15 +45,25 @@ fun App() {
|
||||
mapTileProvider,
|
||||
viewPoint,
|
||||
onClick = { coordinates = focus },
|
||||
onFeatureClick = {
|
||||
|
||||
},
|
||||
config = MapViewConfig(inferViewBoxFromFeatures = 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)
|
||||
|
||||
//remember feature Id
|
||||
val circleId: FeatureId = circle(pointTwo)
|
||||
val circleId: FeatureId = custom(position = pointThree) {
|
||||
drawRect(
|
||||
color = Color.Red,
|
||||
topLeft = it,
|
||||
size = Size(20f, 20f)
|
||||
)
|
||||
}
|
||||
|
||||
line(pointOne, pointTwo)
|
||||
text(pointOne, "Home")
|
||||
|
@ -41,6 +41,7 @@ actual fun MapView(
|
||||
computeViewPoint: (canvasSize: DpSize) -> MapViewPoint,
|
||||
features: Map<FeatureId, MapFeature>,
|
||||
onClick: MapViewPoint.() -> Unit,
|
||||
onFeatureClick: (FeatureId) -> Unit,
|
||||
config: MapViewConfig,
|
||||
modifier: Modifier,
|
||||
) {
|
||||
@ -219,7 +220,10 @@ actual fun MapView(
|
||||
feature.color.toPaint()
|
||||
)
|
||||
}
|
||||
|
||||
is MapCustomFeature -> drawIntoCanvas { canvas ->
|
||||
val offset = feature.position.toOffset()
|
||||
feature.drawFeature(this, offset)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user