Skip to content

Commit 20f874e

Browse files
committed
Improve tile layer architecture
Signed-off-by: Kyle Corry <[email protected]>
1 parent 9bb0515 commit 20f874e

File tree

12 files changed

+210
-241
lines changed

12 files changed

+210
-241
lines changed

app/src/main/java/com/kylecorry/trail_sense/shared/map_layers/tiles/ITileSourceSelector.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ package com.kylecorry.trail_sense.shared.map_layers.tiles
33
import com.kylecorry.sol.science.geology.CoordinateBounds
44

55
interface ITileSourceSelector {
6-
fun getRegionLoaders(bounds: CoordinateBounds): List<IGeographicImageRegionLoader>
6+
suspend fun getRegionLoaders(bounds: CoordinateBounds): List<IGeographicImageRegionLoader>
77
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.kylecorry.trail_sense.shared.map_layers.ui.layers
2+
3+
import com.kylecorry.trail_sense.tools.map.map_layers.BaseMapMapLayerPreferences
4+
5+
class BaseMapLayer : TileMapLayer<BaseMapTileSource>(BaseMapTileSource()) {
6+
7+
fun setPreferences(prefs: BaseMapMapLayerPreferences) {
8+
percentOpacity = prefs.opacity.get() / 100f
9+
invalidate()
10+
}
11+
}

app/src/main/java/com/kylecorry/trail_sense/shared/map_layers/ui/layers/BaseMapLayerManager.kt

Lines changed: 0 additions & 113 deletions
This file was deleted.
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package com.kylecorry.trail_sense.shared.map_layers.ui.layers
2+
3+
import android.content.Context
4+
import android.graphics.Color
5+
import androidx.core.graphics.toColorInt
6+
import com.kylecorry.andromeda.bitmaps.operations.Conditional
7+
import com.kylecorry.andromeda.bitmaps.operations.ReplaceColor
8+
import com.kylecorry.andromeda.core.cache.AppServiceRegistry
9+
import com.kylecorry.sol.math.geometry.Size
10+
import com.kylecorry.sol.science.geology.CoordinateBounds
11+
import com.kylecorry.sol.units.Coordinate
12+
import com.kylecorry.trail_sense.shared.map_layers.tiles.IGeographicImageRegionLoader
13+
import com.kylecorry.trail_sense.shared.map_layers.tiles.ITileSourceSelector
14+
import com.kylecorry.trail_sense.tools.photo_maps.domain.MapCalibration
15+
import com.kylecorry.trail_sense.tools.photo_maps.domain.MapCalibrationPoint
16+
import com.kylecorry.trail_sense.tools.photo_maps.domain.MapMetadata
17+
import com.kylecorry.trail_sense.tools.photo_maps.domain.MapProjectionType
18+
import com.kylecorry.trail_sense.tools.photo_maps.domain.PercentCoordinate
19+
import com.kylecorry.trail_sense.tools.photo_maps.domain.PhotoMap
20+
import com.kylecorry.trail_sense.tools.photo_maps.infrastructure.tiles.PhotoMapTileSourceSelector
21+
22+
class BaseMapTileSource : ITileSourceSelector {
23+
24+
private val context = AppServiceRegistry.get<Context>()
25+
private val internalSelector = PhotoMapTileSourceSelector(
26+
context,
27+
listOf(
28+
PhotoMap(
29+
-1,
30+
"Land",
31+
"land.webp",
32+
MapCalibration(
33+
true, true, 0f, listOf(
34+
MapCalibrationPoint(
35+
Coordinate(-90.0, -180.0),
36+
PercentCoordinate(0f, 1f)
37+
),
38+
MapCalibrationPoint(
39+
Coordinate(90.0, 180.0),
40+
PercentCoordinate(1f, 0f)
41+
)
42+
)
43+
),
44+
MapMetadata(
45+
Size(3800f, 1900f),
46+
null,
47+
0,
48+
MapProjectionType.CylindricalEquidistant
49+
),
50+
isAsset = true,
51+
isFullWorld = true // TODO: Derive this using calibration points
52+
)
53+
),
54+
maxLayers = 1,
55+
loadPdfs = false,
56+
isPixelPerfect = true,
57+
operations = listOf(
58+
Conditional(
59+
SOURCE_MAP_COLOR_WATER != DESTINATION_MAP_COLOR_WATER,
60+
ReplaceColor(
61+
SOURCE_MAP_COLOR_WATER,
62+
DESTINATION_MAP_COLOR_WATER
63+
)
64+
),
65+
Conditional(
66+
SOURCE_MAP_COLOR_DESERT != DESTINATION_MAP_COLOR_DESERT,
67+
ReplaceColor(
68+
SOURCE_MAP_COLOR_DESERT,
69+
DESTINATION_MAP_COLOR_DESERT
70+
)
71+
),
72+
Conditional(
73+
SOURCE_MAP_COLOR_ROCK != DESTINATION_MAP_COLOR_ROCK,
74+
ReplaceColor(
75+
SOURCE_MAP_COLOR_ROCK,
76+
DESTINATION_MAP_COLOR_ROCK
77+
)
78+
),
79+
Conditional(
80+
SOURCE_MAP_COLOR_GRASS != DESTINATION_MAP_COLOR_GRASS,
81+
ReplaceColor(
82+
SOURCE_MAP_COLOR_GRASS,
83+
DESTINATION_MAP_COLOR_GRASS
84+
)
85+
),
86+
Conditional(
87+
SOURCE_MAP_COLOR_ICE != DESTINATION_MAP_COLOR_ICE,
88+
ReplaceColor(
89+
SOURCE_MAP_COLOR_ICE,
90+
DESTINATION_MAP_COLOR_ICE
91+
)
92+
)
93+
)
94+
)
95+
96+
override suspend fun getRegionLoaders(bounds: CoordinateBounds): List<IGeographicImageRegionLoader> {
97+
return internalSelector.getRegionLoaders(bounds)
98+
}
99+
100+
companion object {
101+
private val SOURCE_MAP_COLOR_DESERT = Color.rgb(232, 225, 182)
102+
private val SOURCE_MAP_COLOR_ROCK = Color.rgb(202, 195, 184)
103+
private val SOURCE_MAP_COLOR_GRASS = Color.rgb(189, 204, 150)
104+
private val SOURCE_MAP_COLOR_ICE = Color.rgb(245, 244, 242)
105+
private const val SOURCE_MAP_COLOR_WATER = Color.BLACK
106+
107+
private val DESTINATION_MAP_COLOR_DESERT = SOURCE_MAP_COLOR_DESERT
108+
private val DESTINATION_MAP_COLOR_ROCK = SOURCE_MAP_COLOR_ROCK
109+
private val DESTINATION_MAP_COLOR_GRASS = SOURCE_MAP_COLOR_GRASS
110+
private val DESTINATION_MAP_COLOR_ICE = SOURCE_MAP_COLOR_ICE
111+
private val DESTINATION_MAP_COLOR_WATER = "#AAD3DF".toColorInt()
112+
}
113+
}

app/src/main/java/com/kylecorry/trail_sense/shared/map_layers/ui/layers/TiledMapLayer.kt renamed to app/src/main/java/com/kylecorry/trail_sense/shared/map_layers/ui/layers/TileMapLayer.kt

Lines changed: 28 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -9,75 +9,42 @@ import com.kylecorry.trail_sense.main.errors.SafeMode
99
import com.kylecorry.trail_sense.shared.map_layers.MapLayerBackgroundTask
1010
import com.kylecorry.trail_sense.shared.map_layers.tiles.ITileSourceSelector
1111
import com.kylecorry.trail_sense.shared.map_layers.tiles.TileLoader
12-
import com.kylecorry.trail_sense.tools.map.map_layers.BaseMapMapLayerPreferences
13-
import com.kylecorry.trail_sense.tools.photo_maps.map_layers.PhotoMapMapLayerPreferences
1412
import kotlinx.coroutines.CancellationException
1513

16-
class TiledMapLayer : IAsyncLayer {
14+
abstract class TileMapLayer<T : ITileSourceSelector>(
15+
protected val source: T,
16+
private val taskRunner: MapLayerBackgroundTask = MapLayerBackgroundTask(),
17+
private val minZoomLevel: Int? = null
18+
) : IAsyncLayer {
1719

1820
private var shouldReloadTiles = true
1921
private var backgroundColor: Int = Color.WHITE
20-
var controlsPdfCache = false
21-
private var minZoom: Int = 0
22+
protected var controlsPdfCache = false
2223
private val loader = TileLoader()
2324
private val tilePaint = Paint().apply {
2425
isAntiAlias = true
2526
isFilterBitmap = true
2627
}
27-
private val taskRunner = MapLayerBackgroundTask()
2828
private var updateListener: (() -> Unit)? = null
2929

30-
var sourceSelector: ITileSourceSelector? = null
31-
set(value) {
32-
field = value
33-
loader.clearCache()
34-
shouldReloadTiles = true
35-
}
36-
37-
fun setPreferences(prefs: PhotoMapMapLayerPreferences) {
38-
_percentOpacity = prefs.opacity.get() / 100f
39-
invalidate()
40-
}
41-
42-
fun setPreferences(prefs: BaseMapMapLayerPreferences) {
43-
_percentOpacity = prefs.opacity.get() / 100f
44-
invalidate()
45-
}
46-
4730
fun setBackgroundColor(color: Int) {
4831
this.backgroundColor = color
4932
shouldReloadTiles = true
5033
}
5134

52-
fun setMinZoom(minZoom: Int) {
53-
this.minZoom = minZoom
54-
shouldReloadTiles = true
55-
}
56-
57-
override fun draw(drawer: ICanvasDrawer, map: IMapView) {
58-
// Avoid drawing while in safe mode
59-
if (SafeMode.isEnabled()) {
60-
return
61-
}
62-
35+
init {
6336
// Load tiles if needed
64-
taskRunner.scheduleUpdate(
65-
map.mapBounds,
66-
map.metersPerPixel,
67-
shouldReloadTiles
68-
) { bounds, metersPerPixel ->
37+
taskRunner.addTask { bounds, metersPerPixel ->
6938
shouldReloadTiles = false
7039
try {
71-
sourceSelector?.let {
72-
loader.loadTiles(
73-
it,
74-
bounds,
75-
metersPerPixel,
76-
minZoom,
77-
backgroundColor,
78-
controlsPdfCache
79-
)
80-
}
40+
loader.loadTiles(
41+
source,
42+
bounds,
43+
metersPerPixel,
44+
minZoomLevel ?: 0,
45+
backgroundColor,
46+
controlsPdfCache
47+
)
8148
updateListener?.invoke()
8249
} catch (e: CancellationException) {
8350
System.gc()
@@ -88,6 +55,17 @@ class TiledMapLayer : IAsyncLayer {
8855
}
8956
}
9057

58+
}
59+
60+
override fun draw(drawer: ICanvasDrawer, map: IMapView) {
61+
// Avoid drawing while in safe mode
62+
if (SafeMode.isEnabled()) {
63+
return
64+
}
65+
66+
// Load tiles if needed
67+
taskRunner.scheduleUpdate(map.mapBounds, map.metersPerPixel, shouldReloadTiles)
68+
9169
// Render loaded tiles
9270
synchronized(loader.lock) {
9371
tilePaint.alpha = 255
@@ -139,8 +117,5 @@ class TiledMapLayer : IAsyncLayer {
139117
updateListener = listener
140118
}
141119

142-
private var _percentOpacity: Float = 1f
143-
144-
override val percentOpacity: Float
145-
get() = _percentOpacity
120+
override var percentOpacity: Float = 1f
146121
}

0 commit comments

Comments
 (0)