Supported Projections¶
vibeProj supports 24 coordinate projections. Each has both a NumPy/CuPy element-wise implementation and a fused NVRTC GPU kernel.
Projection table¶
Projection |
Internal Name |
EPSG Examples |
Notes |
|---|---|---|---|
Transverse Mercator / UTM |
|
32601–32760, 27700 |
6th-order Krueger series |
Web Mercator |
|
3857 |
Spherical Mercator |
Mercator (ellipsoidal) |
|
3395 |
Variant A/B |
Lambert Conformal Conic |
|
2154 |
1SP and 2SP |
Albers Equal Area |
|
5070 |
Conic equal-area |
Polar Stereographic |
|
3031, 3413 |
Variants A/B/C |
Lambert Azimuthal Equal Area |
|
3035 |
Oblique/equatorial/polar |
Oblique Stereographic |
|
28992 |
Double projection via conformal sphere |
Plate Carree |
|
4087 |
Equidistant cylindrical |
Sinusoidal |
|
– |
Pseudocylindrical equal-area |
Equal Earth |
|
8857 |
Spherical or ellipsoidal authalic form |
Cylindrical Equal Area |
|
6933 |
EASE-Grid 2.0 |
Orthographic |
|
– |
Globe view |
Gnomonic |
|
– |
Great circle navigation |
Mollweide |
|
– |
Equal-area world maps |
Robinson |
|
– |
Compromise world maps |
Winkel Tripel |
|
– |
National Geographic standard |
Natural Earth |
|
– |
Polynomial pseudocylindrical |
Azimuthal Equidistant (spherical) |
|
– |
Requires an explicit spherical CRS ( |
Geostationary Satellite |
|
– |
Sweep X/Y and custom satellite height |
Oblique Mercator (Hotine) |
|
3375 |
Variants A/B |
Krovak |
|
5513, 5514 |
Regular Southing/Westing and north-oriented Easting/Northing |
Eckert IV |
|
– |
Pseudocylindrical equal-area |
Eckert VI |
|
– |
Pseudocylindrical equal-area |
Using projections via EPSG codes¶
Most projections are resolved automatically from EPSG codes via pyproj:
from vibeproj import Transformer
# UTM Zone 31N
t = Transformer.from_crs("EPSG:4326", "EPSG:32631")
# Netherlands national grid (oblique stereographic)
t = Transformer.from_crs("EPSG:4326", "EPSG:28992")
# LAEA Europe
t = Transformer.from_crs("EPSG:4326", "EPSG:3035")
Using projections without EPSG codes¶
Some projections (orthographic, gnomonic, etc.) don’t have standard EPSG codes. Use them via the pipeline API directly:
from vibeproj.crs import ProjectionParams
from vibeproj.ellipsoid import WGS84
from vibeproj.pipeline import TransformPipeline
# Orthographic centered on Paris
params = ProjectionParams(
projection_name="ortho",
ellipsoid=WGS84,
lon_0=2.35,
lat_0=48.86,
north_first=False,
)
src = ProjectionParams(projection_name="longlat", ellipsoid=WGS84, north_first=True)
pipe = TransformPipeline(src, params)
x, y = pipe.transform(lat_array, lon_array, np) # or cp for GPU
Gnomonic is spherical-only. Define it with an explicit spherical ellipsoid
(+R in a CRS definition, or SPHERE in ProjectionParams). Ellipsoidal
Gnomonic definitions raise UnsupportedProjectionError; vibeProj does not
silently substitute spherical equations. Forward points at or behind the
horizon are outside the projection domain and return non-finite coordinates,
matching PROJ. The inverse remains stable at the projection center and for
very large finite projected radii.
Sinusoidal supports both explicit spherical definitions and ellipsoidal CRS
definitions such as ESRI:54008; the ellipsoidal path uses meridional distance
and the ellipsoidal prime-vertical radius in both CPU and fused CUDA execution.
The seventh-order meridional series is supported for finite eccentricity squared
in the inclusive range 0 <= es <= 0.012 and finite positive semi-major axes
no larger than 6,400,000 m. This covers terrestrial Earth and Mars ellipsoids.
More eccentric or larger custom bodies raise UnsupportedProjectionError
during projection setup instead of returning an unqualified approximation.
Mercator honors the declared scale factor for variant A and derives the scale
at the natural origin from the standard parallel for variant B (for example,
EPSG:3994 and EPSG:3388).
Spherical Azimuthal Equidistant is available with an explicit radius, for
example +proj=aeqd +lat_0=45 +lon_0=0 +R=6378137 +type=crs. Ellipsoidal
Azimuthal Equidistant, Modified Azimuthal Equidistant, and Guam Projection are
not implemented. Constructing a Transformer for those methods raises
UnsupportedProjectionError; they never silently execute spherical formulas.
Geostationary CRS definitions retain both +sweep=x and +sweep=y plus the
declared satellite height +h. Height must be positive and no more than
1e10 equatorial radii. Forward points behind the visible ellipsoid limb and
inverse points outside the Earth-intersection disk or principal scan-angle
range return non-finite sentinels.
Krovak uses one north-oriented mathematical core for both public variants.
EPSG:5514 exposes Easting/Northing. EPSG:5513 applies the declared negative
axes and exposes X=Southing, Y=Westing. Because those are explicit X/Y axes,
PROJ visualization order—and therefore always_xy=True—keeps Southing first
and Westing second rather than relabeling them as conventional E/N. Krovak’s
false easting and northing parameters follow its method-specific subtractive
convention; metre and non-metre units retain positive public unit factors.
For custom nonzero offsets, vibeProj matches PROJ forward coordinates and
applies the same convention symmetrically in inverse transforms, so its inverse
exactly undoes its forward result. This intentionally avoids the asymmetric
custom-offset inverse behavior exposed by legacy PROJ pipelines through 9.5.
The authoritative EPSG:5513 and EPSG:5514 definitions use zero offsets and are
unaffected by this compatibility distinction.
Datum shifting¶
When the source and destination CRS use different geodetic datums or reference frames, vibeProj asks pyproj/PROJ for the coordinate-operation plan instead of guessing from ellipsoid parameters. If the selected or best supported operation contains a Helmert step, vibeProj applies a Helmert 7-parameter transformation automatically.
# Cross-datum: WGS84 -> British National Grid (OSGB36 / Airy 1830)
t = Transformer.from_crs("EPSG:4326", "EPSG:27700")
x, y = t.transform(-0.1278, 51.5074)
print(t.accuracy) # "sub-meter"
Helmert parameters are extracted from pyproj’s EPSG database at construction time; the actual datum shift math runs on vibeProj’s own GPU kernels (or NumPy on CPU). Same-datum transforms have zero overhead. Some datum pairs, such as common WGS84/NAD83 operations, are also represented by PROJ as explicit no-op operations with meter-level expected accuracy; vibeProj keeps those no-op transforms but reports them separately from same-datum sub-millimeter transforms.
15-parameter time-dependent Helmert is also supported for sub-decimeter
accuracy on modern datum pairs (e.g. ITRF to ETRS89). Pass an explicit
epoch or let vibeProj resolve it from the source CRS coordinate epoch:
t = Transformer.from_crs("EPSG:4326", "EPSG:27700", epoch=2024.0)
print(t.accuracy) # "sub-decimeter" when 15-param rates are present
SVD-compressed datum corrections¶
For datum pairs where Helmert alone is insufficient (e.g. NAD27 to NAD83), vibeProj includes baked SVD-compressed corrections fitted from public domain grid data (NADCON5). These are applied automatically as an additive correction after the Helmert shift, achieving sub-5cm accuracy without external grid files.
# NAD27 → NAD83 (SVD correction applied automatically)
t = Transformer.from_crs("EPSG:4267", "EPSG:4269")
x, y = t.transform(-90.0, 40.0)
print(t.accuracy) # "sub-5cm"
Currently baked pairs:
NAD27 to NAD83 (CONUS) — rank-10 SVD, P95 accuracy 0.15 cm vs pyproj
For datum pairs without a baked SVD correction or Helmert parameters, vibeProj
emits a RuntimeWarning and falls back to projection math without a datum
shift. Results may differ from pyproj by meters to hundreds of meters in these
cases.
Not yet supported:
Raw NTv2 / NADCON grid loading — vibeProj does not load external grid files at runtime. Datum pairs not covered by baked SVD corrections or Helmert fall back to no datum shift. Use pyproj or rasterio directly if you need coverage beyond the baked pairs.
Known limitations¶
Oblique Stereographic (
sterea): The double-projection through a conformal sphere introduces ~130m systematic offset from pyproj’s more rigorous method in the forward direction. The inverse conformal sphere conversion has a known accuracy limitation (~0.2 degrees). Roundtrip accuracy is sub-millimetre.Winkel Tripel (
wintri): The inverse uses Newton iteration and converges to ~0.005 degrees rather than machine precision.