OperationCandidate

class geodetic_engine.geodesy.OperationCandidate[source]

Bases: object

One coordinate operation PROJ offers for a CRS pair, not yet applied.

Listed by geodetic_engine.geodesy.transformation.available_operations(), this package’s equivalent of inspecting a pyproj.transformer.TransformerGroup directly. Nothing here has been checked against a request or applied to coordinates; it is information to choose an operation= argument from, not a result.

A candidate is not always a single registered operation. A registered concatenated operation such as EPSG:8047 applies two Helmerts and still has its own code, because the authority publishes the chain itself. But when PROJ has to assemble a chain of its own to span the pair – which a bound CRS on either side reliably causes – no authority code names the result, so auth_name, code and method_name are all None. Either way steps lists the operations actually applied, and passing the candidate as operation= pins down every one of them; see references.

auth_name

Authority of the operation, for example "EPSG", or None when no authority publishes this chain as one operation.

code

Code of the operation, or None in that same case.

name

Name of the operation. For an unregistered chain, the step names joined with " + ".

method_name

Name of the operation method, or None when the candidate applies more than one operation.

accuracy

Stated accuracy in metres, or None when PROJ reports none.

area_of_use

The area the operation is valid for, with its bounding box, or None.

ballpark

Whether this candidate is a ballpark approximation.

requires_epoch

Whether applying it would need a coordinate epoch.

grids

Grid files it depends on. Not all need be installed.

usable

Whether it could be applied right now: not a ballpark, and every grid it depends on is installed.

steps

The substantive operations this candidate applies, in pipeline order, excluding the axis-order bookkeeping PROJ inserts around them. Always at least one.

projjson

PROJJSON of the pipeline PROJ would build. Read it through to_json_dict() or to_wkt() rather than directly.

property authority_code: str | None

"AUTH:CODE" of the operation as a whole, or None if it has none.

A registered concatenated operation such as EPSG:8047 has one even though it applies two Helmerts, because the authority publishes the chain itself under that code. A chain PROJ assembled on its own, which a bound CRS on either side of the pair causes, has none: reporting the first step’s code for it would understate what is being applied by a whole datum shift. Use references in that case.

property is_chained: bool

Whether this candidate applies more than one substantive operation.

True for a registered concatenated operation as well as for an unregistered chain, so it does not by itself say whether the candidate has an authority_code.

property references: tuple[str, ...]

This candidate as operation= references.

A single entry – the authority_code, or the name if there is none – whenever one reference names the whole candidate. Otherwise one entry per step, since an unregistered chain can only be pinned down by naming every operation in it. Passing the candidate object as operation= expands to exactly this.

Example

>>> candidate = OperationCandidate(
...     auth_name="EPSG", code="1133", name="ED50 to WGS 84 (1)",
...     method_name=None, accuracy=10.0, area_of_use=None,
...     ballpark=False, requires_epoch=False, grids=(), usable=True,
...     steps=(OperationStep("EPSG", "1133", "ED50 to WGS 84 (1)", None),),
... )
>>> candidate.references
('EPSG:1133',)
to_json_dict()[source]

Export the pipeline PROJ would build for this candidate as PROJJSON.

This is the whole pipeline as PROJ assembled it, not the registry’s entry for authority_code: it includes the source and target CRS, every step, and the axis-order bookkeeping PROJ inserts to meet this package’s xy value order. That last part is why the name inside carries PROJ’s “(with axis order normalized for visualization)” annotation while name does not.

Return type:

dict[str, Any] | None

Returns:

The PROJJSON as a dict, or None where PROJ gave the candidate none or the pipeline cannot be exported faithfully because a step is applied inverted (see has_inverted_step). The raw text is still on projjson for anyone who needs to inspect it knowing that caveat.

Example

>>> from geodetic_engine.geodesy import available_operations
>>> candidate = available_operations("EPSG:4230", "EPSG:4326")[0]
>>> candidate.to_json_dict()["type"]
'ConcatenatedOperation'
to_wkt(*, pretty=False)[source]

Export the pipeline PROJ would build for this candidate as WKT2.

Rendered from what PROJ assembled rather than looked up by code, so it also works for a candidate the EPSG dataset does not define, such as a chain across two bound CRSs. The consequence is that the registry’s descriptive metadata is not present: expect the method, parameters and ID, but no VERSION, USAGE or REMARK. Read the parameters from here; read the scope and area of validity from the EPSG dataset via authority_code, or from area_of_use.

Parameters:

pretty (bool, default: False) – Whether to indent the output over several lines.

Return type:

str | None

Returns:

The WKT2 of the candidate, or None where it cannot be exported faithfully: either PROJ built something that is not a coordinate operation in its own right, or a step is applied inverted and WKT2 cannot say so (see has_inverted_step). Transform a point and read pipeline in the latter case, which keeps the inversion explicit.

Example

>>> from geodetic_engine.geodesy import available_operations
>>> candidate = available_operations("EPSG:4230", "EPSG:4326")[0]
>>> candidate.to_wkt()[:21]
'CONCATENATEDOPERATION'
__init__(auth_name, code, name, method_name, accuracy, area_of_use, ballpark, requires_epoch, grids, usable, steps=(), projjson='')