-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Detail Bug Report
Summary
- Context: The
Locationrecord is a fundamental domain model used throughout the SDK to represent geographic coordinates (latitude and longitude). - Bug: The
Locationrecord uses the default Java recordequals()andhashCode()implementations, which perform a bitwise comparison of thedoublefields. This fails to account for geographic equivalence where different coordinate pairs represent the same physical location. - Actual vs. expected: Currently,
Locationobjects with equivalent coordinates (e.g., longitude 180° vs -180°, or different longitudes at the poles) are considered unequal; they are expected to be equal geographically. - Impact: Using
Locationas a key in collections (likeHashMaporHashSet) will lead to duplicate entries for the same geographic point, and comparisons between locations returned from different API calls may fail unexpectedly.
Code with bug
public record Location(double latitude, double longitude) { // <-- BUG 🔴 [Uses default record equality which doesn't account for geographic equivalence]
private static final double MIN_LATITUDE = -90.0;
private static final double MAX_LATITUDE = 90.0;
private static final double MIN_LONGITUDE = -180.0;
private static final double MAX_LONGITUDE = 180.0;
// ...
public Location {
validateLatitudeLongitude(latitude, longitude);
}
// ...
}Failing test
Antimeridian case showing inequivalence of equivalent coordinates:
LongitudeEqualityTest > antimeridianEquality() FAILED
org.opentest4j.AssertionFailedError: Location(0.0, 180.0) should equal Location(0.0, -180.0) ==> expected: <Location[latitude=0.0, longitude=180.0]> but was: <Location[latitude=0.0, longitude=-180.0]>
Recommended fix
Normalize coordinates in the compact constructor of the Location record to ensure a canonical representation:
- Normalize longitude to a standard range (e.g., 180.0 and -180.0 should both become 180.0).
- If latitude is 90.0 or -90.0 (the poles), set longitude to a constant value (e.g., 0.0).
- Convert negative zero (-0.0) to positive zero (0.0) for both latitude and longitude.
public Location {
validateLatitudeLongitude(latitude, longitude);
// Normalize negative zero
if (latitude == -0.0) latitude = 0.0; // <-- FIX 🟢
if (longitude == -0.0) longitude = 0.0; // <-- FIX 🟢
// Normalize poles: at the poles, longitude is irrelevant.
if (latitude == 90.0 || latitude == -90.0) {
longitude = 0.0;
} else if (longitude == -180.0) {
// Normalize antimeridian to 180.0
longitude = 180.0;
}
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working