nord-sahara-wgs84
Converts coordinates between Nord Sahara 1959 (EPSG:4307), the classic Algerian datum on the Clarke 1880 (RGS) ellipsoid, and WGS 84, and to and from the UTM zones 29N–32N on both datums. It is a small pure-Python library and CLI with no runtime dependencies. Every number is checked against PROJ.
Install
pip install nord-sahara-wgs84 # or: uv tool install nord-sahara-wgs84
uvx --from nord-sahara-wgs84 ns59 convert --from ns59 --to wgs84 3.0588 36.7538 # run without installing
This installs the nord_sahara_wgs84 module and the ns59 command (Python 3.13+).
Quick start (from a checkout)
uv sync
uv run ns59 convert --from ns59 --to wgs84 3.0588 36.7538 # lon lat
# 3.058054140 36.753905322
uv run ns59 convert --from ns59-utm31 --to wgs84-utm31 -v 500000 4070000
uv run ns59 convert --from 30732 --to 4326 --op auto 712000 3530000 # best local operation
printf "x,y,name\n500000,4000000,well-1\n" | uv run ns59 convert --from 30731 --to 32631 --csv
uv run ns59 ops # published transformations
uv run ns59 crs # supported CRSs
uv run pytest # tests (needs the dev dependency pyproj)
from nord_sahara_wgs84 import convert, ns59_to_wgs84
r = convert(500000, 4070000, "EPSG:30731", "EPSG:32631") # easting/northing in, out
print(r.x, r.y, r.operation.name)
lat, lon, h = ns59_to_wgs84(36.7538, 3.0588, op=1253) # pick an EPSG operation
Axis order is always x/y, so (lon, lat) or (easting, northing), like PROJ's
always_xy=True. The lower-level ns59_to_wgs84 / wgs84_to_ns59 take
(lat, lon).
Supported CRSs: EPSG:4307, 4326, 30729–30732 (Nord Sahara 1959 / UTM 29–32N)
and 32629–32632 (WGS 84 / UTM 29–32N). Aliases such as ns59, wgs84,
ns59-utm31 and wgs84-utm32 also work.
The transformations
The EPSG dataset publishes no grid (NTv2 or similar) for Nord Sahara 1959, only Helmert parameter sets. All of them are included, with the values exactly as published:
| EPSG | name | method | accuracy | area of use |
|---|---|---|---|---|
| 10296 (default) | Nord Sahara 1959 to WGS 84 (11) | Position Vector, 7 param. | 1 m | Algeria |
| 5660 | … (9) | Position Vector, 7 param. | 1 m | Algeria |
| 1815 | … (4) | Position Vector, 7 param. | 5 m | District 3 |
| 5630 | … (8) | Geocentric translations | 5 m | Ahnet licence area |
| 15874 | … (7) | Geocentric translations | 5 m | Hassi Mouina licence area |
| 1253 | … (1) | Geocentric translations | 44 m | Algeria onshore |
| 1255 | … (2) | Geocentric translations | 44 m | Algeria north of 32°N |
| 1816 | … (5) | Geocentric translations | 100 m | In Amenas |
| 1817 | … (6) | Geocentric translations | 100 m | Hassi Bir Reikaz |
| 7442 | … (10) | Geocentric translations | 100 m | Ain Tsila |
The default (10296) is also what PROJ ranks first for this pair. --op auto
picks the most accurate operation whose area of use contains the point. The
published accuracy is how well the parameters reproduce the real
relationship between the datums. It is not a property of this code.
How it works
- UTM → geographic on the source ellipsoid, if needed. Transverse Mercator uses Krüger's series to order n⁶ in Karney's (2011) formulation. That is nanometre-accurate in the zone and sub-millimetre several degrees outside it.
- Geographic → geocentric (ECEF) on Clarke 1880 (RGS): a = 6 378 249.145 m, 1/f = 293.465.
- Helmert in ECEF. EPSG 9606 (position vector) uses the linearised rotation matrix, rotations in arc-seconds and scale in ppm. EPSG 9603 uses translations only. The reverse direction applies the transposed matrix, as PROJ does.
- Geocentric → geographic on WGS 84 (Bowring start plus fixed-point iteration), then → UTM if needed.
As in EPSG and PROJ, these operations work in the geog2D domain. The input ellipsoidal height feeds the geocentric step but comes back unchanged, so heights are not transformed.
Tests
uv run pytest runs 52 tests, including one doctest:
- every operation, forward and reverse, against PROJ at 200 random points across Algeria each (tolerance 1e-9° ≈ 0.1 mm)
- geocentric conversions on both ellipsoids against
+proj=cart(1 µm) - UTM 29–32N on both datums against PROJ, inside and up to 3° outside each zone (1 mm), plus inverse round trips
- projected → projected across datums against a PROJ pipeline
- the default operation against PROJ's own choice
- the CLI (single point, CSV batch with pass-through columns, errors)
Results agree with PROJ to about 1e-12°. The round trip NS59 → WGS 84 → NS59 is only good to a few millimetres, because the height is not carried through the shift and the linearised rotation is not exactly orthogonal. PROJ behaves the same way.
Status and limitations
- Only the CRSs listed above are supported. The Lambert projections Nord Algérie / Sud Algérie (EPSG:30791/30792) and Voirol 1875/1879 are not included yet.
- There is no vertical datum handling: heights are ellipsoidal and passed through.
- UTM zone exceptions (Norway/Svalbard) are irrelevant here and not handled.
- Pure Python and slow for millions of points. Use PROJ/pyproj for bulk work. This project exists to show the maths plainly.
Data sources and license
Code: MIT, see LICENSE.
The transformation parameters, ellipsoid constants, CRS definitions and areas of use come from the EPSG Geodetic Parameter Dataset (IOGP), read from the copy distributed with PROJ 9.8. Under the EPSG terms of use the data may be used and redistributed, but the dataset is © IOGP and must not be modified and presented as EPSG data. See https://epsg.org/terms-of-use.html. pyproj and PROJ (MIT) are used only as test oracles.
Metadata
Release files for nord-sahara-wgs84 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| nord_sahara_wgs84-0.1.0.tar.gz | 13.5 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nord_sahara_wgs84-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 30.4 kB
Release files / nord_sahara_wgs84-0.1.0.tar.gz
| Download URL | nord_sahara_wgs84-0.1.0.tar.gz |
|---|---|
| Size | 13.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
80a4e8d76a3724bde00bfd419e3cf69355f705a67d2930b49783cded0fc889f0
|
|
BLAKE2b-256 checksum How to use checksums |
28ff4485b5a543ebc3caac37b1569ef597df9dd0a1e281ab069ca127af8ea010
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency logRelease files / nord_sahara_wgs84-0.1.0-py3-none-any.whl
| Download URL | nord_sahara_wgs84-0.1.0-py3-none-any.whl |
|---|---|
| Size | 16.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
db204719a4133860791e906b016008b247d3c70198033d7dc999d1f78a7c46ba
|
|
BLAKE2b-256 checksum How to use checksums |
f4cd3db815658b60cf453b7e57853653ef5daa6dc495806b62b6c1d07b7f5806
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency logSecurity for nord-sahara-wgs84 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for nord_sahara_wgs84-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.