Add geojson demo

This commit is contained in:
Alexander Nozik 2022-12-27 11:51:14 +03:00
parent 5da23b83c1
commit 8969b2b094
6 changed files with 61 additions and 26 deletions

View File

@ -1,4 +1,3 @@
import org.jetbrains.compose.compose
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
plugins {
@ -19,6 +18,7 @@ kotlin {
val jvmMain by getting {
dependencies {
implementation(projects.mapsKtCompose)
implementation(projects.mapsKtGeojson)
implementation(compose.desktop.currentOs)
implementation("io.ktor:ktor-client-cio")
implementation("ch.qos.logback:logback-classic:1.2.11")

View File

@ -13,9 +13,11 @@ import androidx.compose.ui.window.application
import center.sciprog.maps.compose.*
import center.sciprog.maps.coordinates.*
import center.sciprog.maps.features.*
import center.sciprog.maps.geojson.geoJson
import io.ktor.client.HttpClient
import io.ktor.client.engine.cio.CIO
import kotlinx.coroutines.delay
import java.net.URL
import java.nio.file.Path
import kotlin.math.PI
import kotlin.random.Random
@ -44,8 +46,6 @@ fun App() {
val pointTwo = 55.929444 to 37.518434
val pointThree = 60.929444 to 37.518434
val dragPoint = 55.744 to 37.614
MapView(
mapTileProvider = mapTileProvider,
// initialViewPoint = MapViewPoint(
@ -62,6 +62,8 @@ fun App() {
)
) {
geoJson(URL("https://raw.githubusercontent.com/ggolikov/cities-comparison/master/src/moscow.geo.json"))
image(pointOne, Icons.Filled.Home)
val marker1 = rectangle(55.744 to 37.614, size = DpSize(10.dp, 10.dp), color = Color.Magenta)

View File

@ -29,11 +29,7 @@ public value class GeoJsonFeature(override val json: JsonObject) : GeoJson {
public val geometry: GeoJsonGeometry? get() = json[GEOMETRY_KEY]?.jsonObject?.let { GeoJsonGeometry(it) }
public fun getProperty(propertyName: String): JsonElement? = properties?.get(propertyName)
public fun getString(propertyName: String): String? = getProperty(propertyName)?.jsonPrimitive?.contentOrNull
public companion object{
public companion object {
public const val GEOMETRY_KEY: String = "geometry"
}
}
@ -62,6 +58,13 @@ public value class GeoJsonFeatureCollection(override val json: JsonObject) : Geo
}
}
public fun GeoJson(json: JsonObject): GeoJson =
when (json[TYPE_KEY]?.jsonPrimitive?.contentOrNull ?: error("Not a GeoJson")) {
"Feature" -> GeoJsonFeature(json)
"FeatureCollection" -> GeoJsonFeatureCollection(json)
else -> GeoJsonGeometry(json)
}
/**
* Combine a collection of features to a new [GeoJsonFeatureCollection]
*/

View File

@ -83,10 +83,12 @@ public value class GeoJsonPolygon(override val json: JsonObject) : GeoJsonGeomet
require(type == "Polygon") { "Not a GeoJson Polygon geometry" }
}
public val coordinates: List<Gmc>
get() = json[COORDINATES_KEY]?.jsonArray
?.map { it.toGmc() }
?: error("Coordinates are not provided")
public val coordinates: List<List<Gmc>>
get() = json[COORDINATES_KEY]?.jsonArray?.map { polygon ->
polygon.jsonArray.map { point ->
point.toGmc()
}
} ?: error("Coordinates are not provided")
}
@JvmInline
@ -95,10 +97,12 @@ public value class GeoJsonMultiPolygon(override val json: JsonObject) : GeoJsonG
require(type == "MultiPolygon") { "Not a GeoJson MultiPolygon geometry" }
}
public val coordinates: List<List<Gmc>>
get() = json[COORDINATES_KEY]?.jsonArray?.map { lineJson ->
lineJson.jsonArray.map {
it.toGmc()
public val coordinates: List<List<List<Gmc>>>
get() = json[COORDINATES_KEY]?.jsonArray?.map { allPolygons ->
allPolygons.jsonArray.map { polygon ->
polygon.jsonArray.map { point ->
point.toGmc()
}
}
} ?: error("Coordinates are not provided")
}

View File

@ -16,7 +16,7 @@ public fun FeatureBuilder<Gmc>.geoJsonGeometry(
geometry: GeoJsonGeometry,
color: Color = defaultColor,
id: String? = null,
): FeatureId<*> = when (geometry) {
): FeatureId<Feature<Gmc>> = when (geometry) {
is GeoJsonLineString -> points(
geometry.coordinates,
color = color,
@ -42,7 +42,7 @@ public fun FeatureBuilder<Gmc>.geoJsonGeometry(
is GeoJsonMultiPolygon -> group(id = id) {
geometry.coordinates.forEach {
points(
it,
it.first(),
color = color,
pointMode = PointMode.Polygon
)
@ -51,7 +51,7 @@ public fun FeatureBuilder<Gmc>.geoJsonGeometry(
is GeoJsonPoint -> circle(geometry.coordinates, color = color, id = id)
is GeoJsonPolygon -> points(
geometry.coordinates,
geometry.coordinates.first(),
color = color,
pointMode = PointMode.Polygon
)
@ -67,18 +67,23 @@ public fun FeatureBuilder<Gmc>.geoJsonFeature(
geoJson: GeoJsonFeature,
color: Color = defaultColor,
id: String? = null,
) {
val geometry = geoJson.geometry ?: return
): FeatureId<Feature<Gmc>>? {
val geometry = geoJson.geometry ?: return null
val idOverride = geoJson.properties?.get("id")?.jsonPrimitive?.contentOrNull ?: id
val colorOverride = geoJson.properties?.get("color")?.jsonPrimitive?.intOrNull?.let { Color(it) } ?: color
geoJsonGeometry(geometry, colorOverride, idOverride)
return geoJsonGeometry(geometry, colorOverride, idOverride)
}
public fun FeatureBuilder<Gmc>.geoJson(
geoJson: GeoJsonFeatureCollection,
geoJson: GeoJson,
id: String? = null,
): FeatureId<FeatureGroup<Gmc>> = group(id = id) {
): FeatureId<Feature<Gmc>>? = when (geoJson) {
is GeoJsonFeature -> geoJsonFeature(geoJson, id = id)
is GeoJsonFeatureCollection -> group(id = id) {
geoJson.features.forEach {
geoJsonFeature(it)
}
}
is GeoJsonGeometry -> geoJsonGeometry(geoJson, id = id)
}

View File

@ -0,0 +1,21 @@
package center.sciprog.maps.geojson
import center.sciprog.maps.coordinates.Gmc
import center.sciprog.maps.features.FeatureBuilder
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonObject
import java.net.URL
/**
* Add geojson features from url
*/
public fun FeatureBuilder<Gmc>.geoJson(
geoJsonUrl: URL,
id: String? = null,
) {
val jsonString = geoJsonUrl.readText()
val json = Json.parseToJsonElement(jsonString).jsonObject
val geoJson = GeoJson(json)
geoJson(geoJson, id)
}