Garmin: deduplicate degrees ↔ semicircles math in GarminUtils

The watch encodes lat/lon as signed 32-bit semicircles (1<<31 == 180°). Move the bidirectional conversion behind named helpers backed by a single constant, and migrate toLocationData and FieldDefinitionCoordinate onto them.
This commit is contained in:
Ingvar Stepanyan
2026-06-06 21:26:51 +02:00
committed by José Rebelo
parent 25e322ea9a
commit 32a18d8d81
2 changed files with 16 additions and 6 deletions
@@ -10,10 +10,21 @@ public final class GarminUtils {
// utility class // utility class
} }
/** Watch lat/lon resolution: 180° spans the signed-32-bit range, so 1 semicircle = 180/2^31 degrees. */
public static final double SEMICIRCLE_DEGREES = 180.0D / 0x80000000L;
public static double semicirclesToDegrees(final int semicircles) {
return semicircles * SEMICIRCLE_DEGREES;
}
public static int degreesToSemicircles(final double degrees) {
return (int) Math.round(degrees / SEMICIRCLE_DEGREES);
}
public static GdiCore.CoreService.LocationData toLocationData(final Location location, final GdiCore.CoreService.DataType dataType) { public static GdiCore.CoreService.LocationData toLocationData(final Location location, final GdiCore.CoreService.DataType dataType) {
final GdiCore.CoreService.LatLon positionForWatch = GdiCore.CoreService.LatLon.newBuilder() final GdiCore.CoreService.LatLon positionForWatch = GdiCore.CoreService.LatLon.newBuilder()
.setLat((int) ((location.getLatitude() * 2.147483648E9d) / 180.0d)) .setLat(degreesToSemicircles(location.getLatitude()))
.setLon((int) ((location.getLongitude() * 2.147483648E9d) / 180.0d)) .setLon(degreesToSemicircles(location.getLongitude()))
.build(); .build();
float vAccuracy = 0; float vAccuracy = 0;
@@ -2,13 +2,12 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDef
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.GarminUtils;
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.FieldDefinition; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.FieldDefinition;
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.baseTypes.BaseType; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.baseTypes.BaseType;
public class FieldDefinitionCoordinate extends FieldDefinition { public class FieldDefinitionCoordinate extends FieldDefinition {
final double conversionFactor = (180.0D / 0x80000000L);
public FieldDefinitionCoordinate(int localNumber, int size, BaseType baseType, String name) { public FieldDefinitionCoordinate(int localNumber, int size, BaseType baseType, String name) {
super(localNumber, size, baseType, name, 1, 0); super(localNumber, size, baseType, name, 1, 0);
} }
@@ -19,12 +18,12 @@ public class FieldDefinitionCoordinate extends FieldDefinition {
if (rawValue == null) { if (rawValue == null) {
return null; return null;
} }
return ((long) rawValue) * conversionFactor; return GarminUtils.semicirclesToDegrees(((Number) rawValue).intValue());
} }
@Override @Override
public void encode(ByteBuffer byteBuffer, Object o) { public void encode(ByteBuffer byteBuffer, Object o) {
baseType.encode(byteBuffer, (int) Math.round((double) o / conversionFactor), 1, 0); baseType.encode(byteBuffer, GarminUtils.degreesToSemicircles((double) o), 1, 0);
} }