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

lucuma.core.math.Place.scala Maven / Gradle / Ivy

There is a newer version: 0.108.0
Show newest version
// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA)
// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause

package lucuma.core.math

import cats.Eq
import cats.Show
import coulomb.*
import coulomb.ops.algebra.cats.all.given
import coulomb.units.si.Meter
import eu.timepit.refined.cats.*
import eu.timepit.refined.types.numeric.NonNegInt
import monocle.Focus
import monocle.Lens
import org.typelevel.cats.time.*

import java.time.ZoneId

/** A point on Earth, given latitude, longitude and altitude in m above sea level. */
final case class Place(
  val latitude:  Lat,
  val longitude: Lon,
  val altitude:  Quantity[NonNegInt, Meter],
  val timezone:  ZoneId
) {
  // This is needed for the JVM based test. The JVM doesn't like interacting with the refined type
  final val altitudeDouble: Double = altitude.value.value.toDouble
}

object Place {

  /** @group Typeclass Instances */
  given Eq[Place] =
    Eq.by(x => (x.latitude, x.longitude, x.altitude, x.timezone))

  /** @group Typeclass Instances */
  given Show[Place] = Show.fromToString

  /** @group Optics */
  val latitude: Lens[Place, Lat] =
    Focus[Place](_.latitude)

  /** @group Optics */
  val longitude: Lens[Place, Lon] =
    Focus[Place](_.longitude)

  /** @group Optics */
  val altitude: Lens[Place, Quantity[NonNegInt, Meter]] =
    Focus[Place](_.altitude)

  /** @group Optics */
  val timezone: Lens[Place, ZoneId] =
    Focus[Place](_.timezone)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy