• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

icsm-au / DynAdjust / 4558854622

pending completion
4558854622

push

github

GitHub
Merge pull request #213 from icsm-au/1.2.7

949 of 949 new or added lines in 30 files covered. (100.0%)

30192 of 38394 relevant lines covered (78.64%)

3682.47 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.45
/dynadjust/dynadjust/dnageoidwrapper/dnageoidwrapper.cpp
1
//============================================================================
2
// Name         : dnageoidwrapper.cpp
3
// Author       : Roger Fraser
4
// Contributors :
5
// Version      : 1.00
6
// Copyright    : Copyright 2017 Geoscience Australia
7
//
8
//                Licensed under the Apache License, Version 2.0 (the "License");
9
//                you may not use this file except in compliance with the License.
10
//                You may obtain a copy of the License at
11
//               
12
//                http ://www.apache.org/licenses/LICENSE-2.0
13
//               
14
//                Unless required by applicable law or agreed to in writing, software
15
//                distributed under the License is distributed on an "AS IS" BASIS,
16
//                WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
//                See the License for the specific language governing permissions and
18
//                limitations under the License.
19
//
20
// Description  : AusGeoid Grid File (NTv2) Interpolation library Executable
21
//============================================================================
22

23
#include <dynadjust/dnageoidwrapper/dnageoidwrapper.hpp>
24

25
using namespace dynadjust;
26

27
bool CreateNTv2Grid(dna_geoid_interpolation* g, const char* dat_gridfilePath, const n_file_par* grid)
2✔
28
{
29
        // example:
30
        // geoid -d ausgeoid09_gda94_v1.01_clip_1x1.dat -c -g ausgeoid_clip_1.0.1.0.gsb --grid-shift radians --grid-version 1.0.1.0 --system-fr ___GDA94 --system-to ___AHD71 --sub-grid-n 1D-grid --creation 21.04.2021 --update 22.04.2021
31
        //
32
        
33
        cout << "+ Creating NTv2 geoid grid file from WINTER DAT file format..." << endl;
2✔
34

35
        try {
2✔
36
                g->CreateNTv2File(dat_gridfilePath, grid);
2✔
37
        }
38
        catch (const NetGeoidException& e) {
×
39
                cout << endl << "- Error: " << e.what() << endl;
×
40
                return false;
×
41
        }
×
42
        cout << endl;
2✔
43

44
        // Open the new grid file and print its properties
45
        if (!reportGridProperties(g, grid->filename, grid->filetype))
2✔
46
                return false;
×
47

48
        return true;
49
}
50

51
        
52
bool ExportNTv2GridToAscii(dna_geoid_interpolation* g, const char* dat_gridfilePath, const char* gridfileType, const char* gridshiftType, const char* exportfileType)
2✔
53
{
54
        // example:
55
        // geoid -g ausgeoid_clip_1.0.1.0.gsb --grid-shift radians --export-ntv2-asc
56
        //
57

58
        path asciiGridFile(dat_gridfilePath);
2✔
59
        string outfile = asciiGridFile.filename().string() + "." + exportfileType;
4✔
60

61
        int ioStatus;
2✔
62
        
63
        cout << endl << "+ Exporting NTv2 geoid grid file to " << leafStr<string>(outfile) << "... ";
4✔
64

65
        try {
2✔
66
                g->ExportToAscii(dat_gridfilePath, gridfileType, gridshiftType, outfile.c_str(), &ioStatus);
2✔
67
        }
68
        catch (const NetGeoidException& e) {
×
69
                cout << endl << "- Error: " << e.what() << endl;
×
70
                return false;
×
71
        }
×
72

73
        cout << "done." << endl << endl;
2✔
74

75
        // Open the new grid file and print its properties
76
        if (!reportGridProperties(g, outfile.c_str(), exportfileType))
2✔
77
                return false;
×
78

79
        return true;
80
}
2✔
81

82

83
        
84
bool ExportNTv2GridToBinary(dna_geoid_interpolation* g, const char* dat_gridfilePath, const char* gridfileType, const char* gridshiftType, const char* exportfileType)
2✔
85
{
86
        path asciiGridFile(dat_gridfilePath);
2✔
87
        string outfile = asciiGridFile.filename().string() + "." + exportfileType;
4✔
88

89
        int ioStatus;
2✔
90
        
91
        cout << endl << "+ Exporting geoid file to " << leafStr<string>(outfile) << "... ";
4✔
92

93
        try {
2✔
94
                g->ExportToBinary(dat_gridfilePath, gridfileType, gridshiftType, outfile.c_str(), &ioStatus);
2✔
95
        }
96
        catch (const NetGeoidException& e) {
×
97
                cout << endl << "- Error: " << e.what() << endl;
×
98
                return false;
×
99
        }
×
100

101
        cout << "done." << endl << endl;
2✔
102

103
        // Open the grid file and print its properties
104
        if (!reportGridProperties(g, outfile.c_str(), exportfileType))
2✔
105
                return false;
×
106

107
        return true;
108
}
2✔
109

110
void ReturnBadStationRecords(dna_geoid_interpolation* g, project_settings& p)
2✔
111
{
112
        string records, filename(p.g.network_name);
2✔
113
        string badpointsPath(formPath<string>(p.g.output_folder, filename, "int"));
2✔
114
        stringstream ss;
2✔
115
        std::ofstream badpoints_log;
2✔
116

117
        ss << "- Error: Could not open " << filename << " for writing." << endl;
2✔
118
        try {
2✔
119
                // Create dynadjust log file.  Throws runtime_error on failure.
120
                file_opener(badpoints_log, badpointsPath);
2✔
121
        }
122
        catch (const runtime_error& e) {
×
123
                ss << e.what();
×
124
                throw boost::enable_current_exception(runtime_error(ss.str()));
×
125
        }
×
126
        catch (...) {
×
127
                throw boost::enable_current_exception(runtime_error(ss.str()));
×
128
        }
×
129

130
        // Print formatted header
131
        print_file_header(badpoints_log, "DYNADJUST GEOID INTERPOLATION LOG FILE");
2✔
132

133
        badpoints_log << setw(PRINT_VAR_PAD) << left << "File name:" << badpointsPath << endl << endl;
2✔
134
        
135
        badpoints_log << setw(PRINT_VAR_PAD) << left << "Command line arguments: ";
2✔
136
        badpoints_log << p.n.command_line_arguments << endl << endl;
2✔
137

138
        badpoints_log << setw(PRINT_VAR_PAD) << left << "Network name:" <<  p.g.network_name << endl;
2✔
139
        badpoints_log << setw(PRINT_VAR_PAD) << left << "Stations file:" << system_complete(p.n.bst_file).string() << endl;
2✔
140
        badpoints_log << setw(PRINT_VAR_PAD) << left << "Geoid model: " << system_complete(p.n.ntv2_geoid_file).string() << endl << endl;
2✔
141
        badpoints_log << setw(PRINT_VAR_PAD) << left << "Stations not interpolated:" << g->PointsNotInterpolated() << endl;
2✔
142
        badpoints_log << OUTPUTLINE << endl << endl;
2✔
143
        
144
        records = g->ReturnBadStationRecords();
2✔
145

146
        badpoints_log << records << endl;
2✔
147

148
        if (p.g.verbose > 1)
2✔
149
        {
150
                string data("<file record or filename>");
1✔
151
                badpoints_log << endl << endl <<
1✔
152
                        "DYNADJUST GEOID INTERPOLARION ERROR CODES" << endl << endl <<
1✔
153
                        setw(PAD) << "Code" << "Description (short and long)" << endl <<
1✔
154
                        "------------------------------------------------------" << endl;
1✔
155
                for (int i=ERR_AUS_BINARY; i<=ERR_INTERPOLATION_TYPE; ++i)
31✔
156
                {
157
                        badpoints_log << 
30✔
158
                                setw(PAD) << i << 
30✔
159
                                setw(ZONE) << "Short: " << g->ErrorCaption(i) << endl <<
90✔
160
                                setw(PAD) << " " <<
161
                                setw(ZONE) << "Long:  " << g->ErrorString(i, data) << endl;
60✔
162
                }
163
        }
1✔
164
        
165

166
        badpoints_log.close();
2✔
167

168
        cout << endl << "  See " << badpointsPath << " to view the list of stations for which an" << endl <<
2✔
169
                "  N-value could not be interpolated." << endl;
2✔
170

171
}
2✔
172

173

174
        
175
bool createGridIndex(dna_geoid_interpolation* g, const char* gridfilePath, const char* gridfileType, const int& quiet)
18✔
176
{
177
        if (!quiet)
18✔
178
                cout << "+ Opening grid file... ";
18✔
179
        try {
18✔
180
                g->CreateGridIndex(gridfilePath, gridfileType);
18✔
181
        }
182
        catch (const NetGeoidException& e) {
1✔
183
                cout << endl << "- Error: " << e.what() << endl;
1✔
184
                return false;
1✔
185
        }
1✔
186

187
        if (!quiet)
17✔
188
                cout << "done." << endl;
18✔
189

190
        return true;
191
}
192
        
193

194
bool reportGridProperties(dna_geoid_interpolation* g, const char* gridfilePath, const char* gridfileType)
7✔
195
{
196
        n_file_par grid_properties;
7✔
197
        
198
        try {
7✔
199
                g->ReportGridProperties(gridfilePath, gridfileType, &grid_properties);
7✔
200
        }
201
        catch (const NetGeoidException& e) {
×
202
                cout << endl << "- Error: " << e.what() << endl;
×
203
                return false;
×
204
        }
×
205

206
        bool isRadians(false);
7✔
207
        string shiftType(grid_properties.chGs_type);
7✔
208
        if (iequals(trimstr(shiftType), "radians"))
7✔
209
                isRadians = true;
3✔
210

211
        string formattedLimit;
7✔
212

213
        cout << "+ Grid properties for " << gridfilePath << ":" << endl;
7✔
214
        cout << "  - GS_TYPE  = " << grid_properties.chGs_type << endl;                                                        // grid shift type (GS_TYPE)
7✔
215
        cout << "  - VERSION  = " << grid_properties.chVersion << endl;                                                        // grid file version (VERSION)
7✔
216
        cout << "  - SYSTEM_F = " << grid_properties.chSystem_f << endl;                                                // reference system (SYSTEM_F)
7✔
217
        cout << "  - SYSTEM_T = " << grid_properties.chSystem_t << endl;                                                // reference system (SYSTEM_T)
7✔
218
        cout << "  - MAJOR_F  = " << setprecision(3) << fixed << grid_properties.daf << endl;        // semi major of from system (MAJOR_F)
7✔
219
        cout << "  - MAJOR_T  = " << setprecision(3) << fixed << grid_properties.dat << endl;        // semi major of to system (MAJOR_T)
7✔
220
        cout << "  - MINOR_F  = " << setprecision(3) << fixed << grid_properties.dbf << endl;        // semi minor of from system (MINOR_F)
7✔
221
        cout << "  - MINOR_T  = " << setprecision(3) << fixed << grid_properties.dbt << endl;        // semi minor of to system (MINOR_T)
7✔
222
        cout << "  - NUM_OREC = " << grid_properties.iH_info << endl;                                                        // Number of header identifiers (NUM_OREC)
7✔
223
        cout << "  - NUM_SREC = " << grid_properties.iSubH_info << endl;                                                // Number of sub-header idents (NUM_SREC)
7✔
224
        cout << "  - NUM_FILE = " << grid_properties.iNumsubgrids << endl;                                                // number of subgrids in file (NUM_FILE)
7✔
225

226
        for (int i=0; i<grid_properties.iNumsubgrids; ++i)
14✔
227
        {
228
                string formattedLimit;
7✔
229
                cout << "  - SUBGRID " << i << ":" << endl;
7✔
230
                cout << "    - SUB_NAME = " << grid_properties.ptrIndex[i].chSubname << endl;                  // name of subgrid (SUB_NAME)
7✔
231
                cout << "    - PARENT   = " << grid_properties.ptrIndex[i].chParent << endl;                // name of parent grid (PARENT)
7✔
232
                cout << "    - CREATED  = " << grid_properties.ptrIndex[i].chCreated << endl;                // date of creation (CREATED)
7✔
233
                cout << "    - UPDATED  = " << grid_properties.ptrIndex[i].chUpdated << endl;                // date of last file update (UPDATED)
7✔
234
                
235
                // In ptrIndex, all values for the limits of a grid are held in seconds, despite
236
                // whether the grid node records are in radians.
237

238
                // lower latitude (S_LAT)
239
                cout << "    - S_LAT    = " << right << setw(isRadians ? ZONE : REL) << grid_properties.ptrIndex[i].dSlat;                                                
11✔
240
                formattedLimit = "(" + FormatDmsString(DegtoDms(grid_properties.ptrIndex[i].dSlat / DEG_TO_SEC), 6, true, false) + ")";
7✔
241
                cout << right << setw(MEASR) << formattedLimit << endl;                                                                
7✔
242
                
243
                // upper latitude (N_LAT)
244
                cout << "    - N_LAT    = " << right << setw(isRadians ? ZONE : REL) << grid_properties.ptrIndex[i].dNlat;
7✔
245
                formattedLimit = "(" + FormatDmsString(DegtoDms(grid_properties.ptrIndex[i].dNlat / DEG_TO_SEC), 6, true, false) + ")";
7✔
246
                cout << right << setw(MEASR) << formattedLimit << endl;                                                                
7✔
247
                
248
                // lower longitude (E_LONG)
249
                cout << "    - E_LONG   = " << right << setw(isRadians ? ZONE : REL) << grid_properties.ptrIndex[i].dElong;
7✔
250
                formattedLimit = "(" + FormatDmsString(DegtoDms(grid_properties.ptrIndex[i].dElong / DEG_TO_SEC), 6, true, false) + ")";
7✔
251
                cout << right << setw(MEASR) << formattedLimit << endl;
7✔
252

253
                // upper longitude (W_LONG)
254
                cout << "    - W_LONG   = " << right << setw(isRadians ? ZONE : REL) << grid_properties.ptrIndex[i].dWlong;
7✔
255
                formattedLimit = "(" + FormatDmsString(DegtoDms(grid_properties.ptrIndex[i].dWlong / DEG_TO_SEC), 6, true, false) + ")";
7✔
256
                cout << right << setw(MEASR) << formattedLimit << endl;
7✔
257
                
258
                cout << "    - LAT_INC  = " << fixed << grid_properties.ptrIndex[i].dLatinc << endl;                // latitude interval (LAT_INC)
7✔
259
                cout << "    - LONG_INC = " << fixed << grid_properties.ptrIndex[i].dLonginc << endl;                // longitude interval (LONG_INC)
7✔
260
                cout << "    - GS_COUNT = " << fixed << setprecision(0) << grid_properties.ptrIndex[i].lGscount;                                                // number of nodes (GS_COUNT)
7✔
261
        }
7✔
262
        cout << endl;
7✔
263
        return true;
7✔
264
}
14✔
265

266
bool InterpolateGridPoint(dna_geoid_interpolation* g, geoid_point* apInterpolant, 
2✔
267
        const int& method, const int& coordinate_format, const string& inputLatitude, const string& inputLongitude)
268
{
269
        try {
2✔
270
                if (method == BICUBIC)
2✔
271
                        g->BiCubicTransformation(apInterpolant);
1✔
272
                else
273
                        g->BiLinearTransformation(apInterpolant);
1✔
274
        }
275
        catch (const NetGeoidException& e) {
×
276
                cout << endl << "- Error: " << e.what() << endl;
×
277
                return false;
×
278
        }
×
279

280
        if (apInterpolant->cVar.IO_Status != ERR_TRANS_SUCCESS)
2✔
281
                return false;
282
        
283
        cout << "+ Interpolation results for ";
2✔
284
        cout << inputLatitude << ", " << inputLongitude;
2✔
285
        if (coordinate_format == DMS)
2✔
286
                //cout << fixed << setprecision(6) << DegtoDms<double>(apInterpolant->cVar.dLatitude) << ", " << DegtoDms<double>(apInterpolant->cVar.dLongitude) << " (ddd.mmssss):" << endl;
287
                cout << " (ddd.mmssss):" << endl;
2✔
288
        else
289
                //cout << fixed << setprecision(6) << apInterpolant->cVar.dLatitude << ", " << apInterpolant->cVar.dLongitude << " (ddd.dddddd):" << endl;
290
                cout << " (ddd.dddddd):" << endl;
×
291
        
292
        cout << endl;
2✔
293

294
        cout << "  N value          = " << setw(6) << 
2✔
295
                right << setprecision(3) << apInterpolant->gVar.dN_value << " metres" << endl;                        // N value
2✔
296
        cout << "  Deflections:" << endl;
2✔
297
        cout << "  - Prime meridian = " << setw(6) << 
2✔
298
                right << fixed << setprecision(2) << apInterpolant->gVar.dDefl_meridian << " seconds" << endl;                        // N value
2✔
299
        cout << "  - Prime vertical = " << setw(6) << 
2✔
300
                right << apInterpolant->gVar.dDefl_primev << " seconds" << endl;                        // N value
2✔
301
        cout << endl;
2✔
302
        return true;
2✔
303

304
} // InterpolateGridPoint
305
        
306

307
bool InterpolateGridPointFile(dna_geoid_interpolation* g, const char* inputfilePath, 
6✔
308
        const int& method, const int EllipsoidtoOrtho, const int& coordinate_format, 
309
        bool exportDnaGeoidFile, const char* dnageofilePath, string& outputfilePath)
310
{
311
        path inputFile(inputfilePath);
6✔
312
        if (inputFile.has_extension())
6✔
313
                outputfilePath = inputFile.stem().string() + "_out" + inputFile.extension().string();
6✔
314
        else
315
        {
316
                outputfilePath = inputfilePath; 
×
317
                outputfilePath.append("_out");
×
318
        }
319

320
        char outfilePath[601];
6✔
321
        strcpy(outfilePath, outputfilePath.c_str());
6✔
322

323
        try {
6✔
324
                g->FileTransformation(inputfilePath, outfilePath, 
6✔
325
                        method, EllipsoidtoOrtho, coordinate_format, 
326
                        exportDnaGeoidFile, dnageofilePath);
327
        }
328
        catch (const NetGeoidException& e) {
×
329
                cout << endl << "- Error: " << e.what() << endl;
×
330
                return false;
×
331
        }
×
332

333
        return true;
334

335
} // InterpolateGridPointFile
6✔
336

337

338
bool InterpolateGridBinaryStationFile(dna_geoid_interpolation* g, const string& bstnfilePath,
9✔
339
        const int& method, bool convertHeights, 
340
        bool exportDnaGeoidFile, const char* dnageofilePath)
341
{
342
        try {
9✔
343
                g->PopulateBinaryStationFile(bstnfilePath, method, convertHeights, 
9✔
344
                        exportDnaGeoidFile, dnageofilePath);
345
        }
346
        catch (const NetGeoidException& e) {
×
347
                cout << endl << "- Error: " << e.what() << endl;
×
348
                return false;
×
349
        }
×
350

351
        return true;
352

353
} // InterpolateGridBinaryStationFile
354

355

356
string GetFileType(const string inputfilePath)
25✔
357
{
358
        path inputFile(inputfilePath);
25✔
359
        if (inputFile.has_extension())
25✔
360
                return inputFile.extension().string();
50✔
361
        else
362
                return "";
×
363
}
25✔
364

365
int ParseCommandLineOptions(const int& argc, char* argv[], const variables_map& vm, project_settings& p)
29✔
366
{
367
        // capture command line arguments
368
        for (int cmd_arg(0); cmd_arg<argc; ++cmd_arg)
208✔
369
        {
370
                 p.n.command_line_arguments += argv[cmd_arg];
179✔
371
                 p.n.command_line_arguments += " ";
179✔
372
        }
373

374
        // Has the user supplied a project file?
375
        if (vm.count(PROJECT_FILE))
29✔
376
        {
377
                if (exists(p.g.project_file))
1✔
378
                {
379
                        try {
×
380
                                CDnaProjectFile projectFile(p.g.project_file, geoidSetting);
×
381
                                p = projectFile.GetSettings();
×
382
                        }
×
383
                        catch (const runtime_error& e) {
×
384
                                cout << endl << "- Error: " << e.what() << endl;
×
385
                                return EXIT_FAILURE;
×
386
                        }
×
387
                        
388
                        return EXIT_SUCCESS;
×
389
                }
390

391
                cout << endl << "- Error: project file " << p.g.project_file << " does not exist." << endl << endl;
1✔
392
                return EXIT_FAILURE;
1✔
393
        }
394

395
        if (!vm.count(NETWORK_NAME) &&                                // User wants to populate a binary station file for a particular DynAdjust project
72✔
396
                !vm.count(INTERACTIVE) &&                                // User wants to interpolate geoid information from the command line
58✔
397
                !vm.count(CREATE_NTV2) &&                                // User wants to create a NTv2 grid file
54✔
398
                !vm.count(SUMMARY) &&                                        // User wants to print to the screen the details of the grid file
51✔
399
                !vm.count(INPUT_FILE) &&                                // User wants to interpolate geoid information in text file mode
44✔
400
                !vm.count(DAT_FILEPATH) &&                                // User supplied file path to WINTER DAT file
38✔
401
                !vm.count(EXPORT_NTV2_ASCII_FILE) &&        // User wants to export a geoid file to ASCII
64✔
402
                !vm.count(EXPORT_NTV2_BINARY_FILE))                // User wants to export a geoid file to binary
34✔
403
        {
404
                cout << endl << "- Nothing to do - no standard options specified. " << endl << endl;
1✔
405
                return EXIT_FAILURE;
1✔
406
        }
407

408
        // check mandatory arguments for NTv2 file creation
409
        if (vm.count(CREATE_NTV2) && !vm.count(DAT_FILEPATH))
31✔
410
        {
411
                cout << endl << "- Error: no dat file specified. " << endl << endl;
×
412
                return EXIT_FAILURE;
×
413
        }
414

415
        // check mandatory arguments for interactive mode
416
        if (vm.count(INTERACTIVE) && !vm.count(LATITUDE))
31✔
417
        {
418
                cout << endl << "- Error: Interpolation latitide not specified. " << endl << endl;
×
419
                return EXIT_FAILURE;
×
420
        }
421

422
        // check mandatory arguments for interactive mode
423
        if (vm.count(INTERACTIVE) && !vm.count(LONGITUDE))
31✔
424
        {
425
                cout << endl << "- Error: Interpolation longitude not specified. " << endl << endl;
×
426
                return EXIT_FAILURE;
×
427
        }
428

429
        // check mandatory arguments for text file mode
430
        if (!vm.count(INPUT_FILE) && !vm.count(NTV2_FILEPATH) && !vm.count(CREATE_NTV2))
49✔
431
        {
432
                cout << endl << "- Error: Interpolation input file not specified. " << endl << endl;
1✔
433
                return EXIT_FAILURE;
1✔
434
        }
435

436
        // check mandatory arguments for NTv2 file summary
437
        if (vm.count(SUMMARY) && !vm.count(NTV2_FILEPATH))
28✔
438
        {
439
                cout << endl << "- Error: No NTv2 grid file specified. " << endl << endl;
×
440
                return EXIT_FAILURE;
×
441
        }
442

443
        // check mandatory arguments for DynAdjust station file population
444
        if (vm.count(NETWORK_NAME) && !vm.count(NTV2_FILEPATH))
48✔
445
        {
446
                cout << endl << "- Error: No NTv2 grid file specified. " << endl << endl;
×
447
                return EXIT_FAILURE;
×
448
        }
449

450
        // binary station file location (input)
451
        if (vm.count(NETWORK_NAME))
26✔
452
        {
453
                p.g.project_file = formPath<string>(p.g.output_folder, p.g.network_name, "dnaproj");
11✔
454

455
                // define bst file name
456
                p.n.bst_file = formPath<string>(p.g.input_folder, p.g.network_name, "bst");
11✔
457
                p.n.file_mode = 1;
11✔
458
                if (!exists(p.n.bst_file))
11✔
459
                {
460
                        // Look for it in the input folder
461
                        p.n.bst_file = formPath<string>(p.g.input_folder, leafStr<string>(p.n.bst_file));
1✔
462

463
                        if (!exists(p.n.bst_file))
1✔
464
                        {
465
                                cout << endl << "- Error: ";  
1✔
466
                                cout << "Binary station file " << p.n.bst_file << " does not exist." << endl << endl;  
1✔
467
                                return EXIT_FAILURE;
1✔
468
                        }
469
                }
470
        }
471

472
        // Geoid DAT grid file file location (input)
473
        if (vm.count(DAT_FILEPATH))
25✔
474
        {
475
                if (!exists(p.n.rdat_geoid_file))
2✔
476
                {
477
                        // Look for it in the input folder
478
                        p.n.rdat_geoid_file = formPath<string>(p.g.input_folder, leafStr<string>(p.n.rdat_geoid_file));
×
479

480
                        if (!exists(p.n.rdat_geoid_file))
×
481
                        {
482
                                cout << endl << "- Error: ";  
×
483
                                cout << "WINTER DAT grid file " << p.n.rdat_geoid_file << " does not exist." << endl << endl;  
×
484
                                return EXIT_FAILURE;
×
485
                        }
486
                }
487
        }
488

489
        // Is geoid to run in file mode?
490
        if (vm.count(INPUT_FILE))
25✔
491
        {
492
                p.n.file_mode = 1;
6✔
493

494
                // Geoid DAT grid file file location (input)
495
                if (!exists(p.n.input_file))
6✔
496
                {
497
                        // Look for it in the input folder
498
                        p.n.input_file = formPath<string>(p.g.input_folder, leafStr<string>(p.n.input_file));
×
499

500
                        if (!exists(p.n.input_file))
×
501
                        {
502
                                cout << endl << "- Error: ";  
×
503
                                cout << "Input coordinates text file " << leafStr<string>(p.n.input_file) << " does not exist." << endl << endl;  
×
504
                                return EXIT_FAILURE;
×
505
                        }
506
                }
507
        }
508

509
        if (vm.count(EXPORT_GEO_FILE))
25✔
510
        {
511
                if (vm.count(NETWORK_NAME))
7✔
512
                        p.n.geo_file = formPath<string>(p.g.output_folder, p.g.network_name, "geo");        // dna geoid file
5✔
513
                p.n.export_dna_geo_file = 1;
7✔
514
        }
515

516
        if (vm.count(DDEG_FORMAT))
25✔
517
                p.n.coordinate_format = DDEG;
2✔
518
        
519
        // Change behaviour of geoid to always convert orthometric heights to ellipsoid
520
        // deprecate this command
521
        //if (vm.count(CONVERT_BST_HT))
522
        p.n.convert_heights = 1;
25✔
523
        //else
524
        //        p.n.convert_heights = 0;
525

526
        return EXIT_SUCCESS;
25✔
527
}
528

529
int main(int argc, char* argv[])
42✔
530
{
531
        variables_map vm;
42✔
532
        positional_options_description positional_options;
42✔
533
        
534
        options_description standard_options("+ " + string(ALL_MODULE_STDOPT), PROGRAM_OPTIONS_LINE_LENGTH);
84✔
535
        options_description ntv2_options("+ " + string(GEOID_MODULE_NTV2), PROGRAM_OPTIONS_LINE_LENGTH);
84✔
536
        options_description interpolate_options("+ " + string(GEOID_MODULE_INTERPOLATE), PROGRAM_OPTIONS_LINE_LENGTH);
84✔
537
        options_description interactive_options("+ " + string(GEOID_MODULE_INTERACTIVE), PROGRAM_OPTIONS_LINE_LENGTH);
84✔
538
        options_description file_interpolate_options("+ " + string(GEOID_MODULE_FILE), PROGRAM_OPTIONS_LINE_LENGTH);
84✔
539
        options_description export_options("+ " + string(ALL_MODULE_EXPORT), PROGRAM_OPTIONS_LINE_LENGTH);
84✔
540
        options_description generic_options("+ " + string(ALL_MODULE_GENERIC), PROGRAM_OPTIONS_LINE_LENGTH);
84✔
541

542
        string cmd_line_usage("+ ");
42✔
543
        cmd_line_usage.append(__BINARY_NAME__).append(" usage:  ").append(__BINARY_NAME__).append(" [options]");
42✔
544
        options_description allowable_options(cmd_line_usage, PROGRAM_OPTIONS_LINE_LENGTH);
42✔
545

546
        n_file_par ntv2;
42✔
547
        ntv2.ptrIndex = new n_gridfileindex[1];
84✔
548
        geoid_point apInterpolant;
42✔
549

550
        project_settings p;
42✔
551

552
        string cmd_line_banner, gs_type("seconds"), version("1.0.0.0"), system_f("GDA94   "), system_t("AHD_1971");
42✔
553
        string subgridname("AUSGEOID"), parent(""), created(""), updated("");
42✔
554

555
        string inputLatitude, inputLongitude;
42✔
556
        
557
        fileproc_help_header(&cmd_line_banner);
42✔
558
        p.g.project_file = "";
42✔
559

560
        try {
42✔
561
                // Declare a group of options that will be 
562
                // allowed only on command line                
563
                standard_options.add_options()
42✔
564
                        (PROJECT_FILE_P, value<string>(&p.g.project_file),
42✔
565
                                "Project file name. Full path to project file. If none specified, a new file is created using input-folder and network-name.")
566
                        (NETWORK_NAME_N, value<string>(&p.g.network_name), 
42✔
567
                                string("Network name. If [" + string(NETWORK_NAME) + "].bst exists, all records within the binary station file will be populated with N value and deflections of the vertical.").c_str())
84✔
568
                        (INPUT_FOLDER_I, value<string>(&p.g.input_folder),
42✔
569
                                "Path containing all input files.")
570
                        (OUTPUT_FOLDER_O, value<string>(&p.g.output_folder),                // default is ./,
42✔
571
                                "Path for all output files.")
572
                        ;
573

574
                interpolate_options.add_options()
42✔
575
                        (INTERACTIVE_E, "Interpolate geoid information using coordinates provided on the command line.")
42✔
576
                        (INPUT_FILE_T, value<string>(&p.n.input_file),
42✔
577
                                "Interpolate geoid information using coordinates contained in a text file. "
578
                                "arg is the path of the input text file. "
579
                                "The supported text file formats include formatted text (*.txt) and comma separated values (*.csv) files. "
580
                                "Refer to the User's Guide for file format information.")
581
                        (METHOD_M, value<UINT16>(&p.n.interpolation_method),
42✔
582
                                "Interpolation method.\n  0  Bi-linear\n  1  Bi-cubic (default)")
583
                        (CONVERT_BST_HT, 
42✔
584
                                "DEPRECATED. If a user-supplied height in the binary file is orthometric, the height will be converted to ellipsoidal automatically.")
585
                        (DDEG_FORMAT, "Specify input coordinates in decimal degrees (dd.dddddd).  Default is degrees, minutes and seconds (dd.mmssss).")
42✔
586
                        (CREATE_NTV2_C, "Create NTv2 grid file from standard DAT file.")
42✔
587
                        (NTV2_FILEPATH_G, value<string>(&p.n.ntv2_geoid_file), "Full file path of the NTv2 grid file.")
42✔
588
                        (SUMMARY_U, "Print a summary of the grid file.")
42✔
589
                        ;
590

591
                // Declare a group of options that will be 
592
                // allowed both on command line and in
593
                // config file        
594
                ntv2_options.add_options()
42✔
595
                        (DAT_FILEPATH_D, value<string>(&p.n.rdat_geoid_file), 
42✔
596
                                "File path of the WINTER DAT grid file.")
597
                        (NTV2_GS_TYPE, value<string>(&gs_type),
42✔
598
                                "Units in which the grid parameters and deflections of the vertical will be stored. arg is either 'seconds' or 'radians'. Default is seconds.")
599
                        (NTV2_VERSION, value<string>(&version),
42✔
600
                                "Grid file version. Default is 1.0.0.0.")
601
                        (NTV2_SYSTEM_F, value<string>(&system_f),
42✔
602
                                "The 'From' reference system. Default is GDA94.")
603
                        (NTV2_SYSTEM_T, value<string>(&system_t),
42✔
604
                                "The 'To' reference system. Default is AHD_1971")
605
                        (NTV2_MAJOR_F, value<double>(&ntv2.daf),
42✔
606
                                "Semi major of 'From' system. Default is 6378137.000")
607
                        (NTV2_MAJOR_T, value<double>(&ntv2.dat),
42✔
608
                                "Semi major of 'To' system. Default is 6378137.000")
609
                        (NTV2_MINOR_F, value<double>(&ntv2.dbf),
42✔
610
                                "Semi minor of 'From' system. Default is 6356752.314")
611
                        (NTV2_MINOR_T, value<double>(&ntv2.dbt),
42✔
612
                                "Semi minor of 'To' system. Default is 6356752.314")
613
                        (NTV2_SUB_NAME, value<string>(&subgridname),
42✔
614
                                "The name of the sub-grid. Default is AUSGEOID")
615
                        (NTV2_CREATED, value<string>(&created), 
42✔
616
                                "Date of geoid model creation. arg is a dot delimited string \"dd.mm.yyyy\". Default is today's date if no value is supplied.")
617
                        (NTV2_UPDATED, value<string>(&updated), 
42✔
618
                                "Date of last file update. arg is a dot delimited string \"dd.mm.yyyy\". Default is today's date if no value is supplied.")
619
                        ;
620

621
                interactive_options.add_options()
42✔
622
                        (LATITUDE, value<string>(&inputLatitude),
42✔
623
                                "Latitude of the interpolant. Default is degrees, minutes and seconds (dd.mmssss).")
624
                        (LONGITUDE, value<string>(&inputLongitude),
42✔
625
                                "Longitude of the interpolant. Default is degrees, minutes and seconds (dd.mmssss).")
626
                        ;
627

628
                file_interpolate_options.add_options()
42✔
629
                        (DIRECTION_R, value<UINT16>(&p.n.ellipsoid_to_ortho), 
42✔
630
                                "Conversion of heights:\n  0  Orthometric to ellipsoid (default)\n  1  Ellipsoid to orthometric")
631
                        ;
632

633
                // Declare a group of options that will be 
634
                // allowed both on command line and in
635
                // config file        
636
                export_options.add_options()
42✔
637
                        (EXPORT_GEO_FILE, 
42✔
638
                                "Create a DNA geoid file from interpolated geoid information.")
639
                        (EXPORT_NTV2_ASCII_FILE,
42✔
640
                                "Export a binary NTv2 geoid file to ASCII (.asc) format.")
641
                        (EXPORT_NTV2_BINARY_FILE,
42✔
642
                                "Export an ASCII NTv2 geoid file to binary (.gsb) format.")
643
                        ;
644

645
                generic_options.add_options()
42✔
646
                        (VERBOSE, value<UINT16>(&p.g.verbose),
42✔
647
                                string("When importing geoid information into a project, print the stations for which an N-value could not be interpolated to a log (*.int) file.\n  0: No information (default)\n  1: Helpful information\n  2: Extended information").c_str())
42✔
648
                                (QUIET,
42✔
649
                                        string("Suppresses all explanation of what ").append(__BINARY_NAME__).append(" is doing unless an error occurs").c_str())
84✔
650
                                        (VERSION_V, "Display the current program version")
42✔
651
                        (HELP_H, "Show this help message")
42✔
652
                        (HELP_MODULE, value<string>(),
42✔
653
                                "Provide help for a specific help category.")
654
                        ;
655

656
                allowable_options.add(standard_options).add(interpolate_options).add(ntv2_options).add(interactive_options).add(file_interpolate_options).add(export_options).add(generic_options);
42✔
657

658
                // add "positional options" to handle command line tokens which have no option name
659
                positional_options.add(NETWORK_NAME, -1);
42✔
660

661
                command_line_parser parser(argc, argv);
42✔
662
                store(parser.options(allowable_options).positional(positional_options).run(), vm);
42✔
663
                notify(vm);
41✔
664
        } 
1✔
665
        catch (const std::exception& e) {
1✔
666
                cout << endl << "- Error: " << e.what() << endl;
1✔
667
                cout << cmd_line_banner << allowable_options << endl;
1✔
668
                return EXIT_FAILURE;
1✔
669
        }
1✔
670
        catch (...) 
×
671
        {
672
                cout << endl << "- Exception of unknown type!\n";
×
673
                return EXIT_FAILURE;
×
674
        }
×
675

676
        if (argc < 2)
41✔
677
        {
678
                cout << endl << "- Nothing to do - no options provided. " << endl << endl;  
1✔
679
                cout << cmd_line_banner << allowable_options << endl;
1✔
680
                return EXIT_FAILURE;
681
        }
682

683
        if (vm.count(VERSION))
40✔
684
        {
685
                cout << cmd_line_banner << endl;
2✔
686
                return EXIT_SUCCESS;
687
        }
688

689
        if (vm.count(HELP))
38✔
690
        {
691
                cout << cmd_line_banner << allowable_options << endl;
42✔
692
                return EXIT_SUCCESS;
693
        }
694

695
        if (vm.count(HELP_MODULE))
37✔
696
        {
697
                cout << cmd_line_banner;
8✔
698
                string original_text = vm[HELP_MODULE].as<string>();
16✔
699
                string help_text = str_upper<string>(original_text);
8✔
700

701
                if (str_upper<string, char>(ALL_MODULE_STDOPT).find(help_text) != string::npos) {
16✔
702
                        cout << standard_options << endl;
1✔
703
                }
704
                else if (str_upper<string, char>(GEOID_MODULE_NTV2).find(help_text) != string::npos) {
14✔
705
                        cout << ntv2_options << endl;
1✔
706
                }
707
                else if (str_upper<string, char>(GEOID_MODULE_INTERPOLATE).find(help_text) != string::npos) {
12✔
708
                        cout << interpolate_options << endl;
1✔
709
                }
710
                else if (str_upper<string, char>(GEOID_MODULE_INTERACTIVE).find(help_text) != string::npos) {
10✔
711
                        cout << interactive_options << endl;
1✔
712
                }
713
                else if (str_upper<string, char>(GEOID_MODULE_FILE).find(help_text) != string::npos) {
8✔
714
                        cout << file_interpolate_options << endl;
1✔
715
                }
716
                else if (str_upper<string, char>(ALL_MODULE_EXPORT).find(help_text) != string::npos) {
6✔
717
                        cout << export_options << endl;
1✔
718
                }
719
                else if (str_upper<string, char>(ALL_MODULE_GENERIC).find(help_text) != string::npos) {
4✔
720
                        cout << generic_options << endl;
1✔
721
                }
722
                else {
723
                        cout << endl << "- Error: Help module '" <<
1✔
724
                                original_text << "' is not in the list of options." << endl;
8✔
725
                        return EXIT_FAILURE;
726
                }
727

728
                return EXIT_SUCCESS;
7✔
729
        }
8✔
730

731
        if (ParseCommandLineOptions(argc, argv, vm, p) != EXIT_SUCCESS)
29✔
732
                return EXIT_FAILURE;
733

734
        // Has the user supplied a project file?
735
        bool userSuppliedProjectFile(false);
25✔
736
        if (!p.g.project_file.empty())
25✔
737
                userSuppliedProjectFile = true;
10✔
738

739
        // Capture NTv2 file path and extension
740
        // grid file path not supplied.  Generate name from dat file
741
        if (p.n.ntv2_geoid_file.empty())
25✔
742
        {
743
                path gsbFile(p.n.rdat_geoid_file);
×
744
                p.n.ntv2_geoid_file = gsbFile.stem().string() + gsbFile.extension().string() + ".gsb";
×
745
                strcpy(ntv2.filename, p.n.ntv2_geoid_file.c_str());
×
746
                strcpy(ntv2.filetype, GSB);
×
747
        }
×
748
        else
749
        {
750
                string extension(GetFileType(p.n.ntv2_geoid_file));
25✔
751
                if (extension.empty())
25✔
752
                {
753
                        cout << endl << "- Error: NTv2 grid file type cannot be determined from a file without a file extension. " << endl << endl;
×
754
                        return EXIT_FAILURE;
755
                }
756

757
                if (!iequals(extension.substr(1), GSB) &&
56✔
758
                        !iequals(extension.substr(1), ASC))
37✔
759
                {
760
                        cout << endl << "- Error: NTv2 grid file type cannot be determined from file extension \"" << extension << "\"." << endl << 
×
761
                                "         Supported types are ." << GSB << " and ." << ASC << " only." << endl << endl;
×
762
                        return EXIT_FAILURE;
763
                }
764

765
                if (vm.count(EXPORT_NTV2_ASCII_FILE) &&
52✔
766
                        iequals(extension.substr(1), ASC))
29✔
767
                {
768
                        cout << endl << "- Error: Export to ASCII NTv2 grid file option only supported for " << GSB " grid files." << endl << endl;
×
769
                        return EXIT_FAILURE;
770
                }
771

772
                if (vm.count(EXPORT_NTV2_BINARY_FILE) &&
52✔
773
                        iequals(extension.substr(1), GSB))
29✔
774
                {
775
                        cout << endl << "- Error: Export to Binary NTv2 grid file option only supported for " << ASC " grid files." << endl << endl;
×
776
                        return EXIT_FAILURE;
777
                }
778

779
                strcpy(ntv2.filename, p.n.ntv2_geoid_file.c_str());
25✔
780
                strcpy(ntv2.filetype, extension.substr(1).c_str());
25✔
781
        }        
25✔
782
        
783
        if (vm.count(QUIET))
25✔
784
                p.g.quiet = 1;
×
785

786
        if (vm.count(NTV2_GS_TYPE))
25✔
787
        {
788
                gs_type = trimstr(gs_type);
3✔
789
                // Unknown type?
790
                if (!iequals(gs_type, "seconds") && !iequals(gs_type, "radians"))
3✔
791
                        gs_type = "seconds";
×
792
                str_toupper<int>(gs_type);
3✔
793
        }
794
        
795
        if (!p.g.quiet)
25✔
796
        {
797
                cout << endl << cmd_line_banner;
25✔
798

799
                cout << "+ Options:" << endl; 
25✔
800
                
801
                if (vm.count(NETWORK_NAME))
25✔
802
                        cout << setw(PRINT_VAR_PAD) << left << "  Network name: " <<  p.g.network_name << endl;
10✔
803

804
                if (p.n.file_mode || vm.count(CREATE_NTV2))
36✔
805
                {
806
                        cout << setw(PRINT_VAR_PAD) << left << "  Input folder: " << p.g.input_folder << endl;
18✔
807
                        cout << setw(PRINT_VAR_PAD) << left << "  Output folder: " << p.g.output_folder << endl;
18✔
808

809
                        if (!p.n.bst_file.empty())
18✔
810
                        {
811
                                cout << setw(PRINT_VAR_PAD) << left << "  Binary station file: " << p.n.bst_file << endl;
10✔
812
                                //cout << setw(PRINT_VAR_PAD) << left << "  Convert orthometric heights: ";
813
                                //if (p.n.convert_heights)
814
                                //        cout << "Yes" << endl;
815
                                //else
816
                                //        cout << "No" << endl;
817
                        }
818

819
                        if (!p.n.input_file.empty())
18✔
820
                                cout << setw(PRINT_VAR_PAD) << left << "  ASCII file: " << p.n.input_file << endl;
6✔
821
                }
822
                
823
                cout << setw(PRINT_VAR_PAD) << left << "  Geoid grid file: " <<  ntv2.filename << endl;
25✔
824
                
825
                // Not applicable for project file use
826
                if (vm.count(CREATE_NTV2))
25✔
827
                {
828
                        cout << setw(PRINT_VAR_PAD) << left << "  WINTER DAT file: " << leafStr<string>(p.n.rdat_geoid_file) << endl;
4✔
829

830
                        if (vm.count(NTV2_GS_TYPE))
2✔
831
                                cout << setw(PRINT_VAR_PAD) << left << "  Grid shift type: " << gs_type.c_str() << endl;
1✔
832
                        if (vm.count(NTV2_VERSION))
2✔
833
                                cout << setw(PRINT_VAR_PAD) << left << "  Grid file version: " << version.c_str() << endl;
1✔
834
                        if (vm.count(NTV2_SYSTEM_F))
2✔
835
                                cout << setw(PRINT_VAR_PAD) << left << "  From reference system: " << system_f.c_str() << endl;
1✔
836
                        if (vm.count(NTV2_SYSTEM_T))
2✔
837
                                cout << setw(PRINT_VAR_PAD) << left << "  To reference system: " << system_t.c_str() << endl;
1✔
838
                        if (vm.count(NTV2_MAJOR_F))
2✔
839
                                cout << setw(PRINT_VAR_PAD) << left << "  From semi-major: " << fixed << setprecision(3) << ntv2.daf << endl;
×
840
                        if (vm.count(NTV2_MAJOR_T))
2✔
841
                                cout << setw(PRINT_VAR_PAD) << left << "  To semi-major: " << ntv2.dat << endl;
×
842
                        if (vm.count(NTV2_MINOR_F))
2✔
843
                                cout << setw(PRINT_VAR_PAD) << left << "  From semi-minor: " << ntv2.dbf << endl;
×
844
                        if (vm.count(NTV2_MINOR_T))
2✔
845
                                cout << setw(PRINT_VAR_PAD) << left << "  To semi-minor: " << ntv2.dbt << endl;
×
846
                        if (vm.count(NTV2_SUB_NAME))
2✔
847
                                cout << setw(PRINT_VAR_PAD) << left << "  Sub-grid name: " << subgridname.c_str() << endl;
1✔
848
                        
849
                        date creationDate, updateDate;
2✔
850
                        if (created.empty())
2✔
851
                                created = "today";
1✔
852
                        
853
                        if (updated.empty())
2✔
854
                                updated = "today";
1✔
855
                        
856
                        creationDate = dateFromString<date>(created);
2✔
857
                        updateDate = dateFromString<date>(updated);
2✔
858

859
                        // Print dates by default
860
                        //if (vm.count(NTV2_CREATED))
861
                        cout << setw(PRINT_VAR_PAD) << left << "  Date of file creation: " << 
2✔
862
                                stringFromDate<date>(creationDate, "%d %B %Y") << endl;
4✔
863
                        //if (vm.count(NTV2_UPDATED))
864
                        cout << setw(PRINT_VAR_PAD) << left << "  Date of file update: " << 
2✔
865
                                stringFromDate<date>(updateDate, "%d %B %Y") << endl;
4✔
866

867
                        created = stringFromDate<date>(creationDate, "%d%m%Y");
2✔
868
                        updated = stringFromDate<date>(updateDate, "%d%m%Y");
2✔
869

870
                }
871

872
                if (vm.count(EXPORT_NTV2_ASCII_FILE) ||
73✔
873
                        vm.count(EXPORT_NTV2_BINARY_FILE))
71✔
874
                {
875
                        cout << setw(PRINT_VAR_PAD) << left << "  Export NTv2 grid file to: ";
4✔
876
                        if (vm.count(EXPORT_NTV2_ASCII_FILE))
4✔
877
                                cout << "ASCII (." << ASC << ")" << endl;
2✔
878
                        if (vm.count(EXPORT_NTV2_BINARY_FILE))
4✔
879
                                cout << "Binary (." << GSB << ")" << endl;
2✔
880

881
                        if (vm.count(NTV2_GS_TYPE))
4✔
882
                                cout << setw(PRINT_VAR_PAD) << left << "  Grid shift type: " << gs_type.c_str() << endl;
2✔
883
                }
884

885
                if (p.n.file_mode || vm.count(INTERACTIVE))
36✔
886
                {
887
                        cout << setw(PRINT_VAR_PAD) << left << "  Interpolation method: ";
18✔
888
                        if (p.n.interpolation_method == BICUBIC)
18✔
889
                                cout << "Bi-cubic" << endl;
15✔
890
                        else
891
                                cout << "Bi-linear" << endl;
3✔
892

893
                        cout << setw(PRINT_VAR_PAD) << left << "  Input coordinate format: ";
18✔
894
                        if (p.n.coordinate_format == DDEG)
18✔
895
                                cout << "Decimal degrees" << endl;
2✔
896
                        else
897
                                cout << "Degrees minutes seconds" << endl;
16✔
898
                        
899
                        if (!vm.count(INTERACTIVE))
18✔
900
                        {
901
                                cout << setw(PRINT_VAR_PAD) << left << "  Transformation direction: ";
16✔
902
                                if (p.n.ellipsoid_to_ortho == 0)
16✔
903
                                        cout << "Orthometric to ellipsoid" << endl;
16✔
904
                                else
905
                                        cout << "Ellipsoid to orthometric" << endl;
×
906
                        }
907
                }
908

909
                if (p.n.export_dna_geo_file)
25✔
910
                        cout << setw(PRINT_VAR_PAD) << left << "  Export to DNA geoid file: " << "Yes" << endl;
7✔
911

912
                cout << endl;
25✔
913

914
                if (vm.count(CONVERT_BST_HT))
25✔
915
                        cout << "- Warning: The '--" << CONVERT_BST_HT << "' option has been deprecated. Orthometric" << endl <<
8✔
916
                                "  heights in the binary file will be converted to ellipsoidal by default, " << endl <<
8✔
917
                            "  unless the transformation direction has been modified by supplying the " << endl << 
8✔
918
                            "  '--" << DIRECTION << "' option with an argument of 1." << endl;
8✔
919

920
                cout << endl;
25✔
921
        
922
                // File interpolation mode...
923
                if (p.n.file_mode)
25✔
924
                {
925
                        if (!p.n.bst_file.empty())
16✔
926
                                cout << "+ Binary station file interpolation mode." << endl << endl;
10✔
927
                        else
928
                                cout << "+ ASCII file interpolation mode." << endl << endl;
6✔
929
                }                        
930
        }
931

932
        dna_geoid_interpolation g;
25✔
933
        
934
        // Not applicable for project file use
935
        if (vm.count(CREATE_NTV2))
25✔
936
        {
937
                if (vm.count(NTV2_GS_TYPE))
2✔
938
                        strcpy(ntv2.chGs_type, gs_type.c_str());
1✔
939
                if (vm.count(NTV2_VERSION))
2✔
940
                        strcpy(ntv2.chVersion, version.c_str());
1✔
941
                if (vm.count(NTV2_SYSTEM_F))
2✔
942
                        strcpy(ntv2.chSystem_f, system_f.c_str());
1✔
943
                if (vm.count(NTV2_SYSTEM_T))
2✔
944
                        strcpy(ntv2.chSystem_t, system_t.c_str());
1✔
945
                
946
                // subgrid header string handlers
947
                if (vm.count(NTV2_SUB_NAME))
2✔
948
                        strcpy(ntv2.ptrIndex[0].chSubname, subgridname.c_str());
1✔
949
                strcpy(ntv2.ptrIndex[0].chParent, "NONE    ");                // don't give the user the option - must be "NONE    " !!!
2✔
950
                strcpy(ntv2.ptrIndex[0].chCreated, created.c_str());
2✔
951
                strcpy(ntv2.ptrIndex[0].chUpdated, updated.c_str());
2✔
952

953
                // Create a new grid file from AusGeoid DAT file
954
                if (!CreateNTv2Grid(&g, p.n.rdat_geoid_file.c_str(), &ntv2))
2✔
955
                {
956
                        if (ntv2.ptrIndex)
×
957
                                delete [] ntv2.ptrIndex;
×
958
                        return EXIT_FAILURE;
×
959
                }
960

961
                if (ntv2.ptrIndex)
2✔
962
                        delete [] ntv2.ptrIndex;
2✔
963

964
                cout << endl << "+ Geoid file creation completed successfully." << endl << endl;
2✔
965

966
                return EXIT_SUCCESS;
967
        }
968
        else if (vm.count(EXPORT_NTV2_ASCII_FILE))
23✔
969
        {
970
                if (p.n.ntv2_geoid_file.empty())
2✔
971
                {
972
                        cout << endl << "- Error: No NTv2 grid file specified. " << endl << endl;
×
973
                        return EXIT_FAILURE;
974
                }
975

976
                if (vm.count(NTV2_GS_TYPE))
2✔
977
                        strcpy(ntv2.chGs_type, gs_type.c_str());
1✔
978

979
                if (!ExportNTv2GridToAscii(&g, ntv2.filename, ntv2.filetype, ntv2.chGs_type, ASC))
2✔
980
                        return EXIT_FAILURE;
981
                
982
                cout << "+ Geoid file creation completed successfully." << endl << endl;
2✔
983

984
                return EXIT_SUCCESS;
985
        }
986
        else if (vm.count(EXPORT_NTV2_BINARY_FILE))
21✔
987
        {
988
                if (p.n.ntv2_geoid_file.empty())
2✔
989
                {
990
                        cout << endl << "- Error: No NTv2 grid file specified. " << endl << endl;
×
991
                        return EXIT_FAILURE;
992
                }
993

994
                if (vm.count(NTV2_GS_TYPE))
2✔
995
                        strcpy(ntv2.chGs_type, gs_type.c_str());
1✔
996

997
                if (!ExportNTv2GridToBinary(&g, ntv2.filename, ntv2.filetype, ntv2.chGs_type, GSB))
2✔
998
                        return EXIT_FAILURE;
999

1000
                cout << "+ Geoid file creation completed successfully." << endl << endl;
2✔
1001

1002
                return EXIT_SUCCESS;
1003
        }
1004

1005
        // Not applicable for project file use
1006
        if (vm.count(SUMMARY))
19✔
1007
        {
1008
                // Open the grid file and print its properties
1009
                if (!reportGridProperties(&g, ntv2.filename, ntv2.filetype))
1✔
1010
                        return EXIT_FAILURE;
1011

1012
                return EXIT_SUCCESS;
1✔
1013
        }
1014

1015
        // Not applicable for project file use
1016
        if (vm.count(INTERACTIVE))
18✔
1017
        {
1018
                apInterpolant.cVar.dLatitude = DoubleFromString<double>(inputLatitude);
2✔
1019
                apInterpolant.cVar.dLongitude = DoubleFromString<double>(inputLongitude);
2✔
1020

1021
                stringstream ssInput;
2✔
1022
                ssInput << inputLatitude << ", " << inputLongitude;
2✔
1023
                g.SetInputCoordinates(ssInput.str());
4✔
1024

1025
                if  (p.n.coordinate_format == DMS)
2✔
1026
                {
1027
                        apInterpolant.cVar.dLatitude = DmstoDeg<double>(apInterpolant.cVar.dLatitude);
2✔
1028
                        apInterpolant.cVar.dLongitude = DmstoDeg<double>(apInterpolant.cVar.dLongitude);
2✔
1029
                }
1030

1031
                // Get geoid values for a point
1032
                if (!createGridIndex(&g, ntv2.filename, ntv2.filetype, p.g.quiet))
2✔
1033
                        return EXIT_FAILURE;
1034

1035
                if (!InterpolateGridPoint(&g, &apInterpolant, p.n.interpolation_method,
4✔
1036
                        p.n.coordinate_format, inputLatitude, inputLongitude))
2✔
1037
                {
1038
                        cout << endl;
×
1039
                        if (apInterpolant.cVar.IO_Status == ERR_FINDSUBGRID_OUTSIDE)
×
1040
                                reportGridProperties(&g, ntv2.filename, ntv2.filetype);
×
1041

1042
                        return EXIT_FAILURE;
×
1043
                }
1044
                return EXIT_SUCCESS;
1045
        }
2✔
1046
         
1047
        // Should a file be processed?
1048
        if (!p.n.file_mode)
16✔
1049
                return EXIT_SUCCESS;
1050
        
1051
        // Get geoid values for a point
1052
        if (!createGridIndex(&g, ntv2.filename, ntv2.filetype, p.g.quiet))
16✔
1053
                return EXIT_FAILURE;
1054

1055
        if (!p.g.quiet)
15✔
1056
        {
1057
                cout << "+ Interpolating geoid components";
15✔
1058
                if (!p.n.bst_file.empty() && p.n.convert_heights)
15✔
1059
                        cout << " and reducing" << endl <<
9✔
1060
                                "  heights to the ellipsoid";
9✔
1061
                cout << "... ";
15✔
1062
        }
1063
        
1064
        cpu_timer time;
15✔
1065

1066
        char dnageoFile[601], *geoFileptr;
15✔
1067
        geoFileptr = NULL;
15✔
1068
        memset(dnageoFile, '\0', sizeof(dnageoFile));
15✔
1069
        string outputfilePath;
15✔
1070
                
1071
        if (!p.n.geo_file.empty())
15✔
1072
        {
1073
                sprintf(dnageoFile, "%s", p.n.geo_file.c_str());
5✔
1074
                geoFileptr = dnageoFile;
5✔
1075
        }
1076
                
1077
        if (!p.n.bst_file.empty())
15✔
1078
        {
1079
                // populate binary station file with geoid separation and deflections
1080
                if (!InterpolateGridBinaryStationFile(&g, p.n.bst_file.c_str(), p.n.interpolation_method, 
9✔
1081
                        p.n.convert_heights ? true : false, 
9✔
1082
                        p.n.export_dna_geo_file? true : false, geoFileptr))
9✔
1083
                                return EXIT_FAILURE;
1084
        }
1085
        else if (!p.n.input_file.empty())
6✔
1086
        {
1087
                // Ascii text file (similar to old winter format)
1088
                if (!InterpolateGridPointFile(&g, p.n.input_file.c_str(), p.n.interpolation_method, 
12✔
1089
                        p.n.ellipsoid_to_ortho, p.n.coordinate_format,
6✔
1090
                        p.n.export_dna_geo_file? true : false, geoFileptr,
6✔
1091
                        outputfilePath))
1092
                                return EXIT_FAILURE;
1093
        }
1094
        else
1095
                return EXIT_SUCCESS;
1096
                
1097
        if (!p.g.quiet)
15✔
1098
        {
1099
                cout << "done." << endl;
15✔
1100
                cout << "+ Interpolated data for " << g.PointsInterpolated();
15✔
1101
                if (g.PointsInterpolated() == 1)
15✔
1102
                        cout << " point." << endl;
×
1103
                else
1104
                        cout << " points." << endl;
15✔
1105

1106
                if (g.PointsNotInterpolated() > 0)
15✔
1107
                {
1108
                        cout << "- Warning: Data for " << g.PointsNotInterpolated();
8✔
1109

1110
                        // Is this wrapper being called to update DynAdjust station file?
1111
                        if (!p.n.bst_file.empty())
8✔
1112
                        {
1113
                                if (g.PointsNotInterpolated() == 1)
2✔
1114
                                        cout << " station";
×
1115
                                else
1116
                                        cout << " stations";
2✔
1117

1118
                                cout << " could not be interpolated.  ";
2✔
1119
                                        
1120
                                if (p.g.verbose > 0)
2✔
1121
                                {
1122
                                        try {
2✔
1123
                                                ReturnBadStationRecords(&g, p);
2✔
1124
                                        }
1125
                                        catch (const runtime_error& e) {
×
1126
                                                // print error message, and continue
1127
                                                cout << "- Error: " << e.what() << endl;
×
1128
                                        }
×
1129
                                }
1130
                                else
1131
                                        cout << "To view the list of stations " << endl <<
×
1132
                                                "  for which an N-value could not be interpolated, call " << __BINARY_NAME__ << " with --verbose-level 1." << endl;
×
1133
                        }
1134
                        // If this point is reached, then this wrapper must have been called
1135
                        // to interpolate points in interactive mode.
1136
                        else //if (!p.n.input_file.empty())
1137
                        {
1138
                                if (g.PointsNotInterpolated() == 1)
6✔
1139
                                        cout << " point";
×
1140
                                else
1141
                                        cout << " points";
6✔
1142

1143
                                cout << " could not be interpolated." << endl;
6✔
1144
                                cout << "  See " << outputfilePath << " for more information." << endl;
6✔
1145
                        }
1146
                }
1147
        }
1148

1149
        // Look for a project file (if the user has specified a network name.  
1150
        // If it exists, open it, load it and update the geoid settings.
1151
        if (userSuppliedProjectFile)
15✔
1152
        {
1153
                CDnaProjectFile projectFile;
9✔
1154
                if (exists(p.g.project_file))
9✔
1155
                        projectFile.LoadProjectFile(p.g.project_file);
9✔
1156

1157
                // Print the project file. If it doesn't exist, it will be created.
1158
                projectFile.UpdateSettingsGeoid(p);
9✔
1159
                projectFile.PrintProjectFile();
9✔
1160
        }
9✔
1161

1162
        if (p.g.quiet)
15✔
1163
                return EXIT_SUCCESS;
1164

1165
        // wall time is in nanoseconds
1166
        // cout << time.elapsed().wall << endl << endl;
1167
        milliseconds elapsed_time(milliseconds(time.elapsed().wall/MILLI_TO_NANO));
15✔
1168
        cout << endl << formatedElapsedTime<string>(&elapsed_time, "+ Geoid file interpolation took ") << endl << endl;
30✔
1169
        
1170
        return EXIT_SUCCESS;
15✔
1171
}
109✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc