Skip to content

Commit daa2b34

Browse files
authored
use vdatum grid date to sort (#47)
* use vdatum grid date to sort * ruff format
1 parent f1c45c3 commit daa2b34

4 files changed

Lines changed: 84 additions & 11 deletions

File tree

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@ Originally developed as the core transformation engine for the [CUDEM](https://g
2020

2121
---
2222

23-
### ❓ Why Transformez?
23+
## ❓ Why Transformez?
2424

2525
Vertical Datum transformations can cause a lot of confusion and headache when trying to process heterogeneous data from around the world into a single unified vertial reference.
2626

2727
**Transformez simplifies this process!**
2828

29+
---
30+
2931
## 📦 Installation
3032

3133
**Install Transformez**
@@ -64,6 +66,7 @@ transformez raster my_dem.tif -I mllw -O 5703
6466
# Download GEBCO and shift EGM96 to WGS84 on the fly
6567
fetchez gebco ... --hook transformez:datum_in=5773,datum_out=4979
6668
```
69+
---
6770

6871
## 📚 Documentation
6972
Would you like to know more? Check out our [Official Documentation](https://transformez.readthedocs.io) to learn about:

src/transformez/grid_engine.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ def coastal_aware_composite(
159159
buffer_pixels=10,
160160
max_discontinuity=0.5,
161161
):
162-
"""Intelligently handles inland decay vs. offshore blending, while
162+
"""Handles inland decay vs. offshore blending, while
163163
filtering out low-resolution global artifacts.
164164
"""
165165

src/transformez/transform.py

Lines changed: 78 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,11 @@ def fetch_grid(self, module_name, **kwargs):
119119

120120
if fn.endswith(".zip"):
121121
datatype = kwargs.get("datatype")
122-
fns_to_extract = [datatype] if datatype else None
122+
if datatype:
123+
fns_to_extract = [datatype, ".met", ".inf"]
124+
else:
125+
fns_to_extract = None
126+
123127
extracted = fetchez.utils.p_f_unzip(
124128
fn, fns=fns_to_extract, outdir=self.cache_dir
125129
)
@@ -166,8 +170,14 @@ def fetch_grid_(self, module_name, **kwargs):
166170
continue
167171

168172
if fn.endswith(".zip"):
173+
datatype = kwargs.get("datatype")
174+
if datatype:
175+
fns_to_extract = [datatype, ".met", ".inf"]
176+
else:
177+
fns_to_extract = None
178+
169179
extracted = fetchez.utils.p_f_unzip(
170-
fn, fns=[r["data_type"]], outdir=self.cache_dir
180+
fn, fns=fns_to_extract, outdir=self.cache_dir
171181
)
172182
valid.extend(
173183
[
@@ -208,17 +218,78 @@ def _get_grid(self, provider, name):
208218
files = self.fetch_grid(provider, datatype=name, query=name)
209219
if provider == "vdatum":
210220
import rasterio
221+
from datetime import datetime
222+
223+
def get_vdatum_date(gtx_path):
224+
"""Finds and parses the release date from VDatum metadata files."""
225+
226+
dir_name = os.path.dirname(gtx_path)
227+
meta_files = [
228+
f for f in os.listdir(dir_name) if f.endswith((".met", ".inf"))
229+
]
230+
231+
if not meta_files:
232+
return datetime(1970, 1, 1)
233+
234+
meta_path = os.path.join(dir_name, meta_files[0])
235+
try:
236+
with open(meta_path, "r") as f:
237+
content = f.read().splitlines()
238+
239+
if not content:
240+
return datetime(1970, 1, 1)
241+
242+
first_line = content[0]
243+
244+
# Parse the first line "#Mon Jul 08 10:27:07 EDT 2019"
245+
if first_line.startswith("#"):
246+
parts = first_line.replace("#", "").split()
247+
if len(parts) >= 6:
248+
year = int(parts[-1])
249+
day = int(parts[2])
250+
month_map = {
251+
"Jan": 1,
252+
"Feb": 2,
253+
"Mar": 3,
254+
"Apr": 4,
255+
"May": 5,
256+
"Jun": 6,
257+
"Jul": 7,
258+
"Aug": 8,
259+
"Sep": 9,
260+
"Oct": 10,
261+
"Nov": 11,
262+
"Dec": 12,
263+
}
264+
month = month_map.get(parts[1][:3].title(), 1)
265+
return datetime(year, month, day)
266+
267+
# Fallback to scanning for "released_date="
268+
for line in content:
269+
if "released_date=" in line:
270+
date_str = line.split("=")[1].strip()
271+
m, d, y = map(int, date_str.split("/"))
272+
return datetime(y, m, d)
273+
274+
except Exception as e:
275+
logger.debug(f"Failed to parse date from {meta_path}: {e}")
276+
277+
return datetime(1970, 1, 1)
278+
279+
def sort_key(filepath):
280+
# Time Sorting (Oldest -> Newest)
281+
date_val = get_vdatum_date(filepath)
211282

212-
def get_bbox_area(filepath):
213283
try:
214284
with rasterio.open(filepath) as src:
215285
b = src.bounds
216-
return (b.right - b.left) * (b.top - b.bottom)
286+
area = (b.right - b.left) * (b.top - b.bottom)
217287
except Exception:
218-
return float("inf")
288+
area = float("inf")
289+
290+
return (date_val.timestamp(), -area)
219291

220-
# Largest (Offshore) loads first, Smallest (Rivers) load last and overwrite
221-
files.sort(key=get_bbox_area, reverse=True)
292+
files.sort(key=sort_key, reverse=True)
222293

223294
if not files:
224295
return np.zeros((self.ny, self.nx))

src/transformez/utils.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ def cmd_exists(x: str) -> bool:
3030
def run_cmd(args):
3131
"""Standalone replacement for utils.run_cmd using subprocess."""
3232

33-
logger.info(f"Running: {' '.join(args) if isinstance(args, list) else args}")
34-
33+
logger.debug(f"Running: {' '.join(args) if isinstance(args, list) else args}")
3534
result = subprocess.run(
3635
args,
3736
shell=False if isinstance(args, list) else True,

0 commit comments

Comments
 (0)