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:
a.kalmakhanov 2022-07-16 14:58:56 +06:00
parent 1ebde3a7a6
commit b520d2f93a
5 changed files with 53 additions and 8 deletions

View File

@ -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
@ -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>,

View File

@ -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,

View File

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

View File

@ -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")

View File

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