viewtif 0.1.9__tar.gz → 0.1.10__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.
- {viewtif-0.1.9 → viewtif-0.1.10}/PKG-INFO +8 -3
- {viewtif-0.1.9 → viewtif-0.1.10}/README.md +7 -2
- {viewtif-0.1.9 → viewtif-0.1.10}/pyproject.toml +1 -1
- {viewtif-0.1.9 → viewtif-0.1.10}/src/viewtif/tif_viewer.py +132 -100
- {viewtif-0.1.9 → viewtif-0.1.10}/.gitignore +0 -0
- {viewtif-0.1.9 → viewtif-0.1.10}/examples/README.md +0 -0
- {viewtif-0.1.9 → viewtif-0.1.10}/examples/sample_data/AG100.v003.13.-017.0001.h5 +0 -0
- {viewtif-0.1.9 → viewtif-0.1.10}/examples/sample_data/ECOSTRESS_LST.tif +0 -0
- {viewtif-0.1.9 → viewtif-0.1.10}/examples/sample_data/HLS_B02.tif +0 -0
- {viewtif-0.1.9 → viewtif-0.1.10}/examples/sample_data/HLS_B03.tif +0 -0
- {viewtif-0.1.9 → viewtif-0.1.10}/examples/sample_data/HLS_B04.tif +0 -0
- {viewtif-0.1.9 → viewtif-0.1.10}/examples/sample_data/Zip_Codes.cpg +0 -0
- {viewtif-0.1.9 → viewtif-0.1.10}/examples/sample_data/Zip_Codes.dbf +0 -0
- {viewtif-0.1.9 → viewtif-0.1.10}/examples/sample_data/Zip_Codes.prj +0 -0
- {viewtif-0.1.9 → viewtif-0.1.10}/examples/sample_data/Zip_Codes.shp +0 -0
- {viewtif-0.1.9 → viewtif-0.1.10}/examples/sample_data/Zip_Codes.shx +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: viewtif
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.10
|
|
4
4
|
Summary: Lightweight GeoTIFF, HDF/HDF5, and Esri File Geodatabase (.gdb) viewer with shapefile overlay and large-raster safeguard.
|
|
5
5
|
Project-URL: Homepage, https://github.com/nkeikon/tifviewer
|
|
6
6
|
Project-URL: Source, https://github.com/nkeikon/tifviewer
|
|
@@ -27,6 +27,11 @@ A lightweight GeoTIFF viewer for quick visualization directly from the command l
|
|
|
27
27
|
|
|
28
28
|
You can visualize single-band GeoTIFFs, RGB composites, and shapefile overlays in a simple Qt-based window.
|
|
29
29
|
|
|
30
|
+
---
|
|
31
|
+
Latest stable release: v0.1.9 (PyPI)
|
|
32
|
+
|
|
33
|
+
Development branch: v0.2.0-dev (experimental, not released)
|
|
34
|
+
|
|
30
35
|
---
|
|
31
36
|
|
|
32
37
|
## Installation
|
|
@@ -87,7 +92,7 @@ viewtif AG100.v003.33.-107.0001.h5 --subset 1 --band 3
|
|
|
87
92
|
|
|
88
93
|
### Update in v1.0.7: File Geodatabase (.gdb) support
|
|
89
94
|
`viewtif` can now open raster datasets stored inside Esri File Geodatabases (`.gdb`), using the GDAL `OpenFileGDB` driver.
|
|
90
|
-
When you open a .gdb directly, `viewtif
|
|
95
|
+
When you open a .gdb directly, `viewtif` will list available raster datasets first, then you can choose one to view.
|
|
91
96
|
|
|
92
97
|
```bash
|
|
93
98
|
# List available raster datasets
|
|
@@ -138,4 +143,4 @@ This project is released under the MIT License.
|
|
|
138
143
|
|
|
139
144
|
## Contributors
|
|
140
145
|
- [@HarshShinde0](https://github.com/HarshShinde0) — added mouse-wheel and trackpad zoom support
|
|
141
|
-
- [@p-vdp](https://github.com/p-vdp) — added File Geodatabase (.gdb) raster support
|
|
146
|
+
- [@p-vdp](https://github.com/p-vdp) — added File Geodatabase (.gdb) raster support
|
|
@@ -7,6 +7,11 @@ A lightweight GeoTIFF viewer for quick visualization directly from the command l
|
|
|
7
7
|
|
|
8
8
|
You can visualize single-band GeoTIFFs, RGB composites, and shapefile overlays in a simple Qt-based window.
|
|
9
9
|
|
|
10
|
+
---
|
|
11
|
+
Latest stable release: v0.1.9 (PyPI)
|
|
12
|
+
|
|
13
|
+
Development branch: v0.2.0-dev (experimental, not released)
|
|
14
|
+
|
|
10
15
|
---
|
|
11
16
|
|
|
12
17
|
## Installation
|
|
@@ -67,7 +72,7 @@ viewtif AG100.v003.33.-107.0001.h5 --subset 1 --band 3
|
|
|
67
72
|
|
|
68
73
|
### Update in v1.0.7: File Geodatabase (.gdb) support
|
|
69
74
|
`viewtif` can now open raster datasets stored inside Esri File Geodatabases (`.gdb`), using the GDAL `OpenFileGDB` driver.
|
|
70
|
-
When you open a .gdb directly, `viewtif
|
|
75
|
+
When you open a .gdb directly, `viewtif` will list available raster datasets first, then you can choose one to view.
|
|
71
76
|
|
|
72
77
|
```bash
|
|
73
78
|
# List available raster datasets
|
|
@@ -118,4 +123,4 @@ This project is released under the MIT License.
|
|
|
118
123
|
|
|
119
124
|
## Contributors
|
|
120
125
|
- [@HarshShinde0](https://github.com/HarshShinde0) — added mouse-wheel and trackpad zoom support
|
|
121
|
-
- [@p-vdp](https://github.com/p-vdp) — added File Geodatabase (.gdb) raster support
|
|
126
|
+
- [@p-vdp](https://github.com/p-vdp) — added File Geodatabase (.gdb) raster support
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "viewtif"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.10"
|
|
8
8
|
description = "Lightweight GeoTIFF, HDF/HDF5, and Esri File Geodatabase (.gdb) viewer with shapefile overlay and large-raster safeguard."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -53,37 +53,52 @@ except Exception:
|
|
|
53
53
|
HAVE_GEO = False
|
|
54
54
|
|
|
55
55
|
def warn_if_large(tif_path, scale=1):
|
|
56
|
-
"""Warn and confirm before loading very large rasters (GeoTIFF, GDB, or HDF).
|
|
57
|
-
|
|
56
|
+
"""Warn and confirm before loading very large rasters (GeoTIFF, GDB, or HDF).
|
|
57
|
+
Works even if GDAL is not installed.
|
|
58
|
+
"""
|
|
58
59
|
import os
|
|
60
|
+
width = height = None
|
|
61
|
+
size_mb = None
|
|
59
62
|
|
|
63
|
+
# Try GDAL if available
|
|
60
64
|
try:
|
|
65
|
+
from osgeo import gdal
|
|
61
66
|
gdal.UseExceptions()
|
|
62
67
|
info = gdal.Info(tif_path, format="json")
|
|
63
68
|
width, height = info.get("size", [0, 0])
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
print(
|
|
72
|
-
|
|
73
|
-
+ (f", ~{size_mb:.1f} MB" if size_mb else "")
|
|
74
|
-
+ "). Loading may freeze. Consider rerunning with --scale (e.g. --scale 10)."
|
|
75
|
-
)
|
|
76
|
-
ans = input("Proceed anyway? [y/N]: ").strip().lower()
|
|
77
|
-
if ans not in ("y", "yes"):
|
|
78
|
-
print("Cancelled.")
|
|
79
|
-
sys.exit(0)
|
|
69
|
+
except ImportError:
|
|
70
|
+
# Fallback if GDAL not installed
|
|
71
|
+
try:
|
|
72
|
+
import rasterio
|
|
73
|
+
with rasterio.open(tif_path) as src:
|
|
74
|
+
width, height = src.width, src.height
|
|
75
|
+
except Exception:
|
|
76
|
+
print("[WARN] Could not estimate raster size (no GDAL/rasterio). Skipping size check.")
|
|
77
|
+
return
|
|
80
78
|
except Exception as e:
|
|
81
|
-
print(f"[WARN] Could not pre-check raster size: {e}")
|
|
79
|
+
print(f"[WARN] Could not pre-check raster size with GDAL: {e}")
|
|
80
|
+
return
|
|
81
|
+
|
|
82
|
+
# File size
|
|
83
|
+
if os.path.exists(tif_path):
|
|
84
|
+
size_mb = os.path.getsize(tif_path) / (1024 ** 2)
|
|
85
|
+
|
|
86
|
+
total_pixels = (width * height) / (scale ** 2)
|
|
87
|
+
if total_pixels > 20_000_000 and scale <= 5:
|
|
88
|
+
msg = (
|
|
89
|
+
f"[WARN] Large raster detected ({width}×{height}, ~{total_pixels/1e6:.1f}M pixels"
|
|
90
|
+
+ (f", ~{size_mb:.1f} MB" if size_mb else "")
|
|
91
|
+
+ "). Loading may freeze. Consider --scale (e.g. --scale 10)."
|
|
92
|
+
)
|
|
93
|
+
print(msg)
|
|
94
|
+
ans = input("Proceed anyway? [y/N]: ").strip().lower()
|
|
95
|
+
if ans not in ("y", "yes"):
|
|
96
|
+
print("Cancelled.")
|
|
97
|
+
sys.exit(0)
|
|
82
98
|
|
|
83
99
|
# -------------------------- QGraphicsView tweaks -------------------------- #
|
|
84
100
|
class RasterView(QGraphicsView):
|
|
85
101
|
def __init__(self, *args, **kwargs):
|
|
86
|
-
import numpy as np
|
|
87
102
|
super().__init__(*args, **kwargs)
|
|
88
103
|
self.setRenderHint(QPainter.RenderHint.SmoothPixmapTransform, False)
|
|
89
104
|
self.setDragMode(QGraphicsView.DragMode.ScrollHandDrag)
|
|
@@ -190,84 +205,96 @@ class TiffViewer(QMainWindow):
|
|
|
190
205
|
except subprocess.CalledProcessError as e:
|
|
191
206
|
print(f"[WARN] Could not inspect FileGDB: {e}")
|
|
192
207
|
sys.exit(0)
|
|
193
|
-
|
|
208
|
+
|
|
209
|
+
# --- Universal size check before loading ---
|
|
194
210
|
warn_if_large(tif_path, scale=self._scale_arg)
|
|
211
|
+
|
|
195
212
|
# --------------------- Detect HDF/HDF5 --------------------- #
|
|
196
213
|
if tif_path.lower().endswith((".hdf", ".h5", ".hdf5")):
|
|
197
214
|
try:
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
+
# Try reading directly with Rasterio first (works for simple HDF layouts)
|
|
216
|
+
with rasterio.open(tif_path) as src:
|
|
217
|
+
print(f"Opened HDF with rasterio: {os.path.basename(tif_path)}")
|
|
218
|
+
arr = src.read().astype(np.float32)
|
|
219
|
+
arr = np.squeeze(arr)
|
|
220
|
+
if arr.ndim == 3:
|
|
221
|
+
arr = np.transpose(arr, (1, 2, 0))
|
|
222
|
+
elif arr.ndim == 2:
|
|
223
|
+
print("Single-band dataset.")
|
|
224
|
+
self.data = arr
|
|
225
|
+
self._transform = src.transform
|
|
226
|
+
self._crs = src.crs
|
|
227
|
+
self.band_count = arr.shape[2] if arr.ndim == 3 else 1
|
|
228
|
+
self.band_index = 0
|
|
229
|
+
self.vmin, self.vmax = np.nanmin(arr), np.nanmax(arr)
|
|
230
|
+
return # ✅ Skip GDAL path if Rasterio succeeded
|
|
231
|
+
|
|
232
|
+
except Exception as e:
|
|
233
|
+
print(f"Rasterio could not open HDF directly: {e}")
|
|
234
|
+
print("Falling back to GDAL...")
|
|
235
|
+
|
|
236
|
+
try:
|
|
237
|
+
from osgeo import gdal
|
|
238
|
+
gdal.UseExceptions()
|
|
239
|
+
|
|
240
|
+
ds = gdal.Open(tif_path)
|
|
241
|
+
subs = ds.GetSubDatasets()
|
|
242
|
+
if not subs:
|
|
243
|
+
raise ValueError("No subdatasets found in HDF/HDF5 file.")
|
|
244
|
+
|
|
245
|
+
print(f"Found {len(subs)} subdatasets in {os.path.basename(tif_path)}:")
|
|
246
|
+
for i, (_, desc) in enumerate(subs):
|
|
247
|
+
print(f"[{i}] {desc}")
|
|
248
|
+
|
|
249
|
+
if subset is None:
|
|
250
|
+
print("\nUse --subset N to open a specific subdataset.")
|
|
251
|
+
sys.exit(0)
|
|
252
|
+
|
|
253
|
+
if subset < 0 or subset >= len(subs):
|
|
254
|
+
raise ValueError(f"Invalid subset index {subset}. Valid range: 0–{len(subs)-1}")
|
|
255
|
+
|
|
256
|
+
sub_name, desc = subs[subset]
|
|
257
|
+
print(f"\nOpening subdataset [{subset}]: {desc}")
|
|
258
|
+
sub_ds = gdal.Open(sub_name)
|
|
259
|
+
|
|
260
|
+
arr = sub_ds.ReadAsArray().astype(np.float32)
|
|
261
|
+
arr = np.squeeze(arr)
|
|
262
|
+
if arr.ndim == 3:
|
|
263
|
+
arr = np.transpose(arr, (1, 2, 0))
|
|
264
|
+
elif arr.ndim == 2:
|
|
265
|
+
print("Single-band dataset.")
|
|
266
|
+
else:
|
|
267
|
+
raise ValueError(f"Unexpected array shape {arr.shape}")
|
|
268
|
+
|
|
269
|
+
# Downsample large arrays for responsiveness
|
|
270
|
+
h, w = arr.shape[:2]
|
|
271
|
+
if h * w > 4_000_000:
|
|
272
|
+
step = max(2, int((h * w / 4_000_000) ** 0.5))
|
|
273
|
+
arr = arr[::step, ::step] if arr.ndim == 2 else arr[::step, ::step, :]
|
|
274
|
+
print(f"⚠️ Large dataset preview: downsampled by {step}x")
|
|
275
|
+
|
|
276
|
+
# Assign
|
|
277
|
+
self.data = arr
|
|
278
|
+
self._transform = None
|
|
279
|
+
self._crs = None
|
|
280
|
+
self.band_count = arr.shape[2] if arr.ndim == 3 else 1
|
|
281
|
+
self.band_index = 0
|
|
282
|
+
self.vmin, self.vmax = np.nanmin(arr), np.nanmax(arr)
|
|
215
283
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
sub_name, desc = subs[subset]
|
|
221
|
-
print(f"\nOpening subdataset [{subset}]: {desc}")
|
|
222
|
-
sub_ds = gdal.Open(sub_name)
|
|
223
|
-
|
|
224
|
-
# --- Read once ---
|
|
225
|
-
arr = sub_ds.ReadAsArray().astype(np.float32)
|
|
226
|
-
#print(f"Raw array shape from GDAL: {arr.shape} (ndim={arr.ndim})")
|
|
227
|
-
|
|
228
|
-
# --- Normalize shape ---
|
|
229
|
-
arr = np.squeeze(arr)
|
|
230
|
-
if arr.ndim == 3:
|
|
231
|
-
# Convert from (bands, rows, cols) → (rows, cols, bands)
|
|
232
|
-
arr = np.transpose(arr, (1, 2, 0))
|
|
233
|
-
#print(f"Transposed to {arr.shape} (rows, cols, bands)")
|
|
234
|
-
elif arr.ndim == 2:
|
|
235
|
-
print("Single-band dataset.")
|
|
236
|
-
else:
|
|
237
|
-
raise ValueError(f"Unexpected array shape {arr.shape}")
|
|
238
|
-
|
|
239
|
-
# --- Downsample large arrays for responsiveness ---
|
|
240
|
-
h, w = arr.shape[:2]
|
|
241
|
-
if h * w > 4_000_000:
|
|
242
|
-
step = max(2, int((h * w / 4_000_000) ** 0.5))
|
|
243
|
-
arr = arr[::step, ::step] if arr.ndim == 2 else arr[::step, ::step, :]
|
|
244
|
-
print(f"⚠️ Large dataset preview: downsampled by {step}x")
|
|
245
|
-
|
|
246
|
-
# --- Final assignments ---
|
|
247
|
-
self.data = arr
|
|
248
|
-
self._transform = None
|
|
249
|
-
self._crs = None
|
|
250
|
-
self.band_count = arr.shape[2] if arr.ndim == 3 else 1
|
|
251
|
-
self.band_index = 0
|
|
252
|
-
self.vmin, self.vmax = np.nanmin(arr), np.nanmax(arr)
|
|
253
|
-
|
|
254
|
-
if self.band_count > 1:
|
|
255
|
-
print(f"This subdataset has {self.band_count} bands — switch with [ and ] keys.")
|
|
256
|
-
else:
|
|
257
|
-
print("This subdataset has 1 band.")
|
|
284
|
+
if self.band_count > 1:
|
|
285
|
+
print(f"This subdataset has {self.band_count} bands — switch with [ and ] keys.")
|
|
286
|
+
else:
|
|
287
|
+
print("This subdataset has 1 band.")
|
|
258
288
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
print(f"Opening band {self.band}/{self.band_count}")
|
|
263
|
-
else:
|
|
264
|
-
self.band_index = 0
|
|
289
|
+
if self.band and self.band <= self.band_count:
|
|
290
|
+
self.band_index = self.band - 1
|
|
291
|
+
print(f"Opening band {self.band}/{self.band_count}")
|
|
265
292
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
293
|
+
except ImportError:
|
|
294
|
+
raise RuntimeError(
|
|
295
|
+
"HDF/HDF5 support requires GDAL (Python bindings).\n"
|
|
296
|
+
"Install it first (e.g., brew install gdal && pip install GDAL)"
|
|
297
|
+
)
|
|
271
298
|
|
|
272
299
|
# --------------------- Regular GeoTIFF --------------------- #
|
|
273
300
|
else:
|
|
@@ -487,8 +514,7 @@ class TiffViewer(QMainWindow):
|
|
|
487
514
|
rgb = np.zeros_like(arr)
|
|
488
515
|
if np.any(finite):
|
|
489
516
|
# Global 2–98 percentile stretch across all bands (QGIS-like)
|
|
490
|
-
global_min = np.nanpercentile(arr, 2)
|
|
491
|
-
global_max = np.nanpercentile(arr, 98)
|
|
517
|
+
global_min, global_max = np.nanpercentile(arr, (2, 98))
|
|
492
518
|
rng = max(global_max - global_min, 1e-12)
|
|
493
519
|
norm = np.clip((arr - global_min) / rng, 0, 1)
|
|
494
520
|
rgb = np.clip(norm * self.contrast, 0, 1)
|
|
@@ -640,8 +666,8 @@ class TiffViewer(QMainWindow):
|
|
|
640
666
|
super().keyPressEvent(ev)
|
|
641
667
|
|
|
642
668
|
|
|
643
|
-
# --------------------------------- CLI ----------------------------------- #
|
|
644
|
-
def
|
|
669
|
+
# --------------------------------- Legacy argparse CLI (not used by default) ----------------------------------- #
|
|
670
|
+
def legacy_argparse_main():
|
|
645
671
|
parser = argparse.ArgumentParser(description="TIFF viewer with RGB (2–98%) & shapefile overlays")
|
|
646
672
|
parser.add_argument("tif_path", nargs="?", help="Path to TIFF (optional if --rgbfiles is used)")
|
|
647
673
|
parser.add_argument("--scale", type=int, default=1, help="Downsample factor (1=full, 10=10x smaller)")
|
|
@@ -653,6 +679,8 @@ def main():
|
|
|
653
679
|
parser.add_argument("--shp-width", type=float, default=1.5, help="Overlay line width (screen pixels). Default: 1.5")
|
|
654
680
|
args = parser.parse_args()
|
|
655
681
|
|
|
682
|
+
from PySide6.QtCore import Qt
|
|
683
|
+
QApplication.setAttribute(Qt.ApplicationAttribute.AA_EnableHighDpiScaling, True)
|
|
656
684
|
app = QApplication(sys.argv)
|
|
657
685
|
win = TiffViewer(
|
|
658
686
|
args.tif_path,
|
|
@@ -677,9 +705,12 @@ def run_viewer(
|
|
|
677
705
|
shapefile=None,
|
|
678
706
|
shp_color=None,
|
|
679
707
|
shp_width=None,
|
|
680
|
-
subset=None
|
|
708
|
+
subset=None
|
|
681
709
|
):
|
|
710
|
+
|
|
682
711
|
"""Launch the TiffViewer app"""
|
|
712
|
+
from PySide6.QtCore import Qt
|
|
713
|
+
QApplication.setAttribute(Qt.ApplicationAttribute.AA_EnableHighDpiScaling, True)
|
|
683
714
|
app = QApplication(sys.argv)
|
|
684
715
|
win = TiffViewer(
|
|
685
716
|
tif_path,
|
|
@@ -690,7 +721,7 @@ def run_viewer(
|
|
|
690
721
|
shapefiles=shapefile,
|
|
691
722
|
shp_color=shp_color,
|
|
692
723
|
shp_width=shp_width,
|
|
693
|
-
subset=subset
|
|
724
|
+
subset=subset
|
|
694
725
|
)
|
|
695
726
|
win.show()
|
|
696
727
|
sys.exit(app.exec())
|
|
@@ -698,16 +729,17 @@ def run_viewer(
|
|
|
698
729
|
import click
|
|
699
730
|
|
|
700
731
|
@click.command()
|
|
701
|
-
@click.version_option("1.
|
|
732
|
+
@click.version_option("0.1.10", prog_name="viewtif")
|
|
702
733
|
@click.argument("tif_path", required=False)
|
|
703
734
|
@click.option("--band", default=1, show_default=True, type=int, help="Band number to display")
|
|
704
|
-
@click.option("--scale", default=1.0, show_default=True, type=
|
|
735
|
+
@click.option("--scale", default=1.0, show_default=True, type=int, help="Scale factor for display")
|
|
705
736
|
@click.option("--rgb", nargs=3, type=int, help="Three band numbers for RGB, e.g. --rgb 4 3 2")
|
|
706
737
|
@click.option("--rgbfiles", nargs=3, type=str, help="Three single-band TIFFs for RGB, e.g. --rgbfiles B4.tif B3.tif B2.tif")
|
|
707
738
|
@click.option("--shapefile", multiple=True, type=str, help="One or more shapefiles to overlay")
|
|
708
739
|
@click.option("--shp-color", default="white", show_default=True, help="Overlay color (name or #RRGGBB).")
|
|
709
740
|
@click.option("--shp-width", default=1.0, show_default=True, type=float, help="Overlay line width (screen pixels).")
|
|
710
741
|
@click.option("--subset", default=None, type=int, help="Open specific subdataset index in .hdf/.h5 file")
|
|
742
|
+
|
|
711
743
|
def main(tif_path, band, scale, rgb, rgbfiles, shapefile, shp_color, shp_width, subset):
|
|
712
744
|
"""Lightweight GeoTIFF viewer."""
|
|
713
745
|
# --- Warn early if shapefile requested but geopandas missing ---
|
|
@@ -727,7 +759,7 @@ def main(tif_path, band, scale, rgb, rgbfiles, shapefile, shp_color, shp_width,
|
|
|
727
759
|
shapefile=shapefile,
|
|
728
760
|
shp_color=shp_color,
|
|
729
761
|
shp_width=shp_width,
|
|
730
|
-
subset=subset
|
|
762
|
+
subset=subset
|
|
731
763
|
)
|
|
732
764
|
|
|
733
765
|
if __name__ == "__main__":
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|