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

icsm-au / DynAdjust / 13494567994

24 Feb 2025 09:15AM UTC coverage: 81.168% (+2.0%) from 79.161%
13494567994

push

github

web-flow
Merge pull request #234 from icsm-au/1.2.8

Version 1.2.8 (fixes, ehnacements, improved datum management)

6131 of 8137 new or added lines in 90 files covered. (75.35%)

162 existing lines in 33 files now uncovered.

32214 of 39688 relevant lines covered (81.17%)

11775.25 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
        std::cout << "+ Creating NTv2 geoid grid file from WINTER DAT file format..." << std::endl;
2✔
34

35
        try {
2✔
36
                g->CreateNTv2File(dat_gridfilePath, grid);
2✔
37
        }
38
        catch (const NetGeoidException& e) {
×
NEW
39
                std::cout << std::endl << "- Error: " << e.what() << std::endl;
×
40
                return false;
×
41
        }
×
42
        std::cout << std::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
        boost::filesystem::path asciiGridFile(dat_gridfilePath);
2✔
59
        std::string outfile = asciiGridFile.filename().string() + "." + exportfileType;
6✔
60

61
        int ioStatus;
2✔
62
        
63
        std::cout << std::endl << "+ Exporting NTv2 geoid grid file to " << leafStr<std::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) {
×
NEW
69
                std::cout << std::endl << "- Error: " << e.what() << std::endl;
×
70
                return false;
×
71
        }
×
72

73
        std::cout << "done." << std::endl << std::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
}
4✔
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
        boost::filesystem::path asciiGridFile(dat_gridfilePath);
2✔
87
        std::string outfile = asciiGridFile.filename().string() + "." + exportfileType;
6✔
88

89
        int ioStatus;
2✔
90
        
91
        std::cout << std::endl << "+ Exporting geoid file to " << leafStr<std::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) {
×
NEW
97
                std::cout << std::endl << "- Error: " << e.what() << std::endl;
×
98
                return false;
×
99
        }
×
100

101
        std::cout << "done." << std::endl << std::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
}
4✔
109

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

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

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

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

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

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

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

166
        badpoints_log.close();
2✔
167

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

171
}
8✔
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
                std::cout << "+ Opening grid file... ";
18✔
179
        try {
18✔
180
                g->CreateGridIndex(gridfilePath, gridfileType);
18✔
181
        }
182
        catch (const NetGeoidException& e) {
1✔
183
                std::cout << std::endl << "- Error: " << e.what() << std::endl;
1✔
184
                return false;
1✔
185
        }
1✔
186

187
        if (!quiet)
17✔
188
                std::cout << "done." << std::endl;
17✔
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) {
×
NEW
202
                std::cout << std::endl << "- Error: " << e.what() << std::endl;
×
203
                return false;
×
204
        }
×
205

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

211
        std::string formattedLimit;
7✔
212

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

226
        for (int i=0; i<grid_properties.iNumsubgrids; ++i)
14✔
227
        {
228
                std::string formattedLimit;
7✔
229
                std::cout << "  - SUBGRID " << i << ":" << std::endl;
7✔
230
                std::cout << "    - SUB_NAME = " << grid_properties.ptrIndex[i].chSubname << std::endl;                  // name of subgrid (SUB_NAME)
7✔
231
                std::cout << "    - PARENT   = " << grid_properties.ptrIndex[i].chParent << std::endl;                // name of parent grid (PARENT)
7✔
232
                std::cout << "    - CREATED  = " << grid_properties.ptrIndex[i].chCreated << std::endl;                // date of creation (CREATED)
7✔
233
                std::cout << "    - UPDATED  = " << grid_properties.ptrIndex[i].chUpdated << std::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
                std::cout << "    - S_LAT    = " << std::right << std::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) + ")";
28✔
241
                std::cout << std::right << std::setw(MEASR) << formattedLimit << std::endl;                                                                
7✔
242
                
243
                // upper latitude (N_LAT)
244
                std::cout << "    - N_LAT    = " << std::right << std::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) + ")";
28✔
246
                std::cout << std::right << std::setw(MEASR) << formattedLimit << std::endl;                                                                
7✔
247
                
248
                // lower longitude (E_LONG)
249
                std::cout << "    - E_LONG   = " << std::right << std::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) + ")";
28✔
251
                std::cout << std::right << std::setw(MEASR) << formattedLimit << std::endl;
7✔
252

253
                // upper longitude (W_LONG)
254
                std::cout << "    - W_LONG   = " << std::right << std::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) + ")";
28✔
256
                std::cout << std::right << std::setw(MEASR) << formattedLimit << std::endl;
7✔
257
                
258
                std::cout << "    - LAT_INC  = " << std::fixed << grid_properties.ptrIndex[i].dLatinc << std::endl;                // latitude interval (LAT_INC)
7✔
259
                std::cout << "    - LONG_INC = " << std::fixed << grid_properties.ptrIndex[i].dLonginc << std::endl;                // longitude interval (LONG_INC)
7✔
260
                std::cout << "    - GS_COUNT = " << std::fixed << std::setprecision(0) << grid_properties.ptrIndex[i].lGscount;                                                // number of nodes (GS_COUNT)
7✔
261
        }
7✔
262
        std::cout << std::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 std::string& inputLatitude, const std::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) {
×
NEW
276
                std::cout << std::endl << "- Error: " << e.what() << std::endl;
×
277
                return false;
×
278
        }
×
279

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

294
        std::cout << "  N value          = " << std::setw(6) << 
2✔
295
                std::right << std::setprecision(3) << apInterpolant->gVar.dN_value << " metres" << std::endl;                        // N value
2✔
296
        std::cout << "  Deflections:" << std::endl;
2✔
297
        std::cout << "  - Prime meridian = " << std::setw(6) << 
2✔
298
                std::right << std::fixed << std::setprecision(2) << apInterpolant->gVar.dDefl_meridian << " seconds" << std::endl;                        // N value
2✔
299
        std::cout << "  - Prime vertical = " << std::setw(6) << 
2✔
300
                std::right << apInterpolant->gVar.dDefl_primev << " seconds" << std::endl;                        // N value
2✔
301
        std::cout << std::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, std::string& outputfilePath)
310
{
311
        boost::filesystem::path inputFile(inputfilePath);
6✔
312
        if (inputFile.has_extension())
6✔
313
                outputfilePath = inputFile.stem().string() + "_out" + inputFile.extension().string();
30✔
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) {
×
NEW
329
                std::cout << std::endl << "- Error: " << e.what() << std::endl;
×
330
                return false;
×
331
        }
×
332

333
        return true;
334

335
} // InterpolateGridPointFile
6✔
336

337

338
bool InterpolateGridBinaryStationFile(dna_geoid_interpolation* g, const std::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) {
×
NEW
347
                std::cout << std::endl << "- Error: " << e.what() << std::endl;
×
348
                return false;
×
349
        }
×
350

351
        return true;
352

353
} // InterpolateGridBinaryStationFile
354

355

356
std::string GetFileType(const std::string inputfilePath)
25✔
357
{
358
        boost::filesystem::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 boost::program_options::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))
58✔
376
        {
377
                if (boost::filesystem::exists(p.g.project_file))
2✔
378
                {
379
                        try {
×
380
                                CDnaProjectFile projectFile(p.g.project_file, geoidSetting);
×
381
                                p = projectFile.GetSettings();
×
382
                        }
×
NEW
383
                        catch (const std::runtime_error& e) {
×
NEW
384
                                std::cout << std::endl << "- Error: " << e.what() << std::endl;
×
385
                                return EXIT_FAILURE;
×
386
                        }
×
387
                        
388
                        return EXIT_SUCCESS;
×
389
                }
390

391
                std::cout << std::endl << "- Error: project file " << p.g.project_file << " does not exist." << std::endl << std::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
74✔
397
                !vm.count(CREATE_NTV2) &&                                // User wants to create a NTv2 grid file
68✔
398
                !vm.count(SUMMARY) &&                                        // User wants to print to the screen the details of the grid file
63✔
399
                !vm.count(INPUT_FILE) &&                                // User wants to interpolate geoid information in text file mode
55✔
400
                !vm.count(DAT_FILEPATH) &&                                // User supplied file path to WINTER DAT file
43✔
401
                !vm.count(EXPORT_NTV2_ASCII_FILE) &&        // User wants to export a geoid file to ASCII
69✔
402
                !vm.count(EXPORT_NTV2_BINARY_FILE))                // User wants to export a geoid file to binary
34✔
403
        {
404
                std::cout << std::endl << "- Nothing to do - no standard options specified. " << std::endl << std::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))
58✔
410
        {
NEW
411
                std::cout << std::endl << "- Error: no dat file specified. " << std::endl << std::endl;
×
412
                return EXIT_FAILURE;
×
413
        }
414

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

422
        // check mandatory arguments for interactive mode
423
        if (vm.count(INTERACTIVE) && !vm.count(LONGITUDE))
58✔
424
        {
NEW
425
                std::cout << std::endl << "- Error: Interpolation longitude not specified. " << std::endl << std::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))
76✔
431
        {
432
                std::cout << std::endl << "- Error: Interpolation input file not specified. " << std::endl << std::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))
54✔
438
        {
NEW
439
                std::cout << std::endl << "- Error: No NTv2 grid file specified. " << std::endl << std::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))
74✔
445
        {
NEW
446
                std::cout << std::endl << "- Error: No NTv2 grid file specified. " << std::endl << std::endl;
×
447
                return EXIT_FAILURE;
×
448
        }
449

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

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

463
                        if (!boost::filesystem::exists(p.n.bst_file))
2✔
464
                        {
465
                                std::cout << std::endl << "- Error: ";  
1✔
466
                                std::cout << "Binary station file " << p.n.bst_file << " does not exist." << std::endl << std::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))
50✔
474
        {
475
                if (!boost::filesystem::exists(p.n.rdat_geoid_file))
4✔
476
                {
477
                        // Look for it in the input folder
NEW
478
                        p.n.rdat_geoid_file = formPath<std::string>(p.g.input_folder, leafStr<std::string>(p.n.rdat_geoid_file));
×
479

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

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

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

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

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

516
        if (vm.count(DDEG_FORMAT))
50✔
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
        boost::program_options::variables_map vm;
42✔
532
        boost::program_options::positional_options_description positional_options;
42✔
533
        
534
        boost::program_options::options_description standard_options("+ " + std::string(ALL_MODULE_STDOPT), PROGRAM_OPTIONS_LINE_LENGTH);
126✔
535
        boost::program_options::options_description ntv2_options("+ " + std::string(GEOID_MODULE_NTV2), PROGRAM_OPTIONS_LINE_LENGTH);
126✔
536
        boost::program_options::options_description interpolate_options("+ " + std::string(GEOID_MODULE_INTERPOLATE), PROGRAM_OPTIONS_LINE_LENGTH);
126✔
537
        boost::program_options::options_description interactive_options("+ " + std::string(GEOID_MODULE_INTERACTIVE), PROGRAM_OPTIONS_LINE_LENGTH);
126✔
538
        boost::program_options::options_description file_interpolate_options("+ " + std::string(GEOID_MODULE_FILE), PROGRAM_OPTIONS_LINE_LENGTH);
126✔
539
        boost::program_options::options_description export_options("+ " + std::string(ALL_MODULE_EXPORT), PROGRAM_OPTIONS_LINE_LENGTH);
126✔
540
        boost::program_options::options_description generic_options("+ " + std::string(ALL_MODULE_GENERIC), PROGRAM_OPTIONS_LINE_LENGTH);
126✔
541

542
        std::string cmd_line_usage("+ ");
42✔
543
        cmd_line_usage.append(__BINARY_NAME__).append(" usage:  ").append(__BINARY_NAME__).append(" [options]");
42✔
544
        boost::program_options::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
        std::string cmd_line_banner, gs_type("seconds"), version("1.0.0.0"), system_f("GDA94   "), system_t("AHD_1971");
42✔
553
        std::string subgridname("AUSGEOID"), parent(""), created(""), updated("");
42✔
554

555
        std::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, boost::program_options::value<std::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, boost::program_options::value<std::string>(&p.g.network_name), 
42✔
567
                                std::string("Network name. If [" + std::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())
210✔
568
                        (INPUT_FOLDER_I, boost::program_options::value<std::string>(&p.g.input_folder),
42✔
569
                                "Path containing all input files.")
570
                        (OUTPUT_FOLDER_O, boost::program_options::value<std::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, boost::program_options::value<std::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, boost::program_options::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, boost::program_options::value<std::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, boost::program_options::value<std::string>(&p.n.rdat_geoid_file), 
42✔
596
                                "File path of the WINTER DAT grid file.")
597
                        (NTV2_GS_TYPE, boost::program_options::value<std::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, boost::program_options::value<std::string>(&version),
42✔
600
                                "Grid file version. Default is 1.0.0.0.")
601
                        (NTV2_SYSTEM_F, boost::program_options::value<std::string>(&system_f),
42✔
602
                                "The 'From' reference system. Default is GDA94.")
603
                        (NTV2_SYSTEM_T, boost::program_options::value<std::string>(&system_t),
42✔
604
                                "The 'To' reference system. Default is AHD_1971")
605
                        (NTV2_MAJOR_F, boost::program_options::value<double>(&ntv2.daf),
42✔
606
                                "Semi major of 'From' system. Default is 6378137.000")
607
                        (NTV2_MAJOR_T, boost::program_options::value<double>(&ntv2.dat),
42✔
608
                                "Semi major of 'To' system. Default is 6378137.000")
609
                        (NTV2_MINOR_F, boost::program_options::value<double>(&ntv2.dbf),
42✔
610
                                "Semi minor of 'From' system. Default is 6356752.314")
611
                        (NTV2_MINOR_T, boost::program_options::value<double>(&ntv2.dbt),
42✔
612
                                "Semi minor of 'To' system. Default is 6356752.314")
613
                        (NTV2_SUB_NAME, boost::program_options::value<std::string>(&subgridname),
42✔
614
                                "The name of the sub-grid. Default is AUSGEOID")
615
                        (NTV2_CREATED, boost::program_options::value<std::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, boost::program_options::value<std::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, boost::program_options::value<std::string>(&inputLatitude),
42✔
623
                                "Latitude of the interpolant. Default is degrees, minutes and seconds (dd.mmssss).")
624
                        (LONGITUDE, boost::program_options::value<std::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, boost::program_options::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, boost::program_options::value<UINT16>(&p.g.verbose),
42✔
647
                                std::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())
84✔
648
                                (QUIET,
42✔
649
                                        std::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_H, boost::program_options::value<std::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
                boost::program_options::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
                std::cout << std::endl << "- Error: " << e.what() << std::endl;
1✔
667
                std::cout << cmd_line_banner << allowable_options << std::endl;
1✔
668
                return EXIT_FAILURE;
1✔
669
        }
1✔
670
        catch (...) 
×
671
        {
NEW
672
                std::cout << std::endl << "- Exception of unknown type!\n";
×
673
                return EXIT_FAILURE;
×
674
        }
×
675

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

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

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

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

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

728
                return EXIT_SUCCESS;
7✔
729
        }
16✔
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
        {
NEW
743
                boost::filesystem::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
                std::string extension(GetFileType(p.n.ntv2_geoid_file));
25✔
751
                if (extension.empty())
25✔
752
                {
NEW
753
                        std::cout << std::endl << "- Error: NTv2 grid file type cannot be determined from a file without a file extension. " << std::endl << std::endl;
×
754
                        return EXIT_FAILURE;
755
                }
756

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

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

772
                if (vm.count(EXPORT_NTV2_BINARY_FILE) &&
52✔
773
                        boost::iequals(extension.substr(1), GSB))
29✔
774
                {
NEW
775
                        std::cout << std::endl << "- Error: Export to Binary NTv2 grid file option only supported for " << ASC " grid files." << std::endl << std::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());
50✔
781
        }        
25✔
782
        
783
        if (vm.count(QUIET))
50✔
784
                p.g.quiet = 1;
×
785

786
        if (vm.count(NTV2_GS_TYPE))
50✔
787
        {
788
                gs_type = trimstr(gs_type);
3✔
789
                // Unknown type?
790
                if (!boost::iequals(gs_type, "seconds") && !boost::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
                std::cout << std::endl << cmd_line_banner;
25✔
798

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

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

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

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

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

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

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

870
                }
871

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

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

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

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

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

912
                std::cout << std::endl;
25✔
913

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

920
                std::cout << std::endl;
25✔
921
        
922
                // File interpolation mode...
923
                if (p.n.file_mode)
25✔
924
                {
925
                        if (!p.n.bst_file.empty())
16✔
926
                                std::cout << "+ Binary station file interpolation mode." << std::endl << std::endl;
10✔
927
                        else
928
                                std::cout << "+ ASCII file interpolation mode." << std::endl << std::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))
50✔
936
        {
937
                if (vm.count(NTV2_GS_TYPE))
4✔
938
                        strcpy(ntv2.chGs_type, gs_type.c_str());
1✔
939
                if (vm.count(NTV2_VERSION))
4✔
940
                        strcpy(ntv2.chVersion, version.c_str());
1✔
941
                if (vm.count(NTV2_SYSTEM_F))
4✔
942
                        strcpy(ntv2.chSystem_f, system_f.c_str());
1✔
943
                if (vm.count(NTV2_SYSTEM_T))
4✔
944
                        strcpy(ntv2.chSystem_t, system_t.c_str());
1✔
945
                
946
                // subgrid header string handlers
947
                if (vm.count(NTV2_SUB_NAME))
4✔
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
                std::cout << std::endl << "+ Geoid file creation completed successfully." << std::endl << std::endl;
2✔
965

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

976
                if (vm.count(NTV2_GS_TYPE))
4✔
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
                std::cout << "+ Geoid file creation completed successfully." << std::endl << std::endl;
2✔
983

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

994
                if (vm.count(NTV2_GS_TYPE))
4✔
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
                std::cout << "+ Geoid file creation completed successfully." << std::endl << std::endl;
2✔
1001

1002
                return EXIT_SUCCESS;
1003
        }
1004

1005
        // Not applicable for project file use
1006
        if (vm.count(SUMMARY))
38✔
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))
36✔
1017
        {
1018
                apInterpolant.cVar.dLatitude = DoubleFromString<double>(inputLatitude);
2✔
1019
                apInterpolant.cVar.dLongitude = DoubleFromString<double>(inputLongitude);
2✔
1020

1021
                std::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
                {
NEW
1038
                        std::cout << std::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
                std::cout << "+ Interpolating geoid components";
15✔
1058
                if (!p.n.bst_file.empty() && p.n.convert_heights)
15✔
1059
                        std::cout << " and reducing" << std::endl <<
9✔
1060
                                "  heights to the ellipsoid";
9✔
1061
                std::cout << "... ";
15✔
1062
        }
1063
        
1064
        boost::timer::cpu_timer time;
15✔
1065

1066
        char dnageoFile[601], *geoFileptr;
15✔
1067
        geoFileptr = NULL;
15✔
1068
        memset(dnageoFile, '\0', sizeof(dnageoFile));
15✔
1069
        std::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, 
18✔
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
                std::cout << "done." << std::endl;
15✔
1100
                std::cout << "+ Interpolated data for " << g.PointsInterpolated();
15✔
1101
                if (g.PointsInterpolated() == 1)
15✔
NEW
1102
                        std::cout << " point." << std::endl;
×
1103
                else
1104
                        std::cout << " points." << std::endl;
15✔
1105

1106
                if (g.PointsNotInterpolated() > 0)
15✔
1107
                {
1108
                        std::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✔
NEW
1114
                                        std::cout << " station";
×
1115
                                else
1116
                                        std::cout << " stations";
2✔
1117

1118
                                std::cout << " could not be interpolated.  ";
2✔
1119
                                        
1120
                                if (p.g.verbose > 0)
2✔
1121
                                {
1122
                                        try {
2✔
1123
                                                ReturnBadStationRecords(&g, p);
2✔
1124
                                        }
NEW
1125
                                        catch (const std::runtime_error& e) {
×
1126
                                                // print error message, and continue
NEW
1127
                                                std::cout << "- Error: " << e.what() << std::endl;
×
1128
                                        }
×
1129
                                }
1130
                                else
NEW
1131
                                        std::cout << "To view the list of stations " << std::endl <<
×
NEW
1132
                                                "  for which an N-value could not be interpolated, call " << __BINARY_NAME__ << " with --verbose-level 1." << std::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✔
NEW
1139
                                        std::cout << " point";
×
1140
                                else
1141
                                        std::cout << " points";
6✔
1142

1143
                                std::cout << " could not be interpolated." << std::endl;
6✔
1144
                                std::cout << "  See " << outputfilePath << " for more information." << std::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 (boost::filesystem::exists(p.g.project_file))
18✔
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 << std::endl << std::endl;
1167
        boost::posix_time::milliseconds elapsed_time(boost::posix_time::milliseconds(time.elapsed().wall/MILLI_TO_NANO));
15✔
1168
        std::cout << std::endl << formatedElapsedTime<std::string>(&elapsed_time, "+ Geoid file interpolation took ") << std::endl << std::endl;
60✔
1169
        
1170
        return EXIT_SUCCESS;
15✔
1171
}
529✔
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

© 2026 Coveralls, Inc