Skip to content

Instantly share code, notes, and snippets.

@zhuker
Created October 21, 2022 14:30
Show Gist options
  • Save zhuker/e33be75ef147c82c14a50e354432c8f1 to your computer and use it in GitHub Desktop.
Save zhuker/e33be75ef147c82c14a50e354432c8f1 to your computer and use it in GitHub Desktop.
distance between gps points
import kotlin.math.*
interface ILatLng {
val lat: Double
val lon: Double
}
enum class Unit(s: String) {
KILOMETERS("km"),
METERS("m"),
MILES("mi"),
NAUTICAL_MILES("nmi"),
FEET("ft"),
INCHES("in"),
RADIANS("rad"),
DEGREES("deg")
}
//# mean earth radius - https://en.wikipedia.org/wiki/Earth_radius#Mean_radius
const val _AVG_EARTH_RADIUS_KM = 6371.0088
private val _CONVERSIONS = mapOf(
Unit.KILOMETERS to 1.0,
Unit.METERS to 1000.0,
Unit.MILES to 0.621371192,
Unit.NAUTICAL_MILES to 0.539956803,
Unit.FEET to 3280.839895013,
Unit.INCHES to 39370.078740158,
Unit.RADIANS to 1 / _AVG_EARTH_RADIUS_KM,
Unit.DEGREES to (1 / _AVG_EARTH_RADIUS_KM) * (180.0 / Math.PI)
)
fun get_avg_earth_radius(unit: Unit): Double {
return _AVG_EARTH_RADIUS_KM * _CONVERSIONS[unit]!!
}
fun haversine(point1: ILatLng, point2: ILatLng, unit: Unit = Unit.KILOMETERS): Double {
val lat1 = Math.toRadians(point1.lat)
val lng1 = Math.toRadians(point1.lon)
val lat2 = Math.toRadians(point2.lat)
val lng2 = Math.toRadians(point2.lon)
val lat = lat2 - lat1
val lng = lng2 - lng1
val d = (sin(lat * 0.5).pow(2)) + cos(lat1) * cos(lat2) * (sin(lng * 0.5).pow(2))
return 2 * get_avg_earth_radius(unit) * asin(sqrt(d))
}
fun ILatLng.dist(that: ILatLng): Double = haversine(this, that, unit = Unit.METERS)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment