Source: https://gometry.monicz.dev/api/crs/

# CRS

Coordinate reference systems, transformations, catalogs, and grid resources.

**Related:** [CRS, units & measurement](https://gometry.monicz.dev/guide/crs/)

## CRS object

## CRS

Accepted call forms

```python
CRS(value: CrsInput) -> CRS
```

Coordinate reference system.

A PROJ-backed CRS object: introspect it (`crs.is_geographic`,
`crs.ellipsoid`), serialize it (`crs.to_wkt()`, `crs.to_epsg()`),
evaluate it (`crs.factors(...)`), assign it to geometries with
`with_crs`, or transform coordinates with `to_crs`. Accepts an authority
string, EPSG code, authority tuple, PROJJSON/CF mapping, WKT/PROJ string,
or another `CRS`.

Equality is structural between `CRS` instances: the stored normalized
definitions must match. Other operand types do not compare equal; use
`CRS(value)` when comparing stored identity with raw input. Operational
equivalence, including axis-order-only differences, is the explicit
`same_as(..., mode='ignore_axis_order')` query. Equal `CRS` values are
hashable and can be used as mapping keys.

Build a CRS from any accepted input.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `value` | `CrsInput` | Authority string, EPSG code, authority tuple, PROJJSON/CF mapping, WKT/PROJ string, CRS-holder object, or another `CRS`. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `CRS` |  |

Raises:

| Type | Description |
| --- | --- |
| `CRSError` | If the value is not a recognized CRS. |

### area\_of\_use `property`

```python
area_of_use: CrsAreaOfUse | None
```

Area of use as a `{west, south, east, north, name}` dict, or `None`.

Returns:

| Type | Description |
| --- | --- |
| `CrsAreaOfUse or None` |  |

### authority `property`

```python
authority: str | None
```

Registry authority (e.g. `"EPSG"`), if identified.

Returns:

| Type | Description |
| --- | --- |
| `str or None` |  |

### axes `property`

```python
axes: list[CrsAxisInfo]
```

Coordinate-system axes as a list of dicts.

Returns:

| Type | Description |
| --- | --- |
| `list of CrsAxisInfo` |  |

### axis\_order `property`

```python
axis_order: list[str]
```

Axis roles in CRS order (lowercase, e.g. `["lat", "lon"]` for a
lat/lon CRS; tokens `"lat"`/`"lon"`/`"x"`/`"y"`/`"z"`/
`"height"`/`"other"`). For the raw PROJ abbreviations use `axes`.

Returns:

| Type | Description |
| --- | --- |
| `list of str` |  |

### celestial\_body `property`

```python
celestial_body: str | None
```

Name of the celestial body (usually `"Earth"`), if known.

Returns:

| Type | Description |
| --- | --- |
| `str or None` |  |

### code `property`

```python
code: str | None
```

Authority code (e.g. `"4326"`), if identified.

Returns:

| Type | Description |
| --- | --- |
| `str or None` |  |

### datum `property`

```python
datum: CrsDatumInfo | None
```

Geodetic datum as a dict, or `None`.

Returns:

| Type | Description |
| --- | --- |
| `CrsDatumInfo or None` |  |

### definition `property`

```python
definition: str
```

Stored definition string for this CRS.

Returns:

| Type | Description |
| --- | --- |
| `str` |  |

### ellipsoid `property`

```python
ellipsoid: CrsEllipsoidInfo | None
```

Reference ellipsoid as a dict, or `None`.

Returns:

| Type | Description |
| --- | --- |
| `CrsEllipsoidInfo or None` |  |

### geodetic\_crs `property`

```python
geodetic_crs: CrsAuthorityObject | None
```

Underlying geodetic CRS as an authority-object dict, or `None`.

Returns:

| Type | Description |
| --- | --- |
| `CrsAuthorityObject or None` |  |

### geoid\_models `property`

```python
geoid_models: list[str]
```

Geoid model names available for this CRS.

Returns:

| Type | Description |
| --- | --- |
| `list of str` |  |

Examples:

```pycon
>>> import gometry as gm
>>> gm.CRS(4326).geoid_models
[]
```

### info `property`

```python
info: CrsInfo
```

Full raw PROJ description as a dict (escape hatch).

Returns:

| Type | Description |
| --- | --- |
| `CrsInfo` |  |

### is\_bound `property`

```python
is_bound: bool
```

Whether this CRS is a bound CRS (carries a datum transform).

Returns:

| Type | Description |
| --- | --- |
| `bool` |  |

### is\_compound `property`

```python
is_compound: bool
```

Whether this CRS is compound (horizontal + vertical).

Returns:

| Type | Description |
| --- | --- |
| `bool` |  |

### is\_deprecated `property`

```python
is_deprecated: bool
```

Whether this CRS is flagged deprecated by its authority.

Returns:

| Type | Description |
| --- | --- |
| `bool` |  |

### is\_derived `property`

```python
is_derived: bool
```

Whether this CRS is derived from a base CRS.

Returns:

| Type | Description |
| --- | --- |
| `bool` |  |

### is\_engineering `property`

```python
is_engineering: bool
```

Whether this CRS is engineering (local/non-geodetic).

Returns:

| Type | Description |
| --- | --- |
| `bool` |  |

### is\_geocentric `property`

```python
is_geocentric: bool
```

Whether this CRS is geocentric (earth-centered Cartesian).

For a compound CRS this is `True` when **any component** is
geocentric (not root-kind only).

Returns:

| Type | Description |
| --- | --- |
| `bool` |  |

### is\_geographic `property`

```python
is_geographic: bool
```

Whether this CRS is geographic (lon/lat on an ellipsoid).

For a compound CRS this is `True` when **any component** is
geographic (not root-kind only) — e.g. `EPSG:9707` (WGS 84 + height).

Returns:

| Type | Description |
| --- | --- |
| `bool` |  |

### is\_projected `property`

```python
is_projected: bool
```

Whether this CRS is projected (planar, metric).

For a compound CRS this is `True` when **any component** is
projected (not root-kind only).

Returns:

| Type | Description |
| --- | --- |
| `bool` |  |

### is\_vertical `property`

```python
is_vertical: bool
```

Whether this CRS is vertical (height/depth only).

For a compound CRS this is `True` when **any component** is
vertical (not root-kind only).

Returns:

| Type | Description |
| --- | --- |
| `bool` |  |

### kind `property`

```python
kind: Literal['geographic_2d', 'geographic_3d', 'geographic', 'geocentric', 'projected', 'vertical', 'compound', 'temporal', 'engineering', 'bound', 'other', 'unknown']
```

CRS kind as a snake\_case token (`"geographic_2d"`, `"geographic_3d"`,
`"projected"`, `"geocentric"`, `"vertical"`, `"compound"`,
`"bound"`, `"other"`, ...).

Returns:

| Type | Description |
| --- | --- |
| `str` |  |

### name `property`

```python
name: str | None
```

Human-readable CRS name, if known.

Returns:

| Type | Description |
| --- | --- |
| `str or None` |  |

### non\_deprecated `property`

```python
non_deprecated: list[CrsAuthorityObject]
```

Non-deprecated authority objects equivalent to this CRS.

Returns:

| Type | Description |
| --- | --- |
| `list of CrsAuthorityObject` |  |

Examples:

```pycon
>>> import gometry as gm
>>> gm.CRS(4326).non_deprecated
[]
```

### prime\_meridian `property`

```python
prime_meridian: CrsPrimeMeridianInfo | None
```

Prime meridian as a dict, or `None`.

Returns:

| Type | Description |
| --- | --- |
| `CrsPrimeMeridianInfo or None` |  |

### factors

Accepted call forms

```python
factors(lon: FloatScalar | ScalarFloatArray, lat: FloatScalar | ScalarFloatArray, *, radians: bool = False) -> CrsProjectionFactors
```

```python
factors(lon: FloatInput, lat: FloatInput, *, radians: bool = False) -> CrsProjectionFactorsBatch
```

Map-projection factors (scale, distortion, Tissot, …) at a lon/lat.

For a **projected** CRS the evaluation point is geographic lon/lat on
the base ellipsoid and the returned scales/distortions describe the
projection at that location. For a pure geographic CRS the factors are
near-identity (meridional/parallel scale ≈ 1).

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `lon` | `float or sequence of float` | Longitude of the evaluation point(s), degrees unless `radians=True`. | *required* |
| `lat` | `float or sequence of float` | Latitude of the evaluation point(s), degrees unless `radians=True`. | *required* |
| `radians` | `bool` | Interpret angular inputs as radians (default `False`). | `False` |

Returns:

| Type | Description |
| --- | --- |
| `dict` | Scalar call: mapping of factor names to floats (`meridional_scale`, `parallel_scale`, `areal_scale`, `angular_distortion`, `meridian_parallel_angle`, `meridian_convergence`, `tissot_semimajor`, `tissot_semiminor`, `dx_dlam`, `dx_dphi`, `dy_dlam`, `dy_dphi`). Array call: same keys with float arrays. |

Raises:

| Type | Description |
| --- | --- |
| `InvalidGeometryError` | If `lon`/`lat` are non-finite or differ in length. |

Examples:

```pycon
>>> import gometry as gm
>>> f = gm.CRS(3857).factors(0.0, 0.0)
>>> round(f['meridional_scale'], 5)
1.0
```

### identify

```python
identify(*, authority: str | None = None) -> list[CrsIdentifyCandidate]
```

Candidate authority matches for this CRS, best first.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `authority` | `str` | Restrict matches to this authority. | `None` |

Returns:

| Type | Description |
| --- | --- |
| `list of CrsIdentifyCandidate` |  |

Raises:

| Type | Description |
| --- | --- |
| `CRSError` | If identification fails. |

Examples:

```pycon
>>> import gometry as gm
>>> gm.CRS(4326).identify()[0]['code']
'4326'
```

### operation

```python
operation(target: CrsInput, *, at: tuple[float, float] | tuple[float, float, float] | tuple[float, float, float, float] | None = None, area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> CrsOperationInfo
```

Best coordinate operation from this CRS to `target`.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `target` | `CRS - like` | Destination CRS. | *required* |
| `at` | `tuple of float` | Coordinate at which to select the best operation: `(x, y)`, `(x, y, z)`, or `(x, y, z, t)` in the source CRS. This is an alternative to a broader `area_of_interest`. | `None` |
| `area_of_interest` | `sequence of float` | `(west, south, east, north)` area of interest. | `None` |
| `source_epoch` | `numeric scalar or 0-D numeric array` | Coordinate epochs for dynamic CRS. | `None` |
| `target_epoch` | `numeric scalar or 0-D numeric array` | Coordinate epochs for dynamic CRS. | `None` |
| `authority` | `str` | Restrict candidate coordinate operations to this authority (e.g. `'EPSG'`). | `None` |
| `accuracy` | `float` | Maximum acceptable operation accuracy, in meters. | `None` |
| `allow_ballpark` | `bool` | Allow low-accuracy ballpark operations when no precise one exists. | `None` |
| `only_best` | `bool` | Require PROJ's best operation. If a required transformation grid is unavailable, raise `TransformError` instead of using a less accurate fallback operation. | `None` |
| `force_over` | `bool` | Keep coordinates on the source side of the antimeridian instead of wrapping into `[-180, 180]` (PROJ `FORCE_OVER=YES`). Like `only_best`, this also collapses operation selection to a single candidate, so enumerating surfaces return exactly one operation. | `False` |

Returns:

| Type | Description |
| --- | --- |
| `CrsOperationInfo` | The operation or a nested step's `definition` may be `None` when the selected default angular semantics cannot be represented faithfully by an executable PROJ string. Method, parameters, steps, grids, source, target, and epoch metadata remain available. |

Raises:

| Type | Description |
| --- | --- |
| `CRSError` | If the CRS arguments are unrecognized. |

Examples:

```pycon
>>> import gometry as gm
>>> gm.CRS(4326).operation(3857)['name']
'pipeline'
```

### operations

```python
operations(target: CrsInput, *, area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> list[CrsOperationInfo]
```

All candidate operations from this CRS to `target`, best first.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `target` | `CRS - like` | Destination CRS. | *required* |
| `area_of_interest` | `sequence of float` | `(west, south, east, north)` area of interest. | `None` |
| `source_epoch` | `numeric scalar or 0-D numeric array` | Coordinate epochs for dynamic CRS. | `None` |
| `target_epoch` | `numeric scalar or 0-D numeric array` | Coordinate epochs for dynamic CRS. | `None` |
| `authority` | `str` | Restrict candidate coordinate operations to this authority (e.g. `'EPSG'`). | `None` |
| `accuracy` | `float` | Maximum acceptable operation accuracy, in meters. | `None` |
| `allow_ballpark` | `bool` | Allow low-accuracy ballpark operations when no precise one exists. | `None` |
| `only_best` | `bool` | Require PROJ's best operation. If a required transformation grid is unavailable, raise `TransformError` instead of using a less accurate fallback operation. | `None` |
| `force_over` | `bool` | Keep coordinates on the source side of the antimeridian instead of wrapping into `[-180, 180]` (PROJ `FORCE_OVER=YES`). Like `only_best`, this also collapses operation selection to a single candidate, so enumerating surfaces return exactly one operation. | `False` |

Returns:

| Type | Description |
| --- | --- |
| `list of CrsOperationInfo` | A candidate's or nested step's `definition` may be `None` when the selected default angular semantics cannot be represented faithfully by an executable PROJ string. Method, parameters, steps, grids, source, target, and epoch metadata remain available. |

Examples:

```pycon
>>> import gometry as gm
>>> len(gm.CRS(4326).operations(3857)) >= 1
True
```

### same\_as

```python
same_as(other: CrsInput, *, mode: Literal['ignore_axis_order', 'exact']) -> bool
```

Test whether this CRS describes the same system as `other`.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `other` | `CRS - like` | The other CRS-like value to compare against. | *required* |
| `mode` | `str` | One of `'ignore_axis_order'` (same but axis-swapped CRS count as equal), or `'exact'` (strict, detail-identical match). | *required* |

Returns:

| Type | Description |
| --- | --- |
| `bool` |  |

Examples:

```pycon
>>> import gometry as gm
>>> gm.CRS(4326).same_as(gm.CRS(4326), mode='exact')
True
```

### to\_2d

```python
to_2d(*, name: str | None = None) -> CRS
```

Return the 2D (horizontal) form of this CRS.

Converts the CRS definition by removing the ellipsoidal-height axis;
it does not add or remove Z ordinates on geometries — use
`force_2d`/`force_3d` or `with_coordinates(z=...)` for that.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `name` | `str` | Name for the derived CRS. | `None` |

Returns:

| Type | Description |
| --- | --- |
| `CRS` |  |

Examples:

```pycon
>>> import gometry as gm
>>> gm.CRS(4979).to_2d().to_epsg()
4326
```

### to\_3d

```python
to_3d(*, name: str | None = None) -> CRS
```

Return the 3D form of this CRS (adds an ellipsoidal height axis).

Converts the CRS definition only; it does not add or remove Z
ordinates on geometries — use `force_2d`/`force_3d` or `with_coordinates(z=...)` for
that.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `name` | `str` | Name for the derived CRS. | `None` |

Returns:

| Type | Description |
| --- | --- |
| `CRS` |  |

Examples:

```pycon
>>> import gometry as gm
>>> gm.CRS(4326).to_3d().to_epsg()
4979
```

### to\_authority

```python
to_authority(*, authority: str | None = None, min_confidence: int = 70) -> tuple[str, str] | None
```

`(authority, code)` pair, or `None` if it cannot be determined.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `authority` | `str` | Restrict identification to this authority. | `None` |
| `min_confidence` | `int` | Minimum identification confidence (0-100, default 70). | `70` |

Returns:

| Type | Description |
| --- | --- |
| `tuple or None` |  |

Raises:

| Type | Description |
| --- | --- |
| `CRSError` | If `min_confidence` is outside `0`-`100`. |

Examples:

```pycon
>>> import gometry as gm
>>> gm.CRS(4326).to_authority()
('EPSG', '4326')
```

### to\_cf

```python
to_cf(*, wkt_version: Literal['WKT2_2019', 'WKT2_2019_SIMPLIFIED', 'WKT2_2015', 'WKT2_2015_SIMPLIFIED', 'WKT1_GDAL', 'WKT1_ESRI'] = 'WKT2_2019') -> CrsCfInfo
```

CF (Climate and Forecast) grid-mapping attributes as a dict.

Projected `units` is `m`, `ft`, or `us-ft` when every horizontal
axis admits the same token. Otherwise the reconstructible grid mapping
and `units` are omitted; `crs_wkt` still carries the full CRS.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `wkt_version` | `str` | WKT dialect embedded in `crs_wkt` (default `"WKT2_2019"`). | `'WKT2_2019'` |

Returns:

| Type | Description |
| --- | --- |
| `CrsCfInfo` |  |

Raises:

| Type | Description |
| --- | --- |
| `CRSError` | If export fails. |

Examples:

```pycon
>>> import gometry as gm
>>> gm.CRS(4326).to_cf().get('grid_mapping_name')
'latitude_longitude'
```

### to\_epsg

```python
to_epsg(*, min_confidence: int = 70) -> int | None
```

EPSG integer code, or `None` if it cannot be determined.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `min_confidence` | `int` | Minimum identification confidence (0-100, default 70). | `70` |

Returns:

| Type | Description |
| --- | --- |
| `int or None` |  |

Raises:

| Type | Description |
| --- | --- |
| `CRSError` | If `min_confidence` is outside `0`-`100`. |

Examples:

```pycon
>>> import gometry as gm
>>> gm.CRS(4326).to_epsg()
4326
```

### to\_proj

```python
to_proj(*, version: Literal[4, 5] = 5, pretty: bool = False, approximate_tmerc: bool = False, indentation_width: int = 2, max_line_length: int = 80) -> str
```

Serialize this CRS to a PROJ string.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `version` | `int` | PROJ string version (4 or 5). | `5` |
| `pretty` | `bool` | Indent the output (default `False`). | `False` |
| `approximate_tmerc` | `bool` | Use the approximate transverse-Mercator formulation. | `False` |
| `indentation_width` | `int` | Spaces per indent level when `pretty`. | `2` |
| `max_line_length` | `int` | Wrap lines at this width. | `80` |

Returns:

| Type | Description |
| --- | --- |
| `str` |  |

Raises:

| Type | Description |
| --- | --- |
| `CRSError` | If export fails or a formatting option is invalid. |

Examples:

```pycon
>>> import gometry as gm
>>> '+proj=longlat' in gm.CRS(4326).to_proj()
True
```

### to\_projjson

Accepted call forms

```python
to_projjson(*, as_dict: Literal[False] = False, pretty: bool = False, indentation_width: int = 2) -> str
```

```python
to_projjson(*, as_dict: Literal[True]) -> dict[str, object]
```

```python
to_projjson(*, as_dict: bool, pretty: bool = False, indentation_width: int = 2) -> str | dict[str, object]
```

Export this CRS as PROJJSON text or a fresh Python mapping.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `as_dict` | `bool` | Return a Python mapping; the JSON-text form omits `as_dict` and the mapping form requires `as_dict=True`. | *required* |
| `pretty` | `bool` | Indent JSON text (default `False`). Only applies when `as_dict=False`. | `False` |
| `indentation_width` | `int` | Spaces per indent level for pretty JSON text; available only when `as_dict=False`. | `2` |

Returns:

| Type | Description |
| --- | --- |
| `str or dict[str, object]` |  |

Raises:

| Type | Description |
| --- | --- |
| `CRSError` | If export fails or a formatting option is invalid. |
| `GeometryError` | If formatting is requested with `as_dict=True`. |

Examples:

```pycon
>>> import gometry as gm
>>> gm.CRS(4326).to_projjson(as_dict=True)['type']
'GeographicCRS'
```

### to\_wkt

```python
to_wkt(*, version: Literal['WKT2_2019', 'WKT2_2019_SIMPLIFIED', 'WKT2_2015', 'WKT2_2015_SIMPLIFIED', 'WKT1_GDAL', 'WKT1_ESRI'] = 'WKT2_2019', pretty: bool = False, output_axis: Literal['auto', 'yes', 'no'] = 'auto', strict: bool = True, indentation_width: int = 4) -> str
```

Serialize this CRS to WKT.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `version` | `str` | WKT dialect (default `"WKT2_2019"`). | `'WKT2_2019'` |
| `pretty` | `bool` | Indent the WKT output (default `False`). | `False` |
| `output_axis` | `str` | Axis-output policy (`"auto"`, `"yes"`, `"no"`). | `"auto"` |
| `strict` | `bool` | Fail on lossy output (default `True`). | `True` |
| `indentation_width` | `int` | Spaces per indent level when `pretty`. | `4` |

Returns:

| Type | Description |
| --- | --- |
| `str` |  |

Raises:

| Type | Description |
| --- | --- |
| `CRSError` | If export fails or a formatting option is invalid. |

Examples:

```pycon
>>> import gometry as gm
>>> gm.CRS(4326).to_wkt().startswith('GEOGCRS')
True
```

## CRS functions

## crs\_apply

Accepted call forms

```python
crs_apply(operation: str, x: FloatScalar | ScalarFloatArray, y: FloatScalar | ScalarFloatArray, z: None = None, *, t: None = None, direction: Literal['forward', 'inverse'] = 'forward') -> tuple[float, float]
```

```python
crs_apply(operation: str, x: FloatScalar | ScalarFloatArray, y: FloatScalar | ScalarFloatArray, z: FloatScalar | ScalarFloatArray, *, t: None = None, direction: Literal['forward', 'inverse'] = 'forward') -> tuple[float, float, float]
```

```python
crs_apply(operation: str, x: FloatScalar | ScalarFloatArray, y: FloatScalar | ScalarFloatArray, z: None = None, *, t: FloatScalar | ScalarFloatArray, direction: Literal['forward', 'inverse'] = 'forward') -> tuple[float, float, float]
```

```python
crs_apply(operation: str, x: FloatScalar | ScalarFloatArray, y: FloatScalar | ScalarFloatArray, z: FloatScalar | ScalarFloatArray, *, t: FloatScalar | ScalarFloatArray, direction: Literal['forward', 'inverse'] = 'forward') -> tuple[float, float, float, float]
```

```python
crs_apply(operation: str, x: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], y: FloatInput, z: None = None, *, t: None = None, direction: Literal['forward', 'inverse'] = 'forward') -> tuple[NDArray[float64], NDArray[float64]]
```

```python
crs_apply(operation: str, x: FloatInput, y: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], z: None = None, *, t: None = None, direction: Literal['forward', 'inverse'] = 'forward') -> tuple[NDArray[float64], NDArray[float64]]
```

```python
crs_apply(operation: str, x: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], y: FloatInput, z: FloatInput, *, t: None = None, direction: Literal['forward', 'inverse'] = 'forward') -> tuple[NDArray[float64], NDArray[float64], NDArray[float64]]
```

```python
crs_apply(operation: str, x: FloatInput, y: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], z: FloatInput, *, t: None = None, direction: Literal['forward', 'inverse'] = 'forward') -> tuple[NDArray[float64], NDArray[float64], NDArray[float64]]
```

```python
crs_apply(operation: str, x: FloatInput, y: FloatInput, z: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], *, t: None = None, direction: Literal['forward', 'inverse'] = 'forward') -> tuple[NDArray[float64], NDArray[float64], NDArray[float64]]
```

```python
crs_apply(operation: str, x: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], y: FloatInput, z: None = None, *, t: FloatInput, direction: Literal['forward', 'inverse'] = 'forward') -> tuple[NDArray[float64], NDArray[float64], NDArray[float64]]
```

```python
crs_apply(operation: str, x: FloatInput, y: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], z: None = None, *, t: FloatInput, direction: Literal['forward', 'inverse'] = 'forward') -> tuple[NDArray[float64], NDArray[float64], NDArray[float64]]
```

```python
crs_apply(operation: str, x: FloatInput, y: FloatInput, z: None = None, *, t: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], direction: Literal['forward', 'inverse'] = 'forward') -> tuple[NDArray[float64], NDArray[float64], NDArray[float64]]
```

```python
crs_apply(operation: str, x: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], y: FloatInput, z: FloatInput, *, t: FloatInput, direction: Literal['forward', 'inverse'] = 'forward') -> tuple[NDArray[float64], NDArray[float64], NDArray[float64], NDArray[float64]]
```

```python
crs_apply(operation: str, x: FloatInput, y: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], z: FloatInput, *, t: FloatInput, direction: Literal['forward', 'inverse'] = 'forward') -> tuple[NDArray[float64], NDArray[float64], NDArray[float64], NDArray[float64]]
```

```python
crs_apply(operation: str, x: FloatInput, y: FloatInput, z: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], *, t: FloatInput, direction: Literal['forward', 'inverse'] = 'forward') -> tuple[NDArray[float64], NDArray[float64], NDArray[float64], NDArray[float64]]
```

```python
crs_apply(operation: str, x: FloatInput, y: FloatInput, z: FloatInput, *, t: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], direction: Literal['forward', 'inverse'] = 'forward') -> tuple[NDArray[float64], NDArray[float64], NDArray[float64], NDArray[float64]]
```

```python
crs_apply(operation: str, x: FloatInput, y: FloatInput, z: FloatInput | None = None, *, t: FloatInput | None = None, direction: Literal['forward', 'inverse'] = 'forward') -> tuple[float, float] | tuple[float, float, float] | tuple[float, float, float, float] | tuple[NDArray[float64], NDArray[float64]] | tuple[NDArray[float64], NDArray[float64], NDArray[float64]] | tuple[NDArray[float64], NDArray[float64], NDArray[float64], NDArray[float64]]
```

Apply a PROJ pipeline/operation definition to coordinates.

Runs an explicit operation (e.g. a
`+proj=pipeline` string) rather than resolving one from a CRS pair.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `operation` | `str` | PROJ operation or pipeline definition. | *required* |
| `x` | `float or sequence of float` | Coordinate columns (scalars transform a single point). | *required* |
| `y` | `float or sequence of float` | Coordinate columns (scalars transform a single point). | *required* |
| `z` | `float or sequence of float` | Vertical column for 3D operations. | `None` |
| `t` | `float or sequence of float` | Coordinate epoch column. | `None` |
| `direction` | `('forward', 'inverse')` | Operation direction. | `'forward'` |

Returns:

| Type | Description |
| --- | --- |
| `tuple` | The transformed columns — `(x, y)`, `(x, y, z)`, `(x, y, t)` when T is supplied without Z, or `(x, y, z, t)`. Scalars in, scalars out; lane inputs return read-only `float64` `numpy.ndarray` columns (`np.asarray(column)` reads the values directly, `list(column)` materializes them). |

Raises:

| Type | Description |
| --- | --- |
| `TransformError` | If no transform exists between the frames or it fails to apply. |
| `CRSError` | If the operation definition is invalid. |
| `InvalidGeometryError` | If coordinate columns are non-finite or differ in length. |
| `GeometryError` | If `direction` is invalid. |

Notes

Supply a literal operation definition. A definition returned by
`CRS.operation` may be `None` when selected angular semantics cannot be
represented faithfully as an executable PROJ string.

Examples:

```pycon
>>> import gometry as gm
>>> op = '+proj=affine +xoff=1 +yoff=2'
>>> gm.crs_apply(op, -122.4, 37.8)
(-121.4, 39.8)
```

## crs\_authorities

```python
crs_authorities() -> list[str]
```

Names of all registry authorities known to PROJ.

Returns:

| Type | Description |
| --- | --- |
| `list of str` |  |

Examples:

```pycon
>>> import gometry as gm
>>> gm.crs_authorities()[:3]
['EPSG', 'ESRI', 'IAU_2015']
```

## crs\_cache\_info

```python
crs_cache_info() -> CrsCacheInfo
```

Statistics about the CRS caches.

Returns:

| Type | Description |
| --- | --- |
| `dict` | CRS cache statistics (generation, entry counts, per-bucket info). |

Examples:

```pycon
>>> import gometry as gm
>>> gm.crs_cache_info()['total_capacity'] > 0
True
```

## crs\_catalog

```python
crs_catalog(name: str | None = None, *, authority: str | None = None, kind: Literal['crs', 'geodetic', 'geographic', 'geographic_2d', 'geographic_3d', 'geocentric', 'projected', 'vertical', 'compound', 'temporal', 'engineering', 'bound', 'other'] | None = None, area_of_interest: CrsAreaInput | None = None, contains_area_of_interest: bool = False, allow_deprecated: bool = False, celestial_body: str | None = None, approximate: bool = False, limit: int | None = None) -> list[CrsCatalogInfo]
```

Catalog of CRS in the database matching the given filters.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `name` | `str` | Match CRS names using PROJ's database name matcher. | `None` |
| `authority` | `str` | Registry authority to search (default `"EPSG"`). | `None` |
| `kind` | `str` | Restrict to a CRS kind. | `None` |
| `area_of_interest` | `sequence of float, dict, or object` | Filter area as `(west, south, east, north)` in DEGREES, an area mapping, or an AreaOfInterest-like object. | `None` |
| `contains_area_of_interest` | `bool` | Require the CRS area to contain `area_of_interest` (default `False`). | `False` |
| `allow_deprecated` | `bool` | Include deprecated CRS (default `False`). | `False` |
| `celestial_body` | `str` | Restrict to this celestial body. | `None` |
| `approximate` | `bool` | Allow approximate matching when `name` is supplied. | `False` |
| `limit` | `int` | Maximum number of returned records; omitted means no result limit. | `None` |

Returns:

| Type | Description |
| --- | --- |
| `list of CrsCatalogInfo` |  |

Examples:

```pycon
>>> import gometry as gm
>>> any(item['crs'] == 'EPSG:4326' for item in gm.crs_catalog(name='WGS 84'))
True
```

## crs\_celestial\_bodies

```python
crs_celestial_bodies(*, authority: str | None = None) -> list[CrsCelestialBodyInfo]
```

Celestial bodies known to the CRS database.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `authority` | `str` | Restrict to this authority. | `None` |

Returns:

| Type | Description |
| --- | --- |
| `list of CrsCelestialBodyInfo` |  |

Examples:

```pycon
>>> import gometry as gm
>>> gm.crs_celestial_bodies()[0]['name']
'1_Ceres'
```

## crs\_clear\_cache

```python
crs_clear_cache() -> None
```

Clear the CRS object cache.

Returns:

| Type | Description |
| --- | --- |
| `None` |  |

Examples:

```pycon
>>> import gometry as gm
>>> gm.crs_clear_cache()
>>> True
True
```

## crs\_codes

```python
crs_codes(authority: str, *, kind: CrsDatabaseKind | None = None, allow_deprecated: bool = False) -> list[str]
```

Object codes within a registry authority.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `authority` | `str` | Registry authority, e.g. `"EPSG"`. | *required* |
| `kind` | `str` | Restrict to a CRS kind. | `None` |
| `allow_deprecated` | `bool` | Include deprecated codes (default `False`). | `False` |

Returns:

| Type | Description |
| --- | --- |
| `list of str` |  |

Examples:

```pycon
>>> import gometry as gm
>>> gm.crs_codes('EPSG')[:3]
['10150', '10151', '10156']
```

## crs\_configure

```python
crs_configure(*, search_paths: str | PathLike[str] | Iterable[str | PathLike[str]] | None = ..., user_writable_directory: str | PathLike[str] | None = ...) -> CrsRuntimeConfig
```

Configure local CRS engine paths.

Omitted arguments keep their current value, while explicit `None` restores
that field's default. A call without arguments returns the current
configuration unchanged; use `crs_reset` to restore both defaults.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `search_paths` | `str, path, or sequence of these` | Directories PROJ searches for its database and grids. `None` restores the default search paths. When a named grid is absent from these directories, PROJ may also try the bare grid filename in the current working directory. | `...` |
| `user_writable_directory` | `str or path` | Directory PROJ includes in local grid lookup. `None` restores the default writable directory. | `...` |

Notes

The configured directories are not an exclusive grid-file whitelist. A
grid in the current working directory can therefore change grid
availability, the selected transformation, and whether `AccuracyWarning`
is emitted after the configured directories miss.

Returns:

| Type | Description |
| --- | --- |
| `dict` | The effective configuration after applying the changes. |

Examples:

```pycon
>>> import gometry as gm
>>> isinstance(gm.crs_configure(), dict)
True
```

## crs\_ellipsoids

```python
crs_ellipsoids() -> list[CrsEllipsoidCatalogInfo]
```

List ellipsoids in the CRS database.

Returns:

| Type | Description |
| --- | --- |
| `list` | One entry per ellipsoid in the CRS database. |

Examples:

```pycon
>>> import gometry as gm
>>> gm.crs_ellipsoids()[0]['id']
'MERIT'
```

## crs\_engine

```python
crs_engine() -> CrsEngineInfo
```

Name/version of the underlying CRS engine (PROJ).

Returns:

| Type | Description |
| --- | --- |
| `dict` | Engine metadata. `paths` is the effective per-context grid search path configured through :func:`crs_configure`. |

Examples:

```pycon
>>> import gometry as gm
>>> gm.crs_engine()['version']
'9.9.0'
```

## crs\_grid

```python
crs_grid(name: str) -> CrsGridDatabaseInfo
```

Information about a transformation grid.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `name` | `str` | Grid short name (e.g. `'us_noaa_g2018u0.tif'`). | *required* |

Returns:

| Type | Description |
| --- | --- |
| `dict` | Local grid metadata and availability. |

Examples:

```pycon
>>> import gometry as gm
>>> gm.crs_grid('null')['available']
True
```

## crs\_prime\_meridians

```python
crs_prime_meridians() -> list[CrsPrimeMeridianCatalogInfo]
```

List prime meridians in the CRS database.

Returns:

| Type | Description |
| --- | --- |
| `list` | One entry per prime meridian in the CRS database. |

Examples:

```pycon
>>> import gometry as gm
>>> gm.crs_prime_meridians()[0]['id']
'greenwich'
```

## crs\_proj\_operations

```python
crs_proj_operations() -> list[CrsProjOperationCatalogInfo]
```

List PROJ operations available.

Returns:

| Type | Description |
| --- | --- |
| `list` | One entry per available PROJ operation. |

Examples:

```pycon
>>> import gometry as gm
>>> gm.crs_proj_operations()[0]['id']
'adams_hemi'
```

## crs\_reset

```python
crs_reset() -> CrsRuntimeConfig
```

Reset CRS engine configuration to defaults.

Returns:

| Type | Description |
| --- | --- |
| `dict` | The configuration after the reset. |

Examples:

```pycon
>>> import gometry as gm
>>> isinstance(gm.crs_reset(), dict)
True
```

## crs\_roundtrip

Accepted call forms

```python
crs_roundtrip(source: CrsInput, target: CrsInput, x: FloatScalar | ScalarFloatArray, y: FloatScalar | ScalarFloatArray, z: FloatScalar | ScalarFloatArray | None = None, *, t: FloatScalar | ScalarFloatArray | None = None, iterations: int | integer[Any] = 1, direction: Literal['forward', 'inverse'] = 'forward', area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> float
```

```python
crs_roundtrip(source: CrsInput, target: CrsInput, x: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], y: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], z: FloatInput | None = None, *, t: FloatInput | None = None, iterations: int = 1, direction: Literal['forward', 'inverse'] = 'forward', area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> NDArray[float64]
```

```python
crs_roundtrip(source: CrsInput, target: CrsInput, x: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], y: FloatInput, z: FloatInput | None = None, *, t: FloatInput | None = None, iterations: int = 1, direction: Literal['forward', 'inverse'] = 'forward', area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> NDArray[float64]
```

```python
crs_roundtrip(source: CrsInput, target: CrsInput, x: FloatInput, y: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], z: FloatInput | None = None, *, t: FloatInput | None = None, iterations: int = 1, direction: Literal['forward', 'inverse'] = 'forward', area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> NDArray[float64]
```

```python
crs_roundtrip(source: CrsInput, target: CrsInput, x: FloatInput, y: FloatInput, z: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], *, t: FloatInput | None = None, iterations: int = 1, direction: Literal['forward', 'inverse'] = 'forward', area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> NDArray[float64]
```

```python
crs_roundtrip(source: CrsInput, target: CrsInput, x: FloatInput, y: FloatInput, z: FloatInput | None = None, *, t: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], iterations: int = 1, direction: Literal['forward', 'inverse'] = 'forward', area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> NDArray[float64]
```

```python
crs_roundtrip(source: CrsInput, target: CrsInput, x: FloatInput, y: FloatInput, z: FloatInput | None = None, *, t: FloatInput | None = None, iterations: int = 1, direction: Literal['forward', 'inverse'] = 'forward', area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> float | NDArray[float64]
```

Round-trip coordinates through a CRS pair to measure error.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `source` | `CRS - like` | Source and destination CRS-like inputs. | *required* |
| `target` | `CRS - like` | Source and destination CRS-like inputs. | *required* |
| `x` | `float or sequence of float` | Coordinates, scalar or batch. | *required* |
| `y` | `float or sequence of float` | Coordinates, scalar or batch. | *required* |
| `z` | `float or sequence of float` | Height and time ordinates when provided. | `None` |
| `t` | `float or sequence of float` | Height and time ordinates when provided. | `None` |
| `iterations` | `int` | How many forward+inverse passes to apply. | `1` |
| `direction` | `('forward', 'inverse')` | Which leg runs first. | `'forward'` |
| `area_of_interest` | `sequence of float, dict, or object` | Area of interest guiding operation selection, as `(west, south, east, north)` in DEGREES, an area mapping, or an AreaOfInterest-like object. | `None` |
| `source_epoch` | `numeric scalar or 0-D numeric array` | Coordinate epochs for dynamic CRS. | `None` |
| `target_epoch` | `numeric scalar or 0-D numeric array` | Coordinate epochs for dynamic CRS. | `None` |
| `authority` | `str` | Restrict candidate coordinate operations to this authority (e.g. `'EPSG'`). | `None` |
| `accuracy` | `float` | Maximum acceptable operation accuracy, in meters. | `None` |
| `allow_ballpark` | `bool` | Allow low-accuracy ballpark operations when no precise one exists. | `None` |
| `only_best` | `bool` | Require PROJ's best operation. If a required transformation grid is unavailable, raise `TransformError` instead of using a less accurate fallback operation. | `None` |
| `force_over` | `bool` | Keep coordinates on the source side of the antimeridian instead of wrapping into `[-180, 180]` (PROJ `FORCE_OVER=YES`). Like `only_best`, this also collapses operation selection to a single candidate, so enumerating surfaces return exactly one operation. | `False` |

Returns:

| Type | Description |
| --- | --- |
| `float or ndarray` | Euclidean residual of the raw input columns in their original units after the out-and-back legs. When Z or T is present the hypot mixes those column units with X and Y. There is no geodesic distance and no circular-longitude normalization. Scalar in, scalar out, and lane inputs return a read-only `float64` `numpy.ndarray`. |

Raises:

| Type | Description |
| --- | --- |
| `TransformError` | If no transform exists between the frames or it fails to apply. |
| `CRSError` | If `source`/`target` are unrecognized. |
| `InvalidGeometryError` | If coordinate columns are non-finite or differ in length. |
| `GeometryError` | If an epoch option is invalid. |

Examples:

```pycon
>>> import gometry as gm
>>> gm.crs_roundtrip(4326, 3857, -122.4, 37.8) < 1e-9
True
```

## crs\_transform

Accepted call forms

```python
crs_transform(source: CrsInput, target: CrsInput, x: FloatScalar | ScalarFloatArray, y: FloatScalar | ScalarFloatArray, z: None = None, *, t: FloatScalar | ScalarFloatArray | None = None, area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> tuple[float, float]
```

```python
crs_transform(source: CrsInput, target: CrsInput, x: FloatScalar | ScalarFloatArray, y: FloatScalar | ScalarFloatArray, z: FloatScalar | ScalarFloatArray, *, t: FloatScalar | ScalarFloatArray | None = None, area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> tuple[float, float, float]
```

```python
crs_transform(source: CrsInput, target: CrsInput, x: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], y: FloatInput, z: FloatInput | None = None, *, t: FloatInput | None = None, area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> NDArray[float64]
```

```python
crs_transform(source: CrsInput, target: CrsInput, x: FloatInput, y: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], z: FloatInput | None = None, *, t: FloatInput | None = None, area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> NDArray[float64]
```

```python
crs_transform(source: CrsInput, target: CrsInput, x: FloatInput, y: FloatInput, z: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], *, t: FloatInput | None = None, area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> NDArray[float64]
```

```python
crs_transform(source: CrsInput, target: CrsInput, x: FloatInput, y: FloatInput, z: FloatInput | None = None, *, t: FloatColumn | ndarray[tuple[int], dtype[floating[Any] | signedinteger[Any] | unsignedinteger[Any]]], area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> NDArray[float64]
```

```python
crs_transform(source: CrsInput, target: CrsInput, x: FloatInput, y: FloatInput, z: FloatInput | None = None, *, t: FloatInput | None = None, area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> tuple[float, float] | tuple[float, float, float] | NDArray[float64]
```

Reproject raw coordinates from one CRS to another.

For geometries use `to_crs`; this is
the lower-level coordinate-column form.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `source` | `CRS - like` | Source and target CRS-like inputs. | *required* |
| `target` | `CRS - like` | Source and target CRS-like inputs. | *required* |
| `x` | `float or sequence of float` | Coordinate columns (scalars transform a single point). | *required* |
| `y` | `float or sequence of float` | Coordinate columns (scalars transform a single point). | *required* |
| `z` | `float or sequence of float` | Vertical column for 3D transforms. | `None` |
| `t` | `float or sequence of float` | Coordinate epoch column. | `None` |
| `area_of_interest` | `sequence of float, dict, or object` | Area of interest guiding operation selection, as `(west, south, east, north)` in DEGREES, an area mapping, or an AreaOfInterest-like object. | `None` |
| `source_epoch` | `numeric scalar or 0-D numeric array` | Coordinate epochs for dynamic CRS. | `None` |
| `target_epoch` | `numeric scalar or 0-D numeric array` | Coordinate epochs for dynamic CRS. | `None` |
| `authority` | `str` | Restrict candidate coordinate operations to this authority (e.g. `'EPSG'`). | `None` |
| `accuracy` | `float` | Maximum acceptable operation accuracy, in meters. | `None` |
| `allow_ballpark` | `bool` | Allow low-accuracy ballpark operations when no precise one exists. | `None` |
| `only_best` | `bool` | Require PROJ's best operation. If a required transformation grid is unavailable, raise `TransformError` instead of using a less accurate fallback operation. | `None` |
| `force_over` | `bool` | Keep coordinates on the source side of the antimeridian instead of wrapping into `[-180, 180]` (PROJ `FORCE_OVER=YES`). Like `only_best`, this also collapses operation selection to a single candidate, so enumerating surfaces return exactly one operation. | `False` |

Returns:

| Type | Description |
| --- | --- |
| `tuple or ndarray` | Scalars in, scalars out: `(x, y)` or `(x, y, z)`. Lane input returns a read-only `(N, 2)`/`(N, 3)` `float64` matrix (interleaved, the same shape as a NumPy matrix exported from `geometry.coords`), so `result[:, 0]` / `result[:, 1]` read the transformed columns directly. The input epoch `t` is not a transformed spatial ordinate and is not returned (use `apply` if you need the raw columns echoed back). |

Raises:

| Type | Description |
| --- | --- |
| `CRSError` | If `source`/`target` are unrecognized. |
| `TransformError` | If the transform is undefined or fails to apply. |
| `InvalidGeometryError` | If coordinate columns are non-finite or differ in length. |
| `GeometryError` | If an epoch option is invalid. |

See Also

[Geometry.to\_crs](https://gometry.monicz.dev/api/geometry/geometry/#gometry.Geometry.to_crs "to_crs") : Reproject a geometry.

Examples:

```pycon
>>> import gometry as gm
>>> import numpy as np
>>> np.round(np.asarray(gm.crs_transform(4326, 3857, -122.4, 37.8)), 1).tolist()
[-13625505.7, 4551210.9]
```

## crs\_transform\_bounds

Accepted call forms

```python
crs_transform_bounds(source: CrsInput, target: CrsInput, bounds: tuple[float, float, float, float], *, densify: int = 21, area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> tuple[float, float, float, float]
```

```python
crs_transform_bounds(source: CrsInput, target: CrsInput, bounds: tuple[float, float, float, float, float, float], *, densify: int = 21, area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> tuple[float, float, float, float, float, float]
```

```python
crs_transform_bounds(source: CrsInput, target: CrsInput, bounds: NDArray[floating[Any]], *, densify: int = 21, area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> tuple[float, float, float, float] | tuple[float, float, float, float, float, float] | NDArray[float64]
```

```python
crs_transform_bounds(source: CrsInput, target: CrsInput, bounds: Iterable[tuple[float, float, float, float]] | Iterable[tuple[float, float, float, float, float, float]], *, densify: int = 21, area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> NDArray[float64]
```

```python
crs_transform_bounds(source: CrsInput, target: CrsInput, bounds: Iterable[float], *, densify: int = 21, area_of_interest: CrsAreaInput | None = None, source_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, target_epoch: SupportsFloat | SupportsIndex | FloatScalar | ScalarFloatArray | None = None, authority: str | None = None, accuracy: float | None = None, allow_ballpark: bool | None = None, only_best: bool | None = None, force_over: bool = False) -> tuple[float, float, float, float] | tuple[float, float, float, float, float, float]
```

Reproject a bounding box, densifying edges for accuracy.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `source` | `CRS - like` | Source and destination CRS-like inputs. | *required* |
| `target` | `CRS - like` | Source and destination CRS-like inputs. | *required* |
| `bounds` | `sequence of float or iterable of sequences of float` | A scalar box is a 4-value `(minx, miny, maxx, maxy)` sequence or a 6-value `(minx, miny, minz, maxx, maxy, maxz)` sequence in the source CRS. A batch is a nonempty iterable of 4- or 6-value rows; every row must have the same dimensionality. One-dimensional NumPy arrays supply scalar bounds and two-dimensional NumPy arrays supply batch rows. Batch row order is preserved. | *required* |
| `densify` | `int` | Points added per edge before transforming, to track curved edges. Must be a non-boolean, nonnegative integer that fits in `u32`. For a non-identity transform it must be at most 10,000; if the target CRS is geographic, it must also be at least 2. Identity transforms do not sample bounds and skip these transform-specific limits. | `21` |
| `area_of_interest` | `sequence of float, dict, or object` | Area of interest guiding operation selection, as `(west, south, east, north)` in DEGREES, an area mapping, or an AreaOfInterest-like object. | `None` |
| `source_epoch` | `numeric scalar or 0-D numeric array` | Coordinate epochs for dynamic CRS. | `None` |
| `target_epoch` | `numeric scalar or 0-D numeric array` | Coordinate epochs for dynamic CRS. | `None` |
| `authority` | `str` | Restrict candidate coordinate operations to this authority (e.g. `'EPSG'`). | `None` |
| `accuracy` | `float` | Maximum acceptable operation accuracy, in meters. | `None` |
| `allow_ballpark` | `bool` | Allow low-accuracy ballpark operations when no precise one exists. | `None` |
| `only_best` | `bool` | Require PROJ's best operation. If a required transformation grid is unavailable, raise `TransformError` instead of using a less accurate fallback operation. | `None` |
| `force_over` | `bool` | Keep coordinates on the source side of the antimeridian instead of wrapping into `[-180, 180]` (PROJ `FORCE_OVER=YES`). Like `only_best`, this also collapses operation selection to a single candidate, so enumerating surfaces return exactly one operation. Bounds use literal longitude values in this mode: geographic source bounds sample the closed numeric segment between west and east, and geographic target bounds return numeric longitude extrema rather than a periodic cover. Literal identity bounds retain out-of-period values; descending source longitudes use the segment between their sorted endpoints. | `False` |

Returns:

| Type | Description |
| --- | --- |
| `tuple or ndarray` | The reprojected box in the target CRS. Scalar input returns a 4- or 6-value tuple. Batch input returns a `float64` array of shape `(n, 4)` or `(n, 6)` in input row order. |

Raises:

| Type | Description |
| --- | --- |
| `TransformError` | If no transform exists between the frames or it fails to apply. |
| `CRSError` | If `source`/`target` are unrecognized, or a non-identity transform has `densify` above 10,000 or below 2 for a geographic target. |
| `GeometryError` | If a bounds box does not contain four or six finite values, a batch is empty, batch rows have inconsistent dimensions, or `densify` is outside the nonnegative `u32` range. |
| `TypeError` | If `bounds` is not iterable or `densify` is not an integer index value (`bool` is not accepted). |
| `OverflowError` | If `densify` is outside the signed 64-bit input range. |

Examples:

```pycon
>>> import gometry as gm
>>> import numpy as np
>>> np.round(np.asarray(gm.crs_transform_bounds(
...     4326, 3857, (-123, 37, -122, 38))), 0).tolist()
[-13692297.0, 4439107.0, -13580978.0, 4579426.0]
```

## crs\_unit

```python
crs_unit(authority: str, code: str) -> CrsUnitInfo
```

Detail record for a single unit of measure.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `authority` | `str` | Unit authority and code (e.g. `'EPSG'`, `'9001'`). | *required* |
| `code` | `str` | Unit authority and code (e.g. `'EPSG'`, `'9001'`). | *required* |

Returns:

| Type | Description |
| --- | --- |
| `dict` | The unit-of-measure record (name, category, conversion factor). |

Examples:

```pycon
>>> import gometry as gm
>>> gm.crs_unit('EPSG', '9001')['name']
'metre'
```

## crs\_units

```python
crs_units(authority: str, *, category: str | None = None, allow_deprecated: bool = False) -> list[CrsUnitInfo]
```

List the units of measure an authority defines.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `authority` | `str` | Unit authority (e.g. `'EPSG'`). | *required* |
| `category` | `str` | Restrict to one unit category (e.g. `'linear'`, `'angular'`). | `None` |
| `allow_deprecated` | `bool` | Whether deprecated units are included. | `False` |

Returns:

| Type | Description |
| --- | --- |
| `list` | One record per matching unit of measure. |

Examples:

```pycon
>>> import gometry as gm
>>> gm.crs_units('EPSG')[0]['name']
'(bin)'
```

## crs\_utm\_zones

```python
crs_utm_zones(*, datum_name: str | None = None, area_of_interest: CrsAreaInput | None = None, contains_area_of_interest: bool = False, allow_deprecated: bool = False) -> list[CrsCatalogInfo]
```

UTM-zone CRS from the catalog.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `datum_name` | `str` | Restrict to projected CRSs whose displayed name starts with this datum prefix followed by `" / UTM zone "`. Matching is ASCII case-insensitive, but spaces and punctuation are significant. For example, use `"WGS 84"`, `"NAD83(CSRS)"`, or `"ETRS89/DREF91/2016"`. Only CRSs named `"UTM zone"` are included; arbitrary substrings and long datum descriptions do not match. | `None` |
| `area_of_interest` | `sequence of float, dict, or object` | Filter area as `(west, south, east, north)` in DEGREES, an area mapping, or an AreaOfInterest-like object. | `None` |
| `contains_area_of_interest` | `bool` | Require the zone area to contain `area_of_interest` (default `False`). | `False` |
| `allow_deprecated` | `bool` | Include deprecated zones (default `False`). | `False` |

Returns:

| Type | Description |
| --- | --- |
| `list of CrsCatalogInfo` |  |

Examples:

```pycon
>>> import gometry as gm
>>> gm.crs_utm_zones()[0]['code']
'10286'
```
