vibeproj

vibeProj — GPU-accelerated coordinate projection library.

Submodules

Attributes

Exceptions

CoordinateValidationError

Raised when input coordinates are invalid (wrong shape, dtype, etc.).

CRSResolutionError

Raised when a CRS input cannot be parsed or resolved.

UnsupportedProjectionError

Raised when a CRS uses a projection method vibeProj doesn't support.

VibeProjectionError

Base exception for vibeProj errors.

Classes

Transformer

GPU-accelerated coordinate transformer.

Functions

list_projections(→ dict[str, dict])

Return supported projections and their metadata.

warm_up(→ None)

Pre-compile fused NVRTC kernels to eliminate first-call latency.

Package Contents

type vibeproj.CRSInput = int | str | tuple[str, int] | CRS
exception vibeproj.CoordinateValidationError

Bases: VibeProjectionError

Raised when input coordinates are invalid (wrong shape, dtype, etc.).

exception vibeproj.CRSResolutionError

Bases: VibeProjectionError

Raised when a CRS input cannot be parsed or resolved.

exception vibeproj.UnsupportedProjectionError

Bases: VibeProjectionError

Raised when a CRS uses a projection method vibeProj doesn’t support.

exception vibeproj.VibeProjectionError

Bases: Exception

Base exception for vibeProj errors.

class vibeproj.Transformer(crs_from: vibeproj.crs.CRSInput, crs_to: vibeproj.crs.CRSInput, *, always_xy: bool = True, datum_shift: Literal['accurate', 'fast'] = 'accurate', epoch: float | None = None)

GPU-accelerated coordinate transformer.

  • transform(x, y) where x=lon, y=lat for geographic CRS (always_xy=True default)

  • direction=”FORWARD” or “INVERSE”

  • Accepts scalars, lists, numpy arrays, or cupy arrays

When CuPy is available and inputs are on GPU, transforms run on GPU. Otherwise falls back to NumPy on CPU.

Thread Safety

Transformer instances are safe to share across threads. The internal kernel cache uses an RLock to serialize NVRTC compilation on first use; subsequent calls are lock-free. Call compile() at startup to front-load compilation if you want deterministic latency.

static from_crs(crs_from: vibeproj.crs.CRSInput, crs_to: vibeproj.crs.CRSInput, *, always_xy: bool = True, datum_shift: Literal['accurate', 'fast'] = 'accurate', epoch: float | None = None) Transformer

Create a Transformer from source and target CRS.

Parameters

crs_from, crs_to :

EPSG integer (4326), string (“EPSG:4326”), or tuple ((“EPSG”, 4326)).

always_xybool, default True

If True, input/output axis order is always (x, y) — i.e. (longitude, latitude) for geographic CRS and (easting, northing) for projected CRS. This matches shapely and geopandas conventions. If False, uses the CRS native axis order (pyproj default).

datum_shiftstr, default “accurate”

“accurate” — use 15-parameter time-dependent Helmert when available, evaluating rate terms at the given epoch. Falls back to 7-parameter when no rates are present or no epoch can be resolved. “fast” — always use the base 7-parameter Helmert (ignores rate terms).

epochfloat, optional

Decimal year at which to evaluate the time-dependent Helmert (e.g. 2024.0). Only used when datum_shift=”accurate”. If omitted, the source CRS coordinate epoch is used when available.

property is_fused: bool

True if fused GPU kernels are available for this transform.

property accuracy: str

Rough accuracy classification for this transform.

Returns

str

“sub-millimeter” — same datum, projection math only. “sub-decimeter” — cross-datum with 15-param time-dependent Helmert evaluated at a known epoch. “sub-meter” — cross-datum with 7-param Helmert. “degraded — no datum shift applied” — different datums; results may differ from pyproj by meters to hundreds of meters.

compile(*, precision: str = 'auto') None

Pre-compile fused NVRTC kernels for this transformer.

Call this to front-load kernel compilation latency before the first transform. No-op if CuPy is not available.

transform(x: numpy.typing.ArrayLike, y: numpy.typing.ArrayLike, z: None = None, direction: Literal['FORWARD', 'INVERSE'] = 'FORWARD') tuple[Any, Any]
transform(x: numpy.typing.ArrayLike, y: numpy.typing.ArrayLike, z: numpy.typing.ArrayLike, direction: Literal['FORWARD', 'INVERSE'] = 'FORWARD') tuple[Any, Any, Any]

Transform coordinates.

Parameters

x, yscalar, list, numpy array, or cupy array

Input coordinates. With always_xy=True (default): x=longitude, y=latitude for geographic CRS. With always_xy=False: native CRS axis order.

zscalar, list, numpy array, or cupy array, optional

Ellipsoidal height in meters. When a Helmert datum shift is active, z is transformed through the ECEF intermediate (correctness fix). When no datum shift is needed, z is passed through unchanged.

directionstr

“FORWARD” or “INVERSE”.

Returns

tuple of arrays (or scalars if scalar input)

Transformed (x, y) or (x, y, z) if z was provided.

transform_buffers(x: numpy.typing.ArrayLike, y: numpy.typing.ArrayLike, z: None = None, *, direction: Literal['FORWARD', 'INVERSE'] = 'FORWARD', out_x: numpy.typing.ArrayLike | None = None, out_y: numpy.typing.ArrayLike | None = None, out_z: numpy.typing.ArrayLike | None = None, precision: str = 'auto', stream: Any = None) tuple[Any, Any]
transform_buffers(x: numpy.typing.ArrayLike, y: numpy.typing.ArrayLike, z: numpy.typing.ArrayLike, *, direction: Literal['FORWARD', 'INVERSE'] = 'FORWARD', out_x: numpy.typing.ArrayLike | None = None, out_y: numpy.typing.ArrayLike | None = None, out_z: numpy.typing.ArrayLike | None = None, precision: str = 'auto', stream: Any = None) tuple[Any, Any, Any]

Zero-overhead transform for device-resident arrays.

Designed for integration with vibeSpatial’s OwnedGeometryArray. Skips scalar detection, dtype conversion, and array module inference.

Parameters

x, ycupy.ndarray or numpy.ndarray

Coordinate arrays (fp64 storage per ADR-0002).

zcupy.ndarray or numpy.ndarray, optional

Ellipsoidal height array. Transformed through Helmert when a datum shift is active; passed through unchanged otherwise.

directionstr

“FORWARD” or “INVERSE”.

out_x, out_ycupy.ndarray or numpy.ndarray, optional

Pre-allocated fp64 output arrays. Avoids allocation.

out_zcupy.ndarray or numpy.ndarray, optional

Pre-allocated fp64 output height array. Only used when z is provided and a Helmert datum shift is active.

precisionstr

“fp64” = full double precision. “fp32” = fp32 compute with fp64 I/O (ADR-0002 mixed precision). “auto” = fp64 (projection math is trig-dominated / SFU-bound).

streamcupy.cuda.Stream, optional

CUDA stream for async kernel execution. Enables overlapping projection compute with data transfers in pipeline workloads.

Returns

tuple of arrays

Transformed (out_x, out_y) or (out_x, out_y, z_out). Same objects if pre-allocated.

transform_chunked(x: numpy.typing.ArrayLike, y: numpy.typing.ArrayLike, z: None = None, *, direction: Literal['FORWARD', 'INVERSE'] = 'FORWARD', chunk_size: int = 1000000) tuple[numpy.ndarray, numpy.ndarray]
transform_chunked(x: numpy.typing.ArrayLike, y: numpy.typing.ArrayLike, z: numpy.typing.ArrayLike, *, direction: Literal['FORWARD', 'INVERSE'] = 'FORWARD', chunk_size: int = 1000000) tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]

Transform large host-resident arrays in GPU-sized chunks.

Uses a double-buffered pipeline with pinned host memory and 2 CUDA streams to overlap H<->D transfers with GPU compute. Each stream owns a dedicated set of device buffers so chunk N can execute on stream A while chunk N+1 transfers on stream B.

Falls back to CPU transform() when CuPy is not available.

Parameters

x, yarray-like

Input coordinate arrays (host memory).

zarray-like, optional

Ellipsoidal height. Transformed through Helmert when a datum shift is active; passed through unchanged otherwise.

directionstr

“FORWARD” or “INVERSE”.

chunk_sizeint, default 1_000_000

Coordinates per GPU chunk. Larger values use more GPU memory but reduce per-chunk overhead.

Returns

tuple of numpy.ndarray

Transformed (x, y) or (x, y, z) on the host.

transform_bounds(left: float, bottom: float, right: float, top: float, *, densify_pts: int = 21, direction: Literal['FORWARD', 'INVERSE'] = 'FORWARD') tuple[float, float, float, float]

Transform a bounding box, densifying edges to handle projection curvature.

Densifies the four edges of the input bounding box, transforms all points, and returns the min/max envelope of the transformed result. This correctly handles non-linear projection distortion that would be missed by transforming only the four corners.

Parameters

left, bottom, right, topfloat

Bounding box coordinates. With always_xy=True (default): left/right are x (longitude), bottom/top are y (latitude).

densify_ptsint, default 21

Number of additional intermediate points per edge (not counting corner endpoints). Matches pyproj/GDAL convention: 0 means corners only, 21 (the default) adds 21 points between each pair of adjacent corners. Clamped to a minimum of 0.

direction{“FORWARD”, “INVERSE”}

Transform direction.

Returns

tuple of four floats

(left, bottom, right, top) of the transformed bounding box.

Notes

Antimeridian-crossing bounding boxes (where left > right in longitude) are not supported. Split into two boxes at ±180° first.

vibeproj.list_projections() dict[str, dict]

Return supported projections and their metadata.

Returns

dict[str, dict]

Keys are internal projection names. Each value has: - “methods”: list of pyproj method names that map to this projection - “fused”: True if a GPU-accelerated fused kernel is available

vibeproj.warm_up(projections: list[str] | None = None, *, precision: str = 'auto') None

Pre-compile fused NVRTC kernels to eliminate first-call latency.

Parameters

projectionslist of str, optional

Projection names to compile (e.g. [“tmerc”, “webmerc”]). If None, compiles all supported projections.

precisionstr

Compute precision: “auto”/”fp64”/”fp32”/”ds”.

Examples

>>> import vibeproj
>>> vibeproj.warm_up(["tmerc", "webmerc"])  # selective
>>> vibeproj.warm_up()                       # all projections