Files
OpenTracks/src/main/java/de/dennisguse/opentracks/data/models/Speed.java
T
2025-11-17 22:22:44 +01:00

101 lines
2.4 KiB
Java

package de.dennisguse.opentracks.data.models;
import java.time.Duration;
import de.dennisguse.opentracks.settings.UnitSystem;
public record Speed(double speed_mps) {
public static Speed ZERO = Speed.of(0);
public static Speed of(Distance distance, Duration duration) {
if (duration.isZero()) {
return ZERO;
}
return new Speed(distance.toM() / (duration.toMillis() / (double) Duration.ofSeconds(1).toMillis()));
}
public static Speed of(double speed_mps) {
return new Speed(speed_mps);
}
@Deprecated //TODO Remove
public static Speed of(String speed_mps) {
return of(Float.parseFloat(speed_mps));
}
public static Speed ofKMH(double speed_kmh) {
return of(Distance.ofKilometer(speed_kmh), Duration.ofHours(1));
}
public static Speed max(Speed speed1, Speed speed2) {
if (speed1.greaterThan(speed2)) {
return speed1;
}
return speed2;
}
public boolean isZero() {
return this.equals(ZERO);
}
public boolean isInvalid() {
return Double.isNaN(speed_mps) || Double.isInfinite(speed_mps);
}
public boolean lessThan(Speed speed) {
return !greaterThan(speed);
}
public boolean greaterThan(Speed speed) {
return speed_mps > speed.speed_mps;
}
public boolean greaterOrEqualThan(Speed speed) {
return speed_mps >= speed.speed_mps;
}
public double toMPS() {
return speed_mps;
}
/**
* We interpret {@link Speed} here as a {@link Distance} over 1h.
*/
private Distance toH() {
return Distance.of(speed_mps * Duration.ofHours(1).toSeconds());
}
public double toKMH() {
return toH().toKM();
}
public double toMPH() {
return toH().toMI();
}
public double toKnots() {
return toH().toNauticalMiles();
}
public Duration toPace(UnitSystem unitSystem) {
if (isZero()) {
return Duration.ZERO;
}
double distance = Distance.of(speed_mps).toKM_Miles(unitSystem);
return Duration.ofSeconds(Math.round(1 / distance));
}
public double to(UnitSystem unitSystem) {
return switch (unitSystem) {
case METRIC -> toKMH();
case IMPERIAL_FEET, IMPERIAL_METER -> toMPH();
case NAUTICAL_IMPERIAL -> toKnots();
};
}
}