commonMain.org.jetbrains.letsPlot.livemap.geometry.MicroTasks.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of livemap-jvm Show documentation
Show all versions of livemap-jvm Show documentation
A part of the Lets-Plot library.
The newest version!
/*
* Copyright (c) 2019. JetBrains s.r.o.
* Use of this source code is governed by the MIT license that can be found in the LICENSE file.
*/
package org.jetbrains.letsPlot.livemap.geometry
import org.jetbrains.letsPlot.commons.intern.typedGeometry.Geometry
import org.jetbrains.letsPlot.commons.intern.typedGeometry.GeometryType.*
import org.jetbrains.letsPlot.commons.intern.typedGeometry.MultiPolygon
import org.jetbrains.letsPlot.commons.intern.typedGeometry.Vec
import org.jetbrains.letsPlot.commons.intern.util.VecUtil
import org.jetbrains.letsPlot.livemap.core.multitasking.MicroTask
import org.jetbrains.letsPlot.livemap.core.multitasking.map
object MicroTasks {
const val RESAMPLING_PRECISION = 0.004
fun resample(
geometry: Geometry,
transform: (Vec) -> Vec?
): MicroTask> {
return createTransformer(geometry, resample(transform))
}
fun transform(
geometry: Geometry,
transform: (Vec) -> Vec?
): MicroTask> {
return createTransformer(geometry, transform(transform))
}
fun transform(
geometry: MultiPolygon,
transform: (Vec) -> Vec?
): MicroTask> {
return MultiPolygonTransform(geometry, transform(transform))
}
fun resample(
geometry: MultiPolygon,
transform: (Vec) -> Vec?
): MicroTask> {
return MultiPolygonTransform(geometry, resample(transform))
}
private fun transform(
transform: (Vec) -> Vec?
): (Vec, MutableCollection>) -> Unit {
return { p, ring -> transform(p)?.let(ring::add) }
}
private fun resample(
transform: (Vec) -> Vec?
): (Vec, MutableCollection>) -> Unit = IterativeResampler(transform)::next
private fun createTransformer(
geometry: Geometry,
transform: (Vec, MutableCollection>) -> Unit
): MicroTask> {
return when (geometry.type) {
MULTI_POLYGON -> MultiPolygonTransform(geometry.multiPolygon, transform).map(Geometry.Companion::of)
MULTI_LINESTRING -> MultiLineStringTransform(geometry.multiLineString, transform).map(Geometry.Companion::of)
MULTI_POINT -> MultiPointTransform(geometry.multiPoint, transform).map(Geometry.Companion::of)
}
}
internal class IterativeResampler(
private val myTransform: (Vec) -> Vec?
) {
private var myPrevPoint: Vec? = null
private var myRing: MutableCollection>? = null
fun next(p: Vec, ring: MutableCollection>) {
if (myRing == null || // first call
ring !== myRing
) { // next ring
myRing = ring
myPrevPoint = null
}
val prev = myPrevPoint
myPrevPoint = p
when (prev) {
null -> myTransform(p)?.let(myRing!!::add)
else -> myRing!!.addAll(VecUtil.resample(prev, p, RESAMPLING_PRECISION, myTransform).asSequence().drop(1))
}
}
}
}