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

commonMain.org.jetbrains.letsPlot.spatial.SpatialDataset.kt Maven / Gradle / Ivy

There is a newer version: 4.8.0
Show newest version
/*
 * Copyright (c) 2021. 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.spatial

import org.jetbrains.letsPlot.intern.asPlotData

class SpatialDataset private constructor(
    private val map: Map>,
    val geometryKey: String,
    val geometryFormat: GeometryFormat,
    val crs: String?
) : Map> by map {

    override fun toString(): String {
        return "SpatialDataset($geometryFormat, key='$geometryKey', map=${this.map}, crs=${this.crs})"
    }

    companion object {
        private val GEO_COL_NAMES = listOf(
            "geometry", "shape", "coord", "coordinates"
        )

        fun withGEOJSON(
            data: Map,
            geometry: List,
            crs: String? = null
        ): SpatialDataset {
            return create(data, geometry, GeometryFormat.GEOJSON, crs)
        }

        /**
         * WKT is not yet supported by Lets-plot
         */
        fun withWKT(
            data: Map,
            geometry: List,
            crs: String? = null
        ): SpatialDataset {
            return create(data, geometry, GeometryFormat.WKT, crs)
        }

        /**
         * WKB is not yet supported by Lets-plot
         */
        fun withWKB(
            data: Map,
            geometry: List,
            crs: String? = null
        ): SpatialDataset {
            return create(data, geometry, GeometryFormat.WKB, crs)
        }

        private fun create(
            data: Map,
            geometry: List,
            geometryFormat: GeometryFormat,
            crs: String?
        ): SpatialDataset {
            @Suppress("NAME_SHADOWING")
            val data: Map> = asPlotData(data)

            data.entries.forEach {
                require(it.value.size == geometry.size) {
                    "The size of data series '${it.key}' (${it.value.size}) must be equal to the size geometry collection: ${geometry.size}."
                }
            }

            // ToDo: check the geometry format

            val geometryKey = chooseGeometryColName(data.keys)
            val map = data + mapOf(geometryKey to geometry)
            return SpatialDataset(map, geometryKey, geometryFormat, crs)
        }

        private fun chooseGeometryColName(usedNames: Set): String {
            var i = 0
            while (true) {
                val name = GEO_COL_NAMES.map { if (i == 0) it else it + "_$i" }.find { !(it in usedNames) }
                if (name != null) {
                    return name
                }
                i++
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy