Skip to content

Commit

Permalink
[ANDROAPP-4457] Configurable basemaps
Browse files Browse the repository at this point in the history
Signed-off-by: Pablo <[email protected]>
  • Loading branch information
Balcan committed Feb 28, 2024
1 parent 53075be commit 919ea86
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ class MapLayerManager(
var mapLayers: HashMap<String, MapLayer> = hashMapOf()
private var mapStyle: MapStyle? = null
var styleChangeCallback: ((Style) -> Unit)? = null
var currentStylePosition = 0
var currentStylePosition =
baseMapManager.baseMapStyles.indexOfFirst { it.isDefault }.takeIf { it > -1 } ?: 0

private val relationShipColors =
mutableListOf(
Expand Down Expand Up @@ -77,36 +78,42 @@ class MapLayerManager(
mapStyle?.programDarkColor!!,
colorUtils,
)

LayerType.ENROLLMENT_LAYER -> EnrollmentMapLayer(
style,
featureType ?: FeatureType.POINT,
mapStyle?.enrollmentColor!!,
mapStyle?.programDarkColor!!,
colorUtils,
)

LayerType.HEATMAP_LAYER -> HeatmapMapLayer(
style,
)

LayerType.RELATIONSHIP_LAYER -> RelationshipMapLayer(
style,
featureType ?: FeatureType.POINT,
sourceId!!,
getNextAvailableDrawable(sourceId)?.second,
colorUtils,
)

LayerType.EVENT_LAYER -> EventMapLayer(
style,
featureType ?: FeatureType.POINT,
relationShipColors.firstOrNull(),
colorUtils,
)

LayerType.TEI_EVENT_LAYER -> TeiEventMapLayer(
style,
featureType ?: FeatureType.POINT,
sourceId!!,
mapStyle?.programDarkColor!!,
colorUtils,
)

LayerType.FIELD_COORDINATE_LAYER -> FieldMapLayer(
style,
sourceId!!,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.dhis2.maps.layer.basemaps

import android.graphics.Color
import android.widget.ImageView
import androidx.recyclerview.widget.RecyclerView
import org.dhis2.maps.R
import org.dhis2.maps.databinding.BasemapItemBinding
Expand All @@ -14,9 +15,11 @@ class BaseMapHolder(
itemStyle = bindingAdapterPosition
if (baseMap.basemapImage != null) {
baseMapImage.setImageDrawable(baseMap.basemapImage)
baseMapImage.scaleType = ImageView.ScaleType.CENTER_CROP
} else {
baseMapImage.setBackgroundColor(Color.GRAY)
baseMapImage.setImageResource(R.drawable.unknown_base_map)
baseMapImage.scaleType = ImageView.ScaleType.FIT_CENTER
}
basemapName.text = baseMap.basemapName
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package org.dhis2.maps.layer.basemaps
import com.google.gson.annotations.SerializedName

object BaseMapStyleBuilder {
fun build(id: String, tileUrls: List<String>, attribution: String) = BaseMapStyle(
fun build(id: String, tileUrls: List<String>, attribution: String, isDefault: Boolean) = BaseMapStyle(
version = 8,
sources = StyleSources(
rasterTiles = RasterTiles(
Expand All @@ -24,18 +24,20 @@ object BaseMapStyleBuilder {
),
id = id,
glyphs = DEFAULT_GLYPH_URL,
isDefault = isDefault,
)

fun internalBaseMap(): BaseMapStyle {
return build(
OSM_LIGHT,
listOf(
id = OSM_LIGHT,
tileUrls = listOf(
DEFAULT_TILE_URL.replace("{s}", "a"),
DEFAULT_TILE_URL.replace("{s}", "b"),
DEFAULT_TILE_URL.replace("{s}", "c"),
DEFAULT_TILE_URL.replace("{s}", "d"),
),
DEFAULT_ATTRIBUTION,
attribution = DEFAULT_ATTRIBUTION,
isDefault = true,
)
}
}
Expand All @@ -46,6 +48,7 @@ data class BaseMapStyle(
val layers: List<StyleLayers>,
val id: String,
var glyphs: String,
val isDefault: Boolean,
)

data class StyleSources(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ abstract class MapManager(val mapView: MapView) : LifecycleObserver {
val baseMapManager = BaseMapManager(mapView.context, this.mapStyles)
setUi()
map?.setStyle(
baseMapManager.styleJson(this.mapStyles.first()),
baseMapManager.styleJson(
this.mapStyles.find { it.isDefault }
?: mapStyles.first(),
),
) { styleLoaded ->
this.style = styleLoaded
mapLayerManager = MapLayerManager(mapLoaded, baseMapManager, colorUtils).apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import org.hisp.dhis.android.core.map.layer.MapLayerImageryProvider

class MapStyleConfiguration(private val d2: D2) {
fun fetchMapStyles(): List<BaseMapStyle> {
val defaultMap = d2.settingModule().systemSetting().defaultBaseMap().blockingGet()?.value()
return d2.mapsModule().mapLayers().withImageryProviders().blockingGet()
.map { mapLayer ->
val id = mapLayer.displayName()
Expand All @@ -16,20 +17,44 @@ class MapStyleConfiguration(private val d2: D2) {
mapLayer.subdomains(),
)
val attribution = mapLayer.imageryProviders().mapAttribution()
build(id, tileUrls, attribution)
build(id, tileUrls, attribution, defaultMap == mapLayer.uid())
}
}
}

fun String.mapTileUrls(subdomainPlaceholder: String?, subdomains: List<String>?): List<String> {
return subdomains
.takeIf { subdomainPlaceholder != null && !it.isNullOrEmpty() }
?.map { subdomain ->
this.replace(subdomainPlaceholder!!, subdomain)
}
?: listOf(this)
return when {
subdomainPlaceholder != null && !subdomains.isNullOrEmpty() ->
subdomains.map { subdomain -> this.replace(subdomainPlaceholder, subdomain) }

this.contains("{subdomain}") ->
possibleSubdomainsForSubdomain().map { subdomain ->
this.replace("{subdomain}", subdomain)
}

this.contains("{s}") ->
possibleSubdomainsForS().map { subdomain ->
this.replace("{s}", subdomain)
}

else -> listOf(this)
}
}

private fun possibleSubdomainsForS() = listOf(
"a",
"b",
"c",
"d",
)

private fun possibleSubdomainsForSubdomain() = listOf(
"t0",
"t1",
"t2",
"t3",
)

fun List<MapLayerImageryProvider>?.mapAttribution(): String {
if (this == null) return ""
val attribution = StringBuilder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,43 @@ class MapStyleConfigurationTest {
}
}

@Test
fun shouldFetchCustomMaps() {
whenever(d2.mapsModule().mapLayers()) doReturn mock()
whenever(d2.mapsModule().mapLayers().withImageryProviders()) doReturn mock()
whenever(d2.mapsModule().mapLayers().withImageryProviders().blockingGet()) doReturn listOf(
mockMapLayer(
displayName = "basemap 1",
imageUrl = "http://{s}.test.test/x/y/z",
subDomainPlaceHolder = null,
subdomains = null,
imaginaryProviders = listOf(
mockImaginaryProvider("© Maplibre"),
),
),
mockMapLayer(
displayName = "basemap 2",
imageUrl = "http://test.test.{subdomain}/x/y/z",
subDomainPlaceHolder = null,
subdomains = null,
imaginaryProviders = listOf(
mockImaginaryProvider("© Maplibre"),
mockImaginaryProvider("© Carto"),
),
),
)

mapStyleConfiguration.fetchMapStyles().let { result ->
assertTrue(result.size == 2)
assertTrue(result[0].sources.rasterTiles.tiles.size == 4)
assertTrue(result[0].sources.rasterTiles.tiles[0] == "http://a.test.test/x/y/z")
assertTrue(result[0].sources.attribution == "© Maplibre")
assertTrue(result[0].sources.rasterTiles.tiles[1] == "http://b.test.test/x/y/z")
assertTrue(result[1].sources.rasterTiles.tiles.size == 4)
assertTrue(result[1].sources.attribution == "© Maplibre, © Carto")
}
}

private fun mockMapLayer(
displayName: String,
imageUrl: String,
Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ hilt = '2.47'
hiltCompiler = '1.0.0'
jacoco = '0.8.10'
designSystem = "0.2-20240222.160714-31"
dhis2sdk = "1.10.0-20240207.110936-11"
dhis2sdk = "1.10.0-20240219.122222-17"
ruleEngine = "2.1.9"
appcompat = "1.6.1"
annotation = "1.6.0"
Expand Down

0 comments on commit 919ea86

Please sign in to comment.