All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.shiftforward.apso.Geo.scala Maven / Gradle / Ivy

There is a newer version: 0.13.11
Show newest version
package eu.shiftforward.apso

import scala.math.{ abs, acos, cos, sin, toRadians }

/**
 * Object containing geo-location functions.
 */
object Geo {
  /**
   * A pair of `Double` representing, respectively, the latitude and longitude of a position.
   */
  type Coordinates = (Double, Double)

  private[this] val EARTH_RADIUS = 6371.009 // kilometers

  /**
   * Returns the distance in kilometers between two points on the planet Earth, calculated by the
   * spherical law of cosines (https://en.wikipedia.org/wiki/Great-circle_distance#Formulas).
   * @param p1 the coordinates of the first point
   * @param p2 the coordinates of the second point
   * @return the distance in kilometers between two points on the planet Earth.
   */
  def distance(p1: Coordinates, p2: Coordinates) =
    distanceFrom(p1)(p2)

  /**
   * Returns a function that measures the distance to the point `p1` on the planet Earth, calculated
   * by the spherical law of cosines (https://en.wikipedia.org/wiki/Great-circle_distance#Formulas).
   * @param p1 the coordinates of the first point
   * @return a function that given a point `p2` returns the distance in kilometers to the point `p1`.
   */
  def distanceFrom(p1: Coordinates): Coordinates => Double = {
    val lat1 = toRadians(p1._1)
    val sinLat1 = sin(lat1)
    val cosLat1 = cos(lat1)

    p2 => {
      val deltaLong = toRadians(abs(p1._2 - p2._2))
      val lat2 = toRadians(p2._1)

      val c = acos((sinLat1 * sin(lat2)) + (cosLat1 * cos(lat2) * cos(deltaLong)))

      EARTH_RADIUS * c
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy