commonMain.jetbrains.datalore.base.spatial.GeoJson.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lets-plot-common Show documentation
Show all versions of lets-plot-common Show documentation
Lets-Plot JVM package without rendering part
/*
* Copyright (c) 2020. JetBrains s.r.o.
* Use of this source code is governed by the MIT license that can be found in the LICENSE file.
*/
package jetbrains.datalore.base.spatial
import jetbrains.datalore.base.json.FluentArray
import jetbrains.datalore.base.json.FluentObject
import jetbrains.datalore.base.json.JsonSupport
import jetbrains.datalore.base.typedGeometry.*
object GeoJson {
private const val LON_INDEX = 0
private const val LAT_INDEX = 1
fun parse(geoJson: String, handler: SimpleFeature.Consumer.() -> Unit) {
val geoObj = FluentObject(JsonSupport.parseJson(geoJson))
val geometryConsumer = SimpleFeature.Consumer().apply(handler)
Parser().parse(geoObj, geometryConsumer)
}
fun parse(geoJson: String, consumer: SimpleFeature.GeometryConsumer) {
val geoObj = FluentObject(JsonSupport.parseJson(geoJson))
Parser().parse(geoObj, consumer)
}
private class Parser {
internal fun parse(obj: FluentObject, handler: SimpleFeature.GeometryConsumer) {
when (val type = obj.getString("type")) {
"FeatureCollection" -> {
require(obj.contains("features")) { "GeoJson: Missing 'features' in 'FeatureCollection'" }
obj.getArray("features").fluentObjectStream()
.filter { it.getString("type") == "Feature" }
.map { it.getObject("geometry") }
.forEach { parse(it, handler) }
}
"GeometryCollection" -> {
require(obj.contains("geometries")) { "GeoJson: Missing 'geometries' in 'GeometryCollection'" }
obj.getArray("geometries").fluentObjectStream()
.forEach { parse(it, handler) }
}
else -> {
require(obj.contains("coordinates")) { "GeoJson: Missing 'coordinates' in $type" }
val coordinates = obj.getArray("coordinates")
when (type) {
"Point" -> parsePoint(coordinates).let(handler::onPoint)
"LineString" -> parseLineString(coordinates).let(handler::onLineString)
"Polygon" -> parsePolygon(coordinates).let(handler::onPolygon)
"MultiPoint" -> parseMultiPoint(coordinates).let(handler::onMultiPoint)
"MultiLineString" -> parseMultiLineString(coordinates).let(handler::onMultiLineString)
"MultiPolygon" -> parseMultiPolygon(coordinates).let(handler::onMultiPolygon)
else -> error("Not support GeoJson type: $type")
}
}
}
}
private fun parsePoint(jsonPoint: FluentArray): Vec {
return explicitVec(
jsonPoint.getDouble(LON_INDEX),
jsonPoint.getDouble(LAT_INDEX)
)
}
private fun parseLineString(jsonLineString: FluentArray): LineString {
return jsonLineString.mapArray(this::parsePoint).let(::LineString)
}
private fun parseRing(jsonRing: FluentArray): Ring {
return jsonRing.mapArray(this::parsePoint).let(::Ring)
}
private fun parseMultiPoint(jsonMultiPoint: FluentArray): MultiPoint {
return jsonMultiPoint.mapArray(this::parsePoint).let(::MultiPoint)
}
private fun parsePolygon(jsonPolygon: FluentArray): Polygon {
return jsonPolygon.mapArray(this::parseRing).let(::Polygon)
}
private fun parseMultiLineString(jsonLineStrings: FluentArray): MultiLineString {
return jsonLineStrings.mapArray(this::parseLineString).let(::MultiLineString)
}
private fun parseMultiPolygon(jsonMultiPolygon: FluentArray): MultiPolygon {
return jsonMultiPolygon.mapArray(this::parsePolygon).let(::MultiPolygon)
}
private fun FluentArray.mapArray(f: (FluentArray) -> T): List {
return this.stream().map { f(FluentArray(it as List)) }.toList()
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy