Show headwind line in wind forecast preview (#153)
This commit is contained in:
parent
1727e606ee
commit
533cb1e006
@ -70,7 +70,8 @@ abstract class LineGraphForecastDataType(private val karooSystem: KarooSystemSer
|
|||||||
abstract fun getLineData(
|
abstract fun getLineData(
|
||||||
lineData: List<LineData>,
|
lineData: List<LineData>,
|
||||||
isImperial: Boolean,
|
isImperial: Boolean,
|
||||||
upcomingRoute: UpcomingRoute?
|
upcomingRoute: UpcomingRoute?,
|
||||||
|
isPreview: Boolean
|
||||||
): Set<LineGraphBuilder.Line>
|
): Set<LineGraphBuilder.Line>
|
||||||
|
|
||||||
private fun previewFlow(settingsAndProfileStream: Flow<SettingsAndProfile>): Flow<StreamData> =
|
private fun previewFlow(settingsAndProfileStream: Flow<SettingsAndProfile>): Flow<StreamData> =
|
||||||
@ -261,7 +262,12 @@ abstract class LineGraphForecastDataType(private val karooSystem: KarooSystemSer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val pointData = getLineData(data, settingsAndProfile.isImperialTemperature, upcomingRoute)
|
val pointData = getLineData(
|
||||||
|
data,
|
||||||
|
settingsAndProfile.isImperialTemperature,
|
||||||
|
upcomingRoute,
|
||||||
|
config.preview
|
||||||
|
)
|
||||||
val bitmap = LineGraphBuilder(context).drawLineGraph(config.viewSize.first, config.viewSize.second, config.gridSize.first, config.gridSize.second, pointData) { x ->
|
val bitmap = LineGraphBuilder(context).drawLineGraph(config.viewSize.first, config.viewSize.second, config.gridSize.first, config.gridSize.second, pointData) { x ->
|
||||||
val startTime = data.firstOrNull()?.time
|
val startTime = data.firstOrNull()?.time
|
||||||
val time = startTime?.plus(floor(x).toLong(), ChronoUnit.HOURS)
|
val time = startTime?.plus(floor(x).toLong(), ChronoUnit.HOURS)
|
||||||
|
|||||||
@ -8,7 +8,8 @@ class PrecipitationForecastDataType(karooSystem: KarooSystemService) : LineGraph
|
|||||||
override fun getLineData(
|
override fun getLineData(
|
||||||
lineData: List<LineData>,
|
lineData: List<LineData>,
|
||||||
isImperial: Boolean,
|
isImperial: Boolean,
|
||||||
upcomingRoute: UpcomingRoute?
|
upcomingRoute: UpcomingRoute?,
|
||||||
|
isPreview: Boolean
|
||||||
): Set<LineGraphBuilder.Line> {
|
): Set<LineGraphBuilder.Line> {
|
||||||
val precipitationPoints = lineData.map { data ->
|
val precipitationPoints = lineData.map { data ->
|
||||||
if (isImperial) { // Convert mm to inches
|
if (isImperial) { // Convert mm to inches
|
||||||
|
|||||||
@ -8,7 +8,8 @@ class TemperatureForecastDataType(karooSystem: KarooSystemService) : LineGraphFo
|
|||||||
override fun getLineData(
|
override fun getLineData(
|
||||||
lineData: List<LineData>,
|
lineData: List<LineData>,
|
||||||
isImperial: Boolean,
|
isImperial: Boolean,
|
||||||
upcomingRoute: UpcomingRoute?
|
upcomingRoute: UpcomingRoute?,
|
||||||
|
isPreview: Boolean
|
||||||
): Set<LineGraphBuilder.Line> {
|
): Set<LineGraphBuilder.Line> {
|
||||||
val linePoints = lineData.map { data ->
|
val linePoints = lineData.map { data ->
|
||||||
if (isImperial) {
|
if (isImperial) {
|
||||||
|
|||||||
@ -22,7 +22,8 @@ class WindForecastDataType(karooSystem: KarooSystemService) : LineGraphForecastD
|
|||||||
override fun getLineData(
|
override fun getLineData(
|
||||||
lineData: List<LineData>,
|
lineData: List<LineData>,
|
||||||
isImperial: Boolean,
|
isImperial: Boolean,
|
||||||
upcomingRoute: UpcomingRoute?
|
upcomingRoute: UpcomingRoute?,
|
||||||
|
isPreview: Boolean
|
||||||
): Set<LineGraphBuilder.Line> {
|
): Set<LineGraphBuilder.Line> {
|
||||||
val windPoints = lineData.map { data ->
|
val windPoints = lineData.map { data ->
|
||||||
if (isImperial) { // Convert m/s to mph
|
if (isImperial) { // Convert m/s to mph
|
||||||
@ -41,9 +42,16 @@ class WindForecastDataType(karooSystem: KarooSystemService) : LineGraphForecastD
|
|||||||
}
|
}
|
||||||
|
|
||||||
val headwindPoints = try {
|
val headwindPoints = try {
|
||||||
if (upcomingRoute != null){
|
if (upcomingRoute != null || isPreview){
|
||||||
(0..<HEADWIND_SAMPLE_COUNT).mapNotNull { i ->
|
(0..<HEADWIND_SAMPLE_COUNT).mapNotNull { i ->
|
||||||
val t = i / HEADWIND_SAMPLE_COUNT.toDouble()
|
val t = i / HEADWIND_SAMPLE_COUNT.toDouble()
|
||||||
|
|
||||||
|
if (isPreview) {
|
||||||
|
return@mapNotNull LineGraphBuilder.DataPoint(i.toFloat() * (windPoints.size / HEADWIND_SAMPLE_COUNT.toFloat()), (-10f) + (20f * kotlin.random.Random.nextFloat()))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (upcomingRoute == null) return@mapNotNull null
|
||||||
|
|
||||||
val beforeLineData = lineData.getOrNull(floor(lineData.size * t).toInt()) ?: lineData.firstOrNull()
|
val beforeLineData = lineData.getOrNull(floor(lineData.size * t).toInt()) ?: lineData.firstOrNull()
|
||||||
val afterLineData = lineData.getOrNull(ceil(lineData.size * t).toInt()) ?: lineData.lastOrNull()
|
val afterLineData = lineData.getOrNull(ceil(lineData.size * t).toInt()) ?: lineData.lastOrNull()
|
||||||
|
|
||||||
@ -59,9 +67,24 @@ class WindForecastDataType(karooSystem: KarooSystemService) : LineGraphForecastD
|
|||||||
val beforeDistanceAlongRoute = beforeLineData.distance
|
val beforeDistanceAlongRoute = beforeLineData.distance
|
||||||
val afterDistanceAlongRoute = afterLineData.distance
|
val afterDistanceAlongRoute = afterLineData.distance
|
||||||
val distanceAlongRoute = (beforeDistanceAlongRoute + (afterDistanceAlongRoute - beforeDistanceAlongRoute) * dt).coerceIn(0.0, upcomingRoute.routeLength)
|
val distanceAlongRoute = (beforeDistanceAlongRoute + (afterDistanceAlongRoute - beforeDistanceAlongRoute) * dt).coerceIn(0.0, upcomingRoute.routeLength)
|
||||||
val coordsAlongRoute = TurfMeasurement.along(upcomingRoute.routePolyline, distanceAlongRoute, TurfConstants.UNIT_METERS)
|
val coordsAlongRoute = try {
|
||||||
val nextCoordsAlongRoute = TurfMeasurement.along(upcomingRoute.routePolyline, distanceAlongRoute + 5, TurfConstants.UNIT_METERS)
|
TurfMeasurement.along(upcomingRoute.routePolyline, distanceAlongRoute, TurfConstants.UNIT_METERS)
|
||||||
val bearingAlongRoute = TurfMeasurement.bearing(coordsAlongRoute, nextCoordsAlongRoute)
|
} catch(e: Exception) {
|
||||||
|
Log.e(KarooHeadwindExtension.TAG, "Error getting coordinates along route", e)
|
||||||
|
return@mapNotNull null
|
||||||
|
}
|
||||||
|
val nextCoordsAlongRoute = try {
|
||||||
|
TurfMeasurement.along(upcomingRoute.routePolyline, distanceAlongRoute + 5, TurfConstants.UNIT_METERS)
|
||||||
|
} catch(e: Exception) {
|
||||||
|
Log.e(KarooHeadwindExtension.TAG, "Error getting next coordinates along route", e)
|
||||||
|
return@mapNotNull null
|
||||||
|
}
|
||||||
|
val bearingAlongRoute = try {
|
||||||
|
TurfMeasurement.bearing(coordsAlongRoute, nextCoordsAlongRoute)
|
||||||
|
} catch(e: Exception) {
|
||||||
|
Log.e(KarooHeadwindExtension.TAG, "Error calculating bearing along route", e)
|
||||||
|
return@mapNotNull null
|
||||||
|
}
|
||||||
val windBearing = interpolatedWeather.windDirection + 180
|
val windBearing = interpolatedWeather.windDirection + 180
|
||||||
val diff = signedAngleDifference(bearingAlongRoute, windBearing)
|
val diff = signedAngleDifference(bearingAlongRoute, windBearing)
|
||||||
val headwindSpeed = cos( (diff + 180) * Math.PI / 180.0) * interpolatedWeather.windSpeed
|
val headwindSpeed = cos( (diff + 180) * Math.PI / 180.0) * interpolatedWeather.windSpeed
|
||||||
|
|||||||
@ -73,32 +73,13 @@ class OpenWeatherMapWeatherProvider(private val apiKey: String) : WeatherProvide
|
|||||||
settings: HeadwindSettings,
|
settings: HeadwindSettings,
|
||||||
profile: UserProfile?
|
profile: UserProfile?
|
||||||
): WeatherDataResponse = coroutineScope {
|
): WeatherDataResponse = coroutineScope {
|
||||||
|
val selectedCoordinates = coordinates.take(4)
|
||||||
|
|
||||||
val selectedCoordinates = when {
|
|
||||||
coordinates.size <= MAX_API_CALLS -> coordinates
|
|
||||||
else -> {
|
|
||||||
|
|
||||||
val mandatoryCoordinates = coordinates.take(3).toMutableList()
|
|
||||||
|
|
||||||
|
|
||||||
val fourthIndex = if (coordinates.size > 6) {
|
|
||||||
coordinates.size - 3
|
|
||||||
} else {
|
|
||||||
(coordinates.size / 2) + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
mandatoryCoordinates.add(coordinates[fourthIndex.coerceIn(3, coordinates.lastIndex)])
|
|
||||||
mandatoryCoordinates
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.d(KarooHeadwindExtension.TAG, "OpenWeatherMap: searching for ${selectedCoordinates.size} locations from ${coordinates.size} total")
|
Log.d(KarooHeadwindExtension.TAG, "OpenWeatherMap: searching for ${selectedCoordinates.size} locations from ${coordinates.size} total")
|
||||||
selectedCoordinates.forEachIndexed { index, coord ->
|
selectedCoordinates.forEachIndexed { index, coord ->
|
||||||
Log.d(KarooHeadwindExtension.TAG, "Point #$index: ${coord.lat}, ${coord.lon}, distance: ${coord.distanceAlongRoute}")
|
Log.d(KarooHeadwindExtension.TAG, "Point #$index: ${coord.lat}, ${coord.lon}, distance: ${coord.distanceAlongRoute}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val weatherDataForSelectedLocations = selectedCoordinates.map { coordinate ->
|
val weatherDataForSelectedLocations = selectedCoordinates.map { coordinate ->
|
||||||
async {
|
async {
|
||||||
val response = makeOpenWeatherMapRequest(karooSystem, coordinate, apiKey)
|
val response = makeOpenWeatherMapRequest(karooSystem, coordinate, apiKey)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user