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.Composable
|
||||||
import androidx.compose.runtime.mutableStateMapOf
|
import androidx.compose.runtime.mutableStateMapOf
|
||||||
import androidx.compose.runtime.snapshots.SnapshotStateMap
|
import androidx.compose.runtime.snapshots.SnapshotStateMap
|
||||||
|
import androidx.compose.ui.geometry.Offset
|
||||||
import androidx.compose.ui.geometry.Size
|
import androidx.compose.ui.geometry.Size
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.drawscope.DrawScope
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
|
import centre.sciprog.maps.GmcBox
|
||||||
|
|
||||||
typealias FeatureId = String
|
typealias FeatureId = String
|
||||||
|
|
||||||
@ -15,7 +18,7 @@ interface FeatureBuilder {
|
|||||||
fun build(): SnapshotStateMap<FeatureId, MapFeature>
|
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 {
|
private val content: SnapshotStateMap<FeatureId, MapFeature> = mutableStateMapOf<FeatureId, MapFeature>().apply {
|
||||||
putAll(initialFeatures)
|
putAll(initialFeatures)
|
||||||
@ -41,6 +44,21 @@ fun FeatureBuilder.circle(
|
|||||||
id, MapCircleFeature(centerCoordinates.toCoordinates(), zoomRange, size, color)
|
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(
|
fun FeatureBuilder.line(
|
||||||
aCoordinates: Pair<Double, Double>,
|
aCoordinates: Pair<Double, Double>,
|
||||||
bCoordinates: Pair<Double, Double>,
|
bCoordinates: Pair<Double, Double>,
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package centre.sciprog.maps.compose
|
package centre.sciprog.maps.compose
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.geometry.Offset
|
||||||
import androidx.compose.ui.geometry.Size
|
import androidx.compose.ui.geometry.Size
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.ImageBitmap
|
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.painter.Painter
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
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(
|
class MapCircleFeature(
|
||||||
val center: GeodeticMapCoordinates,
|
val center: GeodeticMapCoordinates,
|
||||||
zoomRange: IntRange = defaultZoomRange,
|
zoomRange: IntRange = defaultZoomRange,
|
||||||
@ -68,7 +77,7 @@ class MapBitmapImageFeature(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class MapVectorImageFeature (
|
class MapVectorImageFeature(
|
||||||
val position: GeodeticMapCoordinates,
|
val position: GeodeticMapCoordinates,
|
||||||
val painter: Painter,
|
val painter: Painter,
|
||||||
val size: Size,
|
val size: Size,
|
||||||
|
@ -21,6 +21,7 @@ expect fun MapView(
|
|||||||
computeViewPoint: (canvasSize: DpSize) -> MapViewPoint,
|
computeViewPoint: (canvasSize: DpSize) -> MapViewPoint,
|
||||||
features: Map<FeatureId, MapFeature>,
|
features: Map<FeatureId, MapFeature>,
|
||||||
onClick: MapViewPoint.() -> Unit = {},
|
onClick: MapViewPoint.() -> Unit = {},
|
||||||
|
onFeatureClick: (FeatureId) -> Unit = {},
|
||||||
//TODO consider replacing by modifier
|
//TODO consider replacing by modifier
|
||||||
config: MapViewConfig = MapViewConfig(),
|
config: MapViewConfig = MapViewConfig(),
|
||||||
modifier: Modifier = Modifier.fillMaxSize(),
|
modifier: Modifier = Modifier.fillMaxSize(),
|
||||||
@ -32,13 +33,14 @@ fun MapView(
|
|||||||
initialViewPoint: MapViewPoint,
|
initialViewPoint: MapViewPoint,
|
||||||
features: Map<FeatureId, MapFeature> = emptyMap(),
|
features: Map<FeatureId, MapFeature> = emptyMap(),
|
||||||
onClick: MapViewPoint.() -> Unit = {},
|
onClick: MapViewPoint.() -> Unit = {},
|
||||||
|
onFeatureClick: (FeatureId) -> Unit = {},
|
||||||
config: MapViewConfig = MapViewConfig(),
|
config: MapViewConfig = MapViewConfig(),
|
||||||
modifier: Modifier = Modifier.fillMaxSize(),
|
modifier: Modifier = Modifier.fillMaxSize(),
|
||||||
buildFeatures: @Composable (FeatureBuilder.() -> Unit) = {},
|
buildFeatures: @Composable (FeatureBuilder.() -> Unit) = {},
|
||||||
) {
|
) {
|
||||||
val featuresBuilder = MapFeatureBuilder(features)
|
val featuresBuilder = MapFeatureBuilder(features)
|
||||||
featuresBuilder.buildFeatures()
|
featuresBuilder.buildFeatures()
|
||||||
MapView(mapTileProvider, { initialViewPoint }, featuresBuilder.build(), onClick, config, modifier)
|
MapView(mapTileProvider, { initialViewPoint }, featuresBuilder.build(), onClick, onFeatureClick, config, modifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -47,6 +49,7 @@ fun MapView(
|
|||||||
box: GmcBox,
|
box: GmcBox,
|
||||||
features: Map<FeatureId, MapFeature> = emptyMap(),
|
features: Map<FeatureId, MapFeature> = emptyMap(),
|
||||||
onClick: MapViewPoint.() -> Unit = {},
|
onClick: MapViewPoint.() -> Unit = {},
|
||||||
|
onFeatureClick: (FeatureId) -> Unit = {},
|
||||||
config: MapViewConfig = MapViewConfig(),
|
config: MapViewConfig = MapViewConfig(),
|
||||||
modifier: Modifier = Modifier.fillMaxSize(),
|
modifier: Modifier = Modifier.fillMaxSize(),
|
||||||
buildFeatures: @Composable (FeatureBuilder.() -> Unit) = {},
|
buildFeatures: @Composable (FeatureBuilder.() -> Unit) = {},
|
||||||
@ -62,5 +65,5 @@ fun MapView(
|
|||||||
)
|
)
|
||||||
MapViewPoint(box.center, zoom)
|
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.Icons
|
||||||
import androidx.compose.material.icons.filled.Home
|
import androidx.compose.material.icons.filled.Home
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.geometry.Size
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.window.Window
|
import androidx.compose.ui.window.Window
|
||||||
import androidx.compose.ui.window.application
|
import androidx.compose.ui.window.application
|
||||||
import centre.sciprog.maps.GeodeticMapCoordinates
|
import centre.sciprog.maps.GeodeticMapCoordinates
|
||||||
import centre.sciprog.maps.MapViewPoint
|
import centre.sciprog.maps.MapViewPoint
|
||||||
import centre.sciprog.maps.compose.*
|
import centre.sciprog.maps.compose.*
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.*
|
||||||
import io.ktor.client.engine.cio.CIO
|
import io.ktor.client.engine.cio.*
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.isActive
|
import kotlinx.coroutines.isActive
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -44,15 +45,25 @@ fun App() {
|
|||||||
mapTileProvider,
|
mapTileProvider,
|
||||||
viewPoint,
|
viewPoint,
|
||||||
onClick = { coordinates = focus },
|
onClick = { coordinates = focus },
|
||||||
|
onFeatureClick = {
|
||||||
|
|
||||||
|
},
|
||||||
config = MapViewConfig(inferViewBoxFromFeatures = true)
|
config = MapViewConfig(inferViewBoxFromFeatures = true)
|
||||||
) {
|
) {
|
||||||
val pointOne = 55.568548 to 37.568604
|
val pointOne = 55.568548 to 37.568604
|
||||||
val pointTwo = 55.929444 to 37.518434
|
val pointTwo = 55.929444 to 37.518434
|
||||||
|
val pointThree = 60.929444 to 37.518434
|
||||||
|
|
||||||
image(pointOne, Icons.Filled.Home)
|
image(pointOne, Icons.Filled.Home)
|
||||||
|
|
||||||
//remember feature Id
|
//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)
|
line(pointOne, pointTwo)
|
||||||
text(pointOne, "Home")
|
text(pointOne, "Home")
|
||||||
|
@ -41,6 +41,7 @@ actual fun MapView(
|
|||||||
computeViewPoint: (canvasSize: DpSize) -> MapViewPoint,
|
computeViewPoint: (canvasSize: DpSize) -> MapViewPoint,
|
||||||
features: Map<FeatureId, MapFeature>,
|
features: Map<FeatureId, MapFeature>,
|
||||||
onClick: MapViewPoint.() -> Unit,
|
onClick: MapViewPoint.() -> Unit,
|
||||||
|
onFeatureClick: (FeatureId) -> Unit,
|
||||||
config: MapViewConfig,
|
config: MapViewConfig,
|
||||||
modifier: Modifier,
|
modifier: Modifier,
|
||||||
) {
|
) {
|
||||||
@ -219,7 +220,10 @@ actual fun MapView(
|
|||||||
feature.color.toPaint()
|
feature.color.toPaint()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
is MapCustomFeature -> drawIntoCanvas { canvas ->
|
||||||
|
val offset = feature.position.toOffset()
|
||||||
|
feature.drawFeature(this, offset)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user