Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android annotations: implement Circle, Line, Fill #1724

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.annotation.UiThread
import org.maplibre.android.maps.MapLibreMap
import org.maplibre.android.maps.MapView
import org.maplibre.android.maps.Style
import kotlin.reflect.KClass

/**
* Has logic for spawning annotation managers for its collection of annotations.
Expand All @@ -27,7 +28,9 @@ class KAnnotationContainer(
fun add(annotation: KAnnotation<*>) {
annotationList.add(annotation)
addToManager(annotation)
if (annotation is KSymbol) annotation.icon?.let { style?.addImage(it.image.toString(), it.image) }
if (annotation is Symbol) annotation.icon?.let { style?.addImage(it.image.toString(), it.image) }
if (annotation is Line) annotation.pattern?.let { style?.addImage(it.toString(), it) }
if (annotation is Fill) annotation.pattern?.let { style?.addImage(it.toString(), it) }
}

@UiThread
Expand All @@ -41,17 +44,23 @@ class KAnnotationContainer(
}
}

@UiThread
fun update(annotation: KAnnotation<*>) {
managers[annotation.key()]?.updateSource()
if (annotation is KSymbol) annotation.icon?.let { style?.addImage(it.image.toString(), it.image) }
if (annotation is Symbol) annotation.icon?.let { style?.addImage(it.image.toString(), it.image) }
if (annotation is Line) annotation.pattern?.let { style?.addImage(it.toString(), it) }
if (annotation is Fill) annotation.pattern?.let { style?.addImage(it.toString(), it) }
}

private fun addToManager(annotation: KAnnotation<*>) {
val manager = managers.getOrCreate(annotation.key())
when (annotation) {
is KSymbol -> (manager as SymbolManager?)?.add(annotation)
private fun addToManager(annotation: KAnnotation<*>) =
managers.getOrCreate(annotation.key())?.let { manager ->
when (annotation) {
is Symbol -> (manager as SymbolManager).add(annotation)
is Circle -> (manager as CircleManager).add(annotation)
is Line -> (manager as LineManager).add(annotation)
is Fill -> (manager as FillManager).add(annotation)
}
}
}

@UiThread
fun remove(annotation: KAnnotation<*>) {
Expand All @@ -60,7 +69,10 @@ class KAnnotationContainer(

managers[annotation.key()]?.let { manager ->
when (annotation) {
is KSymbol -> (manager as SymbolManager).add(annotation)
is Symbol -> (manager as SymbolManager).delete(annotation)
is Circle -> (manager as CircleManager).delete(annotation)
is Line -> (manager as LineManager).delete(annotation)
is Fill -> (manager as FillManager).delete(annotation)
}
}

Expand All @@ -82,13 +94,21 @@ class KAnnotationContainer(
private fun groupAnnotations(): Map<Key, List<KAnnotation<*>>> =
annotationList.groupBy { it.key() }

private data class Key(private val type: Class<in KAnnotation<*>>) // TODO will be expanded in the future
private data class Key(val type: KClass<out KAnnotation<*>>) // TODO will be expanded in the future

private fun KAnnotation<*>.key() = Key(this.javaClass)
private fun KAnnotation<*>.key() = Key(this::class)

private fun MutableMap<Key, AnnotationManager<*, *>>.getOrCreate(key: Key): AnnotationManager<*, *>? =
get(key) ?: style?.let {
SymbolManager(mapView, mapLibreMap, it)
when (key.type) {
Symbol::class -> SymbolManager(mapView, mapLibreMap, it)
Circle::class -> CircleManager(mapView, mapLibreMap, it)
Line::class -> LineManager(mapView, mapLibreMap, it)
Fill::class -> FillManager(mapView, mapLibreMap, it)
else -> throw IllegalArgumentException(
"Impossible key! This should never occur because KAnnotation is a sealed class."
louwers marked this conversation as resolved.
Show resolved Hide resolved
)
}
}?.also { put(key, it) }

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import com.mapbox.geojson.Feature
import com.mapbox.geojson.FeatureCollection
import java.util.concurrent.atomic.AtomicBoolean
import org.maplibre.android.geometry.LatLng
import org.maplibre.android.log.Logger
import org.maplibre.android.maps.MapLibreMap
import org.maplibre.android.maps.MapLibreMap.OnMapClickListener
import org.maplibre.android.maps.MapLibreMap.OnMapLongClickListener
Expand Down Expand Up @@ -97,15 +96,19 @@ abstract class AnnotationManager<L : Layer, T : KAnnotation<*>> @UiThread intern
*/
@UiThread
fun add(annotation: T) {
if (annotation.id == 0L) {
// At this point, the annotation has no ID iff the user has added it directly to the manager.
annotation.attach(this, nextId--)
}
annotations[annotation.id]?.let {
throw IllegalStateException("An ID was generated twice.")
if (annotations[annotation.id] === annotation) {
Timber.w("The same annotation was added twice. Ignoring.")
} else {
if (annotation.id == 0L) {
// At this point, the annotation has no ID iff the user has added it directly to the manager.
annotation.attach(this, nextId--)
}
annotations[annotation.id]?.let {
throw IllegalStateException("An ID was generated twice.")
}
annotations[annotation.id] = annotation
updateSource()
}
annotations[annotation.id] = annotation
updateSource()
}

/**
Expand Down
Loading
Loading