Skip to content

Instantly share code, notes, and snippets.

@umpteenthdev
Created March 11, 2019 10:04
Show Gist options
  • Select an option

  • Save umpteenthdev/b9c90262fe771f84467724be472909a1 to your computer and use it in GitHub Desktop.

Select an option

Save umpteenthdev/b9c90262fe771f84467724be472909a1 to your computer and use it in GitHub Desktop.
Base class that describes a coordinate (in decimal degrees)
import kotlin.math.*
const val EARTH_RADIUS_METERS = 6378137
data class Coordinate(
val latitude: Double,
val longitude: Double
) {
/**
* @return a distance in meters between this coordinate and the passed one
*/
fun distanceTo(to: Coordinate): Double {
val distanceLat = Math.toRadians(to.latitude - latitude)
val distanceLng = Math.toRadians(to.longitude - longitude)
val a = sin(distanceLat / 2).pow(2) +
cos(Math.toRadians(latitude)) * cos(Math.toRadians(to.latitude)) *
sin(distanceLng / 2).pow(2)
val c = 2 * atan2(sqrt(a), sqrt(1 - a))
return EARTH_RADIUS_METERS.toDouble() * c
}
/**
* @return a coordinate at the passed distance
* [Source](https://gis.stackexchange.com/questions/2951/algorithm-for-offsetting-a-latitude-longitude-by-some-amount-of-meters)
*/
fun offset(northMetersOffset: Double, eastMetersOffset: Double): Coordinate = Coordinate(
latitude = latitude + northMetersOffset / EARTH_RADIUS_METERS * 180 / PI,
longitude = longitude + eastMetersOffset / (EARTH_RADIUS_METERS * cos(PI * latitude / 180)) * 180 / PI
)
/**
* @return north-west and south-east coordinates at the passed distance
*/
fun getBounds(metersDistance: Double): Pair<Coordinate, Coordinate> {
val sideLength = sqrt(metersDistance.pow(2) / 2)
return offset(sideLength, -sideLength) to offset(-sideLength, sideLength)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment