Skip to content

Commit f63ca6e

Browse files
committed
Create path geojson layer (WIP)
Signed-off-by: Kyle Corry <kylecorry31@gmail.com>
1 parent ed66e0e commit f63ca6e

12 files changed

Lines changed: 160 additions & 77 deletions

File tree

app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/ui/AugmentedRealityFragment.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ import com.kylecorry.trail_sense.tools.diagnostics.status.SensorStatusBadgeProvi
6666
import com.kylecorry.trail_sense.tools.diagnostics.status.StatusBadge
6767
import com.kylecorry.trail_sense.tools.navigation.infrastructure.Navigator
6868
import com.kylecorry.trail_sense.tools.navigation.ui.IMappablePath
69-
import com.kylecorry.trail_sense.tools.paths.map_layers.PathLayerManager
69+
import com.kylecorry.trail_sense.tools.paths.map_layers.LegacyPathLayerManager
7070
import java.time.LocalDate
7171
import java.time.ZonedDateTime
7272
import kotlin.math.hypot
@@ -140,7 +140,7 @@ class AugmentedRealityFragment : BoundFragment<FragmentToolAugmentedRealityBindi
140140
this::onPathFocused
141141
)
142142
}
143-
private var pathLayerManager: PathLayerManager? = null
143+
private var pathLayerManager: LegacyPathLayerManager? = null
144144

145145
private var isCameraEnabled = true
146146

@@ -262,7 +262,7 @@ class AugmentedRealityFragment : BoundFragment<FragmentToolAugmentedRealityBindi
262262
override fun onResume() {
263263
super.onResume()
264264

265-
pathLayerManager = PathLayerManager(
265+
pathLayerManager = LegacyPathLayerManager(
266266
requireContext(),
267267
pathsLayer,
268268
shouldCorrectElevations = userPrefs.augmentedReality.adjustForPathElevation

app/src/main/java/com/kylecorry/trail_sense/tools/map/ui/MapToolLayerManager.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import com.kylecorry.trail_sense.tools.beacons.map_layers.BeaconLayerManager
3939
import com.kylecorry.trail_sense.tools.navigation.infrastructure.Navigator
4040
import com.kylecorry.trail_sense.tools.navigation.map_layers.NavigationLayer
4141
import com.kylecorry.trail_sense.tools.navigation.map_layers.NavigationLayerManager
42+
import com.kylecorry.trail_sense.tools.paths.map_layers.LegacyPathLayer
4243
import com.kylecorry.trail_sense.tools.paths.map_layers.PathLayer
4344
import com.kylecorry.trail_sense.tools.paths.map_layers.PathLayerManager
4445
import com.kylecorry.trail_sense.tools.photo_maps.infrastructure.tiles.PhotoMapRegionLoader

app/src/main/java/com/kylecorry/trail_sense/tools/navigation/map_layers/NavigationLayer.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ import com.kylecorry.trail_sense.tools.navigation.domain.Destination
99
import com.kylecorry.trail_sense.tools.navigation.ui.MappableLocation
1010
import com.kylecorry.trail_sense.tools.navigation.ui.MappablePath
1111
import com.kylecorry.trail_sense.tools.paths.domain.LineStyle
12-
import com.kylecorry.trail_sense.tools.paths.map_layers.PathLayer
12+
import com.kylecorry.trail_sense.tools.paths.map_layers.LegacyPathLayer
1313

1414
class NavigationLayer : BaseLayer() {
1515

16-
private val pathLayer = PathLayer()
16+
private val pathLayer = LegacyPathLayer()
1717

1818
private var _myLocation: Coordinate? = null
1919
private var _destination: Destination? = null

app/src/main/java/com/kylecorry/trail_sense/tools/navigation/ui/layers/NavigationCompassLayerManager.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import com.kylecorry.sol.units.Coordinate
99
import com.kylecorry.trail_sense.R
1010
import com.kylecorry.trail_sense.shared.CustomUiUtils.getPrimaryMarkerColor
1111
import com.kylecorry.trail_sense.shared.UserPreferences
12-
import com.kylecorry.trail_sense.shared.map_layers.MapLayerBackgroundTask
1312
import com.kylecorry.trail_sense.shared.dem.map_layers.ContourLayer
1413
import com.kylecorry.trail_sense.shared.dem.map_layers.ElevationLayer
1514
import com.kylecorry.trail_sense.shared.dem.map_layers.HillshadeLayer
15+
import com.kylecorry.trail_sense.shared.map_layers.MapLayerBackgroundTask
1616
import com.kylecorry.trail_sense.shared.map_layers.ui.layers.ILayerManager
1717
import com.kylecorry.trail_sense.shared.map_layers.ui.layers.IMapView
1818
import com.kylecorry.trail_sense.shared.map_layers.ui.layers.MultiLayerManager
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package com.kylecorry.trail_sense.tools.paths.map_layers
2+
3+
import android.content.Context
4+
import com.kylecorry.andromeda.core.coroutines.onDefault
5+
import com.kylecorry.luna.coroutines.CoroutineQueueRunner
6+
import com.kylecorry.sol.science.geology.CoordinateBounds
7+
import com.kylecorry.sol.units.Coordinate
8+
import com.kylecorry.trail_sense.tools.paths.domain.Path
9+
import com.kylecorry.trail_sense.tools.paths.domain.PathPoint
10+
import com.kylecorry.trail_sense.tools.paths.domain.hiking.HikingService
11+
import com.kylecorry.trail_sense.tools.paths.infrastructure.PathLoader
12+
import com.kylecorry.trail_sense.tools.paths.infrastructure.persistence.PathService
13+
import com.kylecorry.trail_sense.tools.paths.ui.IPathLayer
14+
import com.kylecorry.trail_sense.tools.paths.ui.asMappable
15+
import com.kylecorry.trail_sense.shared.map_layers.ui.layers.BaseLayerManager
16+
import kotlinx.coroutines.CoroutineScope
17+
import kotlinx.coroutines.Dispatchers
18+
import kotlinx.coroutines.cancel
19+
import kotlinx.coroutines.launch
20+
21+
class LegacyPathLayerManager(
22+
private val context: Context,
23+
private val layer: IPathLayer,
24+
private val shouldCorrectElevations: Boolean = false
25+
) :
26+
BaseLayerManager() {
27+
28+
private val pathService = PathService.Companion.getInstance(context)
29+
private val hikingService = HikingService()
30+
private val pathLoader = PathLoader(pathService)
31+
private var paths = emptyList<Path>()
32+
private val scope = CoroutineScope(Dispatchers.Default)
33+
private val loadRunner = CoroutineQueueRunner(2, scope)
34+
private val listenerRunner = CoroutineQueueRunner(scope = scope)
35+
private var loaded = false
36+
private var wasBacktrackOn = false
37+
38+
override fun start() {
39+
loaded = false
40+
scope.launch {
41+
listenerRunner.skipIfRunning {
42+
pathService.getPaths().collect {
43+
paths = it.filter { path -> path.style.visible }
44+
wasBacktrackOn = pathService.getBacktrackPathId() != null
45+
loaded = false
46+
loadRunner.replace {
47+
loadPaths(true)
48+
}
49+
}
50+
}
51+
}
52+
}
53+
54+
override fun stop() {
55+
listenerRunner.cancel()
56+
loadRunner.cancel()
57+
scope.cancel()
58+
}
59+
60+
override fun onBoundsChanged(bounds: CoordinateBounds?) {
61+
super.onBoundsChanged(bounds)
62+
scope.launch {
63+
loadRunner.enqueue {
64+
loadPaths(false)
65+
}
66+
}
67+
}
68+
69+
override fun onLocationChanged(location: Coordinate, accuracy: Float?) {
70+
super.onLocationChanged(location, accuracy)
71+
if (!wasBacktrackOn){
72+
return
73+
}
74+
scope.launch {
75+
loadRunner.enqueue {
76+
loadPaths(false)
77+
}
78+
}
79+
}
80+
81+
private suspend fun loadPaths(reload: Boolean) = onDefault {
82+
bounds?.let {
83+
pathLoader.update(paths, it, it, reload || !loaded)
84+
loaded = true
85+
}
86+
87+
val points = pathLoader.getPointsWithBacktrack(context)
88+
onPathsChanged(paths, points)
89+
}
90+
91+
private fun onPathsChanged(paths: List<Path>, points: Map<Long, List<PathPoint>>) {
92+
val mappablePaths = points.mapNotNull {
93+
val path =
94+
paths.firstOrNull { p -> p.id == it.key } ?: return@mapNotNull null
95+
96+
val correctedPoints = if (shouldCorrectElevations) {
97+
hikingService.correctElevations(it.value.sortedBy { it.id }).reversed()
98+
} else {
99+
it.value
100+
}
101+
102+
correctedPoints.asMappable(context, path)
103+
}
104+
layer.setPaths(mappablePaths)
105+
}
106+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.kylecorry.trail_sense.tools.paths.map_layers
2+
3+
import com.kylecorry.andromeda.geojson.GeoJsonFeature
4+
import com.kylecorry.andromeda.geojson.GeoJsonFeatureCollection
5+
import com.kylecorry.andromeda.geojson.GeoJsonObject
6+
import com.kylecorry.sol.science.geology.CoordinateBounds
7+
import com.kylecorry.trail_sense.shared.extensions.lineString
8+
import com.kylecorry.trail_sense.shared.map_layers.ui.layers.geojson.sources.GeoJsonSource
9+
import com.kylecorry.trail_sense.tools.navigation.ui.IMappablePath
10+
11+
class PathGeoJsonSource : GeoJsonSource {
12+
13+
var paths: List<IMappablePath> = emptyList()
14+
15+
override suspend fun load(
16+
bounds: CoordinateBounds,
17+
metersPerPixel: Float
18+
): GeoJsonObject? {
19+
return GeoJsonFeatureCollection(paths.map {
20+
GeoJsonFeature.lineString(
21+
it.points.map { point -> point.coordinate },
22+
it.id,
23+
it.name,
24+
it.style,
25+
it.color,
26+
it.thicknessScale
27+
)
28+
})
29+
}
30+
}
Lines changed: 8 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,21 @@
11
package com.kylecorry.trail_sense.tools.paths.map_layers
22

3-
import com.kylecorry.andromeda.canvas.ICanvasDrawer
4-
import com.kylecorry.andromeda.core.units.PixelCoordinate
5-
import com.kylecorry.andromeda.geojson.GeoJsonFeature
6-
import com.kylecorry.andromeda.geojson.GeoJsonFeatureCollection
7-
import com.kylecorry.trail_sense.shared.extensions.lineString
8-
import com.kylecorry.trail_sense.shared.map_layers.ui.layers.IAsyncLayer
9-
import com.kylecorry.trail_sense.shared.map_layers.ui.layers.IMapView
10-
import com.kylecorry.trail_sense.shared.map_layers.ui.layers.geojson.GeoJsonRenderer
3+
import com.kylecorry.trail_sense.shared.map_layers.ui.layers.geojson.GeoJsonLayer
114
import com.kylecorry.trail_sense.tools.navigation.ui.IMappablePath
12-
import com.kylecorry.trail_sense.tools.paths.ui.IPathLayer
135

14-
class PathLayer : IAsyncLayer, IPathLayer {
15-
16-
private val geoJsonRenderer = GeoJsonRenderer()
6+
class PathLayer : GeoJsonLayer<PathGeoJsonSource>(PathGeoJsonSource()) {
177

188
fun setPreferences(prefs: PathMapLayerPreferences) {
19-
_percentOpacity = prefs.opacity.get() / 100f
20-
geoJsonRenderer.configureLineStringRenderer(backgroundColor = prefs.backgroundColor.get())
9+
percentOpacity = prefs.opacity.get() / 100f
10+
renderer.configureLineStringRenderer(backgroundColor = prefs.backgroundColor.get())
2111
}
2212

2313
fun setShouldRenderWithDrawLines(shouldRenderWithDrawLines: Boolean) {
24-
geoJsonRenderer.configureLineStringRenderer(shouldRenderWithDrawLines = shouldRenderWithDrawLines)
25-
}
26-
27-
fun setShouldRenderSmoothPaths(shouldRenderSmoothPaths: Boolean) {
28-
geoJsonRenderer.configureLineStringRenderer(shouldRenderSmoothPaths = shouldRenderSmoothPaths)
29-
}
30-
31-
fun setShouldRenderLabels(shouldRenderLabels: Boolean) {
32-
geoJsonRenderer.configureLineStringRenderer(shouldRenderLabels = shouldRenderLabels)
33-
}
34-
35-
override fun setPaths(paths: List<IMappablePath>) {
36-
geoJsonRenderer.setGeoJsonObject(GeoJsonFeatureCollection(paths.map {
37-
GeoJsonFeature.lineString(
38-
it.points.map { point -> point.coordinate },
39-
it.id,
40-
it.name,
41-
it.style,
42-
it.color,
43-
it.thicknessScale
44-
)
45-
}))
46-
}
47-
48-
override fun draw(drawer: ICanvasDrawer, map: IMapView) {
49-
geoJsonRenderer.draw(drawer, map)
14+
renderer.configureLineStringRenderer(shouldRenderWithDrawLines = shouldRenderWithDrawLines)
5015
}
5116

52-
override fun drawOverlay(
53-
drawer: ICanvasDrawer,
54-
map: IMapView
55-
) {
56-
// Do nothing
17+
fun setPaths(paths: List<IMappablePath>) {
18+
source.paths = paths
19+
invalidate()
5720
}
58-
59-
override fun invalidate() {
60-
geoJsonRenderer.invalidate()
61-
}
62-
63-
override fun onClick(drawer: ICanvasDrawer, map: IMapView, pixel: PixelCoordinate): Boolean {
64-
return geoJsonRenderer.onClick(drawer, map, pixel)
65-
}
66-
67-
override fun setHasUpdateListener(listener: (() -> Unit)?) {
68-
geoJsonRenderer.setHasUpdateListener(listener)
69-
}
70-
71-
private var _percentOpacity: Float = 1f
72-
73-
override val percentOpacity: Float
74-
get() = _percentOpacity
7521
}

app/src/main/java/com/kylecorry/trail_sense/tools/paths/map_layers/PathLayerManager.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import kotlinx.coroutines.launch
2020

2121
class PathLayerManager(
2222
private val context: Context,
23-
private val layer: IPathLayer,
23+
private val layer: PathLayer,
2424
private val shouldCorrectElevations: Boolean = false
2525
) :
2626
BaseLayerManager() {

app/src/main/java/com/kylecorry/trail_sense/tools/paths/ui/PathOverviewFragment.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ import com.kylecorry.trail_sense.tools.paths.domain.point_finder.NearestPathLine
6969
import com.kylecorry.trail_sense.tools.paths.domain.point_finder.NearestPathPointNavigator
7070
import com.kylecorry.trail_sense.tools.paths.infrastructure.commands.BacktrackCommand
7171
import com.kylecorry.trail_sense.tools.paths.infrastructure.persistence.PathService
72-
import com.kylecorry.trail_sense.tools.paths.map_layers.PathLayer
72+
import com.kylecorry.trail_sense.tools.paths.map_layers.LegacyPathLayer
7373
import com.kylecorry.trail_sense.tools.paths.ui.commands.ChangePathColorCommand
7474
import com.kylecorry.trail_sense.tools.paths.ui.commands.ChangePathLineStyleCommand
7575
import com.kylecorry.trail_sense.tools.paths.ui.commands.ChangePointStyleCommand
@@ -121,7 +121,7 @@ class PathOverviewFragment : BoundFragment<FragmentPathOverviewBinding>() {
121121
private var slopes: List<Triple<PathPoint, PathPoint, Float>> = emptyList()
122122
private var difficulty = HikingDifficulty.Easy
123123

124-
private val pathLayer = PathLayer()
124+
private val pathLayer = LegacyPathLayer()
125125
private val scaleBarLayer = ScaleBarLayer()
126126

127127
private var lastBounds = CoordinateBounds.empty

app/src/main/java/com/kylecorry/trail_sense/tools/photo_maps/ui/MapDistanceLayer.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import com.kylecorry.trail_sense.tools.navigation.ui.MappablePath
1010
import com.kylecorry.trail_sense.tools.beacons.map_layers.LegacyBeaconLayer
1111
import com.kylecorry.trail_sense.shared.map_layers.ui.layers.ILayer
1212
import com.kylecorry.trail_sense.shared.map_layers.ui.layers.IMapView
13-
import com.kylecorry.trail_sense.tools.paths.map_layers.PathLayer
13+
import com.kylecorry.trail_sense.tools.paths.map_layers.LegacyPathLayer
1414
import com.kylecorry.trail_sense.tools.paths.domain.LineStyle
1515

1616
class MapDistanceLayer(private val onPathChanged: (points: List<Coordinate>) -> Unit = {}) :
@@ -23,7 +23,7 @@ class MapDistanceLayer(private val onPathChanged: (points: List<Coordinate>) ->
2323
add(it.coordinate)
2424
true
2525
}
26-
private val pathLayer = PathLayer()
26+
private val pathLayer = LegacyPathLayer()
2727
private var points = mutableListOf<Coordinate>()
2828

2929
init {

0 commit comments

Comments
 (0)