turkgrid
Türkiye için bağımlılıksız koordinat dönüşüm kütüphanesi · Zero-dependency coordinate toolkit for Türkiye
TUREF / ED50 3° TM ve Gauss-Krüger dilimleri · UTM 35N-38N · EPSG:1784 ED50 datum dönüşümü · GeoJSON · CRS tahmini
🇹🇷 Türkçe • 🇬🇧 English • 📦 PyPI • 💻 GitHub • 🐛 Issues
🇹🇷 Türkçe
turkgrid, Türkiye'de harita, imar planı ve kadastro verilerinde kullanılan koordinat
sistemleri arasında saf Python ile dönüşüm yapar. PROJ, GDAL veya pyproj gerekmez;
NumPy kuruluysa diziler vektörel olarak işlenir. Sonuçlar PROJ ile karşılaştırılarak
test edilir (aşağıdaki doğruluk tablosuna bakın).
Kurulum
pip install turkgrid # yalnızca standart kütüphane
pip install "turkgrid[numpy]" # NumPy dizileriyle vektörel dönüşüm
pip install "turkgrid[dev]" # testler: pytest, ruff, mypy, numpy, pyproj
Python 3.9+ gerekir; Windows, macOS ve Linux'ta çalışır.
Hızlı başlangıç
import turkgrid
# TUREF / TM30 (EPSG:5254) -> WGS 84 boylam/enlem
lon, lat = turkgrid.to_wgs84((412000.0, 4542000.0), 5254)
# Eski ED50 / TM30 planını TUREF / TM30'a taşı (EPSG:1784 datum dönüşümü)
x, y = turkgrid.transform((412000.0, 4542000.0), 2320, 5254)
# Dilimden dilime (TM30 -> TM33), yükseklik (z) korunur
pts = turkgrid.transform([(412000.0, 4542000.0, 35.2)], 5254, 5255)
# Türk ölçü pratiği: önce X (yukarı/kuzey), sonra Y (sağa/doğu)
lon, lat = turkgrid.to_wgs84((4542000.0, 412000.0), 5254, axes_swapped=True)
# Boylama göre dilim ve EPSG kodu
turkgrid.zone_for_lon(29.0) # 30 (merkez meridyen)
turkgrid.epsg_for_lon(29.0, "TM", "ED50") # 2320
turkgrid.epsg_info(5254).to_proj4() # '+proj=tmerc +lat_0=0 +lon_0=30 ...'
NumPy dizileri ((N, 2) veya (N, 3)) ya da ayrı x, y dizileri tek çağrıda
dönüştürülür: turkgrid.transform_xy(x_dizisi, y_dizisi, 2320, 5254).
Koordinat sistemi tahmini
Kaynağı belirsiz plan koordinatları için detect_crs her olası sistemi dener ve
gerekçeleriyle sıralı aday listesi döndürür:
for aday in turkgrid.detect_crs(noktalar, near=(29.06, 40.19)): # near: bilinen yer (Bursa)
print(aday.epsg, aday.name, aday.score, aday.axes_swapped, aday.place)
print(" ", "; ".join(aday.reasons))
Koordinatlardan kesin anlaşılabilenler: eksen sırası (X/Y ters mi), Gauss-Krüger
dilim öneki (ör. 10 465 000 → 10. dilim). Anlaşılamayanlar: 500 000 m sabitli bir
TM doğusunun hangi dilime ait olduğu (bütün dilimlere uyar; Türkiye sınırı dışına
düşen okumalar elenir) ve ED50 ile TUREF farkı (≈ 100-200 m). Bu eşitlikleri
bozmak için near=(boylam, enlem) verin; ED50/TUREF ayrımı için bilinen bir noktayı
near_tolerance_m=20 gibi küçük bir toleransla kullanın.
Komut satırı
turkgrid convert --from 5254 --to 4326 412000 4542000
echo "412000 4542000" | turkgrid convert --from 2320 --to 5254
turkgrid detect noktalar.csv --near 29.06,40.19 -v # ; ayraç ve ondalık virgül desteklenir
turkgrid geojson plan.geojson --to 4326 -o plan_wgs84.geojson
turkgrid info 2320
Datum varsayımları
- TUREF = WGS 84. TUREF (ITRF96, 2005.0) ile WGS 84 Türkiye'de birkaç cm içinde örtüşür; EPSG de "TUREF to WGS 84 (1)" (EPSG:5261) dönüşümünü sıfır parametreli tanımlar. turkgrid bunu PROJ ile aynı şekilde uygular.
- ED50 → WGS 84/TUREF: EPSG:1784 "ED50 to WGS 84 (30)", konum vektörü (position vector, EPSG yöntem 9606): tx −84.1, ty −101.8, tz −129.7 m, rz +0.468″, ölçek +1.05 ppm; HGK'nın yayımladığı EPSG:1783 ile aynı değerler; doğruluk 2 m. Ters yön, ileri dönüşümün tam tersidir (gidiş-dönüş nanometre düzeyinde kapanır).
- Yerel dönüşüm parametreleri (ör. belediye nirengi ağı) gerekiyorsa
turkgrid.Helmert7ile kendi 7 parametrenizi uygulayabilirsiniz.
🇬🇧 English
turkgrid converts between the coordinate reference systems used for maps, zoning
plans and cadastre in Türkiye, in pure Python: no PROJ, GDAL or pyproj needed, and
NumPy (optional) vectorises arrays. Every supported pair is tested against PROJ.
Installation
pip install turkgrid # standard library only
pip install "turkgrid[numpy]" # vectorised NumPy array support
pip install "turkgrid[dev]" # pytest, ruff, mypy, numpy, pyproj (for the PROJ tests)
Quickstart
import turkgrid
lon, lat = turkgrid.to_wgs84((412000.0, 4542000.0), 5254) # TUREF / TM30 -> WGS 84
x, y = turkgrid.transform((412000.0, 4542000.0), 2320, 5254) # ED50 / TM30 -> TUREF / TM30
xy = turkgrid.from_wgs84((29.0, 41.0), "EPSG:32635") # WGS 84 -> UTM 35N
pts = turkgrid.transform([(412000.0, 4542000.0, 35.2)], 5254, 5255) # zone to zone, z kept
t = turkgrid.Transformer(2320, 5254) # reusable; t.inverse(), t.description
gj = turkgrid.reproject_geojson(geojson_dict, 4326) # reads a legacy "crs" member
best = turkgrid.detect_crs(points)[0] # candidates with score, axes_swapped, reasons, place
- Coordinates are easting, northing / longitude, latitude. Turkish surveys
often store northing first; pass
axes_swapped=True(andoutput_swapped=True). - Inputs: one point (tuple, extra ordinates kept), a sequence of points (returns a
list), or a NumPy array of shape
(2,)/(N, 2+)(returns a new array).transform_xy(x, y, src, dst)takes floats or arrays. - EPSG codes may be
5254,"5254","EPSG:5254", an OGC URN/URL or"CRS84".
CRS detection
detect_crs(points, near=None, near_tolerance_m=25_000) reads every supported CRS into
the numbers (in both axis orders), projects a sample to WGS 84 and scores each reading
by the share of points that fall in Türkiye (coarse outline plus a ~20 km buffer), the
share inside the CRS's zone, and optional closeness to a known location. Candidates
come back best-first with human-readable reasons, the nearest province centre and
any ties. Axis order and Gauss-Krüger zone prefixes are unambiguous; the zone of a
plain TM easting and the ED50/TUREF datum are not, and stay tied unless near= breaks
the tie (use a surveyed point and a ~20 m tolerance to separate the datums).
Command line
turkgrid convert --from 5254 --to 4326 412000 4542000 # or pipe "x y" lines on stdin
turkgrid detect points.csv [--near lon,lat] [--json] [-v]
turkgrid geojson in.geojson --to 4326 -o out.geojson # --from defaults to the crs member
turkgrid info [EPSG]
Datum assumptions
- TUREF is taken as WGS 84 (they agree to a few centimetres in Türkiye). EPSG:5261 "TUREF to WGS 84 (1)" is a zero-parameter transformation, applied as PROJ does.
- ED50 → WGS 84 / TUREF uses EPSG:1784 "ED50 to WGS 84 (30)", position vector (EPSG method 9606): tx −84.1, ty −101.8, tz −129.7 m, rx = ry = 0, rz +0.468″, scale +1.05 ppm; same values as EPSG:1783 (published by HGK, the Turkish General Directorate of Mapping); stated accuracy 2 m. It is applied on the ellipsoid surface (height 0), like PROJ. The reverse direction is the exact inverse of the forward one (round trips close to nanometres), solved by fixed-point refinement.
- Plain
pyproj.Transformer.from_crs(2320, 5254)may choose another operation (e.g. via ETRS89 with EPSG:5260, a few cm different, or a generic ED50 set metres away) unless an area of interest or the operation is given; turkgrid always uses EPSG:1784.
Supported EPSG codes · Desteklenen EPSG kodları
| Family / Sistem | Central meridian / Merkez meridyen | TUREF (GRS80) | ED50 (Int. 1924) | WGS 84 |
|---|---|---|---|---|
| 3° TM, FE 500 000 m, k0 = 1 | 27, 30, 33, 36, 39, 42, 45 | 5253 – 5259 | 2319 – 2325 | – |
| 3° Gauss-Krüger, FE = zone·10⁶ + 500 000 m (zones 9 – 15) | 27 … 45 | 5269 – 5275 | 2206 – 2212 | – |
| 6° UTM 35N – 38N, k0 = 0.9996 | 27, 33, 39, 45 | – | 23035 – 23038 | 32635 – 32638 |
| Geographic / Coğrafi | – | 5252 | 4230 | 4326 |
| Web Mercator | – | – | – | 3857 |
All 40 definitions (names, central meridians, false eastings, ellipsoids) are checked against PROJ's EPSG database (v12.029) in the test-suite.
Accuracy vs PROJ · PROJ ile karşılaştırma
Measured with pyproj 3.8 / PROJ 9.8.1 over all 1 600 ordered pairs of the 40 codes, 200 random points per source CRS spread over Türkiye (maximum horizontal difference):
| Pair type / Dönüşüm türü | Max difference vs PROJ |
|---|---|
| Same datum: TM ↔ GK ↔ UTM ↔ geographic ↔ Web Mercator (incl. TUREF ↔ WGS 84) | < 0.00001 mm (≈ 6 nm) |
| ED50 → TUREF / WGS 84 (EPSG:1784 forward) | < 0.00001 mm (≈ 8 nm) |
| TUREF / WGS 84 → ED50 (EPSG:1784 reverse) | ≤ 1.13 mm ¹ |
| Krüger series (6th order) inside / far outside a zone | nanometres (Karney 2011) |
¹ Not an error in turkgrid: PROJ's reverse operation evaluates the WGS 84 point at height 0 and is therefore not an exact inverse of its forward operation — a PROJ ED50 → WGS 84 → ED50 round trip fails to close by up to 1.08 mm. turkgrid's round trip closes to < 0.00001 mm. The 2 m accuracy of EPSG:1784 itself dominates either way.
Speed (one core): pure Python ~100 000 points/s for TM ↔ WGS 84 and ~50 000 points/s with the ED50 shift; with NumPy arrays ~800 000 points/s including the ED50 shift.
Migration from cad2geo / NCZ2Geo · Geçiş notu
turkgrid unifies the projection code of the author's
cad2geo (cad2geo.reproject,
cad2geo.crs) and NCZ2Geo
(ncz2geo._projection, ncz2geo.transformer). Neither package is changed by this
release; they can later add turkgrid>=0.1 as a dependency and keep their public
functions as thin wrappers:
| Existing function | turkgrid equivalent |
|---|---|
cad2geo.to_wgs84(x, y, epsg, axes_swapped) |
turkgrid.to_wgs84((x, y), epsg, axes_swapped=...) |
cad2geo.reproject_geojson(gj, epsg, axes_swapped, ndigits) |
turkgrid.reproject_geojson(gj, 4326, epsg, axes_swapped=..., precision=ndigits) |
cad2geo.supported_epsg_codes() / cad2geo.crs tables |
turkgrid.supported_epsg_codes(), turkgrid.epsg_info(), turkgrid.epsg_for_lon() |
cad2geo.detect_crs(text, coords) (coordinate part) |
turkgrid.detect_crs(coords) (keep the metadata-text parsing in cad2geo) |
ncz2geo._projection.to_wgs84 / from_wgs84 |
turkgrid.transform_xy(x, y, srid, 4326) and back |
ncz2geo.transformer.reproject_coordinate |
turkgrid.transform_xy(x, y, src, dst) |
ncz2geo.transformer.Helmert7Params, helmert_7parameter_transform |
turkgrid.Helmert7(...).apply(x, y, z) |
Behavioural differences to note when switching: the TM series is 6th order instead of 4th (sub-nanometre instead of sub-millimetre), ED50 inversion is exact, and TUREF ↔ WGS 84 follows PROJ's EPSG:5261 handling. turkgrid covers every code of both packages (a superset: NCZ2Geo bundles 26 of these 40 codes, cad2geo 37 without Web Mercator); NCZ2Geo keeps its WKT/PROJJSON definitions for its file writers.
Development · Geliştirme
git clone https://github.com/YusufEminoglu/turkgrid_sdk.git
cd turkgrid_sdk
pip install -e ".[dev]"
python -m pytest # 198 tests incl. doctests; PROJ tests skip without pyproj
python -m ruff check . && python -m ruff format --check src tests && python -m mypy src
License · Lisans
MIT © 2026 Yusuf Eminoğlu. Parts of the code originate from the author's own cad2geo and NCZ2Geo packages, which are published under GPL-2.0-or-later; as the sole author and copyright holder of that code, the author releases it here under the MIT license. The MIT license is GPL-compatible, so both packages can depend on turkgrid.
References: C. F. F. Karney (2011), Transverse Mercator with an accuracy of a few nanometers, J. Geodesy 85:475-485 · IOGP EPSG Geodetic Parameter Dataset, operations 1783, 1784, 5260, 5261 · IOGP Guidance Note 7-2 (method 9606, position vector).
Metadata
Release files for turkgrid 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 | Actions |
|---|---|---|---|---|
| turkgrid-0.1.0.tar.gz | 52.2 kB | With provenance | Details for turkgrid-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| turkgrid-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for turkgrid-0.1.0-py3-none-any.whl |
Total release size: 90.8 kB
Release files / turkgrid-0.1.0.tar.gz
| Download URL | turkgrid-0.1.0.tar.gz |
|---|---|
| Size | 52.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
66aa07cebd458a8efe4f8d572af36ef6654e46f4e8b4b458bda5d6fd22fd4015
|
|
BLAKE2b-256 checksum How to use checksums |
912b4045e1845252e41cd788c4d13efbb9bca507540dc44d72841ea436ddb127
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 Nov 8, 2026.
Transparency logRelease files / turkgrid-0.1.0-py3-none-any.whl
| Download URL | turkgrid-0.1.0-py3-none-any.whl |
|---|---|
| Size | 38.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d24a1bb626a973e33d6b16e05983370c879892bda6257f9ae4a03745c15f4318
|
|
BLAKE2b-256 checksum How to use checksums |
d773c3639cc61a54ead83eb50936b4299a37c4ba213301eeff0950575adc7e37
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 Nov 8, 2026.
Transparency logSecurity for turkgrid 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
Both files in this release have been uploaded with provenance metadata.
Attestation for turkgrid-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 Nov 8, 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.
To learn more about protecting yourself from malicious actors, visit our package security documentation.