import squants.space.{Radians, Meters}
import squants.{Angle, Length}
object Geospatial {
case class Longitude(angle: Angle) {
require(
(Radians(-Math.PI) <= angle) && (angle < Radians(Math.PI)),
"angle.inRadians must be greater than or equal to -Math.PI and less than Math.PI"
)
}
case class Latitude(angle: Angle) {
require(
(Radians(-(Math.PI * 0.5d)) <= angle) && (angle < Radians(Math.PI * 0.5d)),
"angle.inRadians must be greater than or equal to -(Math.PI * 0.5d) and less than (Math.PI * 0.5d)"
)
}
case class Distance(length: Length) {
require(
Meters(0.0d) <= length,
"length.inMeters must be greater than or equal to 0.0d"
)
}
case class Bearing(angle: Angle) {
require(
(Radians(0.0d) <= angle) && (angle < Radians(Math.PI * 2.0d)),
"angle.inRadians must be greater than or equal to 0.0d and less than (Math.PI * 2.0d)"
)
}
case class Coordinate(longitude: Longitude, latitude: Latitude)
def calculateDistance(
coordinate1: Coordinate,
coordinate2: Coordinate
): (Distance, Bearing, Bearing) = {
def calculateDistanceUsingLegacyCodeRifeWithDoubles(
coordinate1LongitudeInRadians: Double,
coordinate1LatitudeInRadians: Double,
coordinate2LongitudeInRadians: Double,
coordinate2LatitudeInRadians: Double
): (Double, Double, Double) = {
//Legacy code encapsulated here only works with meters and radians
//returns (distance, initial bearing, final bearing)
(1.0d, 1.0d, 2.0d) //TODO: replace with real calculation results
}
val (coordinate1InRadians, coordinate2InRadians) = (
(coordinate1.longitude.angle.toRadians, coordinate1.latitude.angle.toRadians),
(coordinate2.longitude.angle.toRadians, coordinate2.latitude.angle.toRadians)
)
val (distanceInMeters, bearingInitialInRadians, bearingFinalInRadians) =
calculateDistanceUsingLegacyCodeRifeWithDoubles(
coordinate1InRadians._1,
coordinate1InRadians._2,
coordinate2InRadians._1,
coordinate2InRadians._2
)
(
Distance(Meters(distanceInMeters)),
Bearing(Radians(bearingInitialInRadians)),
Bearing(Radians(bearingFinalInRadians))
)
}
def calculateCoordinate(
coordinate1: Coordinate,
bearingInitial: Bearing,
distance: Distance
): Coordinate = {
def calculateCoordinateUsingLegacyCodeRifeWithDoubles(
coordinate1Longitude: Double,
coordinate1Latitude: Double,
bearingInitialInRadians: Double,
distanceInMeters: Double
): (Double, Double) = {
//Legacy code encapsulated here only works with meters and radians
//returns (longitude, latitude)
(-1.0d, 1.0d) //TODO: replace with real calculation results
}
val (coordinate1InRadians, bearingInitialInRadians, distanceInMeters) = (
(coordinate1.longitude.angle.toRadians, coordinate1.latitude.angle.toRadians),
bearingInitial.angle.toRadians,
distance.length.toMeters
)
val (longitude, latitude) =
calculateCoordinateUsingLegacyCodeRifeWithDoubles(
coordinate1InRadians._1,
coordinate1InRadians._2,
bearingInitialInRadians,
distanceInMeters
)
Coordinate(Longitude(Radians(longitude)), Latitude(Radians(latitude)))
}
}
Comments
0 B
|👍
/👎
0 B
|👍
/👎