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 |
Polynomial pseudocylindrical |
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 |
|
– |
Distance-from-center |
Geostationary Satellite |
|
– |
Weather satellite view |
Oblique Mercator (Hotine) |
|
3375 |
Variants A/B |
Krovak |
|
5514 |
North-orientated variant |
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
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¶
Equal Earth (
eqearth): Uses the spherical polynomial formula on geodetic latitude rather than converting to authalic latitude first. This means absolute metre values differ from pyproj by ~15%. Roundtrip accuracy is exact (forward and inverse are self-consistent).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.Geostationary (
geos): The inverse has limited accuracy for off-nadir points due to a simplified geocentric latitude conversion.Winkel Tripel (
wintri): The inverse uses Newton iteration and converges to ~0.005 degrees rather than machine precision.