# `Astro.Solar.Eclipse.Local`
[🔗](https://github.com/kipcole9/astro/blob/v2.11.0/lib/astro/solar/eclipse/local.ex#L1)

The local circumstances of a solar eclipse: how it is seen from a
place on the Earth.

The Besselian elements (see `Astro.Solar.Eclipse`) describe the
Moon's shadow on the fundamental plane. An observer is put in the
same frame: at a moment, with the shadow axis at declination `d` and
local hour angle `H = μ + λ` for an east longitude `λ`, the observer
is at

* `ξ = ρ cos φ′ sin H`,

* `η = ρ sin φ′ cos d − ρ cos φ′ sin d cos H`, and

* `ζ = ρ sin φ′ sin d + ρ cos φ′ cos d cos H`,

where `ρ sin φ′` and `ρ cos φ′` are the observer's geocentric
coordinates, from the geodetic latitude `φ`, the Earth's flattening
and the height above the ellipsoid. `ζ` is the observer's height
above the plane, where the shadow cones have radii
`L1 = l1 − ζ tan f1` and `L2 = l2 − ζ tan f2`, and the observer is
`m = √((x − ξ)² + (y − η)²)` from the axis.

* The eclipse is seen where `m < L1`, inside the penumbra.

* *Maximum eclipse* is the moment of least `m`, found by golden
  section search.

* The *contacts* are the moments the observer crosses a cone: first
  and last contact where `m = L1`, and second and third where
  `m = |L2|`, inside the umbra (total, `L2 < 0`) or the antumbra
  (annular, `L2 > 0`). Each is found by bisection.

* The *magnitude* at maximum is the fraction of the Sun's diameter
  covered, measured along the line through the centres of the two
  disks, `(L1 − m) / (L1 + L2)`. It exceeds 1 inside the umbra. This
  is the local magnitude NASA and the USNO give; the magnitude of a
  central eclipse in the catalogues is the ratio of the Moon's
  apparent diameter to the Sun's on the central line instead.

* The *obscuration* is the fraction of the Sun's area covered: the
  Sun and the Moon are disks of radii `(L1 + L2) / 2` and
  `(L1 − L2) / 2` on the plane, `m` apart, and the obscuration is the
  area they share over the Sun's.

* The Sun's *altitude* is that of the shadow axis,
  `sin h = sin d sin φ + cos d cos φ cos H`, which differs from the
  Sun's direction by a few arc seconds. It is geometric: refraction,
  which lifts the Sun by about 34′ at the horizon, is not applied.

The elements are geocentric, so the geometry is the same whether or
not the Sun is above the horizon. An eclipse is *seen* from a place
if at some moment between first and last contact the Sun's upper
limb is above the horizon, allowing for standard refraction, which is
the condition for sunrise.

Because `μ` is the Greenwich hour angle at the moment, the observer's
longitude is used as it is. NASA's and the USNO's elements use an
ephemeris hour angle and correct the longitude by ΔT instead; the two
agree when they use the same ΔT.

# `eclipse_type`

```elixir
@type eclipse_type() :: :partial | :annular | :total
```

How a solar eclipse is seen from a place: only the penumbra passes
over it, the antumbra does, or the umbra does.

# `t`

```elixir
@type t() :: %Astro.Solar.Eclipse.Local{
  annular_begins: DateTime.t() | nil,
  annular_ends: DateTime.t() | nil,
  magnitude: float(),
  maximum: DateTime.t(),
  obscuration: float(),
  partial_begins: DateTime.t(),
  partial_ends: DateTime.t(),
  sun_altitudes: %{required(atom()) =&gt; float()},
  total_begins: DateTime.t() | nil,
  total_ends: DateTime.t() | nil,
  type: eclipse_type()
}
```

The local circumstances of a solar eclipse. The contacts and maximum
eclipse are `t:DateTime.t/0`s, `nil` for the contacts the eclipse
does not have there; the Sun's altitudes are geometric, in degrees,
keyed by the contact.

# `circumstances`

```elixir
@spec circumstances(Astro.Time.moment(), Geo.PointZ.t()) ::
  {:ok, map()} | {:error, :not_visible}
```

Returns the local circumstances at a location of the solar eclipse
whose greatest eclipse is at a moment.

### Arguments

* `greatest` is the `t:Astro.Time.moment/0` of greatest eclipse, as
  `Astro.Solar.Eclipse.eclipse_at_or_after/1` returns it.

* `location` is a `t:Geo.PointZ.t/0`, its altitude in metres above
  the ellipsoid.

### Returns

* `{:ok, circumstances}`, a map with the keys of `t:t/0`, the
  contacts and maximum as moments.

* `{:error, :not_visible}` if the location is outside the penumbra
  throughout, or the Sun is below the horizon from first contact to
  last.

### Examples

Dallas saw totality on 8 April 2024:

    iex> {:ok, eclipse} = Astro.Solar.Eclipse.eclipse_at_or_after(739_300.0)
    iex> dallas = %Geo.PointZ{coordinates: {-96.80, 32.78, 0.0}}
    iex> {:ok, local} = Astro.Solar.Eclipse.Local.circumstances(eclipse.greatest, dallas)
    iex> {local.type, Float.round(local.magnitude, 3)}
    {:total, 1.015}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
