immutable_features #24
@ -23,7 +23,6 @@ import kotlinx.coroutines.flow.StateFlow
|
|||||||
import kotlinx.coroutines.flow.sample
|
import kotlinx.coroutines.flow.sample
|
||||||
import space.kscience.attributes.Attributes
|
import space.kscience.attributes.Attributes
|
||||||
import space.kscience.attributes.plus
|
import space.kscience.attributes.plus
|
||||||
import space.kscience.maps.utils.GroupAttributesCalculator
|
|
||||||
import kotlin.time.Duration
|
import kotlin.time.Duration
|
||||||
import kotlin.time.Duration.Companion.milliseconds
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
|
||||||
@ -104,13 +103,24 @@ public fun <T : Any> FeatureCanvas(
|
|||||||
}
|
}
|
||||||
clipRect {
|
clipRect {
|
||||||
ComposeFeatureDrawScope(this, state, painterCache, textMeasurer).apply(draw).apply {
|
ComposeFeatureDrawScope(this, state, painterCache, textMeasurer).apply(draw).apply {
|
||||||
val attributesCalculator = GroupAttributesCalculator(features)
|
|
||||||
|
val attributesCache = mutableMapOf<List<String>, Attributes>()
|
||||||
|
|
||||||
|
fun computeGroupAttributes(path: List<String>): Attributes = attributesCache.getOrPut(path) {
|
||||||
|
if (path.isEmpty()) return Attributes.EMPTY
|
||||||
|
else if (path.size == 1) {
|
||||||
|
features[path.first()]?.attributes ?: Attributes.EMPTY
|
||||||
|
} else {
|
||||||
|
computeGroupAttributes(path.dropLast(1)) + (features[path.first()]?.attributes
|
||||||
|
?: Attributes.EMPTY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
features.entries.sortedBy { it.value.z }
|
features.entries.sortedBy { it.value.z }
|
||||||
.filter { state.viewPoint.zoom in it.value.zoomRange }
|
.filter { state.viewPoint.zoom in it.value.zoomRange }
|
||||||
.forEach { (id, feature) ->
|
.forEach { (id, feature) ->
|
||||||
val path = id.split("/")
|
val path = id.split("/")
|
||||||
drawFeature(feature, attributesCalculator.computeGroupAttributes(path.dropLast(1)))
|
drawFeature(feature, computeGroupAttributes(path.dropLast(1)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
package space.kscience.maps.utils
|
|
||||||
|
|
||||||
import space.kscience.attributes.Attributes
|
|
||||||
import space.kscience.attributes.plus
|
|
||||||
import space.kscience.maps.features.Feature
|
|
||||||
|
|
||||||
public class GroupAttributesCalculator<T : Any>(
|
|
||||||
private val features: Map<String, Feature<T>>,
|
|
||||||
private val attributesCache: MutableMap<List<String>, Attributes> = mutableMapOf()
|
|
||||||
) {
|
|
||||||
public fun computeGroupAttributes(path: List<String>): Attributes = attributesCache.getOrPut(path){
|
|
||||||
if (path.isEmpty()) return Attributes.EMPTY
|
|
||||||
else if (path.size == 1) {
|
|
||||||
features[path.first()]?.attributes ?: Attributes.EMPTY
|
|
||||||
} else {
|
|
||||||
computeGroupAttributes(path.dropLast(1)) + (features[path.first()]?.attributes ?: Attributes.EMPTY)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,7 +11,6 @@ import space.kscience.attributes.plus
|
|||||||
import space.kscience.maps.features.*
|
import space.kscience.maps.features.*
|
||||||
import space.kscience.maps.scheme.XY
|
import space.kscience.maps.scheme.XY
|
||||||
import space.kscience.maps.scheme.XYCanvasState
|
import space.kscience.maps.scheme.XYCanvasState
|
||||||
import space.kscience.maps.utils.GroupAttributesCalculator
|
|
||||||
|
|
||||||
|
|
||||||
public class FeatureStateSnapshot<T : Any>(
|
public class FeatureStateSnapshot<T : Any>(
|
||||||
@ -166,10 +165,19 @@ public fun FeatureStateSnapshot<XY>.generateSvg(
|
|||||||
features.entries.sortedBy { it.value.z }
|
features.entries.sortedBy { it.value.z }
|
||||||
.filter { state.viewPoint.zoom in it.value.zoomRange }
|
.filter { state.viewPoint.zoom in it.value.zoomRange }
|
||||||
.forEach { (id, feature) ->
|
.forEach { (id, feature) ->
|
||||||
val attributesCalculator = GroupAttributesCalculator(features)
|
val attributesCache = mutableMapOf<List<String>, Attributes>()
|
||||||
|
|
||||||
|
fun computeGroupAttributes(path: List<String>): Attributes = attributesCache.getOrPut(path){
|
||||||
|
if (path.isEmpty()) return Attributes.EMPTY
|
||||||
|
else if (path.size == 1) {
|
||||||
|
features[path.first()]?.attributes ?: Attributes.EMPTY
|
||||||
|
} else {
|
||||||
|
computeGroupAttributes(path.dropLast(1)) + (features[path.first()]?.attributes ?: Attributes.EMPTY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val path = id.split("/")
|
val path = id.split("/")
|
||||||
drawFeature(feature, attributesCalculator.computeGroupAttributes(path.dropLast(1)))
|
drawFeature(feature, computeGroupAttributes(path.dropLast(1)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return svgGraphics2D.getSVGElement(id)
|
return svgGraphics2D.getSVGElement(id)
|
||||||
|
Loading…
Reference in New Issue
Block a user