Attribute serialization
This commit is contained in:
parent
190834634f
commit
0f00abb1b2
66
README.md
66
README.md
@ -1,13 +1,63 @@
|
||||
# Maps-kt
|
||||
|
||||
This repository is a work-in-progress implementation of Map-with-markers component for Compose-Multiplatform
|
||||
|
||||
## [maps-kt-core](maps-kt-core)
|
||||
A multiplatform coordinates representation and conversion.
|
||||
![](docs/images/Screenshot%202023-01-12%20110429.png)
|
||||
|
||||
## [maps-kt-compose](maps-kt-compose)
|
||||
A compose multiplatform (currently desktop only, contributions of android target are welcome) implementation of a map component, features and builder.
|
||||
## Modules
|
||||
|
||||
## [maps-kt-scheme](maps-kt-scheme)
|
||||
An alternative component used for the same functionality on 2D schemes. Not all features from maps could be ported because it requires some code duplication (ideas for common API are welcome).
|
||||
|
||||
## [demo](demo)
|
||||
Demonstration projects for different features
|
||||
### [demo](demo)
|
||||
>
|
||||
>
|
||||
> **Maturity**: EXPERIMENTAL
|
||||
|
||||
### [maps-kt-compose](maps-kt-compose)
|
||||
> Compose-multiplaform implementation for web-mercator tiled maps
|
||||
>
|
||||
> **Maturity**: DEVELOPMENT
|
||||
>
|
||||
> **Features:**
|
||||
> - [osm](maps-kt-compose/#) : OpenStreetMap tile provider.
|
||||
|
||||
|
||||
### [maps-kt-core](maps-kt-core)
|
||||
> Core cartography, UI-agnostic
|
||||
>
|
||||
> **Maturity**: DEVELOPMENT
|
||||
>
|
||||
> **Features:**
|
||||
> - [angles and distances](maps-kt-core/#) : Type-safe angle and distance measurements.
|
||||
> - [ellipsoid](maps-kt-core/#) : Ellipsoid geometry and distances
|
||||
> - [mercator](maps-kt-core/#) : Mercator and web-mercator projections
|
||||
|
||||
|
||||
### [maps-kt-features](maps-kt-features)
|
||||
>
|
||||
>
|
||||
> **Maturity**: EXPERIMENTAL
|
||||
|
||||
### [maps-kt-geojson](maps-kt-geojson)
|
||||
>
|
||||
>
|
||||
> **Maturity**: EXPERIMENTAL
|
||||
|
||||
### [maps-kt-scheme](maps-kt-scheme)
|
||||
>
|
||||
>
|
||||
> **Maturity**: EXPERIMENTAL
|
||||
|
||||
### [maps](demo/maps)
|
||||
>
|
||||
>
|
||||
> **Maturity**: EXPERIMENTAL
|
||||
|
||||
### [polygon-editor](demo/polygon-editor)
|
||||
>
|
||||
>
|
||||
> **Maturity**: EXPERIMENTAL
|
||||
|
||||
### [scheme](demo/scheme)
|
||||
>
|
||||
>
|
||||
> **Maturity**: EXPERIMENTAL
|
||||
|
@ -8,7 +8,7 @@ plugins {
|
||||
|
||||
allprojects {
|
||||
group = "center.sciprog"
|
||||
version = "0.2.1-dev-1"
|
||||
version = "0.2.1-dev-2"
|
||||
}
|
||||
|
||||
apiValidation{
|
||||
@ -41,5 +41,7 @@ subprojects {
|
||||
}
|
||||
}
|
||||
|
||||
readme.readmeTemplate = file("docs/templates/README-TEMPLATE.md")
|
||||
|
||||
|
||||
|
||||
|
4
demo/README.md
Normal file
4
demo/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
# Module demo
|
||||
|
||||
|
||||
|
4
demo/maps/README.md
Normal file
4
demo/maps/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
# Module maps
|
||||
|
||||
|
||||
|
4
demo/polygon-editor/README.md
Normal file
4
demo/polygon-editor/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
# Module polygon-editor
|
||||
|
||||
|
||||
|
4
demo/scheme/README.md
Normal file
4
demo/scheme/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
# Module scheme
|
||||
|
||||
|
||||
|
BIN
docs/images/Screenshot 2023-01-12 110429.png
Normal file
BIN
docs/images/Screenshot 2023-01-12 110429.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 591 KiB |
17
docs/templates/ARTIFACT-TEMPLATE.md
vendored
Normal file
17
docs/templates/ARTIFACT-TEMPLATE.md
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
## Artifact:
|
||||
|
||||
The Maven coordinates of this project are `${group}:${name}:${version}`.
|
||||
|
||||
**Gradle Kotlin DSL:**
|
||||
```kotlin
|
||||
repositories {
|
||||
maven("https://repo.kotlin.link")
|
||||
mavenCentral()
|
||||
// development and snapshot versions
|
||||
maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("${group}:${name}:${version}")
|
||||
}
|
||||
```
|
9
docs/templates/README-TEMPLATE.md
vendored
Normal file
9
docs/templates/README-TEMPLATE.md
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
# Maps-kt
|
||||
|
||||
This repository is a work-in-progress implementation of Map-with-markers component for Compose-Multiplatform
|
||||
|
||||
![](docs/images/Screenshot%202023-01-12%20110429.png)
|
||||
|
||||
## Modules
|
||||
|
||||
${modules}
|
33
maps-kt-compose/README.md
Normal file
33
maps-kt-compose/README.md
Normal file
@ -0,0 +1,33 @@
|
||||
# Module kmath-core
|
||||
|
||||
The core interfaces of KMath.
|
||||
|
||||
- [osm](#) : OpenStreetMap tile provider.
|
||||
|
||||
|
||||
## Artifact:
|
||||
|
||||
The Maven coordinates of this project are `center.sciprog:maps-kt-compose:0.2.1-dev-2`.
|
||||
|
||||
**Gradle Groovy:**
|
||||
```groovy
|
||||
repositories {
|
||||
maven { url 'https://repo.kotlin.link' }
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'center.sciprog:maps-kt-compose:0.2.1-dev-2'
|
||||
}
|
||||
```
|
||||
**Gradle Kotlin DSL:**
|
||||
```kotlin
|
||||
repositories {
|
||||
maven("https://repo.kotlin.link")
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("center.sciprog:maps-kt-compose:0.2.1-dev-2")
|
||||
}
|
||||
```
|
@ -46,4 +46,14 @@ java {
|
||||
|
||||
tasks.withType<Test> {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
readme {
|
||||
description = "Compose-multiplaform implementation for web-mercator tiled maps"
|
||||
maturity = space.kscience.gradle.Maturity.EXPERIMENTAL
|
||||
propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md"))
|
||||
|
||||
feature(
|
||||
id = "osm",
|
||||
) { "OpenStreetMap tile provider." }
|
||||
}
|
7
maps-kt-compose/docs/README-TEMPLATE.md
Normal file
7
maps-kt-compose/docs/README-TEMPLATE.md
Normal file
@ -0,0 +1,7 @@
|
||||
# Module kmath-core
|
||||
|
||||
The core interfaces of KMath.
|
||||
|
||||
${features}
|
||||
|
||||
${artifact}
|
35
maps-kt-core/README.md
Normal file
35
maps-kt-core/README.md
Normal file
@ -0,0 +1,35 @@
|
||||
# Module kmath-core
|
||||
|
||||
The core interfaces of KMath.
|
||||
|
||||
- [angles and distances](#) : Type-safe angle and distance measurements.
|
||||
- [ellipsoid](#) : Ellipsoid geometry and distances
|
||||
- [mercator](#) : Mercator and web-mercator projections
|
||||
|
||||
|
||||
## Artifact:
|
||||
|
||||
The Maven coordinates of this project are `center.sciprog:maps-kt-core:0.2.1-dev-2`.
|
||||
|
||||
**Gradle Groovy:**
|
||||
```groovy
|
||||
repositories {
|
||||
maven { url 'https://repo.kotlin.link' }
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'center.sciprog:maps-kt-core:0.2.1-dev-2'
|
||||
}
|
||||
```
|
||||
**Gradle Kotlin DSL:**
|
||||
```kotlin
|
||||
repositories {
|
||||
maven("https://repo.kotlin.link")
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("center.sciprog:maps-kt-core:0.2.1-dev-2")
|
||||
}
|
||||
```
|
@ -1,4 +1,22 @@
|
||||
plugins {
|
||||
id("space.kscience.gradle.mpp")
|
||||
`maven-publish`
|
||||
}
|
||||
|
||||
readme {
|
||||
description = "Core cartography, UI-agnostic"
|
||||
maturity = space.kscience.gradle.Maturity.DEVELOPMENT
|
||||
propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md"))
|
||||
|
||||
feature(
|
||||
id = "angles and distances",
|
||||
) { "Type-safe angle and distance measurements." }
|
||||
|
||||
feature(
|
||||
id = "ellipsoid",
|
||||
) { "Ellipsoid geometry and distances" }
|
||||
|
||||
feature(
|
||||
id = "mercator",
|
||||
) { "Mercator and web-mercator projections" }
|
||||
}
|
7
maps-kt-core/docs/README-TEMPLATE.md
Normal file
7
maps-kt-core/docs/README-TEMPLATE.md
Normal file
@ -0,0 +1,7 @@
|
||||
# Module kmath-core
|
||||
|
||||
The core interfaces of KMath.
|
||||
|
||||
${features}
|
||||
|
||||
${artifact}
|
32
maps-kt-features/README.md
Normal file
32
maps-kt-features/README.md
Normal file
@ -0,0 +1,32 @@
|
||||
# Module maps-kt-features
|
||||
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
## Artifact:
|
||||
|
||||
The Maven coordinates of this project are `center.sciprog:maps-kt-features:0.2.1-dev-2`.
|
||||
|
||||
**Gradle Groovy:**
|
||||
```groovy
|
||||
repositories {
|
||||
maven { url 'https://repo.kotlin.link' }
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'center.sciprog:maps-kt-features:0.2.1-dev-2'
|
||||
}
|
||||
```
|
||||
**Gradle Kotlin DSL:**
|
||||
```kotlin
|
||||
repositories {
|
||||
maven("https://repo.kotlin.link")
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("center.sciprog:maps-kt-features:0.2.1-dev-2")
|
||||
}
|
||||
```
|
@ -12,4 +12,10 @@ kotlin {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
kscience{
|
||||
useSerialization{
|
||||
json()
|
||||
}
|
||||
}
|
@ -1,8 +1,20 @@
|
||||
package center.sciprog.attributes
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
public interface Attribute<T>
|
||||
|
||||
public abstract class SerializableAttribute<T>(
|
||||
public val serialId: String,
|
||||
public val serializer: KSerializer<T>,
|
||||
) : Attribute<T>
|
||||
|
||||
public interface AttributeWithDefault<T> : Attribute<T> {
|
||||
public val default: T
|
||||
}
|
||||
|
||||
public interface SetAttribute<V> : Attribute<Set<V>>
|
||||
|
||||
public object NameAttribute : Attribute<String>
|
||||
public object NameAttribute : SerializableAttribute<String>("name", String.serializer())
|
||||
|
||||
|
@ -5,27 +5,30 @@ import center.sciprog.maps.features.ZAttribute
|
||||
import kotlin.jvm.JvmInline
|
||||
|
||||
@JvmInline
|
||||
public value class Attributes internal constructor(internal val map: Map<Attribute<*>, Any>) {
|
||||
public value class Attributes internal constructor(public val content: Map<out Attribute<*>, Any>) {
|
||||
|
||||
public val keys: Set<Attribute<*>> get() = content.keys
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
public operator fun <T> get(attribute: Attribute<T>): T? = map[attribute] as? T
|
||||
public operator fun <T> get(attribute: Attribute<T>): T? = content[attribute] as? T
|
||||
|
||||
// public operator fun <T> Attribute<T>.invoke(value: T?): Attributes = withAttribute(this, value)
|
||||
|
||||
override fun toString(): String = "Attributes(value=${map.entries})"
|
||||
override fun toString(): String = "Attributes(value=${content.entries})"
|
||||
|
||||
public companion object {
|
||||
public val EMPTY: Attributes = Attributes(emptyMap())
|
||||
}
|
||||
}
|
||||
|
||||
public fun <T> Attributes.getOrDefault(attribute: AttributeWithDefault<T>): T = get(attribute) ?: attribute.default
|
||||
|
||||
public fun <T, A : Attribute<T>> Attributes.withAttribute(
|
||||
attribute: A,
|
||||
attrValue: T?,
|
||||
): Attributes = Attributes(
|
||||
if (attrValue == null) {
|
||||
map - attribute
|
||||
content - attribute
|
||||
} else {
|
||||
map + (attribute to attrValue)
|
||||
content + (attribute to attrValue)
|
||||
}
|
||||
)
|
||||
|
||||
@ -38,7 +41,7 @@ public fun <T, A : SetAttribute<T>> Attributes.withAttributeElement(
|
||||
): Attributes {
|
||||
val currentSet: Set<T> = get(attribute) ?: emptySet()
|
||||
return Attributes(
|
||||
map + (attribute to (currentSet + attrValue))
|
||||
content + (attribute to (currentSet + attrValue))
|
||||
)
|
||||
}
|
||||
|
||||
@ -51,7 +54,7 @@ public fun <T, A : SetAttribute<T>> Attributes.withoutAttributeElement(
|
||||
): Attributes {
|
||||
val currentSet: Set<T> = get(attribute) ?: emptySet()
|
||||
return Attributes(
|
||||
map + (attribute to (currentSet - attrValue))
|
||||
content + (attribute to (currentSet - attrValue))
|
||||
)
|
||||
}
|
||||
|
||||
@ -60,7 +63,7 @@ public fun <T : Any, A : Attribute<T>> Attributes(
|
||||
attrValue: T,
|
||||
): Attributes = Attributes(mapOf(attribute to attrValue))
|
||||
|
||||
public operator fun Attributes.plus(other: Attributes): Attributes = Attributes(map + other.map)
|
||||
public operator fun Attributes.plus(other: Attributes): Attributes = Attributes(content + other.content)
|
||||
|
||||
public val Feature<*>.z: Float
|
||||
get() = attributes[ZAttribute] ?: 0f
|
||||
|
@ -17,7 +17,7 @@ public class AttributesBuilder internal constructor(private val map: MutableMap<
|
||||
}
|
||||
|
||||
public fun from(attributes: Attributes) {
|
||||
map.putAll(attributes.map)
|
||||
map.putAll(attributes.content)
|
||||
}
|
||||
|
||||
public fun <V> SetAttribute<V>.add(
|
||||
@ -42,4 +42,6 @@ public class AttributesBuilder internal constructor(private val map: MutableMap<
|
||||
|
||||
public fun AttributesBuilder(
|
||||
attributes: Attributes,
|
||||
): AttributesBuilder = AttributesBuilder(attributes.map.toMutableMap())
|
||||
): AttributesBuilder = AttributesBuilder(attributes.content.toMutableMap())
|
||||
|
||||
public fun Attributes(builder: AttributesBuilder.() -> Unit): Attributes = AttributesBuilder().apply(builder).build()
|
@ -0,0 +1,44 @@
|
||||
@file:Suppress("UNCHECKED_CAST")
|
||||
|
||||
package center.sciprog.attributes
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
import kotlinx.serialization.json.buildJsonObject
|
||||
|
||||
public class AttributesSerializer(
|
||||
private val serializableAttributes: Set<SerializableAttribute<*>>,
|
||||
) : KSerializer<Attributes> {
|
||||
private val jsonSerializer = JsonObject.serializer()
|
||||
override val descriptor: SerialDescriptor get() = jsonSerializer.descriptor
|
||||
|
||||
override fun deserialize(decoder: Decoder): Attributes {
|
||||
val jsonElement = jsonSerializer.deserialize(decoder)
|
||||
val attributeMap: Map<SerializableAttribute<*>, Any> = jsonElement.entries.associate { (key, element) ->
|
||||
val attr = serializableAttributes.find { it.serialId == key }
|
||||
?: error("Attribute serializer for key $key not found")
|
||||
val value = Json.decodeFromJsonElement(attr.serializer, element) ?: error("Null values are not allowed")
|
||||
|
||||
attr to value
|
||||
}
|
||||
return Attributes(attributeMap)
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: Attributes) {
|
||||
val json = buildJsonObject {
|
||||
value.content.forEach { (key, value) ->
|
||||
if (key !in serializableAttributes) error("An attribute key $key is not in the list of allowed attributes for this serializer")
|
||||
val serializableKey = key as SerializableAttribute
|
||||
put(
|
||||
serializableKey.serialId,
|
||||
Json.encodeToJsonElement(serializableKey.serializer as KSerializer<Any>, value)
|
||||
)
|
||||
}
|
||||
}
|
||||
jsonSerializer.serialize(encoder, json)
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package center.sciprog.attributes
|
||||
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.serializer
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
internal class AttributesSerializationTest {
|
||||
|
||||
internal object TestAttribute : SerializableAttribute<Map<String, String>>("test", serializer())
|
||||
|
||||
@Test
|
||||
fun restore() {
|
||||
val serializer = AttributesSerializer(setOf(NameAttribute, TestAttribute))
|
||||
|
||||
|
||||
val attributes = Attributes {
|
||||
NameAttribute("myTest")
|
||||
TestAttribute(mapOf("a" to "aa", "b" to "bb"))
|
||||
}
|
||||
|
||||
val serialized = Json.encodeToString(serializer, attributes)
|
||||
println(serialized)
|
||||
|
||||
val restored = Json.decodeFromString(serializer, serialized)
|
||||
|
||||
assertEquals(attributes, restored)
|
||||
}
|
||||
}
|
32
maps-kt-geojson/README.md
Normal file
32
maps-kt-geojson/README.md
Normal file
@ -0,0 +1,32 @@
|
||||
# Module maps-kt-geojson
|
||||
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
## Artifact:
|
||||
|
||||
The Maven coordinates of this project are `center.sciprog:maps-kt-geojson:0.2.1-dev-2`.
|
||||
|
||||
**Gradle Groovy:**
|
||||
```groovy
|
||||
repositories {
|
||||
maven { url 'https://repo.kotlin.link' }
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'center.sciprog:maps-kt-geojson:0.2.1-dev-2'
|
||||
}
|
||||
```
|
||||
**Gradle Kotlin DSL:**
|
||||
```kotlin
|
||||
repositories {
|
||||
maven("https://repo.kotlin.link")
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("center.sciprog:maps-kt-geojson:0.2.1-dev-2")
|
||||
}
|
||||
```
|
32
maps-kt-scheme/README.md
Normal file
32
maps-kt-scheme/README.md
Normal file
@ -0,0 +1,32 @@
|
||||
# Module maps-kt-scheme
|
||||
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
## Artifact:
|
||||
|
||||
The Maven coordinates of this project are `center.sciprog:maps-kt-scheme:0.2.1-dev-2`.
|
||||
|
||||
**Gradle Groovy:**
|
||||
```groovy
|
||||
repositories {
|
||||
maven { url 'https://repo.kotlin.link' }
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'center.sciprog:maps-kt-scheme:0.2.1-dev-2'
|
||||
}
|
||||
```
|
||||
**Gradle Kotlin DSL:**
|
||||
```kotlin
|
||||
repositories {
|
||||
maven("https://repo.kotlin.link")
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("center.sciprog:maps-kt-scheme:0.2.1-dev-2")
|
||||
}
|
||||
```
|
Loading…
Reference in New Issue
Block a user