/*
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.amplifyframework.geo.maplibre.util
import com.amplifyframework.geo.location.models.AmazonLocationPlace
import com.amplifyframework.geo.models.Coordinates
import com.google.gson.JsonElement
import com.google.gson.JsonNull
import com.google.gson.JsonObject
import com.mapbox.mapboxsdk.plugins.annotation.Symbol
import kotlin.reflect.KProperty1
private fun <T> JsonObject.addStringProperty(ref: T, property: KProperty1<T, String?>) {
val value = property.get(ref)
if (value != null) {
addProperty(property.name, value)
} else {
add(property.name, JsonNull.INSTANCE)
}
}
private fun JsonElement.asOptionalString(): String? {
return if (isJsonNull) null else asString
}
fun JsonElement.toPlace(): AmazonLocationPlace {
val obj = asJsonObject
val coordinates = obj.getAsJsonObject(AmazonLocationPlace::coordinates.name)
return AmazonLocationPlace(
coordinates = Coordinates(
coordinates["latitude"].asDouble,
coordinates["longitude"].asDouble
),
addressNumber = obj[AmazonLocationPlace::addressNumber.name].asOptionalString(),
country = obj[AmazonLocationPlace::country.name].asOptionalString(),
label = obj[AmazonLocationPlace::label.name].asOptionalString(),
municipality = obj[AmazonLocationPlace::municipality.name].asOptionalString(),
neighborhood = obj[AmazonLocationPlace::neighborhood.name].asOptionalString(),
postalCode = obj[AmazonLocationPlace::postalCode.name].asOptionalString(),
region = obj[AmazonLocationPlace::region.name].asOptionalString(),
street = obj[AmazonLocationPlace::street.name].asOptionalString(),
subRegion = obj[AmazonLocationPlace::subRegion.name].asOptionalString(),
)
}
fun AmazonLocationPlace.toJsonElement(): JsonElement {
val place = JsonObject()
place.addStringProperty(this, AmazonLocationPlace::addressNumber)
place.addStringProperty(this, AmazonLocationPlace::country)
place.addStringProperty(this, AmazonLocationPlace::label)
place.addStringProperty(this, AmazonLocationPlace::municipality)
place.addStringProperty(this, AmazonLocationPlace::neighborhood)
place.addStringProperty(this, AmazonLocationPlace::postalCode)
place.addStringProperty(this, AmazonLocationPlace::region)
place.addStringProperty(this, AmazonLocationPlace::street)
place.addStringProperty(this, AmazonLocationPlace::subRegion)
place.add(
AmazonLocationPlace::coordinates.name,
JsonObject().apply {
addProperty("latitude", coordinates.latitude)
addProperty("longitude", coordinates.longitude)
}
)
return place
}
fun Symbol.getPlaceData(): AmazonLocationPlace {
return data?.let { it.toPlace() } ?: throw IllegalStateException("Symbol place data missing")
}