Change the working of groups

This commit is contained in:
Alexander Nozik 2023-01-02 20:28:47 +03:00
parent a8a3da7e70
commit ba962acf5c
8 changed files with 36 additions and 14 deletions

View File

@ -63,6 +63,8 @@ fun App() {
) { ) {
geoJson(URL("https://raw.githubusercontent.com/ggolikov/cities-comparison/master/src/moscow.geo.json")) geoJson(URL("https://raw.githubusercontent.com/ggolikov/cities-comparison/master/src/moscow.geo.json"))
.withAttribute(ColorAttribute, Color.Blue)
.withAttribute(AlphaAttribute, 0.4f)
image(pointOne, Icons.Filled.Home) image(pointOne, Icons.Filled.Home)
@ -117,7 +119,16 @@ fun App() {
visit { id, feature -> visit { id, feature ->
if (feature is PolygonFeature) { if (feature is PolygonFeature) {
(id as FeatureId<PolygonFeature<Gmc>>).onHover { id as FeatureId<PolygonFeature<Gmc>>
id.onClick {
println("Click on $id")
points(
feature.points,
id = "selected",
attributes = Attributes(ZAttribute, 10f)
).color(Color.Blue)
}
id.onHover {
println("Hover on $id") println("Hover on $id")
points( points(
feature.points, feature.points,

View File

@ -120,7 +120,8 @@ public actual fun MapView(
) )
} }
featuresState.features.filter { viewPoint.zoom in it.zoomRange } featuresState.features
.filter { viewPoint.zoom in it.zoomRange }
.forEach { feature -> .forEach { feature ->
drawFeature(mapState, painterCache, feature) drawFeature(mapState, painterCache, feature)
} }

View File

@ -9,7 +9,7 @@ public value class Attributes internal constructor(internal val map: Map<Attribu
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
public operator fun <T> get(attribute: Attribute<T>): T? = map[attribute] as? T public operator fun <T> get(attribute: Attribute<T>): T? = map[attribute] as? T
public fun <T> Attribute<T>.invoke(value: T?): Attributes = withAttribute(this, value) public operator fun <T> Attribute<T>.invoke(value: T?): Attributes = withAttribute(this, value)
override fun toString(): String = "AttributeMap(value=${map.entries})" override fun toString(): String = "AttributeMap(value=${map.entries})"

View File

@ -132,8 +132,10 @@ public data class PolygonFeature<T : Any>(
override fun getBoundingBox(zoom: Float): Rectangle<T>? = boundingBox override fun getBoundingBox(zoom: Float): Rectangle<T>? = boundingBox
override fun contains(viewPoint: ViewPoint<T>): Boolean = override fun contains(viewPoint: ViewPoint<T>): Boolean {
viewPoint.focus in boundingBox!!//with(space) { viewPoint.focus.isInsidePolygon(points) } val boundingBox = boundingBox ?: return false
return viewPoint.focus in boundingBox && with(space) { viewPoint.focus.isInsidePolygon(points) }
}
override fun withAttributes(modify: (Attributes) -> Attributes): Feature<T> = copy(attributes = modify(attributes)) override fun withAttributes(modify: (Attributes) -> Attributes): Feature<T> = copy(attributes = modify(attributes))
} }

View File

@ -81,6 +81,11 @@ public data class FeatureGroup<T : Any>(
feature(this, get(this).withAttributes(modify)) feature(this, get(this).withAttributes(modify))
} }
public fun <F : Feature<T>> FeatureId<F>.withAttributes(modify: Attributes.() -> Attributes): FeatureId<F> {
feature(this, get(this).withAttributes(modify))
return this
}
public fun <F : Feature<T>, V> FeatureId<F>.withAttribute(key: Attribute<V>, value: V?): FeatureId<F> { public fun <F : Feature<T>, V> FeatureId<F>.withAttribute(key: Attribute<V>, value: V?): FeatureId<F> {
feature(this, get(this).withAttributes { withAttribute(key, value) }) feature(this, get(this).withAttributes { withAttribute(key, value) })
return this return this
@ -174,6 +179,7 @@ public data class FeatureGroup<T : Any>(
public fun <F : Feature<T>> FeatureId<F>.color(color: Color): FeatureId<F> = public fun <F : Feature<T>> FeatureId<F>.color(color: Color): FeatureId<F> =
withAttribute(ColorAttribute, color) withAttribute(ColorAttribute, color)
public fun <F : Feature<T>> FeatureId<F>.zoomRange(range: FloatRange): FeatureId<F> = public fun <F : Feature<T>> FeatureId<F>.zoomRange(range: FloatRange): FeatureId<F> =
withAttribute(ZoomRangeAttribute, range) withAttribute(ZoomRangeAttribute, range)
@ -181,7 +187,7 @@ public data class FeatureGroup<T : Any>(
featureMap.values.mapNotNull { it.getBoundingBox(zoom) }.wrapRectangles() featureMap.values.mapNotNull { it.getBoundingBox(zoom) }.wrapRectangles()
} }
override fun withAttributes(modify: Attributes.() -> Attributes): Feature<T> = copy(attributes = attributes) override fun withAttributes(modify: Attributes.() -> Attributes): Feature<T> = copy(attributes = modify(attributes))
public companion object { public companion object {

View File

@ -98,7 +98,9 @@ public fun <T : Any> DrawScope.drawFeature(
is FeatureGroup -> { is FeatureGroup -> {
feature.featureMap.values.forEach { feature.featureMap.values.forEach {
drawFeature(state, painterCache, it) drawFeature(state, painterCache, it.withAttributes {
feature.attributes + this
})
} }
} }

View File

@ -53,15 +53,13 @@ public fun FeatureGroup<Gmc>.geoJsonGeometry(
geoJsonGeometry(it) geoJsonGeometry(it)
} }
} }
}.apply {
withAttribute(AlphaAttribute, 0.5f)
} }
public fun FeatureGroup<Gmc>.geoJsonFeature( public fun FeatureGroup<Gmc>.geoJsonFeature(
geoJson: GeoJsonFeature, geoJson: GeoJsonFeature,
id: String? = null, id: String? = null,
): FeatureId<Feature<Gmc>>? { ): FeatureId<Feature<Gmc>> {
val geometry = geoJson.geometry ?: return null val geometry = geoJson.geometry ?: return group{}
val idOverride = geoJson.properties?.get("id")?.jsonPrimitive?.contentOrNull ?: id val idOverride = geoJson.properties?.get("id")?.jsonPrimitive?.contentOrNull ?: id
val colorOverride = geoJson.properties?.get("color")?.jsonPrimitive?.intOrNull?.let { Color(it) } val colorOverride = geoJson.properties?.get("color")?.jsonPrimitive?.intOrNull?.let { Color(it) }
val jsonGeometry = geoJsonGeometry(geometry, idOverride) val jsonGeometry = geoJsonGeometry(geometry, idOverride)
@ -75,7 +73,7 @@ public fun FeatureGroup<Gmc>.geoJsonFeature(
public fun FeatureGroup<Gmc>.geoJson( public fun FeatureGroup<Gmc>.geoJson(
geoJson: GeoJson, geoJson: GeoJson,
id: String? = null, id: String? = null,
): FeatureId<Feature<Gmc>>? = when (geoJson) { ): FeatureId<Feature<Gmc>> = when (geoJson) {
is GeoJsonFeature -> geoJsonFeature(geoJson, id = id) is GeoJsonFeature -> geoJsonFeature(geoJson, id = id)
is GeoJsonFeatureCollection -> group(id = id) { is GeoJsonFeatureCollection -> group(id = id) {
geoJson.features.forEach { geoJson.features.forEach {

View File

@ -1,7 +1,9 @@
package center.sciprog.maps.geojson package center.sciprog.maps.geojson
import center.sciprog.maps.coordinates.Gmc import center.sciprog.maps.coordinates.Gmc
import center.sciprog.maps.features.Feature
import center.sciprog.maps.features.FeatureGroup import center.sciprog.maps.features.FeatureGroup
import center.sciprog.maps.features.FeatureId
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonObject
import java.net.URL import java.net.URL
@ -12,10 +14,10 @@ import java.net.URL
public fun FeatureGroup<Gmc>.geoJson( public fun FeatureGroup<Gmc>.geoJson(
geoJsonUrl: URL, geoJsonUrl: URL,
id: String? = null, id: String? = null,
) { ): FeatureId<Feature<Gmc>> {
val jsonString = geoJsonUrl.readText() val jsonString = geoJsonUrl.readText()
val json = Json.parseToJsonElement(jsonString).jsonObject val json = Json.parseToJsonElement(jsonString).jsonObject
val geoJson = GeoJson(json) val geoJson = GeoJson(json)
geoJson(geoJson, id) return geoJson(geoJson, id)
} }