# [Component name] Reference

> Reference page in the Diátaxis sense: a neutral, complete, consistently
> structured description of the machinery (functions, fields, endpoints,
> commands or parts) that a user consults while working. Adapted from the
> Diátaxis framework by Daniele Procida (CC BY-SA 4.0). Replace every
> `[bracketed]` value and every entry marked *Example*.

<!--
Guidance: How to use this template
- Reference describes; it does not instruct or explain. Remove any
  sentence that tells the reader what to do ("first, call...") or why the
  design is the way it is. Link to the how-to guide or explanation instead.
- Mirror the structure of the product. If the code has modules A, B and C,
  the reference has sections A, B and C in the same order.
- Every entry uses the same sub-structure. Consistency lets readers scan.
- Be complete and exact: types, defaults, limits, errors, version added.
  Short usage examples are allowed when they illustrate, not teach.
-->

| Field | Value |
|---|---|
| Describes | [Component or library name] [version 3.1] |
| Audience | [Developers using the library / Operators / End users] |
| Owner | [@maintainer] |
| Generated from | [Source docstrings / OpenAPI / Hand-written] |
| Last updated | YYYY-MM-DD |

## Overview

<!-- Guidance: One short paragraph naming what is described and how the page is organised. No tutorials, no rationale. -->

This page describes the public interface of `[geo-utils]` [3.1]: its
modules, functions, data types, constants and errors. Entries are grouped
by module and listed alphabetically within each group. Items not listed
here are internal and may change without notice.

| Module | Contents |
|---|---|
| `geo.distance` | Functions that measure distance between coordinates |
| `geo.types` | Data types used across the package |
| `geo.errors` | Exceptions raised by the package |

## Entry format

<!-- Guidance: State the fixed structure every entry follows so readers know where to find each fact. Keep it identical across all reference pages of the product. -->

Each entry contains, in this order:

| Part | Content |
|---|---|
| Signature | Exact name and parameters as they appear in code |
| Summary | One sentence describing what the item is or returns |
| Parameters | Table: name, type, required, default, description |
| Returns | Type and meaning of the result |
| Raises | Errors and the conditions that cause them |
| Constraints | Limits, units, thread safety, complexity |
| Example | A minimal illustration of input and output |
| Since | Version that introduced the item; changes in later versions |

## Conventions

<!-- Guidance: Define notation once so entries can stay terse. Readers of reference pages scan, so every symbol must mean the same thing everywhere. -->

| Convention | Meaning |
|---|---|
| `*` in a signature | Parameters after it must be passed by keyword |
| Required: Yes | The call fails if the parameter is missing |
| Default: none | The parameter has no default value |
| Units | Distances in kilometres and angles in decimal degrees unless the entry states otherwise |
| Thread safe | The item can be used from several threads at once without locking |
| $O(\cdot)$ | Time complexity in the number of input points |
| *Since* | First version in which the item is public; later changes are listed after it |

All functions accept and return values by value; none modifies its
arguments. Floating-point results follow IEEE 754 double precision and
are not rounded unless the entry states a precision.

## Module `geo.distance`

<!-- Guidance: One subsection per item. Use the entry format exactly; write "None" rather than omitting a part. -->

### `haversine(a, b, *, unit="km")`

*Example entry.* Returns the great-circle distance between two points on
a sphere with the mean Earth radius.

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `a` | `Point` | Yes | none | First point |
| `b` | `Point` | Yes | none | Second point |
| `unit` | `str` | No | `"km"` | One of `"km"`, `"m"`, `"mi"`, `"nmi"` |

**Returns:** `float`, the distance in the requested unit, always $\ge 0$.

**Raises:** `InvalidUnitError` if `unit` is not one of the listed values.

**Constraints:** Uses radius $R = 6371.0088$ km. Error versus the WGS 84
ellipsoid is up to about 0.5%. Pure function; thread safe; $O(1)$.

The distance computed is

$$
d = 2R \arcsin\left(\sqrt{\sin^2\frac{\Delta\varphi}{2} + \cos\varphi_1 \cos\varphi_2 \sin^2\frac{\Delta\lambda}{2}}\right)
$$

**Example:**

```python
>>> haversine(Point(52.52, 13.405), Point(48.857, 2.352))
877.46
```

**Since:** 1.0. `unit="nmi"` added in 2.4.

### `vincenty(a, b, *, unit="km", max_iter=200)`

*Example entry.* Returns the geodesic distance between two points on the
WGS 84 ellipsoid.

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `a` | `Point` | Yes | none | First point |
| `b` | `Point` | Yes | none | Second point |
| `unit` | `str` | No | `"km"` | One of `"km"`, `"m"`, `"mi"`, `"nmi"` |
| `max_iter` | `int` | No | `200` | Iteration limit, 1 to 1000 |

**Returns:** `float`, the distance in the requested unit.

**Raises:** `InvalidUnitError` for an unknown unit; `ConvergenceError`
when the iteration does not converge within `max_iter`, which can happen
for nearly antipodal points.

**Constraints:** Accuracy within 0.5 mm when converged. Thread safe.

**Example:**

```python
>>> vincenty(Point(52.52, 13.405), Point(48.857, 2.352), unit="m")
879697.6
```

**Since:** 2.0.

## Module `geo.types`

<!-- Guidance: For data types, list every field with type, constraints and default. Describe validation behaviour, not how to use the type. -->

### `Point(lat, lon)`

*Example entry.* An immutable geographic coordinate in decimal degrees.

| Field | Type | Constraints | Description |
|---|---|---|---|
| `lat` | `float` | $-90 \le lat \le 90$ | Latitude, positive north |
| `lon` | `float` | $-180 \le lon \le 180$ | Longitude, positive east |

**Raises:** `CoordinateRangeError` on construction if a field is out of range.

**Constraints:** Hashable; equality compares both fields exactly.

**Since:** 1.0.

### `[TypeName]`

[One-sentence summary.]

| Field | Type | Constraints | Description |
|---|---|---|---|
| [field] | [type] | [constraint] | [description] |

**Since:** [x.y].

## Module `geo.errors`

<!-- Guidance: List every error type with its base class and the condition that raises it. -->

| Error | Base class | Raised when | Since |
|---|---|---|---|
| `GeoError` | `Exception` | Base class for all package errors | 1.0 |
| `CoordinateRangeError` | `GeoError`, `ValueError` | A latitude or longitude is out of range | 1.0 |
| `InvalidUnitError` | `GeoError`, `ValueError` | A unit name is not recognised | 1.0 |
| `ConvergenceError` | `GeoError` | An iterative method exceeds its iteration limit | 2.0 |

## Constants

<!-- Guidance: Name, type, exact value and meaning. Do not explain how to choose between them. -->

| Name | Type | Value | Meaning |
|---|---|---|---|
| `EARTH_RADIUS_KM` | `float` | `6371.0088` | Mean Earth radius |
| `WGS84_A` | `float` | `6378137.0` | Semi-major axis in metres |
| `WGS84_F` | `float` | `1 / 298.257223563` | Flattening |

## Version history

<!-- Guidance: Changes to the described interface by version. Keep it factual; migration advice belongs in a migration guide. -->

| Version | Change |
|---|---|
| 3.1 | *Example:* `max_iter` upper bound raised from 500 to 1000 |
| 2.4 | *Example:* Added unit `"nmi"` |
| 2.0 | *Example:* Added `vincenty` and `ConvergenceError` |

## Related documentation

<!-- Guidance: Point to the other three Diátaxis forms so readers who need learning, a recipe or understanding can leave this page. -->

- Tutorial: [Your first distance calculation]
- How-to guide: [How to choose a distance method for your accuracy needs]
- Explanation: [Why the Earth is not a sphere: geodesy basics]

## Standard and licence note

The structure of this template is adapted from the Diátaxis framework by
Daniele Procida (https://diataxis.fr), licensed under CC BY-SA 4.0
(https://creativecommons.org/licenses/by-sa/4.0/). The template text is
original; the adapted structure is shared under CC BY-SA 4.0.
