Merge branch 'mapbox' into mapbox-sdkv3
This commit is contained in:
commit
c67f9f9726
14 changed files with 962 additions and 202 deletions
88
app/src/main/java/eu/ztsh/garmin/data/DataCache.kt
Normal file
88
app/src/main/java/eu/ztsh/garmin/data/DataCache.kt
Normal file
|
@ -0,0 +1,88 @@
|
|||
package eu.ztsh.garmin.data
|
||||
|
||||
import com.mapbox.navigation.core.trip.session.LocationMatcherResult
|
||||
import com.mapbox.navigation.core.trip.session.NavigationSessionState
|
||||
import com.mapbox.navigation.ui.maneuver.model.Maneuver
|
||||
|
||||
class DataCache {
|
||||
|
||||
private val stateCache: State = State()
|
||||
private var maneuverCache: Maneuver? = null
|
||||
private var locationCache: LocationMatcherResult? = null
|
||||
private var session: NavigationSessionState? = null
|
||||
|
||||
// state
|
||||
fun hasChanged(lanes: Lanes?): Boolean {
|
||||
return stateCache.lineArrows == null || stateCache.lineArrows != lanes
|
||||
}
|
||||
|
||||
fun hasChanged(outlines: Outlines?): Boolean {
|
||||
return stateCache.lineOutlines == null || stateCache.lineOutlines != outlines
|
||||
}
|
||||
|
||||
fun hasChanged(distance: Distance?): Boolean {
|
||||
return stateCache.distance == null || stateCache.distance != distance
|
||||
}
|
||||
|
||||
fun hasChanged(direction: Direction?): Boolean {
|
||||
return stateCache.direction == null || stateCache.direction != direction
|
||||
}
|
||||
|
||||
fun hasChanged(speed: Speed?): Boolean {
|
||||
return stateCache.speed == null || stateCache.speed != speed
|
||||
}
|
||||
|
||||
fun hasChanged(arrival: Arrival?): Boolean {
|
||||
return stateCache.arrival == null || stateCache.arrival != arrival
|
||||
}
|
||||
|
||||
// Merge states
|
||||
fun update(state: State) {
|
||||
if (state.lineArrows != null) {
|
||||
stateCache.lineArrows = state.lineArrows
|
||||
}
|
||||
if (state.lineOutlines != null) {
|
||||
state.lineOutlines = state.lineOutlines
|
||||
}
|
||||
if (state.direction != null) {
|
||||
stateCache.direction = state.direction
|
||||
}
|
||||
if (state.distance != null) {
|
||||
stateCache.distance = state.distance
|
||||
}
|
||||
if (state.speed != null) {
|
||||
stateCache.speed = state.speed
|
||||
}
|
||||
if (state.arrival != null) {
|
||||
stateCache.arrival = state.arrival
|
||||
}
|
||||
}
|
||||
|
||||
// maneuver
|
||||
fun hasChanged(maneuver: Maneuver): Boolean {
|
||||
return maneuverCache == null || maneuverCache!! != maneuver
|
||||
}
|
||||
|
||||
fun update(maneuver: Maneuver) {
|
||||
maneuverCache = maneuver
|
||||
}
|
||||
|
||||
// location
|
||||
fun hasChanged(locationMatcherResult: LocationMatcherResult): Boolean {
|
||||
return locationCache == null || locationCache!! != locationMatcherResult
|
||||
}
|
||||
|
||||
fun update(locationMatcherResult: LocationMatcherResult) {
|
||||
locationCache = locationMatcherResult
|
||||
}
|
||||
|
||||
// session
|
||||
fun isActive(): Boolean {
|
||||
return session != null && session is NavigationSessionState.ActiveGuidance
|
||||
}
|
||||
|
||||
fun update(sessionState: NavigationSessionState) {
|
||||
session = sessionState
|
||||
}
|
||||
|
||||
}
|
151
app/src/main/java/eu/ztsh/garmin/data/GarminMapper.kt
Normal file
151
app/src/main/java/eu/ztsh/garmin/data/GarminMapper.kt
Normal file
|
@ -0,0 +1,151 @@
|
|||
package eu.ztsh.garmin.data
|
||||
|
||||
class GarminMapper {
|
||||
|
||||
companion object {
|
||||
|
||||
fun setLines(state: State): IntArray {
|
||||
return intArrayOf(0x02, state.lineOutlines.sumOf { it.value }, state.lineArrows.sumOf { it.value })
|
||||
}
|
||||
|
||||
fun setDirection(state: State): IntArray {
|
||||
return setDirection(state.direction.angle, state.direction.out, state.direction.roundabout)
|
||||
}
|
||||
|
||||
fun setDistance(state: State): IntArray {
|
||||
return setDistance(state.distance, state.unit)
|
||||
}
|
||||
|
||||
fun setSpeed(state: State): IntArray {
|
||||
return setSpeed(state.speed, state.limit, state.speed > state.limit)
|
||||
}
|
||||
|
||||
fun setSpeedFreeRide(state: State): Pair<IntArray, IntArray> {
|
||||
return Pair(setDistance(state.speed), setSpeed(state.limit, limitWarning = state.speed > state.limit))
|
||||
}
|
||||
|
||||
fun setTime(hours: Int, minutes: Int, traffic: Boolean = false, flag: Boolean = false): IntArray {
|
||||
val trafficChar = asChar(traffic)
|
||||
val flagChar = asChar(flag)
|
||||
return if (hours > 99) {
|
||||
intArrayOf(
|
||||
0x05,
|
||||
trafficChar,
|
||||
asDigit(hours / 1000),
|
||||
asDigit(hours / 100),
|
||||
0x00,
|
||||
asDigit(hours / 10),
|
||||
asDigit(hours),
|
||||
0xff,
|
||||
flagChar
|
||||
)
|
||||
} else {
|
||||
intArrayOf(
|
||||
0x05,
|
||||
trafficChar,
|
||||
asDigit(hours / 10),
|
||||
asDigit(hours),
|
||||
0xff,
|
||||
asDigit(minutes / 10),
|
||||
asDigit(minutes),
|
||||
0x00,
|
||||
flagChar
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun setSpeedControl(state: State): IntArray {
|
||||
return intArrayOf(0x04, if (state.control) 0x01 else 0x02)
|
||||
}
|
||||
|
||||
fun setCompass(state: State): IntArray {
|
||||
// TODO: Implement
|
||||
return setDirection(OutAngle.Straight, OutType.ArrowOnly)
|
||||
}
|
||||
|
||||
fun cleanDistance(): IntArray {
|
||||
return intArrayOf(0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
|
||||
}
|
||||
|
||||
private fun setDirection(
|
||||
angle: OutAngle,
|
||||
out: OutType = OutType.Lane,
|
||||
roundabout: OutAngle = OutAngle.AsDirection
|
||||
): IntArray {
|
||||
val param1: Int = when (angle) {
|
||||
OutAngle.LeftDown -> 0x10
|
||||
OutAngle.RightDown -> 0x20
|
||||
else -> out.value
|
||||
}
|
||||
val param2: Int = if (out == OutType.RightRoundabout
|
||||
|| out == OutType.LeftRoundabout
|
||||
) {
|
||||
if (roundabout == OutAngle.AsDirection) angle.value else roundabout.value
|
||||
} else {
|
||||
0x00
|
||||
}
|
||||
val param3: Int =
|
||||
if (angle == OutAngle.LeftDown || angle == OutAngle.RightDown) 0x00 else angle.value
|
||||
return intArrayOf(0x01, param1, param2, param3)
|
||||
}
|
||||
|
||||
private fun setDistance(distance: Int, unit: Unit = Unit.Any): IntArray {
|
||||
return intArrayOf(
|
||||
0x03, asDigit(distance / 1000), asDigit(distance / 100), asDigit(distance / 10),
|
||||
0x00, asDigit(distance), unit.value
|
||||
)
|
||||
}
|
||||
|
||||
private fun setSpeed(
|
||||
speed: Int,
|
||||
limit: Int = 0,
|
||||
limitWarning: Boolean = false,
|
||||
acc: Boolean = false
|
||||
): IntArray {
|
||||
// TODO: car connection
|
||||
val accChar = asChar(acc)
|
||||
val limitWarningChar = asChar(limitWarning)
|
||||
return if (limit > 0) {
|
||||
intArrayOf(
|
||||
0x06,
|
||||
asDigit(speed / 100),
|
||||
asDigit(speed / 10),
|
||||
asDigit(speed),
|
||||
0xff,
|
||||
asDigit(limit / 100),
|
||||
asDigit(limit / 10),
|
||||
asDigit(limit),
|
||||
limitWarningChar,
|
||||
accChar
|
||||
)
|
||||
} else {
|
||||
intArrayOf(
|
||||
0x06,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
asDigit(speed / 100),
|
||||
asDigit(speed / 10),
|
||||
asDigit(speed),
|
||||
limitWarningChar,
|
||||
accChar
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun asDigit(n: Int): Int {
|
||||
if (n == 0) {
|
||||
return 0
|
||||
}
|
||||
val m = n % 10
|
||||
return if (m == 0) 10 else m
|
||||
}
|
||||
|
||||
private fun asChar(boolean: Boolean): Int {
|
||||
return if (boolean) 0xff else 0x00
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
76
app/src/main/java/eu/ztsh/garmin/data/MapboxMapper.kt
Normal file
76
app/src/main/java/eu/ztsh/garmin/data/MapboxMapper.kt
Normal file
|
@ -0,0 +1,76 @@
|
|||
package eu.ztsh.garmin.data
|
||||
|
||||
import com.mapbox.navigation.tripdata.maneuver.model.Maneuver
|
||||
import com.mapbox.navigation.core.trip.session.LocationMatcherResult
|
||||
|
||||
class MapboxMapper {
|
||||
|
||||
companion object {
|
||||
|
||||
fun apply(maneuver: Maneuver): State {
|
||||
val state = State()
|
||||
maneuver.apply {
|
||||
this.primary.apply {
|
||||
state.direction = Direction()
|
||||
when (this.type) {
|
||||
"roundabout" -> {
|
||||
state.direction!!.out = OutType.RightRoundabout
|
||||
}
|
||||
|
||||
"arrive" -> {
|
||||
state.flag = true
|
||||
}
|
||||
}
|
||||
when (this.modifier) {
|
||||
"right" -> {
|
||||
when (this.type) {
|
||||
"turn" -> state.direction!!.angle = OutAngle.Right
|
||||
"roundabout" -> {
|
||||
when (this.degrees) {
|
||||
137.0 -> state.direction!!.angle = OutAngle.EasyRight
|
||||
180.0 -> state.direction!!.angle = OutAngle.Straight
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"left" -> {
|
||||
when (this.type) {
|
||||
"turn" -> state.direction!!.angle = OutAngle.Left
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.stepDistance.apply {
|
||||
this.distanceRemaining?.apply {
|
||||
distanceFormatter.formatDistance(distanceRemaining!!).split(" ").apply {
|
||||
state.distance = Distance(
|
||||
this[0].replace(',', '.').toDouble().toInt(),
|
||||
when (this[1]) {
|
||||
"m" -> Unit.Metres
|
||||
"km" -> Unit.Kilometres
|
||||
else -> Unit.Any
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
this.laneGuidance?.apply {
|
||||
this.allLanes.apply {
|
||||
println()
|
||||
}
|
||||
}
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
fun apply(locationMatcherResult: LocationMatcherResult): State {
|
||||
val state = State()
|
||||
// TODO: speed, limit, location?, bearing
|
||||
return state
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
141
app/src/main/java/eu/ztsh/garmin/data/Model.kt
Normal file
141
app/src/main/java/eu/ztsh/garmin/data/Model.kt
Normal file
|
@ -0,0 +1,141 @@
|
|||
package eu.ztsh.garmin.data
|
||||
|
||||
enum class OutType(val value: Int) {
|
||||
|
||||
Off(0x00),
|
||||
Lane(0x01),
|
||||
LongerLane(0x02),
|
||||
LeftRoundabout(0x04),
|
||||
RightRoundabout(0x08),
|
||||
Flag(0x40),
|
||||
ArrowOnly(0x80);
|
||||
|
||||
}
|
||||
|
||||
|
||||
enum class OutAngle(val value: Int) {
|
||||
|
||||
Down(0x01),
|
||||
SharpRight(0x02),
|
||||
Right(0x04),
|
||||
EasyRight(0x08),
|
||||
Straight(0x10),
|
||||
EasyLeft(0x20),
|
||||
Left(0x40),
|
||||
SharpLeft(0x80),
|
||||
LeftDown(0x81),
|
||||
RightDown(0x82),
|
||||
AsDirection(0x00)
|
||||
|
||||
}
|
||||
|
||||
enum class Unit(val value: Int) {
|
||||
|
||||
Any(0),
|
||||
Metres(1),
|
||||
Kilometres(3),
|
||||
Miles(5),
|
||||
Foot(8)
|
||||
|
||||
}
|
||||
|
||||
enum class Lane(val value: Int) {
|
||||
|
||||
DotsRight(0x01),
|
||||
OuterRight(0x02),
|
||||
MiddleRight(0x04),
|
||||
InnerRight(0x08),
|
||||
InnerLeft(0x10),
|
||||
MiddleLeft(0x20),
|
||||
OuterLeft(0x40),
|
||||
DotsLeft(0x80)
|
||||
|
||||
}
|
||||
|
||||
open class Arrows(val lanes: List<Lane>) {
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as Arrows
|
||||
|
||||
return lanes == other.lanes
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return lanes.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
class Lanes(lanes: List<Lane>) : Arrows(lanes)
|
||||
|
||||
class Outlines(lanes: List<Lane>) : Arrows(lanes)
|
||||
|
||||
class Distance(val distance: Int, val unit: Unit) {
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as Distance
|
||||
|
||||
if (distance != other.distance) return false
|
||||
if (unit != other.unit) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = distance
|
||||
result = 31 * result + unit.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Speed(val speed: Int, val limit: Int)
|
||||
|
||||
class Arrival(val hours: Int, val minutes: Int)
|
||||
|
||||
class State {
|
||||
|
||||
var lineArrows: Lanes? = null
|
||||
var lineOutlines: Outlines? = null
|
||||
var direction : Direction? = null
|
||||
var distance: Distance? = null
|
||||
var speed: Speed? = null
|
||||
var arrival: Arrival? = null
|
||||
// TODO: Bearing
|
||||
// TODO: support
|
||||
var traffic: Boolean? = null
|
||||
var flag: Boolean? = null
|
||||
var control: Boolean? = null
|
||||
|
||||
}
|
||||
|
||||
class Direction {
|
||||
var angle: OutAngle = OutAngle.AsDirection
|
||||
var out: OutType = OutType.Lane
|
||||
var roundabout: OutAngle = OutAngle.AsDirection
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as Direction
|
||||
|
||||
if (angle != other.angle) return false
|
||||
if (out != other.out) return false
|
||||
if (roundabout != other.roundabout) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = angle.hashCode()
|
||||
result = 31 * result + out.hashCode()
|
||||
result = 31 * result + roundabout.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue