All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.org.jetbrains.letsPlot.livemap.geometry.MicroTasks.kt Maven / Gradle / Ivy

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




© 2015 - 2024 Weber Informatics LLC | Privacy Policy