Skip to content

Commit 2247266

Browse files
authored
Merge pull request #32 from EarthObservation/save_vrt
Save vrt
2 parents 76994f8 + fa2ae09 commit 2247266

File tree

6 files changed

+72
-81
lines changed

6 files changed

+72
-81
lines changed

README.md

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[![PyPI](https://img.shields.io/pypi/v/RVT_py?style=flat-square)](https://pypi.org/project/rvt-py/)
2-
[![Anaconda-Server Badge](https://anaconda.org/rvtpy/rvt_py/badges/version.svg)](https://anaconda.org/rvtpy/rvt_py)
3-
[![Anaconda-Server Badge](https://anaconda.org/rvtpy/rvt_py/badges/latest_release_date.svg)](https://anaconda.org/rvtpy/rvt_py)
2+
[![Anaconda-Server Badge](https://anaconda.org/zmigyyy/rvt_py/badges/version.svg)](https://anaconda.org/zmigyyy/rvt_py)
3+
[![Anaconda-Server Badge](https://anaconda.org/zmigyyy/rvt_py/badges/latest_release_date.svg)](https://anaconda.org/zmigyyy/rvt_py)
44

55
# Relief Visualization Toolbox Python library
66

@@ -21,7 +21,7 @@ Methods currently implemented are:
2121
* sky-view factor (as developed by our team),
2222
* anisotropic sky-view factor,
2323
* positive and negative openness,
24-
* local dominance,
24+
* local dominance,
2525
* multi-scale topographic position.
2626

2727
## RVT for Python
@@ -43,10 +43,11 @@ When using the tools, please cite:
4343

4444
## Installation
4545

46-
The RVT Python package can be installed using Conda or PyPI, and can be used in Python scripts, Jupyter Notebooks, QGIS and ArcGIS Pro.
46+
The RVT Python package can be installed using Conda or PyPI, and can be used in Python scripts, Jupyter Notebooks and ArcGIS Pro.
4747

48-
RVT can also be installed as [a set of custom raster functions for ArcGIS](https://rvt-py.readthedocs.io/en/latest/install_arcgis.html "ArcGIS installation") and [a plugin for QGIS](https://rvt-py.readthedocs.io/en/latest/install_qgis.html "QGIS installation").
48+
RVT can also be installed as [a set of custom raster functions for ArcGIS](https://rvt-py.readthedocs.io/en/latest/install_arcgis.html "ArcGIS installation"), and [a plugin for QGIS](https://rvt-py.readthedocs.io/en/latest/install_qgis.html "QGIS installation").
4949

50+
You can also clone the repository.
5051

5152
### Conda
5253

@@ -70,25 +71,14 @@ Then open Command Prompt (Windows) or Terminal (MacOS) and run:
7071

7172
### Requirements
7273

73-
* Python 3.8+
74+
Required libraries (specified versions have been tested, other versions may also work):
7475

75-
> Code was tested on python version 3.11.11
76+
* numpy 1.19.2
77+
* scipy 1.5.2
78+
* gdal 3.0.2
79+
* rasterio 1.2.6
7680

77-
Dependencies for core functionality:
78-
79-
* gdal
80-
* matplotlib
81-
* numpy
82-
* scipy
83-
84-
Dependencies for extended use (running scripts in examples folder):
85-
86-
* pandas
87-
* geopandas
88-
* jupyter
89-
* rasterio
90-
91-
> We recommend using `Anaconda` virtual environments and `conda-forge` channel for installing the required packages (this works best with ``gdal``).
81+
We recommend using Python 3.6 or higher and a Conda environment (this works best with ``gdal``).
9282

9383
## Documentation
9484
Documentation of the package and its use is available at [Relief Visualization Toolbox in Python documentation](https://rvt-py.readthedocs.io/).
@@ -103,7 +93,7 @@ Development of RVT Python scripts was part financed by the Slovenian Research Ag
10393
This project is licensed under the terms of the [Apache License](LICENSE).
10494

10595
## About
106-
RVT Python library by Žiga Kokalj, Žiga Maroh, Krištof Oštir, Klemen Zakšek and Nejc Čož, 2024.
96+
RVT Python library by Žiga Kokalj, Žiga Maroh, Krištof Oštir, Klemen Zakšek and Nejc Čož, 2022.
10797

10898
It is developed in collaboration between ZRC SAZU and University of Ljubljana.
10999

examples/tiled_processing/_test_tiled.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,18 @@
33
if __name__ == "__main__":
44
# List of INPUT DATASETS (have to be in this format)
55
list_tifs = [
6-
r"c:\Users\ncoz\GitHub\erc_potencial\test_data\test_small.tif",
7-
# r"c:\test_data\testmx\2022MxCP_C_dem_05m.tif",
8-
# r"c:\test_data\testmx_s\2022MxCP_C_dem_05m_s.tif"
6+
r"c:\path-to-file\test-file.tif",
97
]
108

119
# Select visualizations
1210
# 'slp', 'hs', 'slrm', 'svf', 'opns', 'neg_opns', 'ld', 'mstp'
1311
vis_types = [
14-
'slrm'
12+
"slrm"
1513
]
1614
# "vat_combined" / "e2MSTP" / "e4MSTP" / "crim" / "rrim"
1715
blend_types = [
18-
"vat_combined"
16+
# "vat_combined"
1917
]
2018

21-
run_main(list_tifs, vis_types, blend_types, save_float=False)
19+
# save_vrt (if True saves VRT, if False saves as TIF mosaic), only used when tiling
20+
run_main(list_tifs, vis_types, blend_types, save_float=False, save_vrt=True)

examples/tiled_processing/rvt_tiled.ipynb

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"cells": [
33
{
44
"cell_type": "code",
5-
"execution_count": 1,
5+
"execution_count": null,
66
"id": "336b1fb4-8369-43b3-9b99-7915bad70954",
77
"metadata": {},
88
"outputs": [],
@@ -22,14 +22,14 @@
2222
},
2323
{
2424
"cell_type": "code",
25-
"execution_count": 2,
25+
"execution_count": null,
2626
"id": "cc536aa8-15f8-4e28-bbab-4c1c5c8f52a3",
2727
"metadata": {},
2828
"outputs": [],
2929
"source": [
3030
"# List of INPUT DATASETS (have to be in this format)\n",
3131
"list_tifs = [\n",
32-
" r\"c:\\Users\\ncoz\\GitHub\\erc_potencial\\test_data\\test_small.tif\"\n",
32+
" r\"c:\\test_data\\2022MxCP_1GB\\2022MxCP_E_dem_05m.tif\"\n",
3333
"]"
3434
]
3535
},
@@ -38,7 +38,13 @@
3838
"id": "caac01bb-d3f1-45d9-b041-ca200f15f44d",
3939
"metadata": {},
4040
"source": [
41-
"The defaults are save in 8-bit format (256 values, RGB). To also save pixel values as float, change the following parameter to \"True\":"
41+
"**save_float**\n",
42+
"* The defaults are saved in 8-bit format (256 values, RGB)\n",
43+
"* To also save pixel values as float, change the `save_float` parameter to `True`\n",
44+
"\n",
45+
"**save_vrt** \n",
46+
"* if `True` the results are left as tiles and a VRT file is created\n",
47+
"* if `False` results are merged into TIF mosaic and indvidual tiles are deleted"
4248
]
4349
},
4450
{
@@ -48,7 +54,8 @@
4854
"metadata": {},
4955
"outputs": [],
5056
"source": [
51-
"save_float = False"
57+
"save_float = False\n",
58+
"save_vrt = True"
5259
]
5360
},
5461
{
@@ -83,14 +90,14 @@
8390
},
8491
{
8592
"cell_type": "code",
86-
"execution_count": 3,
93+
"execution_count": null,
8794
"id": "01d02ac4-16cc-45a9-88d4-ecea209e9a7f",
8895
"metadata": {},
8996
"outputs": [],
9097
"source": [
9198
"# Select visualizations\n",
9299
"vis_types = [\n",
93-
" \"slrm\"\n",
100+
" \n",
94101
"]"
95102
]
96103
},
@@ -122,7 +129,7 @@
122129
},
123130
{
124131
"cell_type": "code",
125-
"execution_count": 4,
132+
"execution_count": null,
126133
"id": "374da272-c812-4dbd-98c4-32e3839c6d60",
127134
"metadata": {},
128135
"outputs": [],
@@ -145,26 +152,17 @@
145152
},
146153
{
147154
"cell_type": "code",
148-
"execution_count": 5,
155+
"execution_count": null,
149156
"id": "0e55d218-4923-440d-988b-75824aceeb72",
150157
"metadata": {},
151-
"outputs": [
152-
{
153-
"name": "stdout",
154-
"output_type": "stream",
155-
"text": [
156-
"Start --- c:/Users/ncoz/GitHub/erc_potencial/test_data/test_small.tif\n",
157-
"Processing as single tile...\n",
158-
"Done with computing blends in 0 min.\n"
159-
]
160-
}
161-
],
158+
"outputs": [],
162159
"source": [
163160
"run_main(\n",
164161
" list_tifs=list_tifs,\n",
165162
" vis_types=vis_types,\n",
166163
" blend_types=blend_types,\n",
167-
" save_float=save_float\n",
164+
" save_float=save_float,\n",
165+
" save_vrt=save_vrt\n",
168166
")"
169167
]
170168
}

examples/tiled_processing/rvt_tiled_GUI.ipynb

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -62,25 +62,10 @@
6262
},
6363
{
6464
"cell_type": "code",
65-
"execution_count": 1,
65+
"execution_count": null,
6666
"id": "4b90a3fd-1fe7-46d4-9cab-e96137dfdd48",
6767
"metadata": {},
68-
"outputs": [
69-
{
70-
"data": {
71-
"application/vnd.jupyter.widget-view+json": {
72-
"model_id": "910520b1f2ea480bbf18ec0a19469004",
73-
"version_major": 2,
74-
"version_minor": 0
75-
},
76-
"text/plain": [
77-
"VBox(children=(HTML(value='<b>RVT - TILED PROCESSING FOR LARGE FILES</b>'), SelectFilesButton(description='Sel…"
78-
]
79-
},
80-
"metadata": {},
81-
"output_type": "display_data"
82-
}
83-
],
68+
"outputs": [],
8469
"source": [
8570
"import tiled_GUI"
8671
]

examples/tiled_processing/tiled_GUI.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ def on_button_clicked(b):
126126
# print(str(save_float_checkbox.value))
127127

128128
run_main(list_tifs, vis_types, blend_types, save_float)
129+
# todo: add save_vrt=True to arguments and create a checkbox for this
129130

130131
button_run_adaf.disabled = False
131132

examples/tiled_processing/tiled_multiprocess.py

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313

1414
import numpy as np
1515
import rasterio
16+
from geopandas import GeoDataFrame
1617
from osgeo import gdal
1718
from rasterio.merge import merge
1819
from rasterio.windows import from_bounds
20+
from shapely.geometry import box
1921

2022
import grid_tools as gt
2123
import rvt.blend
@@ -26,7 +28,7 @@
2628
gdal.UseExceptions()
2729

2830

29-
def run_main(list_tifs, vis_types, blend_types, save_float=False):
31+
def run_main(list_tifs, vis_types, blend_types, save_float=False, save_vrt=False):
3032
for in_file in list_tifs:
3133
in_file = Path(in_file)
3234

@@ -44,6 +46,7 @@ def run_main(list_tifs, vis_types, blend_types, save_float=False):
4446
tile_size = 2000
4547
else:
4648
tile_size = None
49+
raster_bounds = src.bounds
4750

4851
if tile_size:
4952
# # (3) To filter we need polygon covering valid data
@@ -62,6 +65,10 @@ def run_main(list_tifs, vis_types, blend_types, save_float=False):
6265
# save_gpkg=False
6366
# )
6467

68+
# Crop outer tiles to the extents of raster (IMPORTANT so output size is same as input when tiling!)
69+
raster_bbox = box(*raster_bounds)
70+
tiles_extents = GeoDataFrame(geometry=tiles_extents.geometry.intersection(raster_bbox), crs=tiles_extents.crs)
71+
6572
# Add extents column: Extents are (L, B, R, T).
6673
tiles_extents["extents"] = tiles_extents.bounds.apply(lambda x: (x.minx, x.miny, x.maxx, x.maxy), axis=1)
6774

@@ -76,11 +83,12 @@ def run_main(list_tifs, vis_types, blend_types, save_float=False):
7683
blend_types=blend_types,
7784
input_vrt_path=in_file,
7885
tiles_list=tiles_list,
79-
save_float=save_float
86+
save_float=save_float,
87+
save_vrt=save_vrt
8088
)
8189

8290

83-
def tiled_blending(vis_types, blend_types, input_vrt_path, tiles_list, save_float):
91+
def tiled_blending(vis_types, blend_types, input_vrt_path, tiles_list, save_float, save_vrt):
8492
t0 = time.time()
8593

8694
# Prepare paths
@@ -146,15 +154,17 @@ def tiled_blending(vis_types, blend_types, input_vrt_path, tiles_list, save_floa
146154
sf = False
147155
mosaic_path = build_vrt(result_paths, vrt_path, save_float=sf)
148156

149-
# Create mosaic and crop to the original extents
150-
vrt_to_mosaic(
151-
vrt_path=mosaic_path, # ll_path / "test.tif",
152-
output_mosaic_path=ll_path / f"{result}.tif",
153-
)
157+
# Build a mosaic from VRT if selected #todo: before app starts give warning about size if VRT is not ON
158+
if not save_vrt:
159+
# Create mosaic and crop to the original extents
160+
vrt_to_mosaic(
161+
vrt_path=mosaic_path, # ll_path / "test.tif",
162+
output_mosaic_path=ll_path / f"{result}.tif",
163+
)
154164

155-
# Delete temp files
156-
vrt_path.unlink()
157-
shutil.rmtree(result_parent)
165+
# Delete VRT files
166+
vrt_path.unlink()
167+
shutil.rmtree(result_parent)
158168

159169
# print(results)
160170

@@ -1284,6 +1294,9 @@ def get_required_arrays(vis_types, blend_types):
12841294
req_arrays["opns_1"] = True
12851295
req_arrays["neg_opns_1"] = True
12861296

1297+
if "new_blend" in blend_types:
1298+
req_arrays["slrm_1"] = True
1299+
12871300
return req_arrays
12881301

12891302

@@ -1490,6 +1503,7 @@ def get_raster_vrt(vrt_path, extents, buffer):
14901503
vrt_nodata = vrt.nodata
14911504
vrt_transform = vrt.transform
14921505
vrt_crs = vrt.crs
1506+
nodata_val = vrt.nodata
14931507

14941508
# ADD BUFFER TO EXTENTS (LBRT) - transform pixels to meters!
14951509
buffer_m = buffer * vrt_res[0]
@@ -1508,8 +1522,13 @@ def get_raster_vrt(vrt_path, extents, buffer):
15081522
# boundless - if window falls out of bounds, read it and fill with NaNs
15091523
win_array = vrt.read(window=buff_window, boundless=True)
15101524

1525+
# Deal with nodata
1526+
if nodata_val is not None and not np.isnan(nodata_val):
1527+
# Ensure array is float to support np.nan
1528+
win_array = win_array.astype("float32", copy=False)
1529+
win_array[win_array == nodata_val] = np.nan
1530+
15111531
# Save transform object of both extents (original and buffered)
1512-
buff_transform = vrt.window_transform(buff_window)
15131532
orig_transform = vrt.window_transform(orig_window)
15141533

15151534
# For raster with only one band, remove first axis from the array (RVT requirement)
@@ -1519,7 +1538,7 @@ def get_raster_vrt(vrt_path, extents, buffer):
15191538
# Prepare output metadata profile
15201539
out_profile = {
15211540
'driver': 'GTiff',
1522-
'nodata': None,
1541+
'nodata': np.nan,
15231542
'width': win_array.shape[1] - 2 * buffer,
15241543
'height': win_array.shape[0] - 2 * buffer,
15251544
'count': 1,
@@ -1532,7 +1551,6 @@ def get_raster_vrt(vrt_path, extents, buffer):
15321551
"array": win_array,
15331552
"resolution": vrt_res,
15341553
"no_data": vrt_nodata,
1535-
"buff_transform": buff_transform,
15361554
"orig_transform": orig_transform,
15371555
"crs": vrt_crs,
15381556
"profile": out_profile

0 commit comments

Comments
 (0)