turkgrid 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- turkgrid-0.1.0/CHANGELOG.md +33 -0
- turkgrid-0.1.0/CITATION.cff +21 -0
- turkgrid-0.1.0/LICENSE +21 -0
- turkgrid-0.1.0/MANIFEST.in +8 -0
- turkgrid-0.1.0/PKG-INFO +293 -0
- turkgrid-0.1.0/README.md +253 -0
- turkgrid-0.1.0/pyproject.toml +125 -0
- turkgrid-0.1.0/setup.cfg +4 -0
- turkgrid-0.1.0/src/turkgrid/__init__.py +85 -0
- turkgrid-0.1.0/src/turkgrid/__main__.py +7 -0
- turkgrid-0.1.0/src/turkgrid/_backend.py +74 -0
- turkgrid-0.1.0/src/turkgrid/_turkiye.py +122 -0
- turkgrid-0.1.0/src/turkgrid/cli.py +302 -0
- turkgrid-0.1.0/src/turkgrid/crs.py +293 -0
- turkgrid-0.1.0/src/turkgrid/detect.py +268 -0
- turkgrid-0.1.0/src/turkgrid/ellipsoids.py +85 -0
- turkgrid-0.1.0/src/turkgrid/geojson.py +181 -0
- turkgrid-0.1.0/src/turkgrid/helmert.py +205 -0
- turkgrid-0.1.0/src/turkgrid/py.typed +0 -0
- turkgrid-0.1.0/src/turkgrid/tm.py +158 -0
- turkgrid-0.1.0/src/turkgrid/transformer.py +215 -0
- turkgrid-0.1.0/src/turkgrid.egg-info/PKG-INFO +293 -0
- turkgrid-0.1.0/src/turkgrid.egg-info/SOURCES.txt +30 -0
- turkgrid-0.1.0/src/turkgrid.egg-info/dependency_links.txt +1 -0
- turkgrid-0.1.0/src/turkgrid.egg-info/entry_points.txt +2 -0
- turkgrid-0.1.0/src/turkgrid.egg-info/requires.txt +11 -0
- turkgrid-0.1.0/src/turkgrid.egg-info/top_level.txt +1 -0
- turkgrid-0.1.0/tests/test_core.py +243 -0
- turkgrid-0.1.0/tests/test_detect.py +121 -0
- turkgrid-0.1.0/tests/test_geojson_cli.py +232 -0
- turkgrid-0.1.0/tests/test_transform.py +122 -0
- turkgrid-0.1.0/tests/test_vs_pyproj.py +220 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
## [0.1.0] - 2026-11-08
|
|
8
|
+
### Added
|
|
9
|
+
- **CRS registry** (`crs.py`): 40 EPSG codes for Türkiye - TUREF and ED50 3-degree TM
|
|
10
|
+
(5253-5259, 2319-2325), zone-prefixed 3-degree Gauss-Krüger (5269-5275, 2206-2212),
|
|
11
|
+
WGS 84 and ED50 UTM 35N-38N (32635-32638, 23035-23038), geographic WGS 84 / TUREF /
|
|
12
|
+
ED50 (4326, 5252, 4230) and Web Mercator (3857). `epsg_info`, `supported_epsg_codes`,
|
|
13
|
+
`parse_epsg` (codes, `"EPSG:x"`, OGC URNs/URLs, `CRS84`), `zone_for_lon`,
|
|
14
|
+
`utm_zone_for_lon`, `epsg_for_lon`, `CRSInfo.to_proj4()`.
|
|
15
|
+
- **Transverse Mercator** (`tm.py`): Krüger series to 6th order in n with Newton
|
|
16
|
+
inversion of the conformal latitude (Karney 2011), nanometre-level inside the zones.
|
|
17
|
+
- **Datum shift** (`helmert.py`): EPSG:1784 "ED50 to WGS 84 (30)" (position vector),
|
|
18
|
+
exact inverse for the reverse direction, ED50 <-> TUREF read on GRS80 as PROJ does;
|
|
19
|
+
general `Helmert7` with an exact `apply_inverse` and both rotation conventions.
|
|
20
|
+
- **Transformations** (`transformer.py`): `transform`, `transform_xy`, `to_wgs84`,
|
|
21
|
+
`from_wgs84` and a reusable `Transformer`, for single points, sequences (extra
|
|
22
|
+
ordinates kept) and NumPy arrays (vectorised), with `axes_swapped` /
|
|
23
|
+
`output_swapped` for northing-first Turkish survey data.
|
|
24
|
+
- **CRS detection** (`detect.py`): `detect_crs` scores every CRS reading in both axis
|
|
25
|
+
orders against a coarse outline of Türkiye and the zone widths, with optional
|
|
26
|
+
`near=` location, and returns ranked candidates with reasons, ties and the nearest
|
|
27
|
+
province.
|
|
28
|
+
- **GeoJSON** (`geojson.py`): `reproject_geojson` for collections, features and every
|
|
29
|
+
geometry type, honouring and writing the legacy `crs` member and recomputing `bbox`.
|
|
30
|
+
- **CLI** `turkgrid`: `convert`, `detect` (CSV/TXT with delimiter sniffing, decimal
|
|
31
|
+
commas and header detection), `geojson` and `info`.
|
|
32
|
+
- Test-suite of 198 tests (99 % coverage) including a comparison with PROJ for all
|
|
33
|
+
1 600 ordered CRS pairs.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use this software, please cite it as below."
|
|
3
|
+
authors:
|
|
4
|
+
- family-names: "Eminoğlu"
|
|
5
|
+
given-names: "Yusuf"
|
|
6
|
+
email: "yusufeminoglu@gmail.com"
|
|
7
|
+
orcid: "https://orcid.org/0009-0005-6000-2934"
|
|
8
|
+
title: "turkgrid"
|
|
9
|
+
version: "0.1.0"
|
|
10
|
+
date-released: "2026-11-08"
|
|
11
|
+
license: "MIT"
|
|
12
|
+
repository-code: "https://github.com/YusufEminoglu/turkgrid_sdk"
|
|
13
|
+
url: "https://pypi.org/project/turkgrid/"
|
|
14
|
+
abstract: "Zero-dependency coordinate reference toolkit for Türkiye: TUREF/ED50 3-degree TM and Gauss-Krüger zones, UTM 35N-38N, the EPSG:1784 ED50 to WGS 84 shift, GeoJSON reprojection and heuristic CRS detection, validated against PROJ."
|
|
15
|
+
keywords:
|
|
16
|
+
- geodesy
|
|
17
|
+
- coordinate transformation
|
|
18
|
+
- transverse mercator
|
|
19
|
+
- TUREF
|
|
20
|
+
- ED50
|
|
21
|
+
- Türkiye
|
turkgrid-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Yusuf Eminoğlu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
turkgrid-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: turkgrid
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Zero-dependency coordinate toolkit for Türkiye: TUREF/ED50 TM and Gauss-Krüger zones, UTM 35N-38N, the EPSG:1784 ED50 shift and CRS detection.
|
|
5
|
+
Author-email: Yusuf Eminoğlu <yusufeminoglu@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/YusufEminoglu/turkgrid_sdk
|
|
8
|
+
Project-URL: Repository, https://github.com/YusufEminoglu/turkgrid_sdk
|
|
9
|
+
Project-URL: Issues, https://github.com/YusufEminoglu/turkgrid_sdk/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/YusufEminoglu/turkgrid_sdk/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: gis,geodesy,crs,coordinate-transformation,reprojection,transverse-mercator,gauss-kruger,utm,turef,ed50,itrf96,epsg,helmert,datum-shift,geojson,turkey,turkiye,netcad,cadastre
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Operating System :: OS Independent
|
|
20
|
+
Classifier: Natural Language :: English
|
|
21
|
+
Classifier: Natural Language :: Turkish
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
24
|
+
Classifier: Intended Audience :: Science/Research
|
|
25
|
+
Classifier: Intended Audience :: Developers
|
|
26
|
+
Classifier: Typing :: Typed
|
|
27
|
+
Requires-Python: >=3.9
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Provides-Extra: numpy
|
|
31
|
+
Requires-Dist: numpy>=1.20.0; extra == "numpy"
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
34
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
35
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
36
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
37
|
+
Requires-Dist: numpy>=1.20.0; extra == "dev"
|
|
38
|
+
Requires-Dist: pyproj>=3.3.0; extra == "dev"
|
|
39
|
+
Dynamic: license-file
|
|
40
|
+
|
|
41
|
+
<div align="center">
|
|
42
|
+
|
|
43
|
+
# turkgrid
|
|
44
|
+
|
|
45
|
+
[](https://pypi.org/project/turkgrid/)
|
|
46
|
+
[](https://pypi.org/project/turkgrid/)
|
|
47
|
+
[](https://github.com/YusufEminoglu/turkgrid_sdk/blob/main/LICENSE)
|
|
48
|
+
[](https://docs.astral.sh/ruff/)
|
|
49
|
+
[](#development--geliştirme)
|
|
50
|
+
|
|
51
|
+
**Türkiye için bağımlılıksız koordinat dönüşüm kütüphanesi · Zero-dependency coordinate toolkit for Türkiye**
|
|
52
|
+
|
|
53
|
+
TUREF / ED50 3° TM ve Gauss-Krüger dilimleri · UTM 35N-38N · EPSG:1784 ED50 datum dönüşümü · GeoJSON · CRS tahmini
|
|
54
|
+
|
|
55
|
+
[🇹🇷 Türkçe](#-türkçe) • [🇬🇧 English](#-english) • [📦 PyPI](https://pypi.org/project/turkgrid/) • [💻 GitHub](https://github.com/YusufEminoglu/turkgrid_sdk) • [🐛 Issues](https://github.com/YusufEminoglu/turkgrid_sdk/issues)
|
|
56
|
+
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 🇹🇷 Türkçe
|
|
62
|
+
|
|
63
|
+
`turkgrid`, Türkiye'de harita, imar planı ve kadastro verilerinde kullanılan koordinat
|
|
64
|
+
sistemleri arasında **saf Python** ile dönüşüm yapar. PROJ, GDAL veya pyproj gerekmez;
|
|
65
|
+
NumPy kuruluysa diziler vektörel olarak işlenir. Sonuçlar PROJ ile karşılaştırılarak
|
|
66
|
+
test edilir (aşağıdaki doğruluk tablosuna bakın).
|
|
67
|
+
|
|
68
|
+
### Kurulum
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pip install turkgrid # yalnızca standart kütüphane
|
|
72
|
+
pip install "turkgrid[numpy]" # NumPy dizileriyle vektörel dönüşüm
|
|
73
|
+
pip install "turkgrid[dev]" # testler: pytest, ruff, mypy, numpy, pyproj
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Python 3.9+ gerekir; Windows, macOS ve Linux'ta çalışır.
|
|
77
|
+
|
|
78
|
+
### Hızlı başlangıç
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
import turkgrid
|
|
82
|
+
|
|
83
|
+
# TUREF / TM30 (EPSG:5254) -> WGS 84 boylam/enlem
|
|
84
|
+
lon, lat = turkgrid.to_wgs84((412000.0, 4542000.0), 5254)
|
|
85
|
+
|
|
86
|
+
# Eski ED50 / TM30 planını TUREF / TM30'a taşı (EPSG:1784 datum dönüşümü)
|
|
87
|
+
x, y = turkgrid.transform((412000.0, 4542000.0), 2320, 5254)
|
|
88
|
+
|
|
89
|
+
# Dilimden dilime (TM30 -> TM33), yükseklik (z) korunur
|
|
90
|
+
pts = turkgrid.transform([(412000.0, 4542000.0, 35.2)], 5254, 5255)
|
|
91
|
+
|
|
92
|
+
# Türk ölçü pratiği: önce X (yukarı/kuzey), sonra Y (sağa/doğu)
|
|
93
|
+
lon, lat = turkgrid.to_wgs84((4542000.0, 412000.0), 5254, axes_swapped=True)
|
|
94
|
+
|
|
95
|
+
# Boylama göre dilim ve EPSG kodu
|
|
96
|
+
turkgrid.zone_for_lon(29.0) # 30 (merkez meridyen)
|
|
97
|
+
turkgrid.epsg_for_lon(29.0, "TM", "ED50") # 2320
|
|
98
|
+
turkgrid.epsg_info(5254).to_proj4() # '+proj=tmerc +lat_0=0 +lon_0=30 ...'
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
NumPy dizileri (`(N, 2)` veya `(N, 3)`) ya da ayrı `x`, `y` dizileri tek çağrıda
|
|
102
|
+
dönüştürülür: `turkgrid.transform_xy(x_dizisi, y_dizisi, 2320, 5254)`.
|
|
103
|
+
|
|
104
|
+
### Koordinat sistemi tahmini
|
|
105
|
+
|
|
106
|
+
Kaynağı belirsiz plan koordinatları için `detect_crs` her olası sistemi dener ve
|
|
107
|
+
gerekçeleriyle sıralı aday listesi döndürür:
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
for aday in turkgrid.detect_crs(noktalar, near=(29.06, 40.19)): # near: bilinen yer (Bursa)
|
|
111
|
+
print(aday.epsg, aday.name, aday.score, aday.axes_swapped, aday.place)
|
|
112
|
+
print(" ", "; ".join(aday.reasons))
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Koordinatlardan **kesin** anlaşılabilenler: eksen sırası (X/Y ters mi), Gauss-Krüger
|
|
116
|
+
dilim öneki (ör. 10 465 000 → 10. dilim). **Anlaşılamayanlar**: 500 000 m sabitli bir
|
|
117
|
+
TM doğusunun hangi dilime ait olduğu (bütün dilimlere uyar; Türkiye sınırı dışına
|
|
118
|
+
düşen okumalar elenir) ve ED50 ile TUREF farkı (≈ 100-200 m). Bu eşitlikleri
|
|
119
|
+
bozmak için `near=(boylam, enlem)` verin; ED50/TUREF ayrımı için bilinen bir noktayı
|
|
120
|
+
`near_tolerance_m=20` gibi küçük bir toleransla kullanın.
|
|
121
|
+
|
|
122
|
+
### Komut satırı
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
turkgrid convert --from 5254 --to 4326 412000 4542000
|
|
126
|
+
echo "412000 4542000" | turkgrid convert --from 2320 --to 5254
|
|
127
|
+
turkgrid detect noktalar.csv --near 29.06,40.19 -v # ; ayraç ve ondalık virgül desteklenir
|
|
128
|
+
turkgrid geojson plan.geojson --to 4326 -o plan_wgs84.geojson
|
|
129
|
+
turkgrid info 2320
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Datum varsayımları
|
|
133
|
+
|
|
134
|
+
* **TUREF = WGS 84.** TUREF (ITRF96, 2005.0) ile WGS 84 Türkiye'de birkaç cm
|
|
135
|
+
içinde örtüşür; EPSG de "TUREF to WGS 84 (1)" (EPSG:5261) dönüşümünü sıfır
|
|
136
|
+
parametreli tanımlar. turkgrid bunu PROJ ile aynı şekilde uygular.
|
|
137
|
+
* **ED50 → WGS 84/TUREF: EPSG:1784 "ED50 to WGS 84 (30)"**, konum vektörü
|
|
138
|
+
(position vector, EPSG yöntem 9606): tx −84.1, ty −101.8, tz −129.7 m, rz +0.468″,
|
|
139
|
+
ölçek +1.05 ppm; HGK'nın yayımladığı EPSG:1783 ile aynı değerler; doğruluk 2 m.
|
|
140
|
+
Ters yön, ileri dönüşümün **tam tersidir** (gidiş-dönüş nanometre düzeyinde kapanır).
|
|
141
|
+
* Yerel dönüşüm parametreleri (ör. belediye nirengi ağı) gerekiyorsa
|
|
142
|
+
`turkgrid.Helmert7` ile kendi 7 parametrenizi uygulayabilirsiniz.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## 🇬🇧 English
|
|
147
|
+
|
|
148
|
+
`turkgrid` converts between the coordinate reference systems used for maps, zoning
|
|
149
|
+
plans and cadastre in Türkiye, in **pure Python**: no PROJ, GDAL or pyproj needed, and
|
|
150
|
+
NumPy (optional) vectorises arrays. Every supported pair is tested against PROJ.
|
|
151
|
+
|
|
152
|
+
### Installation
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
pip install turkgrid # standard library only
|
|
156
|
+
pip install "turkgrid[numpy]" # vectorised NumPy array support
|
|
157
|
+
pip install "turkgrid[dev]" # pytest, ruff, mypy, numpy, pyproj (for the PROJ tests)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Quickstart
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
import turkgrid
|
|
164
|
+
|
|
165
|
+
lon, lat = turkgrid.to_wgs84((412000.0, 4542000.0), 5254) # TUREF / TM30 -> WGS 84
|
|
166
|
+
x, y = turkgrid.transform((412000.0, 4542000.0), 2320, 5254) # ED50 / TM30 -> TUREF / TM30
|
|
167
|
+
xy = turkgrid.from_wgs84((29.0, 41.0), "EPSG:32635") # WGS 84 -> UTM 35N
|
|
168
|
+
pts = turkgrid.transform([(412000.0, 4542000.0, 35.2)], 5254, 5255) # zone to zone, z kept
|
|
169
|
+
|
|
170
|
+
t = turkgrid.Transformer(2320, 5254) # reusable; t.inverse(), t.description
|
|
171
|
+
gj = turkgrid.reproject_geojson(geojson_dict, 4326) # reads a legacy "crs" member
|
|
172
|
+
best = turkgrid.detect_crs(points)[0] # candidates with score, axes_swapped, reasons, place
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
* Coordinates are **easting, northing** / **longitude, latitude**. Turkish surveys
|
|
176
|
+
often store northing first; pass `axes_swapped=True` (and `output_swapped=True`).
|
|
177
|
+
* Inputs: one point (tuple, extra ordinates kept), a sequence of points (returns a
|
|
178
|
+
list), or a NumPy array of shape `(2,)` / `(N, 2+)` (returns a new array).
|
|
179
|
+
`transform_xy(x, y, src, dst)` takes floats or arrays.
|
|
180
|
+
* EPSG codes may be `5254`, `"5254"`, `"EPSG:5254"`, an OGC URN/URL or `"CRS84"`.
|
|
181
|
+
|
|
182
|
+
### CRS detection
|
|
183
|
+
|
|
184
|
+
`detect_crs(points, near=None, near_tolerance_m=25_000)` reads every supported CRS into
|
|
185
|
+
the numbers (in both axis orders), projects a sample to WGS 84 and scores each reading
|
|
186
|
+
by the share of points that fall in Türkiye (coarse outline plus a ~20 km buffer), the
|
|
187
|
+
share inside the CRS's zone, and optional closeness to a known location. Candidates
|
|
188
|
+
come back best-first with human-readable `reasons`, the nearest province centre and
|
|
189
|
+
any ties. Axis order and Gauss-Krüger zone prefixes are unambiguous; the zone of a
|
|
190
|
+
plain TM easting and the ED50/TUREF datum are not, and stay tied unless `near=` breaks
|
|
191
|
+
the tie (use a surveyed point and a ~20 m tolerance to separate the datums).
|
|
192
|
+
|
|
193
|
+
### Command line
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
turkgrid convert --from 5254 --to 4326 412000 4542000 # or pipe "x y" lines on stdin
|
|
197
|
+
turkgrid detect points.csv [--near lon,lat] [--json] [-v]
|
|
198
|
+
turkgrid geojson in.geojson --to 4326 -o out.geojson # --from defaults to the crs member
|
|
199
|
+
turkgrid info [EPSG]
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Datum assumptions
|
|
203
|
+
|
|
204
|
+
* **TUREF is taken as WGS 84** (they agree to a few centimetres in Türkiye). EPSG:5261
|
|
205
|
+
"TUREF to WGS 84 (1)" is a zero-parameter transformation, applied as PROJ does.
|
|
206
|
+
* **ED50 → WGS 84 / TUREF uses EPSG:1784 "ED50 to WGS 84 (30)"**, position vector
|
|
207
|
+
(EPSG method 9606): tx −84.1, ty −101.8, tz −129.7 m, rx = ry = 0, rz +0.468″,
|
|
208
|
+
scale +1.05 ppm; same values as EPSG:1783 (published by HGK, the Turkish General
|
|
209
|
+
Directorate of Mapping); stated accuracy 2 m. It is applied on the ellipsoid surface
|
|
210
|
+
(height 0), like PROJ. The reverse direction is the **exact inverse** of the forward
|
|
211
|
+
one (round trips close to nanometres), solved by fixed-point refinement.
|
|
212
|
+
* Plain `pyproj.Transformer.from_crs(2320, 5254)` may choose another operation (e.g.
|
|
213
|
+
via ETRS89 with EPSG:5260, a few cm different, or a generic ED50 set metres away)
|
|
214
|
+
unless an area of interest or the operation is given; turkgrid always uses EPSG:1784.
|
|
215
|
+
|
|
216
|
+
## Supported EPSG codes · Desteklenen EPSG kodları
|
|
217
|
+
|
|
218
|
+
| Family / Sistem | Central meridian / Merkez meridyen | TUREF (GRS80) | ED50 (Int. 1924) | WGS 84 |
|
|
219
|
+
|---|---|---|---|---|
|
|
220
|
+
| 3° TM, FE 500 000 m, k0 = 1 | 27, 30, 33, 36, 39, 42, 45 | 5253 – 5259 | 2319 – 2325 | – |
|
|
221
|
+
| 3° Gauss-Krüger, FE = zone·10⁶ + 500 000 m (zones 9 – 15) | 27 … 45 | 5269 – 5275 | 2206 – 2212 | – |
|
|
222
|
+
| 6° UTM 35N – 38N, k0 = 0.9996 | 27, 33, 39, 45 | – | 23035 – 23038 | 32635 – 32638 |
|
|
223
|
+
| Geographic / Coğrafi | – | 5252 | 4230 | 4326 |
|
|
224
|
+
| Web Mercator | – | – | – | 3857 |
|
|
225
|
+
|
|
226
|
+
All 40 definitions (names, central meridians, false eastings, ellipsoids) are checked
|
|
227
|
+
against PROJ's EPSG database (v12.029) in the test-suite.
|
|
228
|
+
|
|
229
|
+
## Accuracy vs PROJ · PROJ ile karşılaştırma
|
|
230
|
+
|
|
231
|
+
Measured with pyproj 3.8 / PROJ 9.8.1 over **all 1 600 ordered pairs** of the 40 codes,
|
|
232
|
+
200 random points per source CRS spread over Türkiye (maximum horizontal difference):
|
|
233
|
+
|
|
234
|
+
| Pair type / Dönüşüm türü | Max difference vs PROJ |
|
|
235
|
+
|---|---|
|
|
236
|
+
| Same datum: TM ↔ GK ↔ UTM ↔ geographic ↔ Web Mercator (incl. TUREF ↔ WGS 84) | < 0.00001 mm (≈ 6 nm) |
|
|
237
|
+
| ED50 → TUREF / WGS 84 (EPSG:1784 forward) | < 0.00001 mm (≈ 8 nm) |
|
|
238
|
+
| TUREF / WGS 84 → ED50 (EPSG:1784 reverse) | ≤ 1.13 mm ¹ |
|
|
239
|
+
| Krüger series (6th order) inside / far outside a zone | nanometres (Karney 2011) |
|
|
240
|
+
|
|
241
|
+
¹ Not an error in turkgrid: PROJ's reverse operation evaluates the WGS 84 point at
|
|
242
|
+
height 0 and is therefore not an exact inverse of its forward operation — a PROJ
|
|
243
|
+
ED50 → WGS 84 → ED50 round trip fails to close by up to 1.08 mm. turkgrid's round trip
|
|
244
|
+
closes to < 0.00001 mm. The 2 m accuracy of EPSG:1784 itself dominates either way.
|
|
245
|
+
|
|
246
|
+
Speed (one core): pure Python ~100 000 points/s for TM ↔ WGS 84 and ~50 000 points/s
|
|
247
|
+
with the ED50 shift; with NumPy arrays ~800 000 points/s including the ED50 shift.
|
|
248
|
+
|
|
249
|
+
## Migration from cad2geo / NCZ2Geo · Geçiş notu
|
|
250
|
+
|
|
251
|
+
turkgrid unifies the projection code of the author's
|
|
252
|
+
[cad2geo](https://github.com/YusufEminoglu/cad2geo_sdk) (`cad2geo.reproject`,
|
|
253
|
+
`cad2geo.crs`) and [NCZ2Geo](https://github.com/YusufEminoglu/NCZ2Geo_sdk)
|
|
254
|
+
(`ncz2geo._projection`, `ncz2geo.transformer`). Neither package is changed by this
|
|
255
|
+
release; they can later add `turkgrid>=0.1` as a dependency and keep their public
|
|
256
|
+
functions as thin wrappers:
|
|
257
|
+
|
|
258
|
+
| Existing function | turkgrid equivalent |
|
|
259
|
+
|---|---|
|
|
260
|
+
| `cad2geo.to_wgs84(x, y, epsg, axes_swapped)` | `turkgrid.to_wgs84((x, y), epsg, axes_swapped=...)` |
|
|
261
|
+
| `cad2geo.reproject_geojson(gj, epsg, axes_swapped, ndigits)` | `turkgrid.reproject_geojson(gj, 4326, epsg, axes_swapped=..., precision=ndigits)` |
|
|
262
|
+
| `cad2geo.supported_epsg_codes()` / `cad2geo.crs` tables | `turkgrid.supported_epsg_codes()`, `turkgrid.epsg_info()`, `turkgrid.epsg_for_lon()` |
|
|
263
|
+
| `cad2geo.detect_crs(text, coords)` (coordinate part) | `turkgrid.detect_crs(coords)` (keep the metadata-text parsing in cad2geo) |
|
|
264
|
+
| `ncz2geo._projection.to_wgs84 / from_wgs84` | `turkgrid.transform_xy(x, y, srid, 4326)` and back |
|
|
265
|
+
| `ncz2geo.transformer.reproject_coordinate` | `turkgrid.transform_xy(x, y, src, dst)` |
|
|
266
|
+
| `ncz2geo.transformer.Helmert7Params`, `helmert_7parameter_transform` | `turkgrid.Helmert7(...).apply(x, y, z)` |
|
|
267
|
+
|
|
268
|
+
Behavioural differences to note when switching: the TM series is 6th order instead of
|
|
269
|
+
4th (sub-nanometre instead of sub-millimetre), ED50 inversion is exact, and TUREF
|
|
270
|
+
↔ WGS 84 follows PROJ's EPSG:5261 handling. turkgrid covers every code of both
|
|
271
|
+
packages (a superset: NCZ2Geo bundles 26 of these 40 codes, cad2geo 37 without Web
|
|
272
|
+
Mercator); NCZ2Geo keeps its WKT/PROJJSON definitions for its file writers.
|
|
273
|
+
|
|
274
|
+
## Development · Geliştirme
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
git clone https://github.com/YusufEminoglu/turkgrid_sdk.git
|
|
278
|
+
cd turkgrid_sdk
|
|
279
|
+
pip install -e ".[dev]"
|
|
280
|
+
python -m pytest # 198 tests incl. doctests; PROJ tests skip without pyproj
|
|
281
|
+
python -m ruff check . && python -m ruff format --check src tests && python -m mypy src
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## License · Lisans
|
|
285
|
+
|
|
286
|
+
MIT © 2026 Yusuf Eminoğlu. Parts of the code originate from the author's own cad2geo
|
|
287
|
+
and NCZ2Geo packages, which are published under GPL-2.0-or-later; as the sole author
|
|
288
|
+
and copyright holder of that code, the author releases it here under the MIT license.
|
|
289
|
+
The MIT license is GPL-compatible, so both packages can depend on turkgrid.
|
|
290
|
+
|
|
291
|
+
**References:** C. F. F. Karney (2011), *Transverse Mercator with an accuracy of a few
|
|
292
|
+
nanometers*, J. Geodesy 85:475-485 · IOGP EPSG Geodetic Parameter Dataset, operations
|
|
293
|
+
1783, 1784, 5260, 5261 · IOGP Guidance Note 7-2 (method 9606, position vector).
|
turkgrid-0.1.0/README.md
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# turkgrid
|
|
4
|
+
|
|
5
|
+
[](https://pypi.org/project/turkgrid/)
|
|
6
|
+
[](https://pypi.org/project/turkgrid/)
|
|
7
|
+
[](https://github.com/YusufEminoglu/turkgrid_sdk/blob/main/LICENSE)
|
|
8
|
+
[](https://docs.astral.sh/ruff/)
|
|
9
|
+
[](#development--geliştirme)
|
|
10
|
+
|
|
11
|
+
**Türkiye için bağımlılıksız koordinat dönüşüm kütüphanesi · Zero-dependency coordinate toolkit for Türkiye**
|
|
12
|
+
|
|
13
|
+
TUREF / ED50 3° TM ve Gauss-Krüger dilimleri · UTM 35N-38N · EPSG:1784 ED50 datum dönüşümü · GeoJSON · CRS tahmini
|
|
14
|
+
|
|
15
|
+
[🇹🇷 Türkçe](#-türkçe) • [🇬🇧 English](#-english) • [📦 PyPI](https://pypi.org/project/turkgrid/) • [💻 GitHub](https://github.com/YusufEminoglu/turkgrid_sdk) • [🐛 Issues](https://github.com/YusufEminoglu/turkgrid_sdk/issues)
|
|
16
|
+
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 🇹🇷 Türkçe
|
|
22
|
+
|
|
23
|
+
`turkgrid`, Türkiye'de harita, imar planı ve kadastro verilerinde kullanılan koordinat
|
|
24
|
+
sistemleri arasında **saf Python** ile dönüşüm yapar. PROJ, GDAL veya pyproj gerekmez;
|
|
25
|
+
NumPy kuruluysa diziler vektörel olarak işlenir. Sonuçlar PROJ ile karşılaştırılarak
|
|
26
|
+
test edilir (aşağıdaki doğruluk tablosuna bakın).
|
|
27
|
+
|
|
28
|
+
### Kurulum
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install turkgrid # yalnızca standart kütüphane
|
|
32
|
+
pip install "turkgrid[numpy]" # NumPy dizileriyle vektörel dönüşüm
|
|
33
|
+
pip install "turkgrid[dev]" # testler: pytest, ruff, mypy, numpy, pyproj
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Python 3.9+ gerekir; Windows, macOS ve Linux'ta çalışır.
|
|
37
|
+
|
|
38
|
+
### Hızlı başlangıç
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
import turkgrid
|
|
42
|
+
|
|
43
|
+
# TUREF / TM30 (EPSG:5254) -> WGS 84 boylam/enlem
|
|
44
|
+
lon, lat = turkgrid.to_wgs84((412000.0, 4542000.0), 5254)
|
|
45
|
+
|
|
46
|
+
# Eski ED50 / TM30 planını TUREF / TM30'a taşı (EPSG:1784 datum dönüşümü)
|
|
47
|
+
x, y = turkgrid.transform((412000.0, 4542000.0), 2320, 5254)
|
|
48
|
+
|
|
49
|
+
# Dilimden dilime (TM30 -> TM33), yükseklik (z) korunur
|
|
50
|
+
pts = turkgrid.transform([(412000.0, 4542000.0, 35.2)], 5254, 5255)
|
|
51
|
+
|
|
52
|
+
# Türk ölçü pratiği: önce X (yukarı/kuzey), sonra Y (sağa/doğu)
|
|
53
|
+
lon, lat = turkgrid.to_wgs84((4542000.0, 412000.0), 5254, axes_swapped=True)
|
|
54
|
+
|
|
55
|
+
# Boylama göre dilim ve EPSG kodu
|
|
56
|
+
turkgrid.zone_for_lon(29.0) # 30 (merkez meridyen)
|
|
57
|
+
turkgrid.epsg_for_lon(29.0, "TM", "ED50") # 2320
|
|
58
|
+
turkgrid.epsg_info(5254).to_proj4() # '+proj=tmerc +lat_0=0 +lon_0=30 ...'
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
NumPy dizileri (`(N, 2)` veya `(N, 3)`) ya da ayrı `x`, `y` dizileri tek çağrıda
|
|
62
|
+
dönüştürülür: `turkgrid.transform_xy(x_dizisi, y_dizisi, 2320, 5254)`.
|
|
63
|
+
|
|
64
|
+
### Koordinat sistemi tahmini
|
|
65
|
+
|
|
66
|
+
Kaynağı belirsiz plan koordinatları için `detect_crs` her olası sistemi dener ve
|
|
67
|
+
gerekçeleriyle sıralı aday listesi döndürür:
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
for aday in turkgrid.detect_crs(noktalar, near=(29.06, 40.19)): # near: bilinen yer (Bursa)
|
|
71
|
+
print(aday.epsg, aday.name, aday.score, aday.axes_swapped, aday.place)
|
|
72
|
+
print(" ", "; ".join(aday.reasons))
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Koordinatlardan **kesin** anlaşılabilenler: eksen sırası (X/Y ters mi), Gauss-Krüger
|
|
76
|
+
dilim öneki (ör. 10 465 000 → 10. dilim). **Anlaşılamayanlar**: 500 000 m sabitli bir
|
|
77
|
+
TM doğusunun hangi dilime ait olduğu (bütün dilimlere uyar; Türkiye sınırı dışına
|
|
78
|
+
düşen okumalar elenir) ve ED50 ile TUREF farkı (≈ 100-200 m). Bu eşitlikleri
|
|
79
|
+
bozmak için `near=(boylam, enlem)` verin; ED50/TUREF ayrımı için bilinen bir noktayı
|
|
80
|
+
`near_tolerance_m=20` gibi küçük bir toleransla kullanın.
|
|
81
|
+
|
|
82
|
+
### Komut satırı
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
turkgrid convert --from 5254 --to 4326 412000 4542000
|
|
86
|
+
echo "412000 4542000" | turkgrid convert --from 2320 --to 5254
|
|
87
|
+
turkgrid detect noktalar.csv --near 29.06,40.19 -v # ; ayraç ve ondalık virgül desteklenir
|
|
88
|
+
turkgrid geojson plan.geojson --to 4326 -o plan_wgs84.geojson
|
|
89
|
+
turkgrid info 2320
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Datum varsayımları
|
|
93
|
+
|
|
94
|
+
* **TUREF = WGS 84.** TUREF (ITRF96, 2005.0) ile WGS 84 Türkiye'de birkaç cm
|
|
95
|
+
içinde örtüşür; EPSG de "TUREF to WGS 84 (1)" (EPSG:5261) dönüşümünü sıfır
|
|
96
|
+
parametreli tanımlar. turkgrid bunu PROJ ile aynı şekilde uygular.
|
|
97
|
+
* **ED50 → WGS 84/TUREF: EPSG:1784 "ED50 to WGS 84 (30)"**, konum vektörü
|
|
98
|
+
(position vector, EPSG yöntem 9606): tx −84.1, ty −101.8, tz −129.7 m, rz +0.468″,
|
|
99
|
+
ölçek +1.05 ppm; HGK'nın yayımladığı EPSG:1783 ile aynı değerler; doğruluk 2 m.
|
|
100
|
+
Ters yön, ileri dönüşümün **tam tersidir** (gidiş-dönüş nanometre düzeyinde kapanır).
|
|
101
|
+
* Yerel dönüşüm parametreleri (ör. belediye nirengi ağı) gerekiyorsa
|
|
102
|
+
`turkgrid.Helmert7` ile kendi 7 parametrenizi uygulayabilirsiniz.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 🇬🇧 English
|
|
107
|
+
|
|
108
|
+
`turkgrid` converts between the coordinate reference systems used for maps, zoning
|
|
109
|
+
plans and cadastre in Türkiye, in **pure Python**: no PROJ, GDAL or pyproj needed, and
|
|
110
|
+
NumPy (optional) vectorises arrays. Every supported pair is tested against PROJ.
|
|
111
|
+
|
|
112
|
+
### Installation
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
pip install turkgrid # standard library only
|
|
116
|
+
pip install "turkgrid[numpy]" # vectorised NumPy array support
|
|
117
|
+
pip install "turkgrid[dev]" # pytest, ruff, mypy, numpy, pyproj (for the PROJ tests)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Quickstart
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
import turkgrid
|
|
124
|
+
|
|
125
|
+
lon, lat = turkgrid.to_wgs84((412000.0, 4542000.0), 5254) # TUREF / TM30 -> WGS 84
|
|
126
|
+
x, y = turkgrid.transform((412000.0, 4542000.0), 2320, 5254) # ED50 / TM30 -> TUREF / TM30
|
|
127
|
+
xy = turkgrid.from_wgs84((29.0, 41.0), "EPSG:32635") # WGS 84 -> UTM 35N
|
|
128
|
+
pts = turkgrid.transform([(412000.0, 4542000.0, 35.2)], 5254, 5255) # zone to zone, z kept
|
|
129
|
+
|
|
130
|
+
t = turkgrid.Transformer(2320, 5254) # reusable; t.inverse(), t.description
|
|
131
|
+
gj = turkgrid.reproject_geojson(geojson_dict, 4326) # reads a legacy "crs" member
|
|
132
|
+
best = turkgrid.detect_crs(points)[0] # candidates with score, axes_swapped, reasons, place
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
* Coordinates are **easting, northing** / **longitude, latitude**. Turkish surveys
|
|
136
|
+
often store northing first; pass `axes_swapped=True` (and `output_swapped=True`).
|
|
137
|
+
* Inputs: one point (tuple, extra ordinates kept), a sequence of points (returns a
|
|
138
|
+
list), or a NumPy array of shape `(2,)` / `(N, 2+)` (returns a new array).
|
|
139
|
+
`transform_xy(x, y, src, dst)` takes floats or arrays.
|
|
140
|
+
* EPSG codes may be `5254`, `"5254"`, `"EPSG:5254"`, an OGC URN/URL or `"CRS84"`.
|
|
141
|
+
|
|
142
|
+
### CRS detection
|
|
143
|
+
|
|
144
|
+
`detect_crs(points, near=None, near_tolerance_m=25_000)` reads every supported CRS into
|
|
145
|
+
the numbers (in both axis orders), projects a sample to WGS 84 and scores each reading
|
|
146
|
+
by the share of points that fall in Türkiye (coarse outline plus a ~20 km buffer), the
|
|
147
|
+
share inside the CRS's zone, and optional closeness to a known location. Candidates
|
|
148
|
+
come back best-first with human-readable `reasons`, the nearest province centre and
|
|
149
|
+
any ties. Axis order and Gauss-Krüger zone prefixes are unambiguous; the zone of a
|
|
150
|
+
plain TM easting and the ED50/TUREF datum are not, and stay tied unless `near=` breaks
|
|
151
|
+
the tie (use a surveyed point and a ~20 m tolerance to separate the datums).
|
|
152
|
+
|
|
153
|
+
### Command line
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
turkgrid convert --from 5254 --to 4326 412000 4542000 # or pipe "x y" lines on stdin
|
|
157
|
+
turkgrid detect points.csv [--near lon,lat] [--json] [-v]
|
|
158
|
+
turkgrid geojson in.geojson --to 4326 -o out.geojson # --from defaults to the crs member
|
|
159
|
+
turkgrid info [EPSG]
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Datum assumptions
|
|
163
|
+
|
|
164
|
+
* **TUREF is taken as WGS 84** (they agree to a few centimetres in Türkiye). EPSG:5261
|
|
165
|
+
"TUREF to WGS 84 (1)" is a zero-parameter transformation, applied as PROJ does.
|
|
166
|
+
* **ED50 → WGS 84 / TUREF uses EPSG:1784 "ED50 to WGS 84 (30)"**, position vector
|
|
167
|
+
(EPSG method 9606): tx −84.1, ty −101.8, tz −129.7 m, rx = ry = 0, rz +0.468″,
|
|
168
|
+
scale +1.05 ppm; same values as EPSG:1783 (published by HGK, the Turkish General
|
|
169
|
+
Directorate of Mapping); stated accuracy 2 m. It is applied on the ellipsoid surface
|
|
170
|
+
(height 0), like PROJ. The reverse direction is the **exact inverse** of the forward
|
|
171
|
+
one (round trips close to nanometres), solved by fixed-point refinement.
|
|
172
|
+
* Plain `pyproj.Transformer.from_crs(2320, 5254)` may choose another operation (e.g.
|
|
173
|
+
via ETRS89 with EPSG:5260, a few cm different, or a generic ED50 set metres away)
|
|
174
|
+
unless an area of interest or the operation is given; turkgrid always uses EPSG:1784.
|
|
175
|
+
|
|
176
|
+
## Supported EPSG codes · Desteklenen EPSG kodları
|
|
177
|
+
|
|
178
|
+
| Family / Sistem | Central meridian / Merkez meridyen | TUREF (GRS80) | ED50 (Int. 1924) | WGS 84 |
|
|
179
|
+
|---|---|---|---|---|
|
|
180
|
+
| 3° TM, FE 500 000 m, k0 = 1 | 27, 30, 33, 36, 39, 42, 45 | 5253 – 5259 | 2319 – 2325 | – |
|
|
181
|
+
| 3° Gauss-Krüger, FE = zone·10⁶ + 500 000 m (zones 9 – 15) | 27 … 45 | 5269 – 5275 | 2206 – 2212 | – |
|
|
182
|
+
| 6° UTM 35N – 38N, k0 = 0.9996 | 27, 33, 39, 45 | – | 23035 – 23038 | 32635 – 32638 |
|
|
183
|
+
| Geographic / Coğrafi | – | 5252 | 4230 | 4326 |
|
|
184
|
+
| Web Mercator | – | – | – | 3857 |
|
|
185
|
+
|
|
186
|
+
All 40 definitions (names, central meridians, false eastings, ellipsoids) are checked
|
|
187
|
+
against PROJ's EPSG database (v12.029) in the test-suite.
|
|
188
|
+
|
|
189
|
+
## Accuracy vs PROJ · PROJ ile karşılaştırma
|
|
190
|
+
|
|
191
|
+
Measured with pyproj 3.8 / PROJ 9.8.1 over **all 1 600 ordered pairs** of the 40 codes,
|
|
192
|
+
200 random points per source CRS spread over Türkiye (maximum horizontal difference):
|
|
193
|
+
|
|
194
|
+
| Pair type / Dönüşüm türü | Max difference vs PROJ |
|
|
195
|
+
|---|---|
|
|
196
|
+
| Same datum: TM ↔ GK ↔ UTM ↔ geographic ↔ Web Mercator (incl. TUREF ↔ WGS 84) | < 0.00001 mm (≈ 6 nm) |
|
|
197
|
+
| ED50 → TUREF / WGS 84 (EPSG:1784 forward) | < 0.00001 mm (≈ 8 nm) |
|
|
198
|
+
| TUREF / WGS 84 → ED50 (EPSG:1784 reverse) | ≤ 1.13 mm ¹ |
|
|
199
|
+
| Krüger series (6th order) inside / far outside a zone | nanometres (Karney 2011) |
|
|
200
|
+
|
|
201
|
+
¹ Not an error in turkgrid: PROJ's reverse operation evaluates the WGS 84 point at
|
|
202
|
+
height 0 and is therefore not an exact inverse of its forward operation — a PROJ
|
|
203
|
+
ED50 → WGS 84 → ED50 round trip fails to close by up to 1.08 mm. turkgrid's round trip
|
|
204
|
+
closes to < 0.00001 mm. The 2 m accuracy of EPSG:1784 itself dominates either way.
|
|
205
|
+
|
|
206
|
+
Speed (one core): pure Python ~100 000 points/s for TM ↔ WGS 84 and ~50 000 points/s
|
|
207
|
+
with the ED50 shift; with NumPy arrays ~800 000 points/s including the ED50 shift.
|
|
208
|
+
|
|
209
|
+
## Migration from cad2geo / NCZ2Geo · Geçiş notu
|
|
210
|
+
|
|
211
|
+
turkgrid unifies the projection code of the author's
|
|
212
|
+
[cad2geo](https://github.com/YusufEminoglu/cad2geo_sdk) (`cad2geo.reproject`,
|
|
213
|
+
`cad2geo.crs`) and [NCZ2Geo](https://github.com/YusufEminoglu/NCZ2Geo_sdk)
|
|
214
|
+
(`ncz2geo._projection`, `ncz2geo.transformer`). Neither package is changed by this
|
|
215
|
+
release; they can later add `turkgrid>=0.1` as a dependency and keep their public
|
|
216
|
+
functions as thin wrappers:
|
|
217
|
+
|
|
218
|
+
| Existing function | turkgrid equivalent |
|
|
219
|
+
|---|---|
|
|
220
|
+
| `cad2geo.to_wgs84(x, y, epsg, axes_swapped)` | `turkgrid.to_wgs84((x, y), epsg, axes_swapped=...)` |
|
|
221
|
+
| `cad2geo.reproject_geojson(gj, epsg, axes_swapped, ndigits)` | `turkgrid.reproject_geojson(gj, 4326, epsg, axes_swapped=..., precision=ndigits)` |
|
|
222
|
+
| `cad2geo.supported_epsg_codes()` / `cad2geo.crs` tables | `turkgrid.supported_epsg_codes()`, `turkgrid.epsg_info()`, `turkgrid.epsg_for_lon()` |
|
|
223
|
+
| `cad2geo.detect_crs(text, coords)` (coordinate part) | `turkgrid.detect_crs(coords)` (keep the metadata-text parsing in cad2geo) |
|
|
224
|
+
| `ncz2geo._projection.to_wgs84 / from_wgs84` | `turkgrid.transform_xy(x, y, srid, 4326)` and back |
|
|
225
|
+
| `ncz2geo.transformer.reproject_coordinate` | `turkgrid.transform_xy(x, y, src, dst)` |
|
|
226
|
+
| `ncz2geo.transformer.Helmert7Params`, `helmert_7parameter_transform` | `turkgrid.Helmert7(...).apply(x, y, z)` |
|
|
227
|
+
|
|
228
|
+
Behavioural differences to note when switching: the TM series is 6th order instead of
|
|
229
|
+
4th (sub-nanometre instead of sub-millimetre), ED50 inversion is exact, and TUREF
|
|
230
|
+
↔ WGS 84 follows PROJ's EPSG:5261 handling. turkgrid covers every code of both
|
|
231
|
+
packages (a superset: NCZ2Geo bundles 26 of these 40 codes, cad2geo 37 without Web
|
|
232
|
+
Mercator); NCZ2Geo keeps its WKT/PROJJSON definitions for its file writers.
|
|
233
|
+
|
|
234
|
+
## Development · Geliştirme
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
git clone https://github.com/YusufEminoglu/turkgrid_sdk.git
|
|
238
|
+
cd turkgrid_sdk
|
|
239
|
+
pip install -e ".[dev]"
|
|
240
|
+
python -m pytest # 198 tests incl. doctests; PROJ tests skip without pyproj
|
|
241
|
+
python -m ruff check . && python -m ruff format --check src tests && python -m mypy src
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## License · Lisans
|
|
245
|
+
|
|
246
|
+
MIT © 2026 Yusuf Eminoğlu. Parts of the code originate from the author's own cad2geo
|
|
247
|
+
and NCZ2Geo packages, which are published under GPL-2.0-or-later; as the sole author
|
|
248
|
+
and copyright holder of that code, the author releases it here under the MIT license.
|
|
249
|
+
The MIT license is GPL-compatible, so both packages can depend on turkgrid.
|
|
250
|
+
|
|
251
|
+
**References:** C. F. F. Karney (2011), *Transverse Mercator with an accuracy of a few
|
|
252
|
+
nanometers*, J. Geodesy 85:475-485 · IOGP EPSG Geodetic Parameter Dataset, operations
|
|
253
|
+
1783, 1784, 5260, 5261 · IOGP Guidance Note 7-2 (method 9606, position vector).
|