-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add spatial types #9
Comments
Could possibly tie this in with Distance measurements via a simple Haversine calculation |
Hi James, thanks for an interesting suggestion! Let me look into this - I will let you know if I manage to add this. |
Hi @jamesdh , It took me a while, but it was bit more complicated then I originally assumed. But the feature is ready, you can test it if you can spare a minute and let me know if this is what you expected. I have created plenty of unit tests for it to make sure it works, including some manual tests with Google Maps, it seems to work OK. Branch: // Latitude and Longitude types are based on Angular units
Latitude latitude = Latitude.ofDegrees(-20.123);
Longitude longitude = Longitude.ofDegrees(20.123);
// They can be reduced to a string in DMS format or in ENG format:
String latInDMS = latitude.toDMSFormat(2); // Outputs: 20°7'22.8"S
String latInENG = latitude.toEngineeringFormat(); // Outputs: -20.123 [°]
// Instance from degrees, minutes, seconds
Latitude latFromDMS = Latitude.ofDegMinSec(20, 7, 22.8, CardinalDirection.SOUTH); // Latitude{-20.123°}
Longitude longFromDMS = Longitude.ofDegMinSec(20, 7, 22.8, CardinalDirection.EAST); // Longitude{20.123°}
// GeoCoordinate class represents a coordinate of specific point on the globe, using Latitude and Longitude
GeoCoordinate coordinateExample = GeoCoordinate.of(latitude, longitude, "my location");
// GeoCoordinate can be reduced to DMS format, ENG format, or decimal degrees format
// Decimal degrees format with coma separating latitude from longitude is for ie: how Google Maps output cords
String geoCoordDMS = coordinateExample.toDMSFormat(2); // 20°7'22.8"S, 20°7'22.8"E
String geoCoordEND = coordinateExample.toEngineeringFormat(2); // -20.12 [°], 20.12 [°]
String geoCoordDEC = coordinateExample.toDecimalDegrees(2); // -20.12, 20.12
// GeoDistance represents spherical distance between two coordinates on Earth
// Distance is calculated based on Haversine equations. It outputs curved distance using Distance instance
// and true bearing withing provided coordinates in range <-180,+180> as Angle instance.
GeoCoordinate wroclaw = GeoCoordinate.of(
Latitude.ofDegrees(51.102772),
Longitude.ofDegrees(16.885802),
"Wroclaw");
GeoCoordinate newYork = GeoCoordinate.of(
Latitude.ofDegrees(40.712671),
Longitude.ofDegrees(-74.004655),
"NewYork");
GeoDistance geoDistance = GeoDistance.ofKilometers(wroclaw, newYork);
String distanceInEng = geoDistance.toEngineeringFormat(); // 6669.896095258197 [km]
Angle trueBearing = geoDistance.getTrueBearing(); // Angle{-61.07915625042435°}
// Geo distance can be specified by providing true bearing and distance from the starting coordinate.
// Target coordinate will be calculated accordingly:
GeoDistance toNewYork = GeoDistance.of(wroclaw, trueBearing, Distance.ofKilometers(6669.896095258197));
String targetCoordinate = toNewYork.getTargetCoordinate().toDecimalDegrees(); // 40.712671, -74.004655
// From created GeoDistance instance we can travel further using two methods: with() and translate().
// a) with() will retain your starting point, create new instance and calculate new distance
GeoCoordinate wellington = GeoCoordinate.of(
Latitude.ofDegrees(-41.289463),
Longitude.ofDegrees(174.774913),
"Wellington");
GeoDistance toWellington = toNewYork.with(wellington);
Distance distance = toWellington.getDistance(); // 18005.6198226 km
String wroclawCoordinate = toWellington.getStartCoordinate().toDecimalDegrees(); // 51.102772, 16.885802
String wellingtonCoordinate = toWellington.getTargetCoordinate().toDecimalDegrees(); // -41.289463, 174.774913
// b) translate() will take your current target coordinate as start coordinate, create new instance and set
// new target based on argument input
GeoDistance toWellingtonBis = toNewYork.translate(wellington);
Distance distanceBis = toWellingtonBis.getDistance(); // 14403.6934729 km
String wroclawCoordinateBis = toWellingtonBis.getStartCoordinate().toDecimalDegrees(); // 40.712671, -74.004655
String wellingtonCoordinateBis = toWellingtonBis.getTargetCoordinate().toDecimalDegrees(); // -41.289463, 174.774913
// Both methods also allow specifying bearing and distance instead of target coordinate
// String parsers:
// Proper deserializers are defined for Spring and Quarkus for proper JSON deserialization / serialization.
// Parsing factories also can be used in code directly:
GeoQuantityParsingFactory geoParsingFactory = PhysicalQuantityParsingFactory.GEO_PARSING_FACTORY;
Latitude parsedLat1 = geoParsingFactory.parseFromDMSFormat(Latitude.class, "20°7'22.8\"S");
Latitude parsedLat2 = geoParsingFactory.parseFromDMSFormat(Latitude.class, "20deg 7min 22.8sec"); |
I have just fixed the arithmetic operations, they now will work as expected and allow for adding quantities to each other, of different types but sharing the same unit type. GeoDistance when other distance or value is added, will assume the same bearing, add new distance to current and recalculate new target coordinate, retaining its starting point. // Arithmetic operations
// Sum of two GeoQuantities
GeoCoordinate start = GeoCoordinate.of(Latitude.ofDegrees(51.1), Longitude.ofDegrees(16.9));
GeoCoordinate target = GeoCoordinate.of(Latitude.ofDegrees(40.8), Longitude.ofDegrees(-74.1));
GeoDistance firstGeoDistance = GeoDistance.ofKilometers(start, target); // 6670.048729447209 km
GeoDistance secondGeoDistance = firstGeoDistance.translate(Distance.ofKilometers(1000)); // 1000 km
GeoDistance sumOfDistances = firstGeoDistance.plus(secondGeoDistance); // 7670.048729447209 km and new target
GeoDistance greaterDistance = sumOfDistances.plus(Distance.ofKilometers(1000)); // 8670.048729447209 km and new target
GeoDistance evenGreaterDistance = greaterDistance.plus(1000); // 9670.048729447209 km and new target |
Included in release: 2.1.1 |
@pjazdzyk you are awesome! I'll haven't had a chance to test this yet, but I'll be coming back around to the project that I originally used unitility with soon. Looking forward to giving this a go! |
Specifically thinking latitude/longitude in decimal degrees vs degrees/minutes/seconds.
The text was updated successfully, but these errors were encountered: