transformez 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.
- transformez-0.1.0/AUTHORS.md +10 -0
- transformez-0.1.0/LICENSE +21 -0
- transformez-0.1.0/PKG-INFO +210 -0
- transformez-0.1.0/README.md +168 -0
- transformez-0.1.0/pyproject.toml +41 -0
- transformez-0.1.0/setup.cfg +4 -0
- transformez-0.1.0/setup.py +2 -0
- transformez-0.1.0/src/transformez/__init__.py +125 -0
- transformez-0.1.0/src/transformez/cli.py +228 -0
- transformez-0.1.0/src/transformez/definitions.py +187 -0
- transformez-0.1.0/src/transformez/grid_engine.py +299 -0
- transformez-0.1.0/src/transformez/hooks.py +140 -0
- transformez-0.1.0/src/transformez/htdp.py +282 -0
- transformez-0.1.0/src/transformez/spatial.py +319 -0
- transformez-0.1.0/src/transformez/srs.py +169 -0
- transformez-0.1.0/src/transformez/transform.py +278 -0
- transformez-0.1.0/src/transformez/utils.py +43 -0
- transformez-0.1.0/src/transformez/vdatum.py +131 -0
- transformez-0.1.0/src/transformez.egg-info/PKG-INFO +210 -0
- transformez-0.1.0/src/transformez.egg-info/SOURCES.txt +22 -0
- transformez-0.1.0/src/transformez.egg-info/dependency_links.txt +1 -0
- transformez-0.1.0/src/transformez.egg-info/entry_points.txt +5 -0
- transformez-0.1.0/src/transformez.egg-info/requires.txt +4 -0
- transformez-0.1.0/src/transformez.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2010-2026 Regents of the University of Colorado
|
|
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.
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: transformez
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A standalone utility for vertical elevation datum transformations.
|
|
5
|
+
Author: Matthew Love
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2010-2026 Regents of the University of Colorado
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
Project-URL: Homepage, https://github.com/ciresdem/transformez
|
|
28
|
+
Project-URL: Issues, https://github.com/ciresdem/transformez/issues
|
|
29
|
+
Keywords: Geospatial
|
|
30
|
+
Classifier: Programming Language :: Python :: 3
|
|
31
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
32
|
+
Classifier: Operating System :: OS Independent
|
|
33
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
License-File: LICENSE
|
|
36
|
+
License-File: AUTHORS.md
|
|
37
|
+
Requires-Dist: numpy<2.0.0
|
|
38
|
+
Requires-Dist: pyproj
|
|
39
|
+
Requires-Dist: rasterio
|
|
40
|
+
Requires-Dist: fetchez>0.3.3
|
|
41
|
+
Dynamic: license-file
|
|
42
|
+
|
|
43
|
+
# 🌍 Transformez ↕
|
|
44
|
+
|
|
45
|
+
**Vertical datum transformations, simplified.**
|
|
46
|
+
|
|
47
|
+
> ⚠️ **BETA STATUS:** This project is in active development (v0.1.0).
|
|
48
|
+
|
|
49
|
+
Transformez is a standalone Python library and CLI for converting geospatial data between vertical datums (e.g., MLLW to NAVD88).
|
|
50
|
+
|
|
51
|
+
## Why Transformez?
|
|
52
|
+
|
|
53
|
+
Vertical datum transformation is often the hardest part of coastal DEM generation. Existing tools are either massive, complex desktop software or buried deep within heavy GIS libraries that are difficult to automate in a headless Linux environment.
|
|
54
|
+
|
|
55
|
+
**Transformez solves this by being:**
|
|
56
|
+
* **Lightweight:** A pure Python package that does one thing well. It doesn't require a GUI or a 5GB installer.
|
|
57
|
+
* **Grid-Based:** It uses the official VDatum GTIF/GTX grids directly, ensuring your transformations match authoritative standards.
|
|
58
|
+
* **Developer Friendly:** It offers a clean Python API for integrating vertical shifts directly into your numpy/rasterio pipelines, plus a CLI for quick batch processing.
|
|
59
|
+
|
|
60
|
+
It works in two ways:
|
|
61
|
+
1. **Standalone CLI:** Generate shift grids (TIF) for any region or match an existing DEM.
|
|
62
|
+
2. **Fetchez Plugin:** Automatically transform data as it is downloaded.
|
|
63
|
+
|
|
64
|
+

|
|
65
|
+
*(Above: A generated vertical shift grid transforming MLLW to NAVD88)*
|
|
66
|
+
|
|
67
|
+
## Features
|
|
68
|
+
|
|
69
|
+
* **Tidal Transformations:** Wraps NOAA's **VDatum** to transform between tidal surfaces (MLLW, MHHW) and geometric datums.
|
|
70
|
+
* **Geoid Grids:** Seamlessly applies PROJ-CDN geoids (GEOID18, GEOID12B, EGM2008).
|
|
71
|
+
* **Time-Dependent Shifts:** Integrates **HTDP** to handle crustal velocities and epoch transformations.
|
|
72
|
+
* **Grid Engine:** Automates the fetching, stitching, and mosaicking of partial VDatum grids into a single continuous shift surface.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Installation
|
|
77
|
+
|
|
78
|
+
* Requires **Fetchez** (v0.3.3+) and standard geospatial libs.
|
|
79
|
+
|
|
80
|
+
* **HTDP / VDatum**: See [NOAA Geodesy Tools](https://geodesy.noaa.gov/TOOLS/Htdp/Htdp.shtml).
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Clone and install
|
|
84
|
+
git clone https://github.com/ciresdem/transformez.git
|
|
85
|
+
cd transformez
|
|
86
|
+
pip install -e .
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Usage
|
|
90
|
+
1. Standalone CLI
|
|
91
|
+
Use transformez to generate shift grids for use in other software (PDAL, GDAL, CARIS) or to transform a specific DEM directly.
|
|
92
|
+
|
|
93
|
+
* Mode A: Region & Resolution
|
|
94
|
+
|
|
95
|
+
Generate a generic shift grid for a specific bounding box.
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Generate a shift grid from MLLW (5866) to NAVD88 (5703)
|
|
99
|
+
# -R: West/East/South/North
|
|
100
|
+
# -E: Grid resolution (e.g., 3 arc-seconds)
|
|
101
|
+
transformez -R -95.5/-94.5/28.5/29.5 -E 3s \
|
|
102
|
+
--vdatum-in "5866" \
|
|
103
|
+
--vdatum-out "5703:g2018" \
|
|
104
|
+
--output mllw_to_navd88.tif
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
* Mode B: Match Input DEM
|
|
108
|
+
|
|
109
|
+
Automatically extract the bounds and resolution from an input DEM and generate a matching transformed output.
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Transform an existing DEM from Ellipsoidal (6319) to Orthometric (5703)
|
|
113
|
+
transformez --dem input_dem.tif \
|
|
114
|
+
--vdatum-in "6319" \
|
|
115
|
+
--vdatum-out "5703" \
|
|
116
|
+
--output output_navd88.tif
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
2. As a Fetchez Hook
|
|
120
|
+
Configure fetchez to generate transformation grids automatically for downloaded data regions.
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Download SRTM and prepare a shift grid from EGM96 to WGS84
|
|
124
|
+
fetchez srtm_plus -R -120/-119/33/34 --hook transformez:datum_in=5773,datum_out=4979
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Python API
|
|
128
|
+
|
|
129
|
+
Transformez can be used directly in Python scripts to generate shift grids or transform arrays.
|
|
130
|
+
|
|
131
|
+
### 1. Generate a Vertical Shift Grid
|
|
132
|
+
Use `VerticalTransform` to calculate the shift array (numpy) between two datums for a specific region.
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
from transformez.transform import VerticalTransform
|
|
136
|
+
from fetchez.spatial import Region
|
|
137
|
+
from transformez.grid_engine import GridWriter
|
|
138
|
+
|
|
139
|
+
# 1. Define the Region (West, East, South, North)
|
|
140
|
+
# and the Grid Dimensions (nx, ny)
|
|
141
|
+
region = Region(-95.5, -94.5, 28.5, 29.5)
|
|
142
|
+
nx, ny = 1200, 1200
|
|
143
|
+
|
|
144
|
+
# 2. Initialize the Transformer
|
|
145
|
+
# - MLLW (5866) -> NAVD88 (5703) via GEOID18
|
|
146
|
+
vt = VerticalTransform(
|
|
147
|
+
region=region,
|
|
148
|
+
nx=nx, ny=ny,
|
|
149
|
+
epsg_in="5866",
|
|
150
|
+
epsg_out="5703:geoid=g2018"
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
# 3. Generate the Shift Array (numpy)
|
|
154
|
+
# Returns: (shift_grid, uncertainty_grid)
|
|
155
|
+
shift_grid, unc = vt._vertical_transform(vt.epsg_in, vt.epsg_out)
|
|
156
|
+
|
|
157
|
+
# 4. Save to GeoTIFF
|
|
158
|
+
GridWriter.write("mllw_to_navd88.tif", shift_grid, region)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### 2. Transform an Existing DEM
|
|
162
|
+
|
|
163
|
+
If you have a DEM and a generated shift grid, you can apply the transformation mathematically using GridEngine.
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
from transformez.grid_engine import GridEngine
|
|
167
|
+
|
|
168
|
+
# Apply the vertical shift: Output = Input + Shift
|
|
169
|
+
# Matches pixels 1:1, handling NoData and bounds automatically.
|
|
170
|
+
GridEngine.apply_vertical_shift(
|
|
171
|
+
src_dem="input_ellipsoidal.tif",
|
|
172
|
+
shift_array=shift_grid, # numpy array from step above
|
|
173
|
+
dst_dem="output_orthometric.tif"
|
|
174
|
+
)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### 3. Parse SRS & Datums
|
|
178
|
+
|
|
179
|
+
You can use the helper classes to resolve complex datum strings or EPSG codes.
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
from transformez.definitions import Datums
|
|
183
|
+
|
|
184
|
+
# Get VDatum CLI string for an EPSG
|
|
185
|
+
v_str = Datums.get_vdatum_id(5866)
|
|
186
|
+
# Returns: 'mllw:m:height'
|
|
187
|
+
|
|
188
|
+
# Get Default Geoid for a Datum
|
|
189
|
+
geoid = Datums.get_default_geoid(5703)
|
|
190
|
+
# Returns: 'g2018'
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Supported Datums
|
|
194
|
+
|
|
195
|
+
Transformez supports EPSG codes and common vertical datum names.
|
|
196
|
+
|
|
197
|
+
**Ellipsoidal:** 6319 (NAD83 2011), 4979 (WGS84)
|
|
198
|
+
|
|
199
|
+
**Orthometric:** 5703 (NAVD88), 5702 (NGVD29), 3855 (EGM2008)
|
|
200
|
+
|
|
201
|
+
**Tidal:** 5866 (MLLW), 5869 (MHHW), 5714 (MSL)
|
|
202
|
+
|
|
203
|
+
**Geoids:** g2018, g2012b, xgeoid20b, egm2008
|
|
204
|
+
|
|
205
|
+
## License
|
|
206
|
+
|
|
207
|
+
This project is licensed under the MIT License - see the [LICENSE](https://github.com/ciresdem/transformez/blob/main/LICENSE) file for details.
|
|
208
|
+
|
|
209
|
+
Copyright (c) 2010-2026 Regents of the University of Colorado
|
|
210
|
+
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# 🌍 Transformez ↕
|
|
2
|
+
|
|
3
|
+
**Vertical datum transformations, simplified.**
|
|
4
|
+
|
|
5
|
+
> ⚠️ **BETA STATUS:** This project is in active development (v0.1.0).
|
|
6
|
+
|
|
7
|
+
Transformez is a standalone Python library and CLI for converting geospatial data between vertical datums (e.g., MLLW to NAVD88).
|
|
8
|
+
|
|
9
|
+
## Why Transformez?
|
|
10
|
+
|
|
11
|
+
Vertical datum transformation is often the hardest part of coastal DEM generation. Existing tools are either massive, complex desktop software or buried deep within heavy GIS libraries that are difficult to automate in a headless Linux environment.
|
|
12
|
+
|
|
13
|
+
**Transformez solves this by being:**
|
|
14
|
+
* **Lightweight:** A pure Python package that does one thing well. It doesn't require a GUI or a 5GB installer.
|
|
15
|
+
* **Grid-Based:** It uses the official VDatum GTIF/GTX grids directly, ensuring your transformations match authoritative standards.
|
|
16
|
+
* **Developer Friendly:** It offers a clean Python API for integrating vertical shifts directly into your numpy/rasterio pipelines, plus a CLI for quick batch processing.
|
|
17
|
+
|
|
18
|
+
It works in two ways:
|
|
19
|
+
1. **Standalone CLI:** Generate shift grids (TIF) for any region or match an existing DEM.
|
|
20
|
+
2. **Fetchez Plugin:** Automatically transform data as it is downloaded.
|
|
21
|
+
|
|
22
|
+

|
|
23
|
+
*(Above: A generated vertical shift grid transforming MLLW to NAVD88)*
|
|
24
|
+
|
|
25
|
+
## Features
|
|
26
|
+
|
|
27
|
+
* **Tidal Transformations:** Wraps NOAA's **VDatum** to transform between tidal surfaces (MLLW, MHHW) and geometric datums.
|
|
28
|
+
* **Geoid Grids:** Seamlessly applies PROJ-CDN geoids (GEOID18, GEOID12B, EGM2008).
|
|
29
|
+
* **Time-Dependent Shifts:** Integrates **HTDP** to handle crustal velocities and epoch transformations.
|
|
30
|
+
* **Grid Engine:** Automates the fetching, stitching, and mosaicking of partial VDatum grids into a single continuous shift surface.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
* Requires **Fetchez** (v0.3.3+) and standard geospatial libs.
|
|
37
|
+
|
|
38
|
+
* **HTDP / VDatum**: See [NOAA Geodesy Tools](https://geodesy.noaa.gov/TOOLS/Htdp/Htdp.shtml).
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Clone and install
|
|
42
|
+
git clone https://github.com/ciresdem/transformez.git
|
|
43
|
+
cd transformez
|
|
44
|
+
pip install -e .
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Usage
|
|
48
|
+
1. Standalone CLI
|
|
49
|
+
Use transformez to generate shift grids for use in other software (PDAL, GDAL, CARIS) or to transform a specific DEM directly.
|
|
50
|
+
|
|
51
|
+
* Mode A: Region & Resolution
|
|
52
|
+
|
|
53
|
+
Generate a generic shift grid for a specific bounding box.
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Generate a shift grid from MLLW (5866) to NAVD88 (5703)
|
|
57
|
+
# -R: West/East/South/North
|
|
58
|
+
# -E: Grid resolution (e.g., 3 arc-seconds)
|
|
59
|
+
transformez -R -95.5/-94.5/28.5/29.5 -E 3s \
|
|
60
|
+
--vdatum-in "5866" \
|
|
61
|
+
--vdatum-out "5703:g2018" \
|
|
62
|
+
--output mllw_to_navd88.tif
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
* Mode B: Match Input DEM
|
|
66
|
+
|
|
67
|
+
Automatically extract the bounds and resolution from an input DEM and generate a matching transformed output.
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# Transform an existing DEM from Ellipsoidal (6319) to Orthometric (5703)
|
|
71
|
+
transformez --dem input_dem.tif \
|
|
72
|
+
--vdatum-in "6319" \
|
|
73
|
+
--vdatum-out "5703" \
|
|
74
|
+
--output output_navd88.tif
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
2. As a Fetchez Hook
|
|
78
|
+
Configure fetchez to generate transformation grids automatically for downloaded data regions.
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# Download SRTM and prepare a shift grid from EGM96 to WGS84
|
|
82
|
+
fetchez srtm_plus -R -120/-119/33/34 --hook transformez:datum_in=5773,datum_out=4979
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Python API
|
|
86
|
+
|
|
87
|
+
Transformez can be used directly in Python scripts to generate shift grids or transform arrays.
|
|
88
|
+
|
|
89
|
+
### 1. Generate a Vertical Shift Grid
|
|
90
|
+
Use `VerticalTransform` to calculate the shift array (numpy) between two datums for a specific region.
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
from transformez.transform import VerticalTransform
|
|
94
|
+
from fetchez.spatial import Region
|
|
95
|
+
from transformez.grid_engine import GridWriter
|
|
96
|
+
|
|
97
|
+
# 1. Define the Region (West, East, South, North)
|
|
98
|
+
# and the Grid Dimensions (nx, ny)
|
|
99
|
+
region = Region(-95.5, -94.5, 28.5, 29.5)
|
|
100
|
+
nx, ny = 1200, 1200
|
|
101
|
+
|
|
102
|
+
# 2. Initialize the Transformer
|
|
103
|
+
# - MLLW (5866) -> NAVD88 (5703) via GEOID18
|
|
104
|
+
vt = VerticalTransform(
|
|
105
|
+
region=region,
|
|
106
|
+
nx=nx, ny=ny,
|
|
107
|
+
epsg_in="5866",
|
|
108
|
+
epsg_out="5703:geoid=g2018"
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
# 3. Generate the Shift Array (numpy)
|
|
112
|
+
# Returns: (shift_grid, uncertainty_grid)
|
|
113
|
+
shift_grid, unc = vt._vertical_transform(vt.epsg_in, vt.epsg_out)
|
|
114
|
+
|
|
115
|
+
# 4. Save to GeoTIFF
|
|
116
|
+
GridWriter.write("mllw_to_navd88.tif", shift_grid, region)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### 2. Transform an Existing DEM
|
|
120
|
+
|
|
121
|
+
If you have a DEM and a generated shift grid, you can apply the transformation mathematically using GridEngine.
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
from transformez.grid_engine import GridEngine
|
|
125
|
+
|
|
126
|
+
# Apply the vertical shift: Output = Input + Shift
|
|
127
|
+
# Matches pixels 1:1, handling NoData and bounds automatically.
|
|
128
|
+
GridEngine.apply_vertical_shift(
|
|
129
|
+
src_dem="input_ellipsoidal.tif",
|
|
130
|
+
shift_array=shift_grid, # numpy array from step above
|
|
131
|
+
dst_dem="output_orthometric.tif"
|
|
132
|
+
)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 3. Parse SRS & Datums
|
|
136
|
+
|
|
137
|
+
You can use the helper classes to resolve complex datum strings or EPSG codes.
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
from transformez.definitions import Datums
|
|
141
|
+
|
|
142
|
+
# Get VDatum CLI string for an EPSG
|
|
143
|
+
v_str = Datums.get_vdatum_id(5866)
|
|
144
|
+
# Returns: 'mllw:m:height'
|
|
145
|
+
|
|
146
|
+
# Get Default Geoid for a Datum
|
|
147
|
+
geoid = Datums.get_default_geoid(5703)
|
|
148
|
+
# Returns: 'g2018'
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Supported Datums
|
|
152
|
+
|
|
153
|
+
Transformez supports EPSG codes and common vertical datum names.
|
|
154
|
+
|
|
155
|
+
**Ellipsoidal:** 6319 (NAD83 2011), 4979 (WGS84)
|
|
156
|
+
|
|
157
|
+
**Orthometric:** 5703 (NAVD88), 5702 (NGVD29), 3855 (EGM2008)
|
|
158
|
+
|
|
159
|
+
**Tidal:** 5866 (MLLW), 5869 (MHHW), 5714 (MSL)
|
|
160
|
+
|
|
161
|
+
**Geoids:** g2018, g2012b, xgeoid20b, egm2008
|
|
162
|
+
|
|
163
|
+
## License
|
|
164
|
+
|
|
165
|
+
This project is licensed under the MIT License - see the [LICENSE](https://github.com/ciresdem/transformez/blob/main/LICENSE) file for details.
|
|
166
|
+
|
|
167
|
+
Copyright (c) 2010-2026 Regents of the University of Colorado
|
|
168
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ['setuptools>=61.0']
|
|
3
|
+
build-backend = 'setuptools.build_meta'
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = 'transformez'
|
|
7
|
+
version = '0.1.0'
|
|
8
|
+
description = 'A standalone utility for vertical elevation datum transformations.'
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
authors = [{ name = 'Matthew Love' }]
|
|
11
|
+
license = { file = 'LICENSE' }
|
|
12
|
+
classifiers = [
|
|
13
|
+
'Programming Language :: Python :: 3',
|
|
14
|
+
'License :: OSI Approved :: MIT License',
|
|
15
|
+
'Operating System :: OS Independent',
|
|
16
|
+
'Topic :: Scientific/Engineering :: GIS',
|
|
17
|
+
]
|
|
18
|
+
dependencies = [
|
|
19
|
+
'numpy<2.0.0',
|
|
20
|
+
'pyproj',
|
|
21
|
+
'rasterio',
|
|
22
|
+
'fetchez>0.3.3',
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
keywords = ["Geospatial"]
|
|
26
|
+
|
|
27
|
+
[project.entry-points."fetchez.plugins"]
|
|
28
|
+
transformez = "transformez"
|
|
29
|
+
|
|
30
|
+
[project.scripts]
|
|
31
|
+
transformez = 'transformez.cli:transformez_cli'
|
|
32
|
+
|
|
33
|
+
[project.urls]
|
|
34
|
+
Homepage = "https://github.com/ciresdem/transformez"
|
|
35
|
+
Issues = "https://github.com/ciresdem/transformez/issues"
|
|
36
|
+
|
|
37
|
+
[tool.setuptools.packages.find]
|
|
38
|
+
where = ["src"] # Look for packages inside the 'src' folder
|
|
39
|
+
include = ["transformez*"] # Include the package named 'transformez'
|
|
40
|
+
exclude = ["tests*", "docs*", "scripts*", "examples*"]
|
|
41
|
+
namespaces = false
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
__version__ = "0.1.0"
|
|
4
|
+
__author__ = "Matthew Love"
|
|
5
|
+
__credits__ = "CIRES"
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
|
|
9
|
+
# --- fix the PROJ_LIB path to work with rasterio/pyproj
|
|
10
|
+
def _find_proj_lib():
|
|
11
|
+
"""Locate the best available PROJ_LIB path."""
|
|
12
|
+
|
|
13
|
+
try:
|
|
14
|
+
import rasterio
|
|
15
|
+
# Common path in wheels: site-packages/rasterio/proj_data
|
|
16
|
+
r_path = os.path.join(os.path.dirname(rasterio.__file__), 'proj_data')
|
|
17
|
+
if os.path.exists(os.path.join(r_path, 'proj.db')):
|
|
18
|
+
return r_path
|
|
19
|
+
|
|
20
|
+
# Linux wheels often put it in .libs adjacent to the package
|
|
21
|
+
# e.g. site-packages/rasterio.libs/proj.db
|
|
22
|
+
parent = os.path.dirname(os.path.dirname(rasterio.__file__))
|
|
23
|
+
libs = glob.glob(os.path.join(parent, 'rasterio.libs*'))
|
|
24
|
+
if libs:
|
|
25
|
+
# Look inside the libs folder
|
|
26
|
+
for root, _, files in os.walk(libs[0]):
|
|
27
|
+
if 'proj.db' in files:
|
|
28
|
+
return root
|
|
29
|
+
except ImportError:
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
# Try PyProj's bundled data (Fallback)
|
|
33
|
+
try:
|
|
34
|
+
import pyproj
|
|
35
|
+
p_path = pyproj.datadir.get_data_dir()
|
|
36
|
+
if os.path.exists(os.path.join(p_path, 'proj.db')):
|
|
37
|
+
return p_path
|
|
38
|
+
except ImportError:
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
return None
|
|
42
|
+
|
|
43
|
+
target_proj_lib = _find_proj_lib()
|
|
44
|
+
|
|
45
|
+
# Unset conflicting system/conda vars if we found a better one
|
|
46
|
+
if 'PROJ_LIB' in os.environ:
|
|
47
|
+
del os.environ['PROJ_LIB']
|
|
48
|
+
|
|
49
|
+
if target_proj_lib:
|
|
50
|
+
os.environ['PROJ_LIB'] = target_proj_lib
|
|
51
|
+
# print(f"DEBUG: PROJ_LIB set to {target_proj_lib}")
|
|
52
|
+
|
|
53
|
+
# # --- PROJ_LIB Fix (Run before any geo-imports) ---
|
|
54
|
+
# # This prevents "PROJ: proj_create_from_database: Cannot find proj.db" errors
|
|
55
|
+
# # when conflicting Conda/System PROJ installations exist.
|
|
56
|
+
# try:
|
|
57
|
+
# # 1. We must import pyproj first to let it find its own bundled data
|
|
58
|
+
# import os
|
|
59
|
+
# import pyproj
|
|
60
|
+
|
|
61
|
+
# # 2. Get the valid data directory from the wheel
|
|
62
|
+
# proj_lib = pyproj.datadir.get_data_dir()
|
|
63
|
+
# #print(proj_lib)
|
|
64
|
+
# # 3. Force the environment variable to use this valid path
|
|
65
|
+
# # (Overriding any bad global/Conda defaults)
|
|
66
|
+
# os.environ['PROJ_LIB'] = proj_lib
|
|
67
|
+
|
|
68
|
+
# except ImportError:
|
|
69
|
+
# # If pyproj isn't installed yet (e.g. during pip install), skip this.
|
|
70
|
+
# pass
|
|
71
|
+
|
|
72
|
+
# --- End PROJ_LIB Fix ---
|
|
73
|
+
|
|
74
|
+
from .hooks import TransformezHook
|
|
75
|
+
#from .modules import DatumGridFetcher
|
|
76
|
+
from fetchez.hooks.registry import HookRegistry
|
|
77
|
+
# form fetchez.registry import FetchezRegistry # Implicitly handled via setup_fetchez passing cls
|
|
78
|
+
|
|
79
|
+
def setup_fetchez(registry_cls):
|
|
80
|
+
"""Called by fetchez when loading plugins.
|
|
81
|
+
Registers modules, hooks, and presets.
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
# module should gather necessary grids to do the transformation
|
|
85
|
+
# Register the Module with Fetchez
|
|
86
|
+
# registry_cls.register_module(
|
|
87
|
+
# mod_key='datum_grids',
|
|
88
|
+
# mod_cls=DatumGridFetcher,
|
|
89
|
+
# metadata={
|
|
90
|
+
# 'desc': 'Fetch NOAA VDatum and PROJ-CDN grids for a region',
|
|
91
|
+
# 'tags': ['vdatum', 'geoid', 'transformation']
|
|
92
|
+
# }
|
|
93
|
+
# )
|
|
94
|
+
|
|
95
|
+
# Register Fetchez Hooks
|
|
96
|
+
HookRegistry.register_hook(TransformezHook)
|
|
97
|
+
|
|
98
|
+
# Register Global Presets
|
|
99
|
+
from fetchez.presets import register_global_preset
|
|
100
|
+
|
|
101
|
+
register_global_preset(
|
|
102
|
+
name="make-shift-grid",
|
|
103
|
+
help_text="Download datum grids and composite them into a single GTX shift grid.",
|
|
104
|
+
hooks=[
|
|
105
|
+
{"name": "transformez", "args": {}}
|
|
106
|
+
]
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
# "transform-pipeline": {
|
|
111
|
+
# "help_text": "Generate shift grid based on region, then apply it to files.",
|
|
112
|
+
# "hooks": [
|
|
113
|
+
# {
|
|
114
|
+
# "name": "transformez",
|
|
115
|
+
# "args": {"stage": "pre", "datum_in": "5703", "output_grid": "/tmp/shift.gtx"}
|
|
116
|
+
# },
|
|
117
|
+
# {
|
|
118
|
+
# "name": "transformez",
|
|
119
|
+
# "args": {"stage": "file", "apply": "True", "output_grid": "/tmp/shift.gtx"}
|
|
120
|
+
# },
|
|
121
|
+
# {
|
|
122
|
+
# "name": "audit"
|
|
123
|
+
# }
|
|
124
|
+
# ]
|
|
125
|
+
# }
|