11package com.kylecorry.trail_sense.shared.dem.map_layers
22
3- import android.graphics.Color
4- import com.kylecorry.andromeda.canvas.ICanvasDrawer
5- import com.kylecorry.andromeda.core.cache.AppServiceRegistry
6- import com.kylecorry.andromeda.core.math.DecimalFormatter
7- import com.kylecorry.andromeda.core.units.PixelCoordinate
8- import com.kylecorry.sol.math.SolMath
9- import com.kylecorry.sol.units.Distance
10- import com.kylecorry.trail_sense.main.errors.SafeMode
11- import com.kylecorry.trail_sense.shared.UserPreferences
12- import com.kylecorry.trail_sense.shared.dem.Contour
13- import com.kylecorry.trail_sense.shared.dem.DEM
14- import com.kylecorry.trail_sense.shared.dem.colors.ElevationColorMap
153import com.kylecorry.trail_sense.shared.dem.colors.ElevationColorMapFactory
16- import com.kylecorry.trail_sense.shared.dem.colors.TrailSenseVibrantElevationColorMap
174import com.kylecorry.trail_sense.shared.map_layers.MapLayerBackgroundTask
18- import com.kylecorry.trail_sense.shared.map_layers.tiles.TileMath
19- import com.kylecorry.trail_sense.shared.map_layers.ui.layers.IAsyncLayer
20- import com.kylecorry.trail_sense.shared.map_layers.ui.layers.IMapView
21- import com.kylecorry.trail_sense.tools.navigation.ui.MappableLocation
22- import com.kylecorry.trail_sense.tools.navigation.ui.MappablePath
23- import com.kylecorry.trail_sense.tools.paths.domain.LineStyle
24- import com.kylecorry.trail_sense.tools.paths.map_layers.PathLayer
5+ import com.kylecorry.trail_sense.shared.map_layers.ui.layers.geojson.GeoJsonLayer
256
26- class ContourLayer (private val taskRunner : MapLayerBackgroundTask = MapLayerBackgroundTask ()) :
27- IAsyncLayer {
28-
29- private val pathLayer = PathLayer ()
30-
31- init {
32- taskRunner.addTask { bounds, metersPerPixel ->
33- val zoomLevel = TileMath .distancePerPixelToZoom(
34- metersPerPixel.toDouble(),
35- (bounds.north + bounds.south) / 2
36- ).coerceAtMost(maxZoomLevel)
37-
38- if (zoomLevel < minZoomLevel) {
39- contours = emptyList()
40- return @addTask
41- }
42-
43- val interval = validIntervals[zoomLevel] ? : validIntervals.values.first()
44- contours = DEM .getContourLines(bounds, interval, validResolutions[zoomLevel]!! )
45- contourInterval = interval
46- lastZoomLevel = zoomLevel
47- var i = - 10000L
48- pathLayer.setPaths(contours.flatMap { level ->
49- val isImportantLine = SolMath .isZero((level.elevation / contourInterval) % 5 , 0.1f )
50- val name = DecimalFormatter .format(
51- Distance .Companion .meters(level.elevation).convertTo(units).value, 0
52- )
53- val color = colorScale.getElevationColor(level.elevation)
54- level.lines.map { line ->
55- MappablePath (
56- i++ ,
57- line.map {
58- MappableLocation (0 , it, Color .TRANSPARENT , null )
59- },
60- color,
61- LineStyle .Solid ,
62- name = if (isImportantLine || showLabelsOnAllContoursZoomLevels.contains(
63- lastZoomLevel
64- )
65- ) {
66- name
67- } else {
68- null
69- },
70- thicknessScale = if (isImportantLine) {
71- 0.8f
72- } else {
73- 0.4f
74- }
75- )
76- }
77-
78- })
79- }
80- }
81-
82- private val units by lazy { AppServiceRegistry .get<UserPreferences >().baseDistanceUnits }
83-
84- private val minZoomLevel = 13
85- private val maxZoomLevel = 19
7+ class ContourLayer (taskRunner : MapLayerBackgroundTask = MapLayerBackgroundTask ()) :
8+ GeoJsonLayer <ContourGeoJsonSource >(ContourGeoJsonSource (), taskRunner) {
869
8710 fun setPreferences (prefs : ContourMapLayerPreferences ) {
88- _percentOpacity = prefs.opacity.get() / 100f
89- pathLayer.setShouldRenderLabels( prefs.showLabels.get())
11+ percentOpacity = prefs.opacity.get() / 100f
12+ renderer.configureLineStringRenderer(shouldRenderLabels = prefs.showLabels.get())
9013 // TODO: More experimentation required before this is enabled for everyone
91- // pathLayer.setShouldRenderSmoothPaths(isDebug())
92- colorScale = ElevationColorMapFactory ().getElevationColorMap(prefs.colorStrategy.get())
14+ // renderer.configureLineStringRenderer(shouldRenderSmoothPaths = isDebug())
15+ source.colorScale =
16+ ElevationColorMapFactory ().getElevationColorMap(prefs.colorStrategy.get())
9317 invalidate()
9418 }
95-
96- private var colorScale: ElevationColorMap = TrailSenseVibrantElevationColorMap ()
97-
98- private val validIntervals by lazy {
99- if (units.isMetric) {
100- mapOf (
101- 13 to 50f ,
102- 14 to 50f ,
103- 15 to 50f ,
104- 16 to 10f ,
105- 17 to 10f ,
106- 18 to 10f ,
107- 19 to 10f
108- )
109- } else {
110- mapOf (
111- 13 to Distance .Companion .feet(200f ).meters().value,
112- 14 to Distance .Companion .feet(200f ).meters().value,
113- 15 to Distance .Companion .feet(200f ).meters().value,
114- 16 to Distance .Companion .feet(40f ).meters().value,
115- 17 to Distance .Companion .feet(40f ).meters().value,
116- 18 to Distance .Companion .feet(40f ).meters().value,
117- 19 to Distance .Companion .feet(40f ).meters().value
118- )
119- }
120- }
121-
122- private val baseResolution = 1 / 240.0
123- private val validResolutions = mapOf (
124- 13 to baseResolution,
125- 14 to baseResolution / 2 ,
126- 15 to baseResolution / 4 ,
127- 16 to baseResolution / 4 ,
128- 17 to baseResolution / 4 ,
129- 18 to baseResolution / 4 ,
130- 19 to baseResolution / 4
131- )
132-
133- private val showLabelsOnAllContoursZoomLevels = setOf (
134- 14 , 15 , 19
135- )
136-
137- private var contours = listOf<Contour >()
138- private var contourInterval = 1f
139- private var lastZoomLevel = - 1
140-
141- override fun draw (
142- drawer : ICanvasDrawer ,
143- map : IMapView
144- ) {
145- if (SafeMode .isEnabled() || map.metersPerPixel > 75f ) {
146- return
147- }
148-
149- taskRunner.scheduleUpdate(map.mapBounds, map.metersPerPixel)
150- pathLayer.draw(drawer, map)
151- }
152-
153- override fun drawOverlay (
154- drawer : ICanvasDrawer ,
155- map : IMapView
156- ) {
157- pathLayer.drawOverlay(drawer, map)
158- }
159-
160- override fun invalidate () {
161- pathLayer.invalidate()
162- }
163-
164- override fun onClick (
165- drawer : ICanvasDrawer ,
166- map : IMapView ,
167- pixel : PixelCoordinate
168- ): Boolean {
169- return false
170- }
171-
172- private var _percentOpacity : Float = 1f
173-
174- override val percentOpacity: Float
175- get() = _percentOpacity
176-
177- override fun setHasUpdateListener (listener : (() -> Unit )? ) {
178- pathLayer.setHasUpdateListener(listener)
179- }
18019}
0 commit comments