/*
* Garmin HUD Companion Application
* Copyright (C) 2022 Piotr Dec / ztsh.eu
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package eu.ztsh.garmin.data
import com.mapbox.navigation.tripdata.maneuver.model.Maneuver
import com.mapbox.navigation.core.trip.session.LocationMatcherResult
import com.mapbox.navigation.tripdata.progress.model.TripProgressUpdateValue
class MapboxMapper {
companion object {
fun asDirection(maneuver: Maneuver): Direction {
val direction = Direction()
maneuver.primary.apply {
when (this.type) {
"roundabout" -> {
direction.out = OutType.RightRoundabout
}
"arrive" -> {
direction.out = OutType.Flag
direction.angle = OutAngle.Right
}
"turn" -> {
when (this.modifier) {
"straight" -> direction.angle = OutAngle.Straight
"slight right" -> direction.angle = OutAngle.EasyRight
"slight left" -> direction.angle = OutAngle.EasyLeft
"sharp right" -> direction.angle = OutAngle.SharpRight
"sharp left" -> direction.angle = OutAngle.SharpLeft
"uturn" -> direction.angle = OutAngle.LeftDown
}
}
}
when (this.modifier) {
"right" -> {
direction.angle = OutAngle.Right
when (this.type) {
"roundabout" -> {
when (this.degrees!!.toInt()) {
in 22..66 -> direction.angle = OutAngle.SharpRight
in 67..111 -> direction.angle = OutAngle.Right
in 112..156 -> direction.angle = OutAngle.EasyRight
in 157..203 -> direction.angle = OutAngle.Straight
in 204..248 -> direction.angle = OutAngle.EasyLeft
in 249..293 -> direction.angle = OutAngle.Left
in 294..338 -> direction.angle = OutAngle.SharpLeft
else -> direction.angle = OutAngle.Down
}
}
"fork", "off ramp" -> {
direction.angle = OutAngle.EasyRight
direction.out = OutType.LongerLane
}
}
}
"left" -> {
direction.angle = OutAngle.Left
when (this.type) {
"fork", "off ramp" -> {
direction.angle = OutAngle.EasyLeft
direction.out = OutType.LongerLane
}
}
}
}
}
return direction
}
fun asDistance(maneuver: Maneuver): Distance {
return maneuver.stepDistance.let { step ->
step.distanceFormatter.formatDistance(step.distanceRemaining!!).split(" ").let {
Distance(
it[0].replace(',', '.').toDouble(),
when (it[1]) {
"m" -> Unit.Metres
"km" -> Unit.Kilometres
else -> Unit.Any
}
)
}
}
}
fun asLanes(maneuver: Maneuver): Lanes {
val laneIterator = Lane.iterator()
val outlines = mutableSetOf()
val lanes = mutableSetOf()
maneuver.laneGuidance?.apply {
this.allLanes.reversed().let {
it.forEach{ indicator ->
val lane = if (laneIterator.hasNext()) laneIterator.next() else Lane.DotsLeft
if (lane == Lane.DotsLeft) {
outlines.add(Lane.DotsLeft)
} else {
outlines.add(lane)
if (indicator.isActive) {
lanes.add(lane)
}
}
}
}
}
return Lanes(Arrows(lanes), Arrows(outlines))
}
fun asSpeed(locationMatcherResult: LocationMatcherResult): Speed {
return Speed(
locationMatcherResult.enhancedLocation.speed.let { it?.let { it / 1000.0 * 3600 }?.toInt() ?: 0 },
locationMatcherResult.speedLimitInfo.speed.let { it ?: 0 },
)
}
fun asEta(trip: TripProgressUpdateValue): Arrival {
val eta = trip.formatter
.getEstimatedTimeToArrival(trip.estimatedTimeToArrival)
.toString().split(":")
return Arrival(eta[0].toInt(), eta[1].toInt())
}
}
}