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(
|
||||
lineData: List<LineData>,
|
||||
isImperial: Boolean,
|
||||
upcomingRoute: UpcomingRoute?
|
||||
upcomingRoute: UpcomingRoute?,
|
||||
isPreview: Boolean
|
||||
): Set<LineGraphBuilder.Line>
|
||||
|
||||
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 startTime = data.firstOrNull()?.time
|
||||
val time = startTime?.plus(floor(x).toLong(), ChronoUnit.HOURS)
|
||||
|
||||
@ -8,7 +8,8 @@ class PrecipitationForecastDataType(karooSystem: KarooSystemService) : LineGraph
|
||||
override fun getLineData(
|
||||
lineData: List<LineData>,
|
||||
isImperial: Boolean,
|
||||
upcomingRoute: UpcomingRoute?
|
||||
upcomingRoute: UpcomingRoute?,
|
||||
isPreview: Boolean
|
||||
): Set<LineGraphBuilder.Line> {
|
||||
val precipitationPoints = lineData.map { data ->
|
||||
if (isImperial) { // Convert mm to inches
|
||||
|
||||
@ -8,7 +8,8 @@ class TemperatureForecastDataType(karooSystem: KarooSystemService) : LineGraphFo
|
||||
override fun getLineData(
|
||||
lineData: List<LineData>,
|
||||
isImperial: Boolean,
|
||||
upcomingRoute: UpcomingRoute?
|
||||
upcomingRoute: UpcomingRoute?,
|
||||
isPreview: Boolean
|
||||
): Set<LineGraphBuilder.Line> {
|
||||
val linePoints = lineData.map { data ->
|
||||
if (isImperial) {
|
||||
|
||||
@ -22,7 +22,8 @@ class WindForecastDataType(karooSystem: KarooSystemService) : LineGraphForecastD
|
||||
override fun getLineData(
|
||||
lineData: List<LineData>,
|
||||
isImperial: Boolean,
|
||||
upcomingRoute: UpcomingRoute?
|
||||
upcomingRoute: UpcomingRoute?,
|
||||
isPreview: Boolean
|
||||
): Set<LineGraphBuilder.Line> {
|
||||
val windPoints = lineData.map { data ->
|
||||
if (isImperial) { // Convert m/s to mph
|
||||
@ -41,9 +42,16 @@ class WindForecastDataType(karooSystem: KarooSystemService) : LineGraphForecastD
|
||||
}
|
||||
|
||||
val headwindPoints = try {
|
||||
if (upcomingRoute != null){
|
||||
if (upcomingRoute != null || isPreview){
|
||||
(0..<HEADWIND_SAMPLE_COUNT).mapNotNull { i ->
|
||||
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 afterLineData = lineData.getOrNull(ceil(lineData.size * t).toInt()) ?: lineData.lastOrNull()
|
||||
|
||||
@ -59,9 +67,24 @@ class WindForecastDataType(karooSystem: KarooSystemService) : LineGraphForecastD
|
||||
val beforeDistanceAlongRoute = beforeLineData.distance
|
||||
val afterDistanceAlongRoute = afterLineData.distance
|
||||
val distanceAlongRoute = (beforeDistanceAlongRoute + (afterDistanceAlongRoute - beforeDistanceAlongRoute) * dt).coerceIn(0.0, upcomingRoute.routeLength)
|
||||
val coordsAlongRoute = TurfMeasurement.along(upcomingRoute.routePolyline, distanceAlongRoute, TurfConstants.UNIT_METERS)
|
||||
val nextCoordsAlongRoute = TurfMeasurement.along(upcomingRoute.routePolyline, distanceAlongRoute + 5, TurfConstants.UNIT_METERS)
|
||||
val bearingAlongRoute = TurfMeasurement.bearing(coordsAlongRoute, nextCoordsAlongRoute)
|
||||
val coordsAlongRoute = try {
|
||||
TurfMeasurement.along(upcomingRoute.routePolyline, distanceAlongRoute, TurfConstants.UNIT_METERS)
|
||||
} 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 diff = signedAngleDifference(bearingAlongRoute, windBearing)
|
||||
val headwindSpeed = cos( (diff + 180) * Math.PI / 180.0) * interpolatedWeather.windSpeed
|
||||
|
||||
@ -73,32 +73,13 @@ class OpenWeatherMapWeatherProvider(private val apiKey: String) : WeatherProvide
|
||||
settings: HeadwindSettings,
|
||||
profile: UserProfile?
|
||||
): WeatherDataResponse = coroutineScope {
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
val selectedCoordinates = coordinates.take(4)
|
||||
|
||||
Log.d(KarooHeadwindExtension.TAG, "OpenWeatherMap: searching for ${selectedCoordinates.size} locations from ${coordinates.size} total")
|
||||
selectedCoordinates.forEachIndexed { index, coord ->
|
||||
Log.d(KarooHeadwindExtension.TAG, "Point #$index: ${coord.lat}, ${coord.lon}, distance: ${coord.distanceAlongRoute}")
|
||||
}
|
||||
|
||||
|
||||
val weatherDataForSelectedLocations = selectedCoordinates.map { coordinate ->
|
||||
async {
|
||||
val response = makeOpenWeatherMapRequest(karooSystem, coordinate, apiKey)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user