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