1
2 ///////////////////////////////////////////////////////////
3 // //
4 // SAGA //
5 // //
6 // System for Automated Geoscientific Analyses //
7 // //
8 // Tool Library //
9 // io_gdal //
10 // //
11 //-------------------------------------------------------//
12 // //
13 // gdal_buildvrt.cpp //
14 // //
15 // Copyright (C) 2019 by //
16 // Volker Wichmann //
17 // //
18 //-------------------------------------------------------//
19 // //
20 // This file is part of 'SAGA - System for Automated //
21 // Geoscientific Analyses'. SAGA is free software; you //
22 // can redistribute it and/or modify it under the terms //
23 // of the GNU General Public License as published by the //
24 // Free Software Foundation, either version 2 of the //
25 // License, or (at your option) any later version. //
26 // //
27 // SAGA is distributed in the hope that it will be //
28 // useful, but WITHOUT ANY WARRANTY; without even the //
29 // implied warranty of MERCHANTABILITY or FITNESS FOR A //
30 // PARTICULAR PURPOSE. See the GNU General Public //
31 // License for more details. //
32 // //
33 // You should have received a copy of the GNU General //
34 // Public License along with this program; if not, see //
35 // <http://www.gnu.org/licenses/>. //
36 // //
37 //-------------------------------------------------------//
38 // //
39 // e-mail: wichmann@laserdata //
40 // //
41 // contact: Volker Wichmann //
42 // LASERDATA GmbH //
43 // Innsbruck, Austria //
44 // //
45 ///////////////////////////////////////////////////////////
46
47 //---------------------------------------------------------
48 #include "gdal_buildvrt.h"
49
50
51 ///////////////////////////////////////////////////////////
52 // //
53 // //
54 // //
55 ///////////////////////////////////////////////////////////
56
57 //---------------------------------------------------------
58 #ifdef GDAL_V2_1_OR_NEWER
59
60 //---------------------------------------------------------
61 #include <cpl_string.h>
62 #include <gdal_utils.h>
63 #include "gdal_driver.h"
64
65
66 ///////////////////////////////////////////////////////////
67 // //
68 // //
69 // //
70 ///////////////////////////////////////////////////////////
71
72 //---------------------------------------------------------
CGDAL_BuildVRT(void)73 CGDAL_BuildVRT::CGDAL_BuildVRT(void)
74 {
75 Set_Name (_TL("Create Virtual Raster (VRT)"));
76
77 Set_Author ("V. Wichmann (c) 2019");
78
79 Add_Reference("GDAL/OGR contributors", "2019",
80 "GDAL/OGR Geospatial Data Abstraction software Library",
81 "A translator library for raster and vector geospatial data formats. Open Source Geospatial Foundation.",
82 SG_T("https://gdal.org"), SG_T("Link")
83 );
84
85 Add_Reference("GDAL/OGR contributors", "2019",
86 "The gdalbuildvrt utility",
87 "GDAL documentation.",
88 SG_T("https://gdal.org/programs/gdalbuildvrt.html"), SG_T("Link")
89 );
90
91 CSG_String Description, Filter, Filter_All;
92
93 Description = _TW(
94 "The tool allows one to create a virtual dataset (VRT) which is a mosaic of the input raster datasets. "
95 "Such a VRT can be used for seamless data access to a large number of raster tiles, a typical application "
96 "is the clipping of raster tiles from such a VRT.\n\n"
97 );
98
99 Description += CSG_String::Format("\nGDAL %s:%s\n\n", _TL("Version"), SG_Get_GDAL_Drivers().Get_Version().c_str());
100
101 Description += _TL("Following raster formats are currently supported:");
102
103 Description += CSG_String::Format("\n<table border=\"1\"><tr><th>%s</th><th>%s</th><th>%s</th></tr>",
104 _TL("ID"), _TL("Name"), _TL("Extension")
105 );
106
107 for(int i=0; i<SG_Get_GDAL_Drivers().Get_Count(); i++)
108 {
109 if( SG_Get_GDAL_Drivers().is_Raster(i) && SG_Get_GDAL_Drivers().Can_Read(i) )
110 {
111 CSG_String ID = SG_Get_GDAL_Drivers().Get_Description(i).c_str();
112 CSG_String Name = SG_Get_GDAL_Drivers().Get_Name (i).c_str();
113 CSG_String Ext = SG_Get_GDAL_Drivers().Get_Extension (i).c_str();
114
115 Description += "<tr><td>" + ID + "</td><td>" + Name + "</td><td>" + Ext + "</td></tr>";
116
117 if( !Ext.is_Empty() )
118 {
119 Ext.Replace("/", ";");
120
121 Filter += Name + "|*." + Ext + "|";
122 Filter_All += (Filter_All.is_Empty() ? "*." : ";*.") + Ext;
123 }
124 }
125 }
126
127 Description += "</table>";
128
129 Set_Description(Description);
130
131 Filter.Prepend(CSG_String::Format("%s|%s|" , _TL("All Recognized Files"), Filter_All.c_str()));
132 Filter.Append (CSG_String::Format("%s|*.*" , _TL("All Files")));
133
134 //-----------------------------------------------------
135 Parameters.Add_FilePath("",
136 "FILES" , _TL("Files"),
137 _TL("The input files."),
138 Filter, NULL, false, false, true
139 );
140
141 Parameters.Add_FilePath("",
142 "FILE_LIST" , _TL("Input File List"),
143 _TL("A text file with the full path to an input grid on each line."),
144 CSG_String::Format("%s|*.txt|%s|*.*",
145 _TL("Text Files"),
146 _TL("All Files")
147 ), NULL, false, false, false
148 )->Set_UseInGUI(false);
149
150 Parameters.Add_FilePath("",
151 "VRT_NAME" , _TL("VRT Filename"),
152 _TL("The full path and name of the .vrt output file."),
153 CSG_String::Format("%s (*.vrt)|*.vrt|%s|*.*",
154 _TL("Virtual Dataset"),
155 _TL("All Files")
156 ), NULL, true, false, false
157 );
158
159 Parameters.Add_Choice("",
160 "RESAMPLING", _TL("Resampling"),
161 _TL("The resampling algorithm used when datasets are queried from the VRT."),
162 CSG_String::Format("{%s}%s|{%s}%s|{%s}%s|{%s}%s|{%s}%s|{%s}%s|{%s}%s",
163 // we use the choices' data item for the option names that have to be passed (untranslated) to the gdal utility call
164 SG_T("nearest" ), _TL("nearest" ),
165 SG_T("bilinear" ), _TL("bilinear" ),
166 SG_T("cubic" ), _TL("cubic" ),
167 SG_T("cubicspline"), _TL("cubic spline"),
168 SG_T("lanczos" ), _TL("lanczos" ),
169 SG_T("average" ), _TL("average" ),
170 SG_T("mode" ), _TL("mode" )
171 ), 0
172 );
173
174 Parameters.Add_Choice("",
175 "RESOLUTION", _TL("Resolution"),
176 _TL("The method how to compute the output resolution if the resolution of all input files is not the same."),
177 CSG_String::Format("{%s}%s|{%s}%s|{%s}%s|{%s}%s",
178 SG_T("highest"), _TL("highest"),
179 SG_T("lowest" ), _TL("lowest" ),
180 SG_T("average"), _TL("average"),
181 SG_T("user" ), _TL("user" )
182 ), 0
183 );
184
185 Parameters.Add_Double("",
186 "CELLSIZE" , _TL("Cellsize"),
187 _TL(""),
188 1., 0., true
189 );
190
191 Parameters.Add_Bool("",
192 "ALIGN" , _TL("Align"),
193 _TL("Align the coordinates of the extent to the cellsize."),
194 true
195 );
196 }
197
198
199 ///////////////////////////////////////////////////////////
200 // //
201 ///////////////////////////////////////////////////////////
202
203 //---------------------------------------------------------
On_Parameters_Enable(CSG_Parameters * pParameters,CSG_Parameter * pParameter)204 int CGDAL_BuildVRT::On_Parameters_Enable(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
205 {
206 if( pParameter->Cmp_Identifier("RESOLUTION") )
207 {
208 pParameters->Set_Enabled("CELLSIZE", pParameter->asInt() == 3);
209 pParameters->Set_Enabled("ALIGN" , pParameter->asInt() == 3);
210 }
211
212 return( CSG_Tool::On_Parameters_Enable(pParameters, pParameter) );
213 }
214
215
216 ///////////////////////////////////////////////////////////
217 // //
218 ///////////////////////////////////////////////////////////
219
220 //---------------------------------------------------------
On_Execute(void)221 bool CGDAL_BuildVRT::On_Execute(void)
222 {
223 char **pFiles = NULL; int nFiles = 0; CSG_Strings Files;
224
225 if( Parameters("FILES")->asFilePath()->Get_FilePaths(Files) )
226 {
227 for(int i=0; i<Files.Get_Count(); i++)
228 {
229 CSG_String File(Files.Get_String(i));
230
231 if( SG_File_Exists(File) )
232 {
233 pFiles = CSLAddString(pFiles, File.b_str()); nFiles++;
234 }
235 }
236 }
237 else if( has_GUI() == false )
238 {
239 SG_UI_Msg_Add(_TL("No files specified with the \"Files\" parameter, trying to use input file list."), true);
240
241 CSG_Table Table(Parameters("FILE_LIST")->asString(), TABLE_FILETYPE_Text_NoHeadLine);
242
243 if( Table.Get_Field_Count() < 1 || Table.Get_Count() < 1 )
244 {
245 Error_Set(_TL("Input file list could not be opened or is empty!"));
246
247 return( false );
248 }
249
250 for(int i=0; i<Table.Get_Count(); i++) // build our own list, as the -input_file_list option is not available in the library call, only in the gdal binary
251 {
252 CSG_String File(Table.Get_Record(i)->asString(0));
253
254 if( SG_File_Exists(File) )
255 {
256 pFiles = CSLAddString(pFiles, File.b_str()); nFiles++;
257 }
258 }
259 }
260
261 if( nFiles < 1 )
262 {
263 Error_Set(_TL("No existing files have been selected for input."));
264
265 return( false );
266 }
267
268 //-----------------------------------------------------
269 char **pOpts = NULL;
270
271 pOpts = CSLAddString(pOpts, "-r");
272 pOpts = CSLAddString(pOpts, Parameters("RESAMPLING")->asChoice()->Get_Data().b_str());
273 pOpts = CSLAddString(pOpts, "-resolution");
274 pOpts = CSLAddString(pOpts, Parameters("RESOLUTION")->asChoice()->Get_Data().b_str());
275
276 if( Parameters("RESOLUTION")->asInt() == 3 ) // user
277 {
278 CSG_String Cellsize(Parameters("CELLSIZE")->asString());
279
280 pOpts = CSLAddString(pOpts, "-tr");
281 pOpts = CSLAddString(pOpts, Cellsize.b_str()); // xres
282 pOpts = CSLAddString(pOpts, Cellsize.b_str()); // yres
283
284 if( Parameters("ALIGN")->asBool() )
285 {
286 pOpts = CSLAddString(pOpts, "-tap");
287 }
288 }
289
290 GDALBuildVRTOptions *pOptions = GDALBuildVRTOptionsNew(pOpts, nullptr);
291
292 //-----------------------------------------------------
293 int bUsageError = 0;
294
295 CSG_String File(Parameters("VRT_NAME")->asString());
296
297 GDALDatasetH hVRT = GDALBuildVRT(File.b_str(), nFiles, nullptr, pFiles, pOptions, &bUsageError);
298
299 if( bUsageError != 0 )
300 {
301 Error_Set(_TL("Unable to build virtual dataset."));
302 }
303
304 CSLDestroy(pFiles);
305 GDALBuildVRTOptionsFree(pOptions);
306 GDALClose(hVRT);
307
308 return( bUsageError == 0 );
309 }
310
311
312 ///////////////////////////////////////////////////////////
313 // //
314 // //
315 // //
316 ///////////////////////////////////////////////////////////
317
318 //---------------------------------------------------------
319 #endif // GDAL_V2_1_OR_NEWER
320