• 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

83.95
/dynadjust/dynadjust/dnaplot/dnaplot.cpp
1
//============================================================================
2
// Name         : dnaplot.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  : DynAdjust Plot library
21
//============================================================================
22

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

25
namespace dynadjust { 
26
namespace networkplot {
27

28
dna_plot::dna_plot()
31✔
29
        : datum_(DEFAULT_EPSG_U)
31✔
30
        , output_folder_("")
31✔
31
        , network_name_("")
31✔
32
        , stationCount_(0)
31✔
33
        , blockCount_(1)
62✔
34
{
35
        v_msr_file_.clear();
31✔
36
        v_isl_const_file_.clear();
31✔
37
        v_isl_pts_file_.clear();
31✔
38
        v_jsl_const_file_.clear();
31✔
39
        v_isl_lbl_file_.clear();
31✔
40
        v_stn_cor_file_.clear();
31✔
41
        v_tectonic_plate_file_.clear();
31✔
42

43
        v_parameterStationList_.clear();
31✔
44

45
        InitialiseAppsandSystemCommands();
31✔
46

47
#ifdef _MSC_VER
48
#if (_MSC_VER < 1900)
49
        {
50
                // this function is obsolete in MS VC++ 14.0, VS2015
51
                // Set scientific format to print two places for the exponent
52
                _set_output_format(_TWO_DIGIT_EXPONENT);
53
        }
54
#endif
55
#endif
56
}
31✔
57
        
58

59
dna_plot::~dna_plot()
31✔
60
{
61
        
62
}
1,085✔
63

64
void dna_plot::InitialiseAppsandSystemCommands()
62✔
65
{
66
        _APP_GMTSET_ = "gmt gmtset";
62✔
67
        _APP_PSCOAST_ = "gmt pscoast";
62✔
68
        _APP_PSCONVERT_ = "gmt psconvert";
62✔
69
        _APP_PSTEXT_ = "gmt pstext";
62✔
70
        _APP_PSVELO_ = "gmt psvelo";
62✔
71
        _APP_PSXY_ = "gmt psxy";
62✔
72
        _APP_PSLEGEND_ = "gmt pslegend";
62✔
73
        
74
        // common commands across Windows / Linux / Apple, or 
75
        // unique to one particular system
76
        _MAKEDIR_CMD_ = "mkdir ";
62✔
77
        _ECHO_CMD_ = "echo ";
62✔
78
        _CHMOD_CMD_ = "chmod +x ";
62✔
79
        _GMT_TMP_DIR_ = "GMT_TMPDIR";
62✔
80

81
        // system-specific variables
82
#if defined(_WIN32) || defined(__WIN32__)
83
        _LEGEND_ECHO_ = _ECHO_CMD_;
84
        _LEGEND_CMD_1_ = " > ";
85
        _LEGEND_CMD_2_ = " >> ";
86
        _COMMENT_PREFIX_ = ":: ";
87
        _CMD_EXT_ = ".bat";
88
        _CMD_HEADER_ = "@echo off";
89
        _PDF_AGGREGATE_ = "pdftk ";
90
        _DELETE_CMD_ = "del /Q /F ";
91
        _COPY_CMD_ = "copy /Y ";
92
        _MOVE_CMD_ = "move /Y ";
93
        _NULL_OUTPUT_ = " > NUL";
94
        _ENV_GMT_TMP_DIR_ = "%" + _GMT_TMP_DIR_ + "%";
95
        _MAKEENV_CMD_ = "set ";
96
        _RMDIR_CMD_ = "rmdir /Q /S ";
97

98
#elif defined(__linux) || defined(sun) || defined(__unix__) || defined(__APPLE__)
99
        _LEGEND_ECHO_ = "";
62✔
100
        _LEGEND_CMD_1_ = "";
62✔
101
        _LEGEND_CMD_2_ = "";
62✔
102
        _COMMENT_PREFIX_ = "# ";
62✔
103
        _CMD_EXT_ = ".sh";
62✔
104
        _CMD_HEADER_ = "#!/bin/bash";
62✔
105
        _PDF_AGGREGATE_ = "pdfunite ";
62✔
106
        _DELETE_CMD_ = "rm -rf ";
62✔
107
        _COPY_CMD_ = "cp ";
62✔
108
        _MOVE_CMD_ = "mv ";
62✔
109
        _NULL_OUTPUT_ = " > /dev/null";
62✔
110
        _MAKETEMP_CMD_ = "mktemp ";
62✔
111
        _ENV_GMT_TMP_DIR_ = "$" + _GMT_TMP_DIR_;
62✔
112
        _MAKEENV_CMD_ = "export ";
62✔
113
        _RMDIR_CMD_ = "rm -rf ";
62✔
114

115
#endif
116

117
}
62✔
118
        
119

120
void dna_plot::CreateSegmentationGraph(const plotGraphMode& graphMode)
×
121
{
122

123
        // Execute gnuplot in a separate process
124
        InvokeGnuplot();
×
125

126
        // clean up gnuplot command file and input data file
127
        CleanupGnuplotFiles(graphMode);
×
128
}
×
129

130
void dna_plot::CleanupGnuplotFiles(const plotGraphMode& graphMode)
×
131
{
132
        if (pprj_->p._keep_gen_files)
×
133
                return;
×
134
        
NEW
135
        std::stringstream ss;
×
136
        ss << _DELETE_CMD_;
×
137

138
        // remove gnuplot command file
139
        ss << pprj_->p._gnuplot_cmd_file << " ";
×
140

141
        // remove gnuplot input file
142
        switch (graphMode)
×
143
        {
144
        case StationsMode:
×
145
                ss << seg_stn_graph_file_;
×
146
                break;
147
        case MeasurementsMode:
×
148
                ss << seg_msr_graph_file_;
×
149
                break;
150
        default:
151
                break;
152
        }
153

154
        // delete
NEW
155
        std::string system_file_cmd = ss.str();
×
156
        std::system(system_file_cmd.c_str());
×
157
}
×
158

159
void dna_plot::CreategnuplotGraphEnvironment(project_settings* pprj, const plotGraphMode& graphMode)
4✔
160
{
161
        InitialiseAppsandSystemCommands();
4✔
162

163
        // Set up the environment
164
        pprj_ = pprj;
4✔
165

166
        if (!boost::filesystem::exists(pprj_->g.output_folder))
8✔
167
        {
NEW
168
                std::stringstream ss("CreategnuplotGraphEnvironment(): Output path does not exist... \n\n    ");
×
169
                ss << pprj_->g.output_folder << ".";
×
170
                SignalExceptionPlot(ss.str(), 0, NULL);
×
171
        }
×
172

173
        output_folder_ = pprj_->g.output_folder;
4✔
174
        network_name_ = pprj_->g.network_name;
4✔
175

176
        /////////////////////////////////////////////////////////
177
        // create gnuplot command file and set gnuplot parameters 
178
        std::string gnuplot_cmd_filename("graph_" + network_name_);
4✔
179

180
        std::string gnuplot_pic_name;
4✔
181
        switch (graphMode)
4✔
182
        {
183
        case StationsMode:
2✔
184
                gnuplot_pic_name = (network_name_ + "_graph_stn");
2✔
185
                gnuplot_cmd_filename.append("_stns");
2✔
186
                break;
187
        case MeasurementsMode:
2✔
188
                gnuplot_pic_name = (network_name_ + "_graph_msr");
2✔
189
                gnuplot_cmd_filename.append("_msrs");
2✔
190
                break;
191
        }
192

193
        gnuplot_cmd_filename.append(_CMD_EXT_);
4✔
194
        std::string gnuplot_cmd_file(output_folder_ + FOLDER_SLASH + gnuplot_cmd_filename);
8✔
195

196
        pprj_->p._gnuplot_cmd_file = gnuplot_cmd_file;
4✔
197
        
198
        // create pdf filename
199
        pprj_->p._pdf_file_name = output_folder_ + FOLDER_SLASH + gnuplot_pic_name + ".pdf";
16✔
200
        
201
        switch (graphMode)
4✔
202
        {
203
        case StationsMode:
2✔
204
                PlotGnuplotDatFileStns();
2✔
205
                break;
206
        case MeasurementsMode:
2✔
207
                PlotGnuplotDatFileMsrs();
2✔
208
                break;
209
        }
210

211
        PrintGnuplotCommandFile(gnuplot_cmd_file, graphMode);
4✔
212

213
}
8✔
214

215
void dna_plot::InvokeGnuplot()
×
216
{
217
        // Invoke gnuplot using absolute path                                
NEW
218
        std::string system_file_cmd = "gnuplot " + boost::filesystem::absolute(pprj_->p._gnuplot_cmd_file).string();
×
219

220
        // set up a thread group to execute the gnuplot in parallel
221
        boost::thread gnuplot_thread{dna_create_threaded_process(system_file_cmd)};
×
222
        
223
        // go!
224
        gnuplot_thread.join();
×
225
}
×
226

227

228
        
229

230
void dna_plot::PlotGnuplotDatFileStns()
2✔
231
{
232
        seg_stn_graph_file_ = output_folder_ + FOLDER_SLASH + network_name_ + "-stn.seg.data";
8✔
233
        
234
        std::ofstream seg_data;
2✔
235
        try {
2✔
236
                // Create gnuplot station segment data file.  Throws runtime_error on failure.
237
                file_opener(seg_data, seg_stn_graph_file_);
2✔
238
        }
NEW
239
        catch (const std::runtime_error& e) {
×
240
                SignalExceptionPlot(e.what(), 0, NULL);
×
241
        }
×
242

243
        std::stringstream ss(""), st("");
6✔
244
        ss << "\"Max block size (" << std::setprecision(0) << blockThreshold_ << ")\" ";
2✔
245
        st << "\"Min inner stns (" << minInnerStns_ << ")\" ";
2✔
246
        seg_data << std::setw(HEADER_18) << std::left << "Block" <<
2✔
247
                std::setw(HEADER_32) << std::left << ss.str() <<
2✔
248
                std::setw(HEADER_32) << std::left << st.str() <<
4✔
249
                std::setw(HEADER_25) << std::left << "\"Total block size\"" <<
2✔
250
                std::setw(HEADER_18) << std::left << "\"Inner stns\"" <<
2✔
251
                std::setw(HEADER_18) << std::left << "\"Junction stns\"" << std::endl;
2✔
252

253
        for (UINT32 block=0; block<blockCount_; ++block)
2✔
254
                seg_data << std::setw(HEADER_18) << std::left << block+1 << 
4✔
255
                        std::setw(HEADER_32) << std::left << std::setprecision(0) << blockThreshold_ <<                                // threshold
4✔
256
                        std::setw(HEADER_32) << std::left << std::setprecision(0) << minInnerStns_ <<                                // threshold
4✔
257
                        std::setw(HEADER_25) << std::left << v_ISL_.at(block).size() + v_JSL_.at(block).size() <<        // block size
4✔
258
                        std::setw(HEADER_18) << std::left << v_ISL_.at(block).size() <<                // inner station count
4✔
259
                        std::setw(HEADER_18) << std::left << v_JSL_.at(block).size() << std::endl;        // junction station count
6✔
260

261
        seg_data.close();
2✔
262
}
2✔
263
        
264

265
void dna_plot::PlotGnuplotDatFileMsrs()
2✔
266
{
267
        seg_msr_graph_file_ = output_folder_ + FOLDER_SLASH + network_name_ + "-msr.seg.data";
8✔
268
        
269
        std::ofstream seg_data;
2✔
270
        try {
2✔
271
                // Create gnuplot measurement segment data file.  Throws runtime_error on failure.
272
                file_opener(seg_data, seg_msr_graph_file_);
2✔
273
        }
NEW
274
        catch (const std::runtime_error& e) {
×
275
                SignalExceptionPlot(e.what(), 0, NULL);
×
276
        }
×
277

278
        UINT16 c;
2✔
279

280
        // print header
281
        seg_data << std::setw(PRINT_VAR_PAD) << std::left << "Block";
2✔
282
        std::stringstream ss;
2✔
283
        ss << "\"Total measurements\"";
2✔
284
        seg_data << std::setw(PRINT_VAR_PAD) << std::left << ss.str();
2✔
285

286
        for (c=0; c<_combined_msr_list.size(); c++)
42✔
287
        {                
288
                if (parsemsrTally_.MeasurementCount(_combined_msr_list.at(c)) == 0)
40✔
289
                        continue;
9✔
290
                ss.str("");
93✔
291
                ss << "\"" << measurement_name<char, std::string>(_combined_msr_list.at(c)) << " (" <<
62✔
292
                        parsemsrTally_.MeasurementCount(_combined_msr_list.at(c)) << ")\"";
31✔
293
                seg_data << std::setw(PRINT_VAR_PAD) << std::left << ss.str();
62✔
294
        }
295
        seg_data << std::endl;
2✔
296

297
        // Tally up measurement types for each block
298
        ComputeMeasurementCount();
2✔
299

300
        // print measurement tally for each block
301
        UINT32 block;
302
        for (block=0; block<blockCount_; ++block)
6✔
303
        {
304
                seg_data << std::setw(PRINT_VAR_PAD) << std::left << block + 1;
4✔
305
                seg_data << std::setw(PRINT_VAR_PAD) << std::left << v_msr_tally_.at(block).TotalCount();
4✔
306

307
                for (c=0; c<_combined_msr_list.size(); c++)
84✔
308
                {
309
                        // do any measurements of this type exist at all?
310
                        if (parsemsrTally_.MeasurementCount(_combined_msr_list.at(c)) > 0)
80✔
311
                        {
312
                                // yes, so test if this block has such measurements...
313
                                //if (v_msr_tally_.at(block).MeasurementCount(_combined_msr_list.at(c)) == 0)                        // no 
314
                                //        seg_data << std::setw(PRINT_VAR_PAD) << std::left << "-";
315
                                //else
316
                                        seg_data << std::setw(PRINT_VAR_PAD) << std::left << v_msr_tally_.at(block).MeasurementCount(_combined_msr_list.at(c));
80✔
317
                        }
318
                }
319
                seg_data << std::endl;
6✔
320
        }
321
        
322
        seg_data.close();
2✔
323
}
2✔
324
        
325

326
void dna_plot::ComputeMeasurementCount()
2✔
327
{
328
        v_msr_tally_.resize(blockCount_);
2✔
329

330
        UINT32 block;
2✔
331
        it_vUINT32 _it_msr;
2✔
332

333
        for (block=0; block<blockCount_; ++block)
6✔
334
        {
335
                for (_it_msr=v_CML_.at(block).begin(); _it_msr<v_CML_.at(block).end(); _it_msr++)
1,207✔
336
                {
337
                        // Increment single station measurement counters...
338
                        switch (bmsBinaryRecords_.at(*_it_msr).measType)
1,203✔
339
                        {
340
                        case 'A': // Horizontal angle
249✔
341
                                v_msr_tally_.at(block).A++;
249✔
342
                                break;
249✔
343
                        case 'B': // Geodetic azimuth
2✔
344
                                v_msr_tally_.at(block).B++;
2✔
345
                                break;
2✔
346
                        case 'C': // Chord dist
1✔
347
                                v_msr_tally_.at(block).C++;
1✔
348
                                break;
1✔
349
                        case 'D': // Direction set
14✔
350
                                if (bmsBinaryRecords_.at(*_it_msr).measStart == xMeas)
14✔
351
                                        v_msr_tally_.at(block).D += bmsBinaryRecords_.at(*_it_msr).vectorCount1;
14✔
352
                                break;
353
                        case 'E': // Ellipsoid arc
2✔
354
                                v_msr_tally_.at(block).E++;
2✔
355
                                break;
2✔
356
                        case 'G': // GPS Baseline (treat as single-baseline cluster)
68✔
357
                                v_msr_tally_.at(block).G ++;
68✔
358
                                break;
68✔
359
                        case 'X': // GPS Baseline cluster
2✔
360
                                if (bmsBinaryRecords_.at(*_it_msr).measStart == xMeas)
2✔
361
                                {
362
                                        if (bmsBinaryRecords_.at(*_it_msr).vectorCount1 == bmsBinaryRecords_.at(*_it_msr).vectorCount2 + 1)
2✔
363
                                                v_msr_tally_.at(block).X += (bmsBinaryRecords_.at(*_it_msr).vectorCount1 * 3);
2✔
364
                                }                                        
365
                                break;
366
                        case 'H': // Orthometric height
15✔
367
                                v_msr_tally_.at(block).H++;
15✔
368
                                break;
15✔
369
                        case 'I': // Astronomic latitude
1✔
370
                                v_msr_tally_.at(block).I++;
1✔
371
                                break;
1✔
372
                        case 'J': // Astronomic longitude
1✔
373
                                v_msr_tally_.at(block).J++;
1✔
374
                                break;
1✔
375
                        case 'K': // Astronomic azimuth
2✔
376
                                v_msr_tally_.at(block).K++;
2✔
377
                                break;
2✔
378
                        case 'L': // Level difference
90✔
379
                                v_msr_tally_.at(block).L++;
90✔
380
                                break;
90✔
381
                        case 'M': // MSL arc
3✔
382
                                v_msr_tally_.at(block).M++;
3✔
383
                                break;
3✔
384
                        case 'P': // Geodetic latitude
1✔
385
                                v_msr_tally_.at(block).P++;
1✔
386
                                break;
1✔
387
                        case 'Q': // Geodetic longitude
1✔
388
                                v_msr_tally_.at(block).Q++;
1✔
389
                                break;
1✔
390
                        case 'R': // Ellipsoidal height
1✔
391
                                v_msr_tally_.at(block).R++;
1✔
392
                                break;
1✔
393
                        case 'S': // Slope distance
458✔
394
                                v_msr_tally_.at(block).S++;
458✔
395
                                break;
458✔
396
                        case 'V': // Zenith distance
288✔
397
                                v_msr_tally_.at(block).V++;
288✔
398
                                break;
288✔
399
                        case 'Y': // GPS point cluster
2✔
400
                                if (bmsBinaryRecords_.at(*_it_msr).measStart == xMeas)
2✔
401
                                {
402
                                        if (bmsBinaryRecords_.at(*_it_msr).vectorCount1 == bmsBinaryRecords_.at(*_it_msr).vectorCount2 + 1)
2✔
403
                                                v_msr_tally_.at(block).Y += (bmsBinaryRecords_.at(*_it_msr).vectorCount1 * 3);
2✔
404
                                }                                        
405
                                break;
406
                        case 'Z': // Vertical angle
2✔
407
                                v_msr_tally_.at(block).Z++;
2✔
408
                                break;
2✔
409
                        default:
×
NEW
410
                                std::stringstream ss;
×
NEW
411
                                ss << "ComputeMeasurementCount(): Unknown measurement type:  " << bmsBinaryRecords_.at(*_it_msr).measType << std::endl;
×
UNCOV
412
                                throw NetPlotException(ss.str(), 0);
×
413
                        }
414
                }
415
        }
416
}
2✔
417

418

419
void dna_plot::PrintGnuplotCommandFile(const std::string& gnuplot_cmd_file, const plotGraphMode& graphMode)
4✔
420
{
421
        try {
4✔
422
                // Create gnuplot batch file.  Throws runtime_error on failure.
423
                file_opener(gnuplotbat_file_, gnuplot_cmd_file);
4✔
424
        }
NEW
425
        catch (const std::runtime_error& e) {
×
426
                SignalExceptionPlot(e.what(), 0, NULL);
×
427
        }
×
428

429
        //if (output_folder_ != ".")
430
        //        gnuplotbat_file_ << "cd '" << output_folder_ << "'" << std::endl << std::endl;
431

432
        //gnuplotbat_file_ << "set terminal postscript eps enhanced color solid colortext" << std::endl << std::endl;
433
        gnuplotbat_file_ << "set terminal pdf enhanced color solid linewidth 0.75" << std::endl << std::endl;
4✔
434
        // gnuplot requires single quotes for filenames
435
        gnuplotbat_file_ << "set output '" << pprj_->p._pdf_file_name << "'" << std::endl;
4✔
436

437
        // histogram style
438
        gnuplotbat_file_ << "set style fill transparent solid 0.4" << std::endl;
4✔
439
        gnuplotbat_file_ << "set boxwidth 0.5" << std::endl;
4✔
440

441
        UINT32 upperLimit(0), block(0);
4✔
442
        
443
        switch (graphMode)
4✔
444
        {
445
        case StationsMode:
446
                for (block=0; block<blockCount_; ++block)
6✔
447
                        if (upperLimit < (v_ISL_.at(block).size() + v_JSL_.at(block).size()))
4✔
448
                                upperLimit = static_cast<UINT32>(v_ISL_.at(block).size() + v_JSL_.at(block).size());
4✔
449
                
450
                upperLimit = std::max(blockThreshold_, upperLimit);
2✔
451

452
                gnuplotbat_file_ << "set title \"" << "Station segmentation summary for " << network_name_ << "\" font \"Calibri,16\" noenhanced" << std::endl << std::endl;
2✔
453
                gnuplotbat_file_ << "set key outside center bottom horizontal Left reverse enhanced autotitles samplen 2.5 font \"Calibri,8\"" << std::endl;
2✔
454
                gnuplotbat_file_ << "set key width -2 height 2.5" << std::endl << std::endl;
2✔
455

456
                break;
457
        case MeasurementsMode:
458
                for (block=0; block<blockCount_; ++block)
6✔
459
                        if (upperLimit < v_msr_tally_.at(block).TotalCount())
4✔
460
                                upperLimit = v_msr_tally_.at(block).TotalCount();
4✔
461
        
462
                gnuplotbat_file_ << "set title \"" << "Measurement segmentation summary for " << network_name_ << "\" font \"Calibri,20\" noenhanced" << std::endl << std::endl;
2✔
463
                //gnuplotbat_file_ << "set key outside right top vertical Left reverse enhanced autotitles columnhead box samplen 2.5 font \"Calibri,8\"" << std::endl;
464
                gnuplotbat_file_ << "set key outside center bottom horizontal Left reverse enhanced autotitles columnhead samplen 2.5 font \"Calibri,8\"" << std::endl;
2✔
465
                //gnuplotbat_file_ << "set key width -15 height 0" << std::endl << std::endl;
466
                gnuplotbat_file_ << "set key width -2 height 2.5" << std::endl << std::endl;
2✔
467

468
                gnuplotbat_file_ << "set style histogram rowstacked title offset character 0, 0, 0" << std::endl;
2✔
469
                gnuplotbat_file_ << "set style data histograms" << std::endl;
2✔
470
                gnuplotbat_file_ << "set datafile missing '-'" << std::endl;
2✔
471
                gnuplotbat_file_ << std::endl;
2✔
472
                break;
473
        }
474

475
        upperLimit = upperLimit + upperLimit / 10;
4✔
476

477
        gnuplotbat_file_ << "set format x '%.0f'" << std::endl;
4✔
478
        gnuplotbat_file_ << "set format y '%.0f'" << std::endl;
4✔
479
        gnuplotbat_file_ << "set yrange[0:" << upperLimit << "]" << std::endl;
4✔
480
        gnuplotbat_file_ << "set auto x" << std::endl;
4✔
481
        gnuplotbat_file_ << "set ytics scale 0.25 font \"Calibri,8\"" << std::endl;
4✔
482

483
        gnuplotbat_file_ << "set xtics scale 0.25 nomirror" << std::endl;
4✔
484

485
        UINT32 fontSize(8);
4✔
486
        if (blockCount_ > 5000)
4✔
487
        {
488
                fontSize = 5;
×
NEW
489
                gnuplotbat_file_ << "set xtics 0,500 font \"Calibri,6\"" << std::endl << std::endl;
×
490
        }
491
        else if (blockCount_ > 1000)
4✔
492
        {
493
                fontSize = 5;
×
NEW
494
                gnuplotbat_file_ << "set xtics 0,100 font \"Calibri,6\"" << std::endl << std::endl;
×
495
        }
496
        else if (blockCount_ > 500)
4✔
497
        {
498
                fontSize = 5;
×
NEW
499
                gnuplotbat_file_ << "set xtics 0,50 font \"Calibri,5\"" << std::endl << std::endl;
×
500
        }
501
        else if (blockCount_ > 100)
4✔
502
        {
503
                fontSize = 5;
×
NEW
504
                gnuplotbat_file_ << "set xtics 0,10 font \"Calibri,6\"" << std::endl << std::endl;
×
505
        }
506
        else if (blockCount_ > 50)
4✔
507
        {
508
                fontSize = 6;
×
NEW
509
                gnuplotbat_file_ << "set xtics 0,5 font \"Calibri,8\"" << std::endl << std::endl;
×
510
        }
511
        else
512
                gnuplotbat_file_ << "set xtics 0,1 font \"Calibri,8\"" << std::endl << std::endl;
4✔
513
        
514

515
        // x-axis label
516
        std::stringstream ss("");
12✔
517
        ss << "Segmented Network Blocks (Total " << std::fixed << std::setprecision(0) << blockCount_ << ")";
4✔
518
        gnuplotbat_file_ << "set xlabel '" << ss.str() << "' font \"Calibri,10\"" << std::endl;
4✔
519

520
        switch (graphMode)
4✔
521
        {
522
        case StationsMode:
2✔
523
                PrintGnuplotCommandFileStns(fontSize);
2✔
524
                break;
525
        case MeasurementsMode:
2✔
526
                PrintGnuplotCommandFileMsrs(fontSize);
2✔
527
                break;
528
        }
529

530
        gnuplotbat_file_.close();
4✔
531
}
4✔
532
        
533
void dna_plot::PrintGnuplotCommandFileStns(const UINT32& fontSize)
2✔
534
{
535
        std::stringstream ss("");
4✔
536
        ss << "Station Count (Total " << std::fixed << std::setprecision(0) << stationCount_ << ")";
2✔
537
        gnuplotbat_file_ << "set ylabel '" << ss.str() << "' font \"Calibri,10\"" << std::endl << std::endl;
2✔
538

539
        // All colours based on a palette:
540
        //   https://coolors.co/ffd275-235789-da5552-43aa8b-39a9db
541
        gnuplotbat_file_ << "set style line 1 lw 0.75 lt 1 pt 7 ps 0.25 lc rgb \"#35A7FF\"         # total block size" << std::endl;                // royalblue
2✔
542
        gnuplotbat_file_ << "set style line 2 lw 2 lt 5 pt 7 ps 0.25 lc rgb \"#43AA8B\"            # threshold" << std::endl;                        // zomp (green)
2✔
543
        gnuplotbat_file_ << "set style line 3 lw 2 lt 5 pt 7 ps 0.25 lc rgb \"#FFD275\"            # minimum inner size" << std::endl;        // orange yellow crayola
2✔
544
        gnuplotbat_file_ << "set style line 4 lw 2 lt 1 pt 7 ps 0.25 lc rgb \"#235789\"            # inners" << std::endl;                                // bdazzled blue
2✔
545
        gnuplotbat_file_ << "set style line 5 lw 2 lt 1 pt 7 ps 0.25 lc rgb \"#DA5552\"            # junctions" << std::endl << std::endl;        // indian red
2✔
546

547
        gnuplotbat_file_ << "plot '" << seg_stn_graph_file_ << "' using 1:4 with boxes ls 1 title columnheader(4), \\" << std::endl;
2✔
548
        gnuplotbat_file_ << "     '" << seg_stn_graph_file_ << "' using 1:4:(sprintf(\"%.0f\",$4)) with labels font \"Calibri," << 
2✔
549
                fontSize << "\" center offset 0,0.5 notitle, \\" << std::endl;
2✔
550
        gnuplotbat_file_ << "     '" << seg_stn_graph_file_ << "' using 1:2 with lines ls 2 title columnheader(2), \\" << std::endl;
2✔
551
        gnuplotbat_file_ << "     '" << seg_stn_graph_file_ << "' using 1:3 with lines ls 3 title columnheader(3), \\" << std::endl;
2✔
552
        gnuplotbat_file_ << "     '" << seg_stn_graph_file_ << "' using 1:5 with linespoints ls 4 title columnheader(5), \\" << std::endl;
2✔
553
        gnuplotbat_file_ << "     '" << seg_stn_graph_file_ << "' using 1:5:(sprintf(\"%.0f\",$5)) with labels tc ls 4 font \"Calibri," << 
2✔
554
                fontSize << "\" center offset 1,0 notitle, \\" << std::endl;
2✔
555
        gnuplotbat_file_ << "     '" << seg_stn_graph_file_ << "' using 1:6 with linespoints ls 5 title columnheader(6), \\" << std::endl;
2✔
556
        gnuplotbat_file_ << "     '" << seg_stn_graph_file_ << "' using 1:6:(sprintf(\"%.0f\",$6)) with labels tc ls 5 font \"Calibri," << 
2✔
557
                fontSize << "\" center offset 1,0 notitle" << std::endl << std::endl;
2✔
558
}
2✔
559
        
560

561
void dna_plot::PrintGnuplotCommandFileMsrs(const UINT32& fontSize)
2✔
562
{
563
        std::stringstream ss("");
4✔
564
        ss << "Measurement Count (Total " << std::fixed << std::setprecision(0) << measurementCount_ << ")";
2✔
565
        gnuplotbat_file_ << "set ylabel '" << ss.str() << "' font \"Calibri,10\"" << std::endl << std::endl;
2✔
566

567
        // All colours based on a palette:
568
        //   https://coolors.co/ffd275-235789-da5552-43aa8b-39a9db
569

570
        UINT32 line(1);
2✔
571
        ss.str("");
6✔
572
        ss << "\"#4169e1\"";
2✔
573
        gnuplotbat_file_ << "set style line " << line++ << " lw 1 lt 1 pt 7 ps 0.5 lc rgb " << std::left << std::setw(PRINT_VAR_PAD) << ss.str() << " # total block size" << std::endl;        // royalblue
2✔
574

575
        // print measurements for each block
576
        UINT32 c;
2✔
577
        std::string colour;
2✔
578
        it_pair_string _it_colour;
2✔
579

580
        std::sort(pprj_->p._msr_colours.begin(), pprj_->p._msr_colours.end(), ComparePairFirst<std::string>());
2✔
581

582
        for (c=0; c<_combined_msr_list.size(); c++)
42✔
583
        {
584
                if (parsemsrTally_.MeasurementCount(_combined_msr_list.at(c)) < 1)
40✔
585
                        continue;
9✔
586
                colour = _combined_msr_list.at(c);
31✔
587
                _it_colour = equal_range(pprj_->p._msr_colours.begin(), pprj_->p._msr_colours.end(), 
31✔
588
                        colour, ComparePairFirst<std::string>());
31✔
589

590
                if (_it_colour.first == _it_colour.second)
31✔
591
                        colour = "light-gray";
×
592
                else
593
                        colour = _it_colour.first->second;
31✔
594
                
595
                ss.str("");
93✔
596
                ss << "\"" << colour << "\"";
31✔
597
                gnuplotbat_file_ << "set style line " << line++ << " lw 1 lt 1 pt 7 ps 0.5 lc rgb " << std::left << std::setw(PRINT_VAR_PAD) << ss.str() << 
62✔
598
                        " # \"" << measurement_name<char, std::string>(_combined_msr_list.at(c)) << "\"" << std::endl;
124✔
599
                
600
        }
601
        gnuplotbat_file_ << std::endl;
2✔
602
        
603
        //UINT32 block(0);
604
        //if (v_msr_tally_.at(block).MeasurementCount(_combined_msr_list.at(c)) == 0)
605
        //        continue;
606

607
        // plot total measurement count
608
        line = 3;
2✔
609
        UINT32 linestyle(line-1), msrs(0);
2✔
610
        gnuplotbat_file_ << "plot '";
2✔
611
        measurementCategories_ = 0;
2✔
612
        
613
        for (c=0; c<_combined_msr_list.size(); c++)
42✔
614
        {
615
                if (parsemsrTally_.MeasurementCount(_combined_msr_list.at(c)) < 1)
40✔
616
                        continue;
9✔
617
                if (msrs++ > 0)
31✔
618
                        gnuplotbat_file_ << ", \\" << std::endl << "     '";
29✔
619
                gnuplotbat_file_ << seg_msr_graph_file_ << "' using " << line++ << ":xtic(1) ls " << linestyle++;
31✔
620
                measurementCategories_++;
31✔
621
        }
622

623
        gnuplotbat_file_ << ", \\" << std::endl << "     '" << seg_msr_graph_file_ << 
4✔
624
                "' using 0:2:(sprintf(\"%d\",$2)) with labels font \"Calibri," << 
4✔
625
                        fontSize << "\" center offset 0,0.5 notitle" << std::endl;
2✔
626
        
627
}
2✔
628

629

630
void dna_plot::InitialiseGMTParameters()
27✔
631
{
632
        // Set initial parameters
633
        if (!boost::filesystem::exists(pprj_->g.output_folder))
54✔
634
        {
NEW
635
                std::stringstream ss("InitialiseGMTParameters(): Output path does not exist... \n\n    ");
×
636
                ss << pprj_->g.output_folder << ".";
×
637
                SignalExceptionPlot(ss.str(), 0, NULL);
×
638
        }
×
639

640
        InitialiseAppsandSystemCommands();
27✔
641

642
        output_folder_ = pprj_->g.output_folder;
27✔
643
        network_name_ = pprj_->g.network_name;
27✔
644

645
        v_isl_const_file_.clear();
27✔
646
        v_jsl_const_file_.clear();
27✔
647
        v_isl_pts_file_.clear();
27✔
648
        v_isl_lbl_file_.clear();
27✔
649
        v_stn_cor_file_.clear();
27✔
650
        v_tectonic_plate_file_.clear();
27✔
651
        v_stn_err_file_.clear();
27✔
652
        v_stn_apu_file_.clear();
27✔
653
        v_jsl_pts_file_.clear();
27✔
654
        v_jsl_lbl_file_.clear();
27✔
655

656
        default_paper_width_ = 59.4;
27✔
657
        default_paper_height_ = 42.0;
27✔
658

659
        plotConstraints_ = false;
27✔
660

661
        lowerDeg_ = 1000.0;
27✔
662
        leftDeg_ = 1000.0;
27✔
663
        upperDeg_ = -1000.0;
27✔
664
        rightDeg_ = -1000.0;
27✔
665

666
        default_limits_ = true;
27✔
667
        
668
        // check for valid plot limits
669
        if (!pprj_->p._bounding_box.empty())
27✔
670
                default_limits_ = false;
6✔
671
        else if (pprj_->p._plot_area_radius > 0. && 
21✔
672
                pprj_->p._plot_centre_latitude > -90.00000001 && 
21✔
673
                pprj_->p._plot_centre_latitude < 90.00000001 && 
4✔
674
                pprj_->p._plot_centre_longitude > -180.00000001 && 
4✔
675
                pprj_->p._plot_centre_longitude < 180.00000001)
676
                        default_limits_ = false;
4✔
677
        else if (pprj_->p._plot_area_radius > 0. && 
17✔
678
                !pprj_->p._plot_station_centre.empty())
17✔
679
                        default_limits_ = false;
1✔
680
}
27✔
681

682

683
void dna_plot::FinaliseGMTParameters()
27✔
684
{
685
        //
686
        // At this point, all limit values are in decimal degrees
687
        //
688

689
        if (rightDeg_ < leftDeg_)
27✔
690
        {
691
                std::stringstream ss;
1✔
692
                ss << "Right limit cannot be less than left limit." << std::endl;
1✔
693
                throw NetPlotException(ss.str(), 0);
2✔
694
        }
1✔
695

696
        if (upperDeg_ < lowerDeg_)
26✔
697
        {
698
                std::stringstream ss;
1✔
699
                ss << "Upper limit cannot be less than lower limit." << std::endl;
1✔
700
                throw NetPlotException(ss.str(), 0);
2✔
701
        }
1✔
702

703
        // calculate dimensions of data extents
704
        dWidth_ = (rightDeg_ - leftDeg_);
25✔
705
        dHeight_ = (upperDeg_ - lowerDeg_);
25✔
706
        
707
        // if data is a single point (or a very small area)
708
        if (dHeight_ < 0.00005)
25✔
709
                dHeight_ += seconds15;
×
710
        if (dWidth_ < 0.00005)
25✔
711
                dWidth_ += seconds15;        
×
712
        
713
        // capture smallest dimension
714
        dDimension_ = (std::min(dWidth_, dHeight_));
25✔
715
        
716
        // Determine a buffer to envelope the entire plot, set to
717
        // 10% of the width/height (whichever is smaller)
718
        dBuffer_ = (dDimension_ * (0.1));
25✔
719

720
        // calculate latitude at which to place the scale bar
721
        dScaleLat_ = (lowerDeg_ - dBuffer_ / 2.0);
25✔
722

723
        // calculate centre point of data
724
        centre_width_ = (rightDeg_ + leftDeg_) / 2.0;
25✔
725
        centre_height_ = (upperDeg_ + lowerDeg_) / 2.0;
25✔
726

727
        // Has the user specified certain limits, or will the data be used to 
728
        // define the limits
729
        if (default_limits_)
25✔
730
        {
731
                // OK, the spatial extent of the data sets the limits, so
732
                // add a buffer accordingly
733
                upperDeg_ += dBuffer_;
16✔
734
                lowerDeg_ -= dBuffer_;
16✔
735
                leftDeg_ -= dBuffer_;
16✔
736
                rightDeg_ += dBuffer_;
16✔
737

738
                if (dDimension_ > seconds60)
16✔
739
                {
740
                        // round down to nearest 5"
741
                        leftDeg_ = leftDeg_ - fmod(leftDeg_, seconds05);
13✔
742
                        lowerDeg_ = lowerDeg_ - fmod(lowerDeg_, seconds05);
13✔
743
                        rightDeg_ = rightDeg_ + (seconds05 - fmod(rightDeg_, seconds05));
13✔
744
                        upperDeg_ = upperDeg_ + (seconds05 - fmod(upperDeg_, seconds05));
13✔
745
                }
746
        }
747
        else
748
        {
749
                // Limits have been calculated via user input, so simply calculate
750
                // calculate latitude at which the scale bar
751
                // will be placed
752
                centre_width_ = pprj_->p._plot_centre_longitude;
9✔
753
                centre_height_ = pprj_->p._plot_centre_latitude;
9✔
754

755
                dScaleLat_ = lowerDeg_ + dBuffer_ / 2.0;
9✔
756
        }
757

758
        // prevent limit values from exceeding 'normal' limits
759
        if (default_limits_)
25✔
760
        {
761
                if (lowerDeg_ < -90.)
16✔
762
                        lowerDeg_ = -90.;
×
763
                if (lowerDeg_ > 90.)
16✔
764
                        lowerDeg_ = 90.;
×
765
        }
766

767
        // set the position of the error ellipse legend
768
        uncertainty_legend_long_ = leftDeg_ + dBuffer_;
25✔
769
        uncertainty_legend_lat_ = dScaleLat_;
25✔
770

771
        if (pprj_->p._plot_correction_arrows)
25✔
772
        {
773
                // set the position of the correction arrow legend
774
                // put the corrections legend on the right hand side
775
                arrow_legend_long_ = rightDeg_ - dBuffer_ * 2.0;
2✔
776
                arrow_legend_lat_ = dScaleLat_;
2✔
777
        }
778

779
        switch (pprj_->p._projection)
25✔
780
        {
781
        case world:
3✔
782
        case orthographic:
3✔
783
        case robinson:
3✔
784
                default_paper_width_ = 27.7;
3✔
785
                default_paper_height_ = 20.1;
3✔
786
                break;
3✔
787
        default:
22✔
788
                default_paper_width_ = 59.4;
22✔
789
                default_paper_height_ = 42.0;
22✔
790
        }        
791

792
        // Portrait or Landscape?
793
        // A3 paper width (landscape) is 42cm, and (portrait) is 29.7cm.  Less 
794
        // nomenclature (~2 cm), this leaves an available width for plotting 
795
        // of 40cm L or 27.7cm P
796
        //
797
        title_block_height_ = 6;
25✔
798
        page_width_ = default_paper_width_;                // centimetres
25✔
799

800
        if (dWidth_ > dHeight_)
25✔
801
                avg_data_scale_ = dHeight_ / default_paper_height_;
20✔
802
        else
803
                avg_data_scale_ = dHeight_ / default_paper_width_;
5✔
804
        
805
        isLandscape = true;
25✔
806
        if (dWidth_ < (dHeight_ + (title_block_height_ * avg_data_scale_)) || !default_limits_)
25✔
807
        {
808
                page_width_ = default_paper_height_;                        // centimetres
11✔
809
                isLandscape = false;
11✔
810
        }        
811

812
        pprj_->p._page_width = page_width_ + 2;
25✔
813

814
        // Scale (for A3 page width)
815
        if ((rightDeg_ - leftDeg_) > Degrees(PI) ||                        // wider than 180 degrees?
25✔
816
                (upperDeg_ - lowerDeg_) > Degrees(PI_135))                // taller than 135 degrees?
14✔
817
        {
818
                // Set the appropriate map projection
819
                if(!pprj_->p._user_defined_projection)
13✔
820
                {
821
                        if ((upperDeg_ - lowerDeg_) > Degrees(PI_135))                // taller than 135 degrees?
5✔
822
                        {
823
                                // Print the entire world on a flat sheet
824
                                pprj_->p._projection = world;
4✔
825

826
                                // Calculate ground width, which in this case is the circumference of the world
827
                                dDimension_ = TWO_PI * datum_.GetEllipsoid().GetSemiMajor();                // set distance circumference of a circle
4✔
828
                                
829
                                // Centre world map according to data centre
830
                                leftDeg_ = centre_width_ - 180.0;
4✔
831
                                rightDeg_ = centre_width_ + 180.0;
4✔
832

833
                                // Normalise limits according to 180 boundary
834
                                if (leftDeg_ < -180.0)
4✔
835
                                        leftDeg_ += 180.0;
×
836
                                if (rightDeg_ > 180.0)
4✔
837
                                        rightDeg_ -= 180.0;
4✔
838
                                
839
                                // Set latitude limits
840
                                lowerDeg_ = -90;
4✔
841
                                upperDeg_ = 90;
4✔
842
                        }
843
                        else
844
                        {
845
                                // Print a globe plot.  Limits are not required
846
                                pprj_->p._projection = orthographic;
1✔
847
                                
848
                                // Calculate ground width between west and east limits (including buffer)
849
                                dDimension_ = Radians(rightDeg_ - leftDeg_) / TWO_PI * datum_.GetEllipsoid().GetSemiMajor();
1✔
850
                        }
851
                }
852
                else
853
                        // Calculate ground width between west and east limits (including buffer)
854
                        dDimension_ = Radians(rightDeg_ - leftDeg_) / TWO_PI * datum_.GetEllipsoid().GetSemiMajor();
8✔
855

856
                // Calculate scale
857
                scale_ = dDimension_ / page_width_ * 100;                // metres
13✔
858
        }
859
        else
860
        {
861
                double azimuth;
12✔
862

863
                // Calculate accurate map width from limits
864
                dDimension_ = RobbinsReverse<double>(                // calculate distance (in metres) of map width
12✔
865
                        Radians(centre_height_), Radians(leftDeg_), Radians(centre_height_), Radians(rightDeg_),
12✔
866
                        &azimuth, datum_.GetEllipsoidRef());
867

868
                // Calculate scale
869
                scale_ = dDimension_ / page_width_ * 100;                // metres
12✔
870

871
                if (!pprj_->p._user_defined_projection)
12✔
872
                {
873
                        // default (large regions)
874
                        pprj_->p._projection = mercator;
11✔
875

876
                        // very high latitudes
877
                        if (fabs(centre_height_) > 80.)
11✔
878
                                pprj_->p._projection = orthographic;
1✔
879
                        //
880
                        // high latitudes
881
                        else if (fabs(centre_height_) > 60.)
10✔
882
                                pprj_->p._projection = albersConic;
1✔
883
                        // sparse latitude coverage
884
                        else if ((upperDeg_ - lowerDeg_) > Degrees(QUART_PI))        // taller than 45 degrees?
9✔
885
                        {
886
                                // tall, narrow plots
887
                                if ((rightDeg_ - leftDeg_) < Degrees(QUART_PI))                // not more than 45 degrees wide?
1✔
888
                                        pprj_->p._projection = orthographic;
×
889
                                // reasonably large area
890
                                else
891
                                        pprj_->p._projection = mercator;
1✔
892
                        }
893
                        //
894
                        // Smallish areas
895
                        else if (scale_ < 750000 && scale_ > 5000)
8✔
896
                                pprj_->p._projection = transverseMercator;
6✔
897
                        //
898
                        // wider than 20 degrees and taller than 20 degrees?
899
                        else if ((rightDeg_ - leftDeg_) > Degrees(PI_20) && (upperDeg_ - lowerDeg_) > Degrees(PI_20))
2✔
900
                                pprj_->p._projection = stereographicConformal;
×
901
                        // 
902
                        // wide plots
903
                        else if ((rightDeg_ - leftDeg_) > Degrees(THIRD_PI))        // wider than 90 degrees?
2✔
904
                                
905
                                pprj_->p._projection = lambertEqualArea;
×
906
                }
907
        }
908

909
        // Update calling app's parameters
910
        pprj_->p._projection = pprj_->p._projection;
25✔
911
        pprj_->p._ground_width = dDimension_;
25✔
912

913
        // Normalise scale
914
        NormaliseScale(scale_);
25✔
915
        mapScale_ = scale_;
25✔
916

917
        // Calculate scale bar, then round
918
        scale_bar_width_ = dDimension_ / 3000.;                // convert to kilometres
25✔
919
        NormaliseScaleBar(scale_bar_width_);
25✔
920

921
        // Calculate best graticule width, then round to the best integer
922
        graticule_width_ = ((rightDeg_ - leftDeg_) / 4.);
25✔
923
        graticule_width_precision_ = 12;
25✔
924
        NormaliseGraticule(graticule_width_, graticule_width_precision_);
25✔
925

926
        scale_precision_ = 0;
25✔
927
        if (scale_bar_width_ < 1.0)
25✔
928
                scale_precision_ = 4;
4✔
929

930
        line_width_ = projectSettings_.p._msr_line_width;
25✔
931
        circle_radius_ = 0.2;
25✔
932
        circle_radius_2_ = circle_radius_;
25✔
933
        circle_line_width_ = (projectSettings_.p._msr_line_width * 1.5);
25✔
934

935
        //if (scale >= 900000)
936
        //{
937
        //        //line_width = 0.05;
938
        //        circle_radius = 0.05;
939
        //        circle_line_width = 0.05;
940
        //}
941

942
        // Determine coastline resolution
943
        coastResolution_ = "l";
25✔
944
        SelectCoastlineResolution(dDimension_, coastResolution_, &pprj_->p);
25✔
945
}
25✔
946

947

948
bool dna_plot::InitialiseandValidateStartingBlock(UINT32& block)
58✔
949
{
950
        block = 0;
58✔
951
        if (pprj_->p._plot_block_number > 0)
58✔
952
        {
953
                block = pprj_->p._plot_block_number - 1;
4✔
954
                return true;
4✔
955
        }
956
        return false;
957
}
958

959
void dna_plot::CreateExtraInputFiles()
25✔
960
{
961
        UINT32 block(0);
25✔
962
        bool oneBlockOnly(true);
25✔
963
                
964
        // one and only block?
965
        oneBlockOnly = InitialiseandValidateStartingBlock(block);
25✔
966

967
        // Now print stations labels (based on font size determined by PrintGMTPlotBatfile)
968
        if (pprj_->p._plot_station_labels)
25✔
969
        {
970
                if (plotBlocks_)
3✔
971
                {
972
                        if (oneBlockOnly)
3✔
973
                                PrintStationLabelsBlock(block);
1✔
974
                        else
975
                                for (block=0; block<blockCount_; ++block)
7✔
976
                                        PrintStationLabelsBlock(block);
5✔
977
                }
978
                else
979
                        PrintStationLabels();
×
980
        }
981

982
        if (pprj_->p._plot_positional_uncertainty)
25✔
983
        {
984
                if (oneBlockOnly)
2✔
985
                        PrintPositionalUncertainty(block);
1✔
986
                else
987
                        for (block=0; block<blockCount_; ++block)
3✔
988
                                PrintPositionalUncertainty(block);
2✔
989
        }
990

991
        if (pprj_->p._plot_error_ellipses)
25✔
992
        {
993
                if (oneBlockOnly)
2✔
994
                        PrintErrorEllipses(block);
1✔
995
                else
996
                        for (block=0; block<blockCount_; ++block)
3✔
997
                                PrintErrorEllipses(block);
2✔
998
        }
999

1000
        if (pprj_->p._plot_correction_arrows)
25✔
1001
        {
1002
                if (oneBlockOnly)
2✔
1003
                        PrintCorrectionArrows(block);
1✔
1004
                else
1005
                        for (block=0; block<blockCount_; ++block)
3✔
1006
                                PrintCorrectionArrows(block);
2✔
1007
        }
1008

1009
        if (pprj_->p._plot_plate_boundaries)
25✔
1010
        {
1011
                if (oneBlockOnly)
2✔
1012
                        PrintPlateBoundaries(block);
×
1013
                else
1014
                        for (block=0; block<blockCount_; ++block)
3✔
1015
                                PrintPlateBoundaries(block);
2✔
1016
        }
1017
}
24✔
1018

1019
void dna_plot::CreateGMTInputFiles()
27✔
1020
{        
1021
        if (plotBlocks_)
27✔
1022
        {
1023
                UINT32 block(0);
3✔
1024
                bool oneBlockOnly(true);
3✔
1025
                
1026
                // one and only block?
1027
                if ((oneBlockOnly = InitialiseandValidateStartingBlock(block)))
3✔
1028
                        block = 0;
1✔
1029
                        
1030
                for (; block<blockCount_; ++block)
8✔
1031
                {
1032
                        PrintStationsDataFileBlock(block);
6✔
1033
                        if (!pprj_->p._omit_measurements)
6✔
1034
                                PrintMeasurementsDatFilesBlock(block);
6✔
1035
                        if (oneBlockOnly)
6✔
1036
                                break;
1037
                }
1038
        }
1039
        else
1040
        {
1041
                v_msr_file_.resize(1);
24✔
1042
                // PrintStationsDataFile calculates plot limits if user has 
1043
                // specified centre station or lat/long, or bounding box
1044
                PrintStationsDataFile();
24✔
1045
                if (!pprj_->p._omit_measurements)
24✔
1046
                        PrintMeasurementsDatFiles();
22✔
1047
        }
1048
}
27✔
1049

1050
void dna_plot::InitialiseGMTFilenames()
27✔
1051
{
1052
        // create bat file name(s), one per block, as:
1053
        //   create_<network_name>_block_#.[bat|sh]
1054
        //
1055
        // Simultaneous plot cmd files are created as:
1056
        //   create_<network_name>_block_0.[bat|sh]
1057
        //
1058
        // Specific block (n) plot cmd files are created as:
1059
        //   create_<network_name>_block_n.[bat|sh]
1060
        v_gmt_cmd_filenames_.clear();
27✔
1061
        v_gmt_pdf_filenames_.clear();
27✔
1062
        std::string gmt_filename, gmt_cmd_basename("create_" + network_name_ + "_block_");
54✔
1063
                
1064
        UINT32 block;
27✔
1065
        bool oneBlockOnly = InitialiseandValidateStartingBlock(block);
27✔
1066

1067
        for (; block<blockCount_; ++block)
56✔
1068
        {
1069
                // gmt command filename
1070
                gmt_filename = gmt_cmd_basename;
30✔
1071
                gmt_filename.append(StringFromT(block)).append(_CMD_EXT_);
60✔
1072

1073
                // Add folder path
1074
                gmt_filename = pprj_->g.output_folder + FOLDER_SLASH + gmt_filename;
60✔
1075

1076
                // Create absolute path                                
1077
                gmt_filename = boost::filesystem::absolute(gmt_filename).string();
150✔
1078

1079
                // Add to the list
1080
                v_gmt_cmd_filenames_.push_back(gmt_filename);
30✔
1081

1082
                // generated pdf filename
1083
                gmt_filename = network_name_;
30✔
1084
                gmt_filename.append("_block_").append(StringFromT(block)).append(".pdf");
60✔
1085
                v_gmt_pdf_filenames_.push_back(output_folder_ + FOLDER_SLASH + gmt_filename);
90✔
1086

1087
                // break out for specific block (n) plots
1088
                if (oneBlockOnly)
30✔
1089
                        break;
1090
        }
1091

1092
        pprj_->p._gmt_cmd_file = output_folder_ + FOLDER_SLASH + leafStr(v_gmt_cmd_filenames_.at(0));
81✔
1093

1094
        pprj_->p._pdf_file_name = output_folder_ + FOLDER_SLASH + network_name_;
54✔
1095

1096
        if (plotBlocks_)
27✔
1097
                pprj_->p._pdf_file_name.append("-phased");
3✔
1098
        else
1099
                pprj_->p._pdf_file_name.append("-simult");
24✔
1100

1101
        if (plotBlocks_ && oneBlockOnly)
27✔
1102
                pprj_->p._pdf_file_name.append("-block-").append(StringFromT(block));
3✔
1103

1104
        pprj_->p._pdf_file_name.append(".pdf");
27✔
1105
        
1106
        // simultaneous
1107
        if (!plotBlocks_)
27✔
1108
                v_gmt_pdf_filenames_.at(0) = pprj_->p._pdf_file_name;
51✔
1109
}
54✔
1110

1111
void dna_plot::CreateGMTCommandFiles()
25✔
1112
{
1113
        UINT32 block(0);
25✔
1114
        bool oneBlockOnly(true);
25✔
1115
        
1116
        if (plotBlocks_)
25✔
1117
        {
1118
                // one and only block?
1119
                if ((oneBlockOnly = InitialiseandValidateStartingBlock(block)))
3✔
1120
                        block = 0;
1✔
1121
        }
1122

1123
        for (; block<blockCount_; ++block)
30✔
1124
        {
1125
                try {
28✔
1126
                        // Create GMT batch file.  Throws runtime_error on failure.
1127
                        file_opener(gmtbat_file_, v_gmt_cmd_filenames_.at(block));
28✔
1128
                }
NEW
1129
                catch (const std::runtime_error& e) {
×
1130
                        SignalExceptionPlot(e.what(), 0, NULL);
×
1131
                }
×
1132

1133
                // set header
1134
                gmtbat_file_ << _CMD_HEADER_ << std::endl;
28✔
1135
                
1136
                // GMT bat file is printed last to reflect the options and dimensions as determined
1137
                // by PrintStationsDataFile and PrintMeasurementsDatFiles
1138
                CreateGMTCommandFile(block);
28✔
1139

1140
                // close the file
1141
                gmtbat_file_.close();
28✔
1142

1143
                // change file permission to executable
1144
#if defined(__linux) || defined(sun) || defined(__unix__) || defined(__APPLE__)                
1145
                std::string system_file_cmd = _CHMOD_CMD_ + v_gmt_cmd_filenames_.at(block);
28✔
1146
                std::system(system_file_cmd.c_str());
28✔
1147
#endif
1148

1149
                // break out for specific block (n) plots
1150
                if (oneBlockOnly)
28✔
1151
                        break;
1152
        }
28✔
1153
}
25✔
1154

1155

1156
void dna_plot::CreateGMTCommandFile(const UINT32& block)
28✔
1157
{
1158
        it_pair_string _it_colour;
28✔
1159
        string_string_pair this_msr;
28✔
1160

1161
        float annot_font_size_primary(9), label_font_size(11.);
28✔
1162
        double symbol_offset(1.0);
28✔
1163
        double label_offset(1.5);
28✔
1164
        double error_ellipse_scale(uncertainty_legend_length_/largest_uncertainty_);
28✔
1165
        UINT32 uncertainty_legend_precision(4);
28✔
1166

1167
        std::string psTempFile("tmp-");
28✔
1168
        psTempFile.append(StringFromT(block)).append(".ps");
56✔
1169
        std::string pdfTempFile("tmp-");
28✔
1170
        pdfTempFile.append(StringFromT(block)).append(".pdf");
56✔
1171

1172
        std::string legendTempFile("map-block");
28✔
1173
        legendTempFile.append(StringFromT(block)).append(".legend");
56✔
1174

1175
        // make temporary directory for gmt.conf gmt.history to prevent corruption of
1176
        // gmt.conf and gmt.history during parallel processing
1177
        gmtbat_file_ << std::endl << _COMMENT_PREFIX_ << "Create temporary folder for gmt.conf and gmt.history" << std::endl;
28✔
1178
        
1179
#if defined(_WIN32) || defined(__WIN32__)
1180
        // set, create and provide access to temporary folder for gmt.conf file
1181
        gmtbat_file_ << _MAKEENV_CMD_ << _GMT_TMP_DIR_ << "=%TEMP%\\gmt.block-" << block << std::endl;
1182
        gmtbat_file_ << _MAKEDIR_CMD_ << _ENV_GMT_TMP_DIR_ << std::endl;
1183
        //gmtbat_file_ << "icacls " << _ENV_GMT_TMP_DIR_ << " /grant Everyone:(f)" << std::endl;
1184

1185
#elif defined(__linux) || defined(sun) || defined(__unix__) || defined(__APPLE__)
1186
        // temporary gmt.conf file location
1187
        gmtbat_file_ << _MAKEENV_CMD_ << _GMT_TMP_DIR_ << "=$(" << _MAKETEMP_CMD_ << "-d ${TMPDIR:-/tmp}/gmt.XXXXXX)" << std::endl << std::endl;
28✔
1188
#endif
1189

1190
        UINT32 colours(0), columns(5);
28✔
1191
        
1192
        if (plotBlocks_)
28✔
1193
                gmtbat_file_ << std::endl << 
6✔
1194
                        _COMMENT_PREFIX_ << "GMT command file for segmented network block " << (block + 1) << std::endl;                
6✔
1195
        else
1196
                gmtbat_file_ << std::endl << 
22✔
1197
                        _COMMENT_PREFIX_ << "GMT command file for simultaneous network" << std::endl << std::endl;
22✔
1198

1199
        // write GMT parameters
1200
        PrintGMTParameters();
28✔
1201

1202
        if (isLandscape)
28✔
1203
                gmtbat_file_ << _APP_GMTSET_ << " PS_PAGE_ORIENTATION landscape" << std::endl << std::endl;
14✔
1204
        else
1205
                gmtbat_file_ << _APP_GMTSET_ << " PS_PAGE_ORIENTATION portrait" << std::endl << std::endl;
14✔
1206
        
1207
        gmtbat_file_ << _APP_GMTSET_ << " FONT_ANNOT " << std::fixed << std::setprecision(1) << annot_font_size_primary << "p" << std::endl;
28✔
1208
        gmtbat_file_ << _APP_GMTSET_ << " FONT_ANNOT_PRIMARY " << std::fixed << std::setprecision(1) << annot_font_size_primary << "p" << std::endl;
28✔
1209
        gmtbat_file_ << _APP_GMTSET_ << " FONT_LABEL " << std::fixed << std::setprecision(1) << label_font_size << "p" << std::endl;
28✔
1210
        if (graticule_width_ < 60./3600.)
28✔
1211
                gmtbat_file_ << _APP_GMTSET_ << " FORMAT_GEO_MAP ddd:mm:ss.x" << std::endl << std::endl;
6✔
1212
        else
1213
                gmtbat_file_ << _APP_GMTSET_ << " FORMAT_GEO_MAP ddd:mm" << std::endl << std::endl;
22✔
1214

1215
        page_width_ = pprj_->p._page_width;
28✔
1216

1217
        switch (pprj_->p._projection)
28✔
1218
        {
1219
        case world:
5✔
1220
                // World map centered on the dateline
1221
                // pscoast -Rg -JQ4.5i -B60f30g30 -Dc -A5000 -Gblack -P > tmp.ps
1222
                
1223
                // Override coastline resolution
1224
                coastResolution_ = "i";
5✔
1225
                pprj_->p._coasline_resolution = intermediate;
5✔
1226
                circle_radius_ = 0.02;
5✔
1227
                circle_line_width_ = 0.02;
5✔
1228
                if (pprj_->p._label_font_size < 0.)
5✔
1229
                        pprj_->p._label_font_size = 5;
5✔
1230

1231
                gmtbat_file_ << _APP_PSCOAST_ << " -Rg" << 
5✔
1232
                        // Carree Cylindrical equidistant projection, which looks the nicest
1233
                        " -JQ" << page_width_  << "c -B60g30 -D" << coastResolution_ << 
10✔
1234
                        " -A10000 -W0.75p,16/169/243 -G245/245/245 -K > " << psTempFile << std::endl;
10✔
1235
                        //
1236
                        // Miller's Cylindrical projection, which is neither equal nor conformal. All meridians and parallels are straight lines.
1237
                        // " -JJ" << page_width  << "c -B60g30 -D" << coastResolution << " -A10000 -W0.75p,16/169/243 -G245/245/245 -P -K > " << psTempFile << std::endl;
1238
                        //
1239
                        // Cylindrical equal-area projection
1240
                        //" -JY" << page_width  << "c -B60g30 -D" << coastResolution << " -A10000 -W0.75p,16/169/243 -G245/245/245 -P -K > " << psTempFile << std::endl;
1241
                break;
1242
        //
1243
        // Orthographic projection
1244
        case orthographic:
3✔
1245
                        
1246
                // Override coastline resolution
1247
                coastResolution_ = "h";
3✔
1248
                pprj_->p._coasline_resolution = high;
3✔
1249
                circle_radius_ = 0.05;
3✔
1250
                circle_line_width_ = 0.05;
3✔
1251
                if (pprj_->p._label_font_size < 0.)
3✔
1252
                        pprj_->p._label_font_size = 5;
3✔
1253

1254
                gmtbat_file_ << _APP_PSCOAST_ << " -Rg -JG" << 
3✔
1255
                        std::fixed << std::setprecision(7) << centre_width_ << "/" <<                // longitude
3✔
1256
                        std::fixed << std::setprecision(7) << centre_height_ << "/" <<                // latitude
3✔
1257
                        std::fixed << std::setprecision(1) << page_width_ << "c -B30g15 -D" << coastResolution_ << 
6✔
1258
                        " -A10000 -W0.75p,16/169/243 -G245/245/245 -P -K > " << psTempFile << std::endl;
6✔
1259
                break;
1260
        //
1261
        // Mercator projection
1262
        case mercator:
8✔
1263
                if (pprj_->p._label_font_size < 0.)
8✔
1264
                        pprj_->p._label_font_size = 6;
4✔
1265

1266
                gmtbat_file_ << _APP_PSCOAST_ << " -R" << 
8✔
1267
                std::fixed << std::setprecision(7) << leftDeg_ << "/" <<
8✔
1268
                std::fixed << std::setprecision(7) << lowerDeg_ << "/" <<
8✔
1269
                std::fixed << std::setprecision(7) << rightDeg_ << "/" <<
8✔
1270
                std::fixed << std::setprecision(7) << upperDeg_;
8✔
1271

1272
                // example: -Jm1.2e-2i
1273
                gmtbat_file_ << "r -JM" << std::fixed << std::setprecision(1) << page_width_ << "c";
8✔
1274
                gmtbat_file_ << " -D" << coastResolution_ << " -N2/0.25p -W0.75p,16/169/243 -G255/255/255 -S233/246/255 -Lf" <<
8✔
1275
                        std::fixed << std::setprecision(5) << centre_width_ << "/" << std::fixed << std::setprecision(5) << dScaleLat_ << "/" << 
8✔
1276
                        std::fixed << std::setprecision(5) << centre_height_ << "/" << std::fixed << std::setprecision(scale_precision_) << scale_bar_width_ << "k+lKilometres+jt " <<
8✔
1277
                        "-B" <<
8✔
1278
                        std::fixed << std::setprecision(graticule_width_precision_) << graticule_width_ << "g" << std::fixed << std::setprecision(graticule_width_precision_) << graticule_width_ << "/" << 
8✔
1279
                        std::fixed << std::setprecision(graticule_width_precision_) << graticule_width_ << "g" << std::fixed << std::setprecision(graticule_width_precision_) << graticule_width_;
8✔
1280

1281
                if (!isLandscape)
8✔
1282
                        gmtbat_file_ << " -P";
6✔
1283
                gmtbat_file_ << " -K > " << psTempFile << std::endl;
8✔
1284
                
1285
                break;
1286
        //
1287
        // Transverse Mercator projection
1288
        case transverseMercator:
7✔
1289
                if (pprj_->p._label_font_size < 0.)
7✔
1290
                        pprj_->p._label_font_size = 6;
7✔
1291

1292
                gmtbat_file_ << _APP_PSCOAST_ << " -R" << 
7✔
1293
                std::fixed << std::setprecision(7) << leftDeg_ << "/" <<
7✔
1294
                std::fixed << std::setprecision(7) << lowerDeg_ << "/" <<
7✔
1295
                std::fixed << std::setprecision(7) << rightDeg_ << "/" <<
7✔
1296
                std::fixed << std::setprecision(7) << upperDeg_;
7✔
1297

1298
                // example: -Jt139.9944444/-24.1486111/1:1000000
1299
                //gmtbat_file_ << "r -Jt" << std::fixed << std::setprecision(7) << centre_width_ << "/" <<
1300
                //        std::fixed << std::setprecision(7) << centre_height_ << "/1:" << std::fixed << std::setprecision(0) << scale;
1301
                gmtbat_file_ << "r -JT" << std::fixed << std::setprecision(7) << centre_width_ << "/" <<
7✔
1302
                        std::fixed << std::setprecision(1) << page_width_ << "c";
7✔
1303

1304
                gmtbat_file_ << " -D" << coastResolution_ << " -N2/0.25p -W0.75p,16/169/243 -G255/255/255 -S233/246/255 -Lf" <<
7✔
1305
                        std::fixed << std::setprecision(5) << centre_width_ << "/" << std::fixed << std::setprecision(5) << dScaleLat_ << "/" << 
7✔
1306
                        std::fixed << std::setprecision(5) << centre_height_ << "/" << std::fixed << std::setprecision(scale_precision_) << scale_bar_width_ << "k+lKilometres+jt " <<
7✔
1307
                        "-B" <<
7✔
1308
                        std::fixed << std::setprecision(graticule_width_precision_) << graticule_width_ << "g" << std::fixed << std::setprecision(graticule_width_precision_) << graticule_width_ << "/" << 
7✔
1309
                        std::fixed << std::setprecision(graticule_width_precision_) << graticule_width_ << "g" << std::fixed << std::setprecision(graticule_width_precision_) << graticule_width_;
7✔
1310

1311
                if (!isLandscape)
7✔
1312
                        gmtbat_file_ << " -P";
3✔
1313
                gmtbat_file_ << " -K > " << psTempFile << std::endl;
7✔
1314
                
1315
                break;
1316
        //
1317
        // Albers conic equal-area projection
1318
        case albersConic:
2✔
1319
                if (pprj_->p._label_font_size < 0.)
2✔
1320
                        pprj_->p._label_font_size = 6;
2✔
1321

1322
                gmtbat_file_ << _APP_PSCOAST_ << " -R" << 
2✔
1323
                        std::fixed << std::setprecision(7) << leftDeg_ << "/" <<
2✔
1324
                        std::fixed << std::setprecision(7) << lowerDeg_ << "/" <<
2✔
1325
                        std::fixed << std::setprecision(7) << rightDeg_ << "/" <<
2✔
1326
                        std::fixed << std::setprecision(7) << upperDeg_;
2✔
1327

1328
                // example: -Jb136.5/-36/-18/-36/1:45000000
1329
                //gmtbat_file_ << "r -Jb" << std::fixed << std::setprecision(7) << centre_width_ << "/" <<
1330
                //        std::fixed << std::setprecision(7) << centre_height_ << "/" <<
1331
                //        std::fixed << std::setprecision(7) << upperDeg_ - fabs(dHeight/3.) << "/" <<
1332
                //        std::fixed << std::setprecision(7) << lowerDeg_ + fabs(dHeight/3.) << "/" <<                                
1333
                //        "1:" << std::fixed << std::setprecision(0) << scale;
1334
                gmtbat_file_ << "r -JB" << std::fixed << std::setprecision(7) << centre_width_ << "/" <<
2✔
1335
                        std::fixed << std::setprecision(7) << centre_height_ << "/" <<
2✔
1336
                        std::fixed << std::setprecision(7) << upperDeg_ - fabs(dHeight_/3.) << "/" <<
2✔
1337
                        std::fixed << std::setprecision(7) << lowerDeg_ + fabs(dHeight_/3.) << "/" <<                                
2✔
1338
                        std::fixed << std::setprecision(1) << page_width_ << "c";
2✔
1339

1340
                gmtbat_file_ << " -D" << coastResolution_ << " -N2/0.25p -W0.75p,16/169/243 -G255/255/255 -S233/246/255 -Lf" <<
2✔
1341
                        std::fixed << std::setprecision(5) << centre_width_ << "/" << std::fixed << std::setprecision(5) << dScaleLat_ << "/" << 
2✔
1342
                        std::fixed << std::setprecision(5) << centre_height_ << "/" << std::fixed << std::setprecision(scale_precision_) << scale_bar_width_ << "k+lKilometres+jt " <<
2✔
1343
                        "-B" <<
2✔
1344
                        //fixed << std::setprecision(7) << DmstoDeg(0.3) << "g" << std::fixed << std::setprecision(7) << DmstoDeg(0.3) << " -K > " << psTempFile << std::endl;
1345
                        std::fixed << std::setprecision(graticule_width_precision_) << graticule_width_ << "g" << std::fixed << std::setprecision(graticule_width_precision_) << graticule_width_ << "/" << 
2✔
1346
                        std::fixed << std::setprecision(graticule_width_precision_) << graticule_width_ << "g" << std::fixed << std::setprecision(graticule_width_precision_) << graticule_width_;
2✔
1347

1348
                if (!isLandscape)
2✔
1349
                        gmtbat_file_ << " -P";
1✔
1350
                gmtbat_file_ << " -K > " << psTempFile << std::endl;
2✔
1351
                break;
1352
        //
1353
        // Lambert Azimuthal Equal-Area                
1354
        case lambertEqualArea:                
1✔
1355
                if (pprj_->p._label_font_size < 0.)
1✔
1356
                        pprj_->p._label_font_size = 6;
1✔
1357

1358
                gmtbat_file_ << _APP_PSCOAST_ << " -R" << 
1✔
1359
                std::fixed << std::setprecision(7) << leftDeg_ << "/" <<
1✔
1360
                std::fixed << std::setprecision(7) << lowerDeg_ << "/" <<
1✔
1361
                std::fixed << std::setprecision(7) << rightDeg_ << "/" <<
1✔
1362
                std::fixed << std::setprecision(7) << upperDeg_;
1✔
1363

1364
                // example: -JA30/-30/4.5i
1365
                gmtbat_file_ << "r -JA" << std::fixed << std::setprecision(7) << centre_width_ << "/" <<
1✔
1366
                        std::fixed << std::setprecision(7) << centre_height_ << "/" <<
1✔
1367
                        std::fixed << std::setprecision(1) << page_width_ << "c";
1✔
1368

1369
                gmtbat_file_ << " -D" << coastResolution_ << " -N2/0.25p -W0.75p,16/169/243 -G255/255/255 -S233/246/255 -Lf" <<
1✔
1370
                        std::fixed << std::setprecision(5) << centre_width_ << "/" << std::fixed << std::setprecision(5) << dScaleLat_ << "/" << 
1✔
1371
                        std::fixed << std::setprecision(5) << centre_height_ << "/" << std::fixed << std::setprecision(scale_precision_) << scale_bar_width_ << "k+lKilometres+jt " <<
1✔
1372
                        "-B" <<
1✔
1373
                        std::fixed << std::setprecision(graticule_width_precision_) << graticule_width_ << "g" << std::fixed << std::setprecision(graticule_width_precision_) << graticule_width_ << "/" << 
1✔
1374
                        std::fixed << std::setprecision(graticule_width_precision_) << graticule_width_ << "g" << std::fixed << std::setprecision(graticule_width_precision_) << graticule_width_;
1✔
1375

1376
                if (!isLandscape)
1✔
1377
                        gmtbat_file_ << " -P";
×
1378
                gmtbat_file_ << " -K > " << psTempFile << std::endl;
1✔
1379
                
1380
                break;
1381
        //
1382
        // General stereographic map
1383
        case stereographicConformal:
1✔
1384
                if (pprj_->p._label_font_size < 0.)
1✔
1385
                        pprj_->p._label_font_size = 6;
1✔
1386

1387
                gmtbat_file_ << _APP_PSCOAST_ << " -R" << 
1✔
1388
                std::fixed << std::setprecision(7) << leftDeg_ << "/" <<
1✔
1389
                std::fixed << std::setprecision(7) << lowerDeg_ << "/" <<
1✔
1390
                std::fixed << std::setprecision(7) << rightDeg_ << "/" <<
1✔
1391
                std::fixed << std::setprecision(7) << upperDeg_;
1✔
1392

1393
                // example: -R100/-40/160/-10r -JS130/-30/4i
1394
                gmtbat_file_ << "r -JS" << std::fixed << std::setprecision(7) << centre_width_ << "/" <<
1✔
1395
                        std::fixed << std::setprecision(7) << centre_height_ << "/" <<
1✔
1396
                        std::fixed << std::setprecision(1) << page_width_ << "c";
1✔
1397

1398
                gmtbat_file_ << " -D" << coastResolution_ << " -N2/0.25p -W0.75p,16/169/243 -G255/255/255 -S233/246/255 -Lf" <<
1✔
1399
                        std::fixed << std::setprecision(5) << centre_width_ << "/" << std::fixed << std::setprecision(5) << dScaleLat_ << "/" << 
1✔
1400
                        std::fixed << std::setprecision(5) << centre_height_ << "/" << std::fixed << std::setprecision(scale_precision_) << scale_bar_width_ << "k+lKilometres+jt " <<
1✔
1401
                        "-B" <<
1✔
1402
                        std::fixed << std::setprecision(graticule_width_precision_) << graticule_width_ << "g" << std::fixed << std::setprecision(graticule_width_precision_) << graticule_width_ << "/" << 
1✔
1403
                        std::fixed << std::setprecision(graticule_width_precision_) << graticule_width_ << "g" << std::fixed << std::setprecision(graticule_width_precision_) << graticule_width_;
1✔
1404

1405
                if (!isLandscape)
1✔
1406
                        gmtbat_file_ << " -P";
×
1407
                gmtbat_file_ << " -K > " << psTempFile << std::endl;
1✔
1408
                
1409
                break;
1410
        // Robinson projection
1411
        case robinson:
1✔
1412
        default:
1✔
1413

1414
                // Robinson map centered on the dateline
1415
                // pscoast -Rwest/east/south/north -JN7.5i -B60f30g30 -Dc -A5000 -Gblack -P > tmp.ps
1416
                // pscoast -R(centre_width_-180)/(centre_width_+180)/-90/90
1417

1418
                // Override coastline resolution
1419
                coastResolution_ = "i";
1✔
1420
                pprj_->p._coasline_resolution = intermediate;
1✔
1421
                circle_radius_ = 0.02;
1✔
1422
                circle_line_width_ = 0.02;
1✔
1423
                if (pprj_->p._label_font_size < 0.)
1✔
1424
                        pprj_->p._label_font_size = 5;
1✔
1425

1426
                gmtbat_file_ << _APP_PSCOAST_ << " -R" << 
1✔
1427
                        (centre_width_-180) << "/" << (centre_width_+180) << "/-90/90"
1✔
1428
                        " -JN" << page_width_  << "c -B60g30 -D" << coastResolution_ << 
2✔
1429
                        " -A10000 -W0.75p,16/169/243 -G245/245/245 -K > " << psTempFile << std::endl;
2✔
1430
        }
1431

1432
        std::sort(pprj_->p._msr_colours.begin(), pprj_->p._msr_colours.end(), ComparePairFirst<std::string>());                
28✔
1433

1434
        if (pprj_->p._plot_plate_boundaries)
28✔
1435
        {
1436
                // print plate boundaries first
1437
                gmtbat_file_ << _APP_PSXY_ << " -R -J \"" << v_tectonic_plate_file_.at(block) << 
4✔
1438
                        "\" -W0.75p,#DA5552 -O -K >> " << psTempFile << std::endl;
4✔
1439
        }
1440

1441
        // Does the user want to print measurements?
1442
        if (!pprj_->p._omit_measurements)
28✔
1443
        {
1444
                // print latitude, longitude and height measurements (large circles) before stations
1445
                for (UINT32 i=0; i<v_msr_file_.at(block).size(); i++)
463✔
1446
                {
1447
                        if (v_msr_file_.at(block).at(i).second != "H" &&
849✔
1448
                                v_msr_file_.at(block).at(i).second != "I" &&
806✔
1449
                                v_msr_file_.at(block).at(i).second != "J" &&
770✔
1450
                                v_msr_file_.at(block).at(i).second != "P" &&
734✔
1451
                                v_msr_file_.at(block).at(i).second != "Q" &&
698✔
1452
                                v_msr_file_.at(block).at(i).second != "R" &&
1,099✔
1453
                                v_msr_file_.at(block).at(i).second != "Y")
322✔
1454
                                continue;
297✔
1455

1456
                        circle_radius_2_ = circle_radius_;
140✔
1457

1458
                        if (v_msr_file_.at(block).at(i).second == "I" ||                // astronomic latitude
140✔
1459
                                v_msr_file_.at(block).at(i).second == "P")                        //   geodetic latitude
122✔
1460
                                circle_radius_2_ = circle_radius_ * 2.75;
36✔
1461
                        else if (v_msr_file_.at(block).at(i).second == "J" ||        // astronomic longitude
104✔
1462
                                v_msr_file_.at(block).at(i).second == "Q")                        //   geodetic longitude
86✔
1463
                                circle_radius_2_ = circle_radius_ * 2.4;
36✔
1464
                        else if (v_msr_file_.at(block).at(i).second == "H" ||        // orthometric height
68✔
1465
                                v_msr_file_.at(block).at(i).second == "R")                        // ellipsoidal height
43✔
1466
                                circle_radius_2_ = circle_radius_ * 1.95;
43✔
1467
                        else if (v_msr_file_.at(block).at(i).second == "Y")                // GPS point cluster
25✔
1468
                                circle_radius_2_ = circle_radius_ * 3.0;
25✔
1469

1470
                        _it_colour = equal_range(pprj_->p._msr_colours.begin(), pprj_->p._msr_colours.end(), 
140✔
1471
                                v_msr_file_.at(block).at(i).second, ComparePairFirst<std::string>());
140✔
1472

1473
                        if (_it_colour.first == _it_colour.second)
140✔
1474
                        {
NEW
1475
                                gmtbat_file_ << _APP_PSXY_ << " -R -J -Skcircle/" << std::fixed << std::setprecision(2) << circle_radius_2_ << 
×
NEW
1476
                                        " \"" << v_msr_file_.at(block).at(i).first << "\" -W" << std::setprecision(2) << circle_line_width_ << 
×
1477
                                        "p,darkgray -Glightgray";
×
NEW
1478
                                gmtbat_file_ << " -O -K >> " << psTempFile << std::endl;
×
1479
                        }
1480
                        else
1481
                        {
1482
                                colours++;
140✔
1483
                                gmtbat_file_ << _APP_PSXY_ << " -R -J -Skcircle/" << std::fixed << std::setprecision(2) << circle_radius_2_ << 
140✔
1484
                                        " \"" << v_msr_file_.at(block).at(i).first << "\" -W" << std::setprecision(2) << circle_line_width_ << 
140✔
1485
                                        "p,";
140✔
1486

1487
                                // Line colour
1488
                                if (v_msr_file_.at(block).at(i).second == "Y")                                                // GNSS Point Cluster
140✔
1489
                                        gmtbat_file_ << "#235789";                                                                        // bdazzled blue
25✔
1490
                                else if (v_msr_file_.at(block).at(i).second == "I" ||                                // astronomic latitude
115✔
1491
                                        v_msr_file_.at(block).at(i).second == "P")                                                // geodetic latitude
97✔
1492
                                        gmtbat_file_ << "#A393BF";                                                                        // glossy grape
36✔
1493
                                else if (v_msr_file_.at(block).at(i).second == "J" ||                                // astronomic longitude
79✔
1494
                                        v_msr_file_.at(block).at(i).second == "Q")                                                // geodetic longitude
61✔
1495
                                        gmtbat_file_ << "#4C1C00";                                                                        // seal brown
36✔
1496
                                else if (v_msr_file_.at(block).at(i).second == "H" ||                                // orthometric height
43✔
1497
                                        v_msr_file_.at(block).at(i).second == "R")                                                // ellipsoidal height
18✔
1498
                                        gmtbat_file_ << "#6622CC";                                                                        // french violet
43✔
1499
                                else
1500
                                        gmtbat_file_ << _it_colour.first->second;
×
1501

1502
                                // Fill colour
1503
                                gmtbat_file_ << " -G" << _it_colour.first->second  << " -O -K >> " << psTempFile << std::endl;
437✔
1504
                        }
1505
                }
1506
        }
1507

1508
        // print stations first to enable measurements to be seen
1509
        gmtbat_file_ << _APP_PSXY_ << " -R -J -Skcircle/" << std::fixed << std::setprecision(2) << circle_radius_ << 
28✔
1510
                " \"" << v_isl_pts_file_.at(block) << "\" -W" << std::setprecision(2) << circle_line_width_ << 
28✔
1511
                "p,#235789 -Gwhite -O -K >> " << psTempFile << std::endl;
28✔
1512

1513
        if (plotConstraints_)
28✔
1514
                // don't plot line, just fill
1515
                gmtbat_file_ << _APP_PSXY_ << " -R -J -Skcircle/" << std::fixed << std::setprecision(2) << circle_radius_ << 
27✔
1516
                        " \"" << v_isl_const_file_.at(block) << "\" -G#235789 -O -K >> " << psTempFile << std::endl;
27✔
1517

1518
        if (plotBlocks_)
28✔
1519
        {
1520
                gmtbat_file_ << _APP_PSXY_ << " -R -J -Skcircle/" << std::fixed << std::setprecision(2) << circle_radius_ << 
6✔
1521
                        " \"" << v_jsl_pts_file_.at(block) << "\" -W" << std::setprecision(2) << circle_line_width_ * 2.0 << 
6✔
1522
                        "p,#DA5552 -Gwhite -O -K >> " << psTempFile << std::endl;
6✔
1523

1524
                if (plotConstraints_)
6✔
1525
                        // don't plot line, just fill
1526
                        gmtbat_file_ << _APP_PSXY_ << " -R -J -Skcircle/" << std::fixed << std::setprecision(2) << circle_radius_ << 
5✔
1527
                                " \"" << v_jsl_const_file_.at(block) << "\" -G#DA5552 -O -K >> " << psTempFile << std::endl;
5✔
1528
        }
1529

1530
        // Does the user want to print measurements?
1531
        if (!pprj_->p._omit_measurements)
28✔
1532
        {
1533
                // now print lines
1534
                for (UINT32 i=0; i<v_msr_file_.at(block).size(); i++)
463✔
1535
                {
1536
                        if (v_msr_file_.at(block).at(i).second == "H")                // already printed
437✔
1537
                                continue;
25✔
1538
                        if (v_msr_file_.at(block).at(i).second == "I")                // ''
412✔
1539
                                continue;
18✔
1540
                        if (v_msr_file_.at(block).at(i).second == "J")                // ''
394✔
1541
                                continue;
18✔
1542
                        if (v_msr_file_.at(block).at(i).second == "P")                // ''
376✔
1543
                                continue;
18✔
1544
                        if (v_msr_file_.at(block).at(i).second == "Q")                // ''
358✔
1545
                                continue;                        
18✔
1546
                        if (v_msr_file_.at(block).at(i).second == "R")                // ''
340✔
1547
                                continue;
18✔
1548
                        if (v_msr_file_.at(block).at(i).second == "Y")                // ''
322✔
1549
                                continue;
25✔
1550
                                
1551
                        _it_colour = equal_range(pprj_->p._msr_colours.begin(), pprj_->p._msr_colours.end(), 
297✔
1552
                                v_msr_file_.at(block).at(i).second, ComparePairFirst<std::string>());
297✔
1553

1554
                        if (_it_colour.first == _it_colour.second)
297✔
1555
                        {
1556
                                gmtbat_file_ << _APP_PSXY_ << " -R -J \"" << v_msr_file_.at(block).at(i).first << 
2✔
1557
                                        "\" " << "-W" << std::setprecision(2) << line_width_ << 
2✔
1558
                                        "p,lightgray";
1✔
1559
                                //if (v_msr_file_.at(block).at(i).second == "Y")                // not a vector measurement, so represent as dashed
1560
                                //        gmtbat_file_ << ",6_8:1p";
1561
                                gmtbat_file_ << " -O -K >> " << psTempFile << std::endl;
1✔
1562
                        }
1563
                        else
1564
                        {
1565
                                colours++;
296✔
1566
                                gmtbat_file_ << _APP_PSXY_ << " -R -J \"" << v_msr_file_.at(block).at(i).first << 
592✔
1567
                                        "\" " << "-W" << std::setprecision(2) << line_width_ << 
592✔
1568
                                        "p," << _it_colour.first->second;
296✔
1569
                                //if (v_msr_file_.at(block).at(i).second == "Y")                // not a vector measurement, so represent as dashed
1570
                                //        gmtbat_file_ << ",6_8:1p";
1571
                                gmtbat_file_ << " -O -K >> " << psTempFile << std::endl;
437✔
1572
                        }
1573
                }
1574
        }
1575

1576
        if (pprj_->p._plot_positional_uncertainty || 
28✔
1577
                pprj_->p._plot_error_ellipses)
25✔
1578
        {
1579
                // calculate scale for uncertainty circles, to the end that 
1580
                // largest_uncertainty_ is uncertainty_legend_length_ cm on the A3 page
1581
                //if (largest_uncertainty_ >= 1.0)
1582
                //        uncertainty_legend_precision = 0;
1583
                /*else*/ if ((largest_uncertainty_ / pprj_->p._pu_ellipse_scale) >= 0.1)
3✔
1584
                        uncertainty_legend_precision = 1;
1585
                else if ((largest_uncertainty_ / pprj_->p._pu_ellipse_scale) >= 0.01)
3✔
1586
                        uncertainty_legend_precision = 2;
1587
                else if ((largest_uncertainty_ / pprj_->p._pu_ellipse_scale) >= 0.001)
3✔
1588
                        uncertainty_legend_precision = 3;
1589
                else
1590
                        uncertainty_legend_precision = 4;
×
1591
        }
1592

1593
        UINT32 precision(10);
28✔
1594

1595
        if (pprj_->p._plot_positional_uncertainty)
28✔
1596
        {
1597
                // print positional uncertainty
1598
                gmtbat_file_ << _APP_PSVELO_ << " -R -J \"" << v_stn_apu_file_.at(block) << 
6✔
1599
                        "\" -Sr" << error_ellipse_scale << "/0.95/0c -L -W1.25p,#FFD275 -O -K >> " << psTempFile << std::endl;
6✔
1600

1601
                // Shift plot north to account for error ellipse legend
1602
                if (pprj_->p._plot_error_ellipses)
3✔
1603
                        gmtbat_file_ << _APP_PSXY_ << " -R -J -T -Y" << 
3✔
1604
                                label_font_size * 1.5 << "p " << 
3✔
1605
                                " -O -K >> " << psTempFile << std::endl;
3✔
1606
                
1607
                // Add text for positional uncertainty legend 
1608
                gmtbat_file_ << _ECHO_CMD_ << 
3✔
1609
                        std::setprecision(precision) << std::fixed << std::left << uncertainty_legend_long_ << " " << 
3✔
1610
                        std::setprecision(precision) << std::fixed << std::left << uncertainty_legend_lat_ << " " << 
3✔
1611
                        " 95% positional uncertainty " <<                                                // the label
1612
                        std::setprecision(uncertainty_legend_precision) <<                        // ''
3✔
1613
                        std::fixed << largest_uncertainty_ / pprj_->p._pu_ellipse_scale << " radius \\(m\\)" <<                                        // radius
3✔
1614
                        " | ";                                                                                                        // Push to pstext
3✔
1615
                gmtbat_file_ << 
3✔
1616
                        _APP_PSTEXT_ << " -R -J -F+f" << 
3✔
1617
                        std::fixed << std::setprecision(0) << 
3✔
1618
                        pprj_->p._label_font_size * 2.0 << "p,Helvetica" <<                // font size and face
3✔
1619
                        "=~" << pprj_->p._label_font_size/2.0 << "p,white" <<                 // outline (or glow)
3✔
1620
                        "+jLM " <<                                                                                                                // justification
1621
                        "-Dj" << pprj_->p._label_font_size * 2.0 <<                                // x shift
3✔
1622
                        "p/0p -O -K >> " << psTempFile << std::endl;                                        // y shift
3✔
1623
        }
1624
        
1625
        if (pprj_->p._plot_error_ellipses)
28✔
1626
        {
1627
                // Terminate a sequence of GMT plotting commands without producing any plotting output
1628
                if (pprj_->p._plot_positional_uncertainty)
3✔
1629
                        gmtbat_file_ << _APP_PSXY_ << " -R -J -T -Y-" << 
3✔
1630
                                label_font_size * 1.5 << "p " << 
3✔
1631
                                " -O -K >> " << psTempFile << std::endl;
3✔
1632

1633
                double ellipse_scale(1.);
3✔
1634

1635
                // The error ellipse legend is printed using the largest uncertainty (semi-major) found, unless
1636
                // positional uncertainty is being printed, in which case the error ellipse is printed using
1637
                // half the size.  This is purely to give the impression that error ellipses are 1 sigma (68%) and
1638
                // positional uncertainty is 95%, or close to 2 sigma.
1639
                if (pprj_->p._plot_positional_uncertainty)
3✔
1640
                        ellipse_scale = 2.;
3✔
1641

1642
                // print error ellipses in indian red
1643
                gmtbat_file_ << _APP_PSVELO_ << " -R -J \"" << v_stn_err_file_.at(block) << 
6✔
1644
                        "\" -Sr" << error_ellipse_scale << "/0.95/0c -L -W0.75p,#DA5552 -O -K >> " << psTempFile << std::endl;
6✔
1645

1646
                // Add text for error ellipse legend 
1647
                gmtbat_file_ << _ECHO_CMD_ <<
3✔
1648
                        std::setprecision(precision) << std::fixed << std::left << uncertainty_legend_long_ << " " << 
3✔
1649
                        std::setprecision(precision) << std::fixed << std::left << uncertainty_legend_lat_ << " " << 
3✔
1650
                        " 1 sigma error ellipse " <<                                                        // the label
1651
                        std::setprecision(uncertainty_legend_precision) <<                        // ''
3✔
1652
                        std::fixed << largest_uncertainty_ / ellipse_scale / pprj_->p._pu_ellipse_scale <<                        // semi-major
3✔
1653
                        ", " <<                                
3✔
1654
                        std::fixed << largest_uncertainty_ / 3.0 / ellipse_scale / pprj_->p._pu_ellipse_scale <<        // semi-minor (make it third the height)
3✔
1655
                        " \\(m\\)" <<
1656
                        " | ";                                                                                                        // Push to pstext
3✔
1657
                gmtbat_file_ << 
3✔
1658
                        _APP_PSTEXT_ << " -R -J -F+f" << 
3✔
1659
                        std::fixed << std::setprecision(0) << 
3✔
1660
                        pprj_->p._label_font_size * 2.0 << "p,Helvetica" <<                                // font size and face
3✔
1661
                        "=~" << pprj_->p._label_font_size/2.0 << "p,white" <<                 // outline (or glow)
3✔
1662
                        "+jLM " <<                                                                                                                // justification
1663
                        "-Dj" << pprj_->p._label_font_size * 2.0 <<                                // x shift
3✔
1664
                        "p/0p -O -K >> " << psTempFile << std::endl;                                        // y shift
3✔
1665
        }
1666
        
1667
        if (pprj_->p._plot_correction_arrows)
28✔
1668
        {
1669
                // calculate scale for arrows, to the end that 
1670
                // average_correction_ is 3cm on the A3 page
1671
                if (average_correction_ < PRECISION_1E4)
3✔
1672
                        average_correction_ = PRECISION_1E4;
×
1673
                double correction_arrow_scale(arrow_legend_length_/average_correction_);
3✔
1674
                UINT32 correction_legend_precision(4);
3✔
1675

1676
                //if (average_correction_ >= 1.0)
1677
                //        correction_legend_precision = 0;
1678
                /*else*/ if (average_correction_ >= 0.1)
3✔
1679
                        correction_legend_precision = 1;
1680
                else if (average_correction_ >= 0.01)
3✔
1681
                        correction_legend_precision = 2;
1682
                else if (average_correction_ >= 0.001)
×
1683
                        correction_legend_precision = 3;
1684
                else
1685
                        correction_legend_precision = 4;
×
1686

1687

1688
                // print text in black (no arrows)
1689
                if (pprj_->p._plot_correction_labels)
3✔
1690
                        gmtbat_file_ << _APP_PSVELO_ << " -R -J \"" << v_stn_cor_file_.at(block) << 
6✔
1691
                                "\" -Se0.0001/0.95+f" << std::setprecision(0) << pprj_->p._label_font_size << 
6✔
1692
                                "p,Helvetica,black -L -A0.0001/0.0001/0.0001c -O -K >> " << psTempFile << std::endl;
3✔
1693

1694
                // print arrows (without black outline!)
1695
                gmtbat_file_ << _APP_PSVELO_ << " -R -J \"" << v_stn_cor_file_.at(block) << 
6✔
1696
                        "\" -Se" << correction_arrow_scale << "/0.95/0c -L -A" << line_width_ / 2.0 * CM_TO_INCH << 
6✔
1697
                        "/0.5/0.1c -G#DA5552 -W0.0p,#DA5552 -O -K >> " << psTempFile << std::endl;
3✔
1698

1699
                // Add text below the corrections arrow legend 
1700
                gmtbat_file_ << _ECHO_CMD_ <<
3✔
1701
                        std::setprecision(precision) << std::fixed << std::left << arrow_legend_long_ << " " << 
3✔
1702
                        std::setprecision(precision) << std::fixed << std::left << arrow_legend_lat_ << " " << 
3✔
1703
                        std::setprecision(correction_legend_precision) <<                        // the label
3✔
1704
                        std::fixed << average_correction_ / pprj_->p._correction_scale <<        " \\(m\\)" <<                                // ''
3✔
1705
                        " | ";                                                                                                        // Push to pstext
3✔
1706
                gmtbat_file_ << 
3✔
1707
                        _APP_PSTEXT_ << " -R -J -F+f" << 
3✔
1708
                        std::fixed << std::setprecision(0) << 
3✔
1709
                        pprj_->p._label_font_size * 2.0 << "p,Helvetica" <<                // font size and face
3✔
1710
                        "=~" << pprj_->p._label_font_size/2.0 << "p,white" <<                 // outline (or glow)
3✔
1711
                        "+jRM " <<                                                                                                                // justification
1712
                        "-Dj" << pprj_->p._label_font_size * 2.0 <<                                  // x shift
3✔
1713
                        "p/0p -O -K >> " << psTempFile << std::endl;                                        // y shift
3✔
1714
                
1715
                gmtbat_file_ << _APP_PSXY_ << " -R -J -T -Y-" << 
3✔
1716
                        label_font_size * 1.5 << "p " << 
3✔
1717
                        " -O -K >> " << psTempFile << std::endl;
3✔
1718

1719
                // Add text above for corrections legend 
1720
                gmtbat_file_ << _ECHO_CMD_ <<
3✔
1721
                        std::setprecision(precision) << std::fixed << std::left << arrow_legend_long_ << " " << 
3✔
1722
                        std::setprecision(precision) << std::fixed << std::left << arrow_legend_lat_ << " " << 
3✔
1723
                        "Corrections scale" <<                                                                        // the label
1724
                        " | ";                                                                                                        // Push to pstext
3✔
1725
                gmtbat_file_ << 
3✔
1726
                        _APP_PSTEXT_ << " -R -J -F+f" << 
3✔
1727
                        std::fixed << std::setprecision(0) << 
3✔
1728
                        pprj_->p._label_font_size * 2.0 << "p,Helvetica" <<                // font size and face
3✔
1729
                        "=~" << pprj_->p._label_font_size/2.0 << "p,white" <<                 // outline (or glow)
3✔
1730
                        "+jCM " <<                                                                                                                // justification
1731
                        "-Dj-" << pprj_->p._label_font_size * 2.0 <<                                // x shift
3✔
1732
                        "p/0p -O -K >> " << psTempFile << std::endl;                                        // y shift
3✔
1733
                
1734
                gmtbat_file_ << _APP_PSXY_ << " -R -J -T -Y" << 
3✔
1735
                        label_font_size * 1.5 << "p " << 
3✔
1736
                        " -O -K >> " << psTempFile << std::endl;
3✔
1737
        }
1738

1739
        if (pprj_->p._plot_station_labels)
28✔
1740
        {
1741
                gmtbat_file_ << _APP_PSTEXT_ << " -R -J \"" << v_isl_lbl_file_.at(block) << "\"";
6✔
1742
                
1743
                // print shadow
1744
                gmtbat_file_ << " -F+f" << 
6✔
1745
                        std::fixed << std::setprecision(0) << 
6✔
1746
                        pprj_->p._label_font_size << "p,Helvetica" <<                                // font size and face
6✔
1747
                        "=~" << pprj_->p._label_font_size/3.0 << "p,white" <<                 // outline (or glow)
6✔
1748
                        "+jLM " <<                                                                                                                // justification
1749
                        "-Dj" << pprj_->p._label_font_size +                                                 
6✔
1750
                                sqrt(pprj_->p._label_font_size) <<                                         // x shift
6✔
1751
                        "p/" << pprj_->p._label_font_size/2.0 <<                                        // y shift
6✔
1752
                        "p -O -K >> " << psTempFile << std::endl;
6✔
1753

1754
                if (plotBlocks_)
6✔
1755
                {
1756
                        gmtbat_file_ << _APP_PSTEXT_ << " -R -J \"" << v_jsl_lbl_file_.at(block) << "\"";
6✔
1757
                        
1758
                        // print shadow
1759
                        gmtbat_file_ << " -F+f" << 
6✔
1760
                                std::fixed << std::setprecision(0) << 
6✔
1761
                                pprj_->p._label_font_size << "p,Helvetica" <<                                // font size and face
6✔
1762
                                "=~" << pprj_->p._label_font_size/3.0 << "p,white" <<                 // outline (or glow)
6✔
1763
                                "+jLM " <<                                                                                                                // justification
1764
                                "-Dj" << pprj_->p._label_font_size +                                                 
6✔
1765
                                        sqrt(pprj_->p._label_font_size) <<                                         // x shift
6✔
1766
                                "p/" << pprj_->p._label_font_size/2.0 <<                                        // y shift
6✔
1767
                                "p -O -K >> " << psTempFile << std::endl;
6✔
1768
                }
1769
        }
1770

1771
        // Prepare to terminate a sequence of GMT plotting commands without producing 
1772
        // any plotting output (depending on whether a title block is required)
1773
        gmtbat_file_ << _APP_PSXY_ << " -R -J -T -O";
28✔
1774

1775
        std::string legendCommand1(_LEGEND_CMD_1_), legendCommand2(_LEGEND_CMD_2_);
84✔
1776

1777
#if defined(_WIN32) || defined(__WIN32__)
1778
        // temporary legend files
1779
        legendCommand1.append(legendTempFile);
1780
        legendCommand2.append(legendTempFile);
1781
#endif
1782
        
1783
        // No title block?
1784
        if (pprj_->p._omit_title_block)
28✔
1785
        {
1786
                // Terminate a sequence of GMT plotting commands without producing any plotting output
1787
                gmtbat_file_ << " >> " << psTempFile << std::endl << std::endl;
2✔
1788
        }
1789
        else
1790
        {
1791
                gmtbat_file_ << " -K >> " << psTempFile << std::endl << std::endl;
26✔
1792
                
1793
                // legend
1794
                gmtbat_file_ << _APP_GMTSET_ << " FONT_TITLE 1" << std::endl;
26✔
1795
                gmtbat_file_ << _APP_GMTSET_ << " FONT_ANNOT_PRIMARY " << label_font_size * 1.1 << "p";
26✔
1796

1797
                gmtbat_file_ << std::endl;
26✔
1798

1799
#if defined(__linux) || defined(sun) || defined(__unix__) || defined(__APPLE__)
1800
                gmtbat_file_ << "cat > " << legendTempFile << " << END" << std::endl;
26✔
1801
#endif
1802

1803
                bool isnameaNumber(is_number<std::string>(pprj_->p._title));
26✔
1804

1805
                gmtbat_file_ << _LEGEND_ECHO_ << "G 0.25" << legendCommand1 << std::endl;
26✔
1806
                gmtbat_file_ << _LEGEND_ECHO_ << "N 1" << legendCommand2 << std::endl;
26✔
1807
                gmtbat_file_ << _LEGEND_ECHO_ << "H " << std::fixed << std::setprecision(0) << label_font_size * 2.0 << "p,Helvetica-Bold ";
26✔
1808
                if (isnameaNumber) 
26✔
1809
                        gmtbat_file_ << "'" << pprj_->p._title << "'";
×
1810
                else
1811
                        gmtbat_file_ << pprj_->p._title;
26✔
1812

1813
                if (blockCount_ > 1)
26✔
1814
                        gmtbat_file_ << "  (Block " << block + 1 << " of " << blockCount_ << ") ";
6✔
1815

1816
                if (!pprj_->p._plot_station_centre.empty())
26✔
1817
                        gmtbat_file_ << " centred on " << pprj_->p._plot_station_centre;
1✔
1818

1819
                gmtbat_file_ << legendCommand2 << std::endl;
26✔
1820
                gmtbat_file_ << _LEGEND_ECHO_ << "G 0.25" << legendCommand2 << std::endl;
26✔
1821

1822
                // Print stations legend
1823
                gmtbat_file_ << _LEGEND_ECHO_ << "D 0 1p" << legendCommand2 << std::endl;                // horizontal line
26✔
1824
                gmtbat_file_ << _LEGEND_ECHO_ << "G 0.25" << legendCommand2 << std::endl;                // space        
26✔
1825

1826
                UINT32 station_count(1);                // Simultaneous or ISL
26✔
1827

1828
                if (plotBlocks_)
26✔
1829
                        station_count++;                        // JSL
6✔
1830
                
1831
                if (plotConstraints_)
26✔
1832
                {
1833
                        station_count++;                        // Simultaneous or ISL constraint stations
25✔
1834
                        if (plotBlocks_)
25✔
1835
                                station_count++;                // JSL constraint stations                                
5✔
1836
                }
1837
                
1838
                //if (pprj_->p._plot_correction_arrows)
1839
                //        station_count++;                        // Corrections to station coordinates
1840

1841
                gmtbat_file_ << _LEGEND_ECHO_ << "N " << station_count << legendCommand2 << std::endl;
26✔
1842
                gmtbat_file_ << _LEGEND_ECHO_ << "V 0 1p" << legendCommand2 << std::endl;                // vertical line
26✔
1843
                
1844
                circle_radius_2_ = circle_radius_ * 1.75;
26✔
1845

1846
                // Simultaneous stations or Phased inner stations
1847
                gmtbat_file_ << _LEGEND_ECHO_ <<
26✔
1848
                        "S " << std::fixed << std::setprecision(1) << symbol_offset << " c " << 
26✔
1849
                        circle_radius_2_ << " white " << 
26✔
1850
                        circle_line_width_ * 2 << "p,#235789 " <<
26✔
1851
                        std::fixed << std::setprecision(1) << label_offset;
26✔
1852
                if (plotBlocks_)
26✔
1853
                        gmtbat_file_ << " Free Inner stations ";
6✔
1854
                else 
1855
                        gmtbat_file_ << " Free Stations";
20✔
1856
                gmtbat_file_ << legendCommand2 << std::endl;
26✔
1857

1858
                // Simultaneous stations or Phased inner stations
1859
                if (plotBlocks_)
26✔
1860
                {
1861
                        gmtbat_file_ << _LEGEND_ECHO_ <<
6✔
1862
                                "S " << std::fixed << std::setprecision(1) << symbol_offset << " c " << 
6✔
1863
                                circle_radius_2_ << " white " << 
6✔
1864
                                circle_line_width_ * 2 << "p,#DA5552 " <<
6✔
1865
                                std::fixed << std::setprecision(1) << label_offset <<
6✔
1866
                                " Free Junction stations" << legendCommand2 << std::endl;
6✔
1867
                }
1868

1869
                if (plotConstraints_)
26✔
1870
                {
1871
                        if (plotBlocks_)
25✔
1872
                        {
1873
                                gmtbat_file_ << _LEGEND_ECHO_ <<
5✔
1874
                                        "S " << std::fixed << std::setprecision(1) << symbol_offset << " c " << 
5✔
1875
                                        circle_radius_2_ << " #235789 " << 
5✔
1876
                                        circle_line_width_ * 2 << "p,#235789 " <<
5✔
1877
                                        std::fixed << std::setprecision(1) << label_offset <<
5✔
1878
                                        " Constrained inner stations" << legendCommand2 << std::endl;
5✔
1879
                                gmtbat_file_ << _LEGEND_ECHO_ <<
5✔
1880
                                        "S " << std::fixed << std::setprecision(1) << symbol_offset << " c " << 
5✔
1881
                                        circle_radius_2_ << " #DA5552 " << 
5✔
1882
                                        circle_line_width_ * 2 << "p,#DA5552 " <<
5✔
1883
                                        std::fixed << std::setprecision(1) << label_offset <<
5✔
1884
                                        " Constrained junction stations" << legendCommand2 << std::endl;
5✔
1885
                        }
1886
                        else
1887
                                gmtbat_file_ << _LEGEND_ECHO_ <<
20✔
1888
                                        "S " << std::fixed << std::setprecision(1) << symbol_offset << " c " << 
20✔
1889
                                        circle_radius_2_ << " #235789 " << 
20✔
1890
                                        circle_line_width_ * 2 << "p,#235789 " <<
20✔
1891
                                        std::fixed << std::setprecision(1) << label_offset <<
20✔
1892
                                        " Constraint stations" << legendCommand2 << std::endl;
20✔
1893
                }                        
1894
                
1895
                title_block_height_ = 5;
26✔
1896

1897
                if (pprj_->p._plot_correction_arrows)
26✔
1898
                {
1899
                //        // Add corrections to end of stations legend
1900
                //        gmtbat_file_ << _LEGEND_ECHO_ <<
1901
                //                "S " << std::fixed << std::setprecision(1) << symbol_offset << 
1902
                //                " v 1.5c/0.04/0.5/0.1 red " <<                        // arrowlength/linewidth/arrowheadwidth/arrowheadlength
1903
                //                line_width * 2 << "p,#DA5552 " 
1904
                //                << std::fixed << std::setprecision(1) << label_offset * 1.5 << " Corrections to stations" << legendCommand2 << std::endl;
1905
                }
1906
                // If corrections are not being printed, then print measurements legend
1907
                else
1908
                {
1909
                        gmtbat_file_ << _LEGEND_ECHO_ << "G 0.25" << legendCommand2 << std::endl;                // space
23✔
1910
                        gmtbat_file_ << _LEGEND_ECHO_ << "D 0 1p" << legendCommand2 << std::endl;                // horizontal line
23✔
1911
                        gmtbat_file_ << _LEGEND_ECHO_ << "G 0.25" << legendCommand2 << std::endl;                // space        
23✔
1912

1913
                        if (v_msr_file_.at(block).size() > columns)
23✔
1914
                                gmtbat_file_ << _LEGEND_ECHO_ << "N " << columns << legendCommand2 << std::endl;
21✔
1915
                        else
1916
                                gmtbat_file_ << _LEGEND_ECHO_ << "N " << v_msr_file_.at(block).size() << legendCommand2 << std::endl;
2✔
1917

1918
                        bool bOtherTypes(false);
1919
                        
1920
                        for (UINT32 i=0; i<v_msr_file_.at(block).size(); i++)
407✔
1921
                        {
1922
                                _it_colour = equal_range(pprj_->p._msr_colours.begin(), pprj_->p._msr_colours.end(), 
384✔
1923
                                        v_msr_file_.at(block).at(i).second, ComparePairFirst<std::string>());
384✔
1924

1925
                                if (_it_colour.first != _it_colour.second)
384✔
1926
                                {
1927
                                        gmtbat_file_ << _LEGEND_ECHO_ << "S " << std::fixed << std::setprecision(1) << symbol_offset;
383✔
1928

1929
                                        circle_radius_2_ = circle_radius_ * 1.75;
383✔
1930

1931
                                        // print a circle or line?
1932
                                        if (v_msr_file_.at(block).at(i).second == "I" ||                        // astronomic latitude
383✔
1933
                                                v_msr_file_.at(block).at(i).second == "P" ||                        //   geodetic latitude
366✔
1934
                                                v_msr_file_.at(block).at(i).second == "J" ||                        // astronomic longitude
349✔
1935
                                                v_msr_file_.at(block).at(i).second == "Q" ||                        //   geodetic longitude
332✔
1936
                                                v_msr_file_.at(block).at(i).second == "H" ||                        // orthometric height
315✔
1937
                                                v_msr_file_.at(block).at(i).second == "R" ||                        // ellipsoidal height
677✔
1938
                                                v_msr_file_.at(block).at(i).second == "Y")                                // GPS point cluster
277✔
1939
                                                gmtbat_file_ << " c " << circle_radius_2_ << " " <<
127✔
1940
                                                                _it_colour.first->second << " " << 
127✔
1941
                                                                circle_line_width_ * 2;                                                                // circle
127✔
1942
                                        else
1943
                                                gmtbat_file_ << " - " << line_width_ * 3 << " " << 
256✔
1944
                                                _it_colour.first->second <<        " " << line_width_ * 7.5;        // line
256✔
1945

1946
                                        gmtbat_file_ << "p,";
383✔
1947

1948
                                        if (v_msr_file_.at(block).at(i).second == "Y")
383✔
1949
                                                gmtbat_file_ << "#235789";                                                        // bdazzled blue
21✔
1950
                                        else if (v_msr_file_.at(block).at(i).second == "I" ||                // astronomic latitude
362✔
1951
                                                v_msr_file_.at(block).at(i).second == "P")                                // geodetic latitude
345✔
1952
                                                gmtbat_file_ << "#A393BF";                                                        // glossy grape
34✔
1953
                                        else if (v_msr_file_.at(block).at(i).second == "J" ||                // astronomic longitude
328✔
1954
                                                v_msr_file_.at(block).at(i).second == "Q")                                // geodetic longitude
311✔
1955
                                                gmtbat_file_ << "#4C1C00";                                                        // seal brown
34✔
1956
                                        else if (v_msr_file_.at(block).at(i).second == "H" ||                // orthometric height
294✔
1957
                                                v_msr_file_.at(block).at(i).second == "R")                                // ellipsoidal height
273✔
1958
                                                gmtbat_file_ << "#6622CC";                                                        // french violet
38✔
1959
                                        else
1960
                                                gmtbat_file_ << _it_colour.first->second;
256✔
1961

1962
                                        gmtbat_file_ << " " << std::fixed << std::setprecision(1) << label_offset << " " << 
383✔
1963
                                                measurement_name<char, std::string>(static_cast<char>(_it_colour.first->first.at(0))) << legendCommand2 << std::endl;
1,149✔
1964
                                }
1965
                                else
1966
                                        bOtherTypes = true;
1967
                        }
1968

1969
                        if (bOtherTypes)
23✔
1970
                                gmtbat_file_ << _LEGEND_ECHO_ <<
1✔
1971
                                        "S " << std::fixed << std::setprecision(1) << symbol_offset << " - 0.5 lightgray " << line_width_ * 2.5 << "p,lightgray " 
1✔
1972
                                        << std::fixed << std::setprecision(1) << label_offset << "  All other types" << legendCommand2 << std::endl;                        
1✔
1973

1974
                        title_block_height_ += floor(((double)colours)/columns) * 0.25;
23✔
1975
                
1976
                }
1977

1978
                gmtbat_file_ << _LEGEND_ECHO_ << "G 0.25" << legendCommand2 << std::endl;                // space
26✔
1979
                gmtbat_file_ << _LEGEND_ECHO_ << "D 0 1p" << legendCommand2 << std::endl;                // horizontal line
26✔
1980
                gmtbat_file_ << _LEGEND_ECHO_ << "G 0.25" << legendCommand2 << std::endl;                // space
26✔
1981
                gmtbat_file_ << _LEGEND_ECHO_ << "N 5" << legendCommand2 << std::endl;
26✔
1982
                gmtbat_file_ << _LEGEND_ECHO_ << "S 0.01 c 0.01 white 1p,white 1 " << pprj_->p._title_block_subname << legendCommand2 << std::endl;
26✔
1983
                gmtbat_file_ << _LEGEND_ECHO_ << "S 0.01 c 0.01 white 1p,white 0 " << pprj_->p._title_block_name << legendCommand2 << std::endl;
26✔
1984
                gmtbat_file_ << _LEGEND_ECHO_ << "S 0.01 c 0.01 white 1p,white 3 " << reference_frame_ << legendCommand2 << std::endl;
26✔
1985
                gmtbat_file_ << _LEGEND_ECHO_ << "S 0.01 c 0.01 white 1p,white 0 " << projectionTypes[pprj_->p._projection] << " projection" << legendCommand2 << std::endl;
26✔
1986
                gmtbat_file_ << _LEGEND_ECHO_ << "S 0.01 c 0.01 white 1p,white 1 Scale 1:" << static_cast<UINT32>(scale_) << " (A3)" << legendCommand2 << std::endl;
26✔
1987

1988
#if defined(__linux) || defined(sun) || defined(__unix__) || defined(__APPLE__)
1989
                gmtbat_file_ << "END" << std::endl << std::endl;
26✔
1990
#endif
1991

1992
                gmtbat_file_ << _APP_PSLEGEND_ << " -R -J -DJTL+w" << std::fixed << std::setprecision(1) << page_width_ << 
26✔
1993
                        "c+jBL+l1.5+o0/1.5c -C0.3/0.3 -O -F+p+gwhite " <<
1994
                        legendTempFile << " -P >> " << psTempFile << std::endl;
26✔
1995

1996
        }
1997

1998

1999
        ////////////////////////////////////////////////
2000
        // conversion to PDF 
2001
        //
2002
        
2003
        gmtbat_file_ << std::endl << _COMMENT_PREFIX_ << "convert ps to pdf" << std::endl;
28✔
2004

2005
        size_t lastindex = v_gmt_pdf_filenames_.at(block).find_last_of("."); 
28✔
2006
        std::string pdf_filename = v_gmt_pdf_filenames_.at(block).substr(0, lastindex);         
56✔
2007
        gmtbat_file_ << _APP_PSCONVERT_ << " -A0.2c+white -Tf -F\"" << pdf_filename << "\" " << psTempFile << std::endl << std::endl;
28✔
2008

2009
        if (pprj_->p._export_png)
28✔
2010
        {
2011
                gmtbat_file_ << std::endl << _COMMENT_PREFIX_ << "convert ps to png" << std::endl;
2✔
2012
                gmtbat_file_ << _APP_PSCONVERT_ << " -A0.2c+white -Tg -F\"" << pdf_filename << "\" " << psTempFile << std::endl << std::endl;
2✔
2013
        }
2014

2015
        ////////////////////////////////////////////////
2016
        
2017
        ////////////////////////////////////////////////
2018
        // clean up legend files
2019
        gmtbat_file_ << _COMMENT_PREFIX_ << "cleanup" << std::endl;
28✔
2020
        gmtbat_file_ << _DELETE_CMD_ << psTempFile;
28✔
2021

2022
        if (!pprj_->p._omit_title_block)
28✔
2023
                gmtbat_file_ << " " << legendTempFile << std::endl;
26✔
2024
        else
2025
                gmtbat_file_ << std::endl;
2✔
2026

2027
        ////////////////////////////////////////////////
2028

2029
        // remove temporary directory for gmt.conf and gmt.history
2030
        gmtbat_file_ << _RMDIR_CMD_ << _ENV_GMT_TMP_DIR_ << std::endl;
28✔
2031

2032
#if defined(__linux) || defined(sun) || defined(__unix__) || defined(__APPLE__)        
2033
        gmtbat_file_ << "unset " << _GMT_TMP_DIR_ << std::endl;
28✔
2034

2035
#endif                
2036

2037
                
2038
        gmtbat_file_ << std::endl;
28✔
2039
                
2040
        //////////////////////////////////////////////////////////////////////////////////////////
2041
        // delete data files
2042
        if (!pprj_->p._keep_gen_files)
28✔
2043
        {
2044
                gmtbat_file_ << _DELETE_CMD_;
28✔
2045

2046
                // stations
2047
                gmtbat_file_ << 
28✔
2048
                        " \"" << v_isl_pts_file_.at(block) << "\"" <<
28✔
2049
                        " \"" << v_isl_const_file_.at(block) << "\"";
56✔
2050

2051
                if (plotBlocks_)
28✔
2052
                {
2053
                        // junction stations5
2054
                        gmtbat_file_ << 
6✔
2055
                                " \"" << v_jsl_const_file_.at(block) << "\"" <<
6✔
2056
                                " \"" << v_jsl_pts_file_.at(block) << "\"";
12✔
2057
                }
2058

2059
                // measurements
2060
                for (UINT32 i=0; i<v_msr_file_.at(block).size(); i++)
465✔
2061
                        gmtbat_file_ << " \"" << v_msr_file_.at(block).at(i).first << "\"";
437✔
2062
        
2063
                // station labels
2064
                if (pprj_->p._plot_station_labels)
28✔
2065
                {
2066
                        gmtbat_file_ << " \"" << v_isl_lbl_file_.at(block) << "\"";
6✔
2067
                
2068
                        if (plotBlocks_)
6✔
2069
                                gmtbat_file_ << " \"" << v_jsl_lbl_file_.at(block) << "\"";
6✔
2070
                }
2071

2072
                if (pprj_->p._plot_positional_uncertainty)
28✔
2073
                        gmtbat_file_ << " \"" << v_stn_apu_file_.at(block) << "\"";
3✔
2074

2075
                if (pprj_->p._plot_error_ellipses)
28✔
2076
                        gmtbat_file_ << " \"" << v_stn_err_file_.at(block) << "\"";
3✔
2077

2078
                if (pprj_->p._plot_correction_arrows)
28✔
2079
                        gmtbat_file_ << " \"" << v_stn_cor_file_.at(block) << "\"";
3✔
2080

2081
                if (pprj_->p._plot_plate_boundaries)
28✔
2082
                        gmtbat_file_ << " \"" << v_tectonic_plate_file_.at(block) << "\"";
2✔
2083

2084
                gmtbat_file_ << std::endl;
28✔
2085
        }
2086
        else
NEW
2087
                gmtbat_file_ << std::endl;
×
2088
        //////////////////////////////////////////////////////////////////////////////////////////
2089

2090
        gmtbat_file_ << std::endl;
28✔
2091

2092
}
84✔
2093

2094
void dna_plot::CreateGMTPlotEnvironment(project_settings* pprj)
27✔
2095
{
2096
        // Set up the environment
2097
        pprj_ = pprj;
27✔
2098

2099
        InitialiseGMTParameters();
27✔
2100

2101
        InitialiseGMTFilenames();
27✔
2102
        CreateGMTInputFiles();
27✔
2103

2104
        FinaliseGMTParameters();
27✔
2105

2106
        // for 1..n blocks, create a shell script that generates a PDF for 
2107
        // a single block.  dnaplotwrapper can then execute each shell
2108
        // script in parallel.
2109
        CreateGMTCommandFiles();
25✔
2110
        
2111
        // Now, based on font size determined by CreateGMTCommandFiles,
2112
        // Print:
2113
        //  - stations labels, 
2114
        //  - positional uncertainty, 
2115
        //  - error ellipses, and 
2116
        //  - correction arrows
2117
        CreateExtraInputFiles();
25✔
2118
}
24✔
2119

2120
void dna_plot::InvokeGMT()
24✔
2121
{
2122
        // set up a thread group to execute the GMT scripts in parallel
2123
        boost::thread_group gmt_plot_threads;
24✔
2124
        
2125
        for (UINT32 plot=0; plot<v_gmt_cmd_filenames_.size(); ++plot)
51✔
2126
        {
2127
                gmt_plot_threads.create_thread(dna_create_threaded_process(v_gmt_cmd_filenames_.at(plot)));
54✔
2128
        }
2129

2130
        // go!
2131
        gmt_plot_threads.join_all();
24✔
2132
}
24✔
2133

2134
// Aggregare individual PDFs created for each block (for
2135
// phased adjustments only).
2136
void dna_plot::AggregateGMTPDFs()
24✔
2137
{
2138
        if (!plotBlocks_)
24✔
2139
                return;
21✔
2140

2141
        std::string system_file_cmd;
3✔
2142
        std::stringstream ss;
3✔
2143

2144
        ss << _PDF_AGGREGATE_;
3✔
2145

2146
        for_each(v_gmt_pdf_filenames_.begin(), v_gmt_pdf_filenames_.end(),
3✔
2147
                [&ss](const std::string& gmt_pdf_file) {
6✔
2148
                        ss << " " << gmt_pdf_file;
6✔
2149
                });
6✔
2150

2151
#if defined(_WIN32) || defined(__WIN32__)
2152
        // assumes pdftk is used.  add extra options
2153
        ss << " cat output " << pprj_->p._pdf_file_name << " dont_ask";
2154
#elif defined(__linux) || defined(sun) || defined(__unix__) || defined(__APPLE__)
2155
        // assumes pdfunite is used (nothing to do here)
2156
        ss << " " << pprj_->p._pdf_file_name;
3✔
2157
#endif
2158

2159
        // aggregate!
2160
        system_file_cmd = ss.str();
3✔
2161

2162
        std::system(system_file_cmd.c_str());
3✔
2163
}
6✔
2164

2165

2166
void dna_plot::CreateGMTPlot()
24✔
2167
{        
2168
        // Execute GMT in parallel
2169
        InvokeGMT();
24✔
2170

2171
        // Combine all multi-page PDFs in one
2172
        AggregateGMTPDFs();
24✔
2173

2174
        // clean up config and PDF files
2175
        CleanupGMTFiles();
24✔
2176
}
24✔
2177

2178
void dna_plot::CleanupGMTFiles()
24✔
2179
{
2180
        if (pprj_->p._keep_gen_files)
24✔
2181
                return;
×
2182
        
2183
        std::stringstream ss;
24✔
2184
        ss << _DELETE_CMD_;
24✔
2185

2186
        // shell scripts
2187
        for_each(v_gmt_cmd_filenames_.begin(), v_gmt_cmd_filenames_.end(),
24✔
2188
                [&ss](const std::string& gmt_cmd_file) {
27✔
2189
                        ss << " \"" << gmt_cmd_file << "\"";
27✔
2190
                });
27✔
2191

2192
        if (plotBlocks_)
24✔
2193
        {
2194
                // PDF files for each block (except simultaneous)
2195
                for_each(v_gmt_pdf_filenames_.begin(), v_gmt_pdf_filenames_.end(),
3✔
2196
                        [&ss](const std::string& gmt_pdf_file) {
6✔
2197
                                ss << " \"" << gmt_pdf_file << "\"";
6✔
2198
                        });
6✔
2199
        }
2200

2201
        // delete
2202
        std::string clean_up_gmt_config_files = ss.str();
24✔
2203
        std::system(clean_up_gmt_config_files.c_str());
24✔
2204

2205
}
24✔
2206
        
2207

2208
void dna_plot::DetermineBoundingBox()
6✔
2209
{
2210
        if (pprj_->p._bounding_box.empty())
6✔
2211
                return;
2212
        
2213
        if (GetFields(const_cast<char*>(pprj_->p._bounding_box.c_str()), ',', false, "ffff", 
6✔
2214
                &upperDeg_, &leftDeg_, &lowerDeg_, &rightDeg_ ) < 4)
2215
                return;
2216
        
2217
        upperDeg_ = DmstoDeg(upperDeg_);
6✔
2218
        rightDeg_ = DmstoDeg(rightDeg_);
6✔
2219
        lowerDeg_ = DmstoDeg(lowerDeg_);
6✔
2220
        leftDeg_ = DmstoDeg(leftDeg_);
6✔
2221

2222
        pprj_->p._plot_centre_longitude = (rightDeg_ + leftDeg_) / 2.0;
6✔
2223
        pprj_->p._plot_centre_latitude = (upperDeg_ + lowerDeg_) / 2.0;
6✔
2224

2225
        default_limits_ = false;
6✔
2226
}
2227
        
2228

2229
void dna_plot::CalculateLimitsFromStation()
1✔
2230
{
2231
        it_pair_string_vUINT32 _it_stnmap;
1✔
2232
        _it_stnmap = equal_range(stnsMap_.begin(), stnsMap_.end(), pprj_->p._plot_station_centre, StationNameIDCompareName());
1✔
2233

2234
        if (_it_stnmap.first == _it_stnmap.second)
1✔
2235
        {
NEW
2236
                std::stringstream ss;
×
2237
                ss.str("");
×
2238
                ss << pprj_->p._plot_station_centre << " is not in the list of network stations.";
×
2239
                SignalExceptionPlot(ss.str(), 0, NULL);
×
2240
        }
×
2241

2242
        pprj_->p._plot_centre_latitude = bstBinaryRecords_.at(_it_stnmap.first->second).initialLatitude;
1✔
2243
        pprj_->p._plot_centre_longitude = bstBinaryRecords_.at(_it_stnmap.first->second).initialLongitude;
1✔
2244
        
2245
        CalculateLimitsFromPoint();
1✔
2246
}
1✔
2247
        
2248

2249
void dna_plot::CalculateLimitsFromPoint()
5✔
2250
{        
2251
        double temp;
5✔
2252
        
2253
        CDnaEllipsoid e(DEFAULT_EPSG_U);
5✔
2254

2255
        VincentyDirect<double>(Radians<double>(pprj_->p._plot_centre_latitude), Radians<double>(pprj_->p._plot_centre_longitude),
10✔
2256
                Radians<double>(0.), pprj_->p._plot_area_radius, &upperDeg_, &temp, &e);
5✔
2257
        upperDeg_ = Degrees(upperDeg_);
5✔
2258
        
2259
        VincentyDirect<double>(Radians<double>(pprj_->p._plot_centre_latitude), Radians<double>(pprj_->p._plot_centre_longitude),
10✔
2260
                Radians<double>(90.), pprj_->p._plot_area_radius, &temp, &rightDeg_, &e);
5✔
2261
        rightDeg_ = Degrees(rightDeg_);
5✔
2262
        
2263
        VincentyDirect<double>(Radians<double>(pprj_->p._plot_centre_latitude), Radians<double>(pprj_->p._plot_centre_longitude), 
10✔
2264
                Radians<double>(180.), pprj_->p._plot_area_radius, &lowerDeg_, &temp, &e);
5✔
2265
        lowerDeg_ = Degrees(lowerDeg_);
5✔
2266
        
2267
        VincentyDirect<double>(Radians<double>(pprj_->p._plot_centre_latitude), Radians<double>(pprj_->p._plot_centre_longitude),
10✔
2268
                Radians<double>(270.), pprj_->p._plot_area_radius, &temp, &leftDeg_, &e);
5✔
2269
        leftDeg_ = Degrees(leftDeg_);
5✔
2270
}
5✔
2271
        
2272

2273
void dna_plot::FormGMTDataFileNames(const UINT32& block)
30✔
2274
{
2275
        std::string firstPartISL = pprj_->g.output_folder + FOLDER_SLASH + network_name_;
30✔
2276
        std::string firstPartSTN = pprj_->g.output_folder + FOLDER_SLASH + network_name_;
30✔
2277

2278
        firstPartSTN.append("_stn");
30✔
2279

2280
        if (plotBlocks_)
30✔
2281
        {
2282
                std::stringstream firstPart;
6✔
2283
                std::string firstPartJSL;
6✔
2284
                
2285
                // add isl and jsl filenames for this block
2286
                firstPart << firstPartSTN << "_block" << block + 1;
6✔
2287
                firstPartISL = firstPart.str() + "_isl";
18✔
2288
                firstPartJSL = firstPart.str() + "_jsl";
18✔
2289
                firstPartSTN = firstPart.str();
6✔
2290

2291
                v_jsl_pts_file_.push_back(firstPartJSL + ".stn.d");
12✔
2292
                v_jsl_const_file_.push_back(firstPartJSL + ".const.d");
12✔
2293

2294
                if (pprj_->p._plot_station_labels)
6✔
2295
                        v_jsl_lbl_file_.push_back(firstPartJSL + ".stn.lbl");
18✔
2296
        }
6✔
2297

2298
        v_isl_pts_file_.push_back(firstPartISL + ".stn.d");
60✔
2299
        v_isl_const_file_.push_back(firstPartISL + ".const.d");
60✔
2300
        
2301
        if (pprj_->p._plot_station_labels)
30✔
2302
                v_isl_lbl_file_.push_back(firstPartISL + ".stn.lbl");
18✔
2303

2304
        if (pprj_->p._plot_positional_uncertainty)
30✔
2305
                v_stn_apu_file_.push_back(firstPartSTN + ".apu.d");
9✔
2306
        
2307
        if (pprj_->p._plot_error_ellipses)
30✔
2308
                v_stn_err_file_.push_back(firstPartSTN + ".err.d");
9✔
2309
        
2310
        if (pprj_->p._plot_correction_arrows)
30✔
2311
                v_stn_cor_file_.push_back(firstPartSTN + ".cor.d");
9✔
2312

2313
        if (pprj_->p._plot_plate_boundaries)
30✔
2314
                v_tectonic_plate_file_.push_back(firstPartSTN + ".plt.d");
6✔
2315
}
60✔
2316

2317
void dna_plot::PrintStationsDataFileBlock(const UINT32& block)
6✔
2318
{
2319
        // Form file names for this block
2320
        FormGMTDataFileNames(block);
6✔
2321
        
2322
        std::ofstream isl_pts, isl_const, jsl_pts, jsl_const;
6✔
2323

2324
        UINT32 block_index(block);
6✔
2325
        if (plotBlocks_ && pprj_->p._plot_block_number > 0)
6✔
2326
                block_index = 0;        // one and only block
1✔
2327

2328
        try {
6✔
2329
                // Create stations data files for ISL/JSL.  Throws runtime_error on failure.
2330
                file_opener(isl_pts, v_isl_pts_file_.at(block_index));
6✔
2331
                file_opener(jsl_pts, v_jsl_pts_file_.at(block_index));
6✔
2332
                // Create constraint stations data files for ISL/JSL.  Throws runtime_error on failure.
2333
                file_opener(isl_const, v_isl_const_file_.at(block_index));
6✔
2334
                file_opener(jsl_const, v_jsl_const_file_.at(block_index));
6✔
2335
        }
NEW
2336
        catch (const std::runtime_error& e) {
×
2337
                SignalExceptionPlot(e.what(), 0, NULL);
×
2338
        }
×
2339

2340
        // print isl coordinates
2341
        it_vstn_t_const _it_stn;
6✔
2342
        for (it_vUINT32 _it_isl=v_ISL_.at(block).begin();
305✔
2343
                _it_isl<v_ISL_.at(block).end(); 
305✔
2344
                ++_it_isl)
299✔
2345
        {
2346
                // Advance iterator
2347
                _it_stn = bstBinaryRecords_.begin() + *_it_isl;
299✔
2348

2349
                // Constrained?
2350
                if (_it_stn->stationConst[0] == 'C' || 
592✔
2351
                        _it_stn->stationConst[1] == 'C' || 
299✔
2352
                        _it_stn->stationConst[2] == 'C')
293✔
2353
                {
2354
                        // Constrained
2355
                        plotConstraints_ = true;
8✔
2356
                        PrintStationDataFile(isl_const, _it_stn);
8✔
2357
                }
2358
                else
2359
                        // Free
2360
                        PrintStationDataFile(isl_pts, _it_stn);
291✔
2361
        }
2362

2363
        isl_pts.close();
6✔
2364
        isl_const.close();
6✔
2365

2366
        // print jsl coordinates
2367
        it_vUINT32 _it_jsl(v_JSL_.at(block).begin());
6✔
2368
        for (it_vUINT32 _it_jsl=v_JSL_.at(block).begin();
29✔
2369
                _it_jsl<v_JSL_.at(block).end(); 
29✔
2370
                ++_it_jsl)
23✔
2371
        {
2372
                // Advance iterator
2373
                _it_stn = bstBinaryRecords_.begin() + *_it_jsl;
23✔
2374

2375
                // Constrained?
2376
                if (_it_stn->stationConst[0] == 'C' || 
46✔
2377
                        _it_stn->stationConst[1] == 'C' || 
23✔
2378
                        _it_stn->stationConst[2] == 'C')
23✔
2379
                {
2380
                        // Constrained
2381
                        plotConstraints_ = true;
1✔
2382
                        PrintStationDataFile(jsl_const, _it_stn);
1✔
2383
                }
2384
                else
2385
                        // Free
2386
                        PrintStationDataFile(jsl_pts, _it_stn);
22✔
2387
        }
2388

2389
        jsl_pts.close();
6✔
2390
        jsl_const.close();
6✔
2391
}
6✔
2392
        
2393
void dna_plot::PrintStationsDataFile()
24✔
2394
{
2395
        // Form file names
2396
        FormGMTDataFileNames();
24✔
2397
        
2398
        std::ofstream stn_pts, stn_const;
24✔
2399
        try {
24✔
2400
                // Create stations data file.  Throws runtime_error on failure.
2401
                file_opener(stn_pts, v_isl_pts_file_.at(0));
24✔
2402
                // Create constraint stations data file.  Throws runtime_error on failure.
2403
                file_opener(stn_const, v_isl_const_file_.at(0));
24✔
2404
        }
NEW
2405
        catch (const std::runtime_error& e) {
×
2406
                SignalExceptionPlot(e.what(), 0, NULL);
×
2407
        }
×
2408

2409
        std::stringstream ss;
24✔
2410

2411
        for (it_vstn_t_const _it_stn(bstBinaryRecords_.begin());
5,684✔
2412
                _it_stn<bstBinaryRecords_.end(); 
5,684✔
2413
                ++_it_stn)
5,660✔
2414
        {
2415
                // Unused Station - don't print.
2416
                if (_it_stn->unusedStation == 1)
5,660✔
2417
                        continue;
×
2418

2419
                // Constrained?
2420
                if (_it_stn->stationConst[0] == 'C' || 
11,235✔
2421
                        _it_stn->stationConst[1] == 'C' || 
5,660✔
2422
                        _it_stn->stationConst[2] == 'C')
5,575✔
2423
                {
2424
                        // Constrained
2425
                        plotConstraints_ = true;
106✔
2426
                        PrintStationDataFile(stn_const, _it_stn);
106✔
2427
                }
2428
                else
2429
                        // Free
2430
                        PrintStationDataFile(stn_pts, _it_stn);
5,554✔
2431
        }
2432

2433
        stn_pts.close();
24✔
2434
        stn_const.close();
24✔
2435

2436
        if (!default_limits_)
24✔
2437
        {
2438
                if (!pprj_->p._bounding_box.empty())
11✔
2439
                        DetermineBoundingBox();
6✔
2440
                else if (pprj_->p._plot_station_centre.empty())
5✔
2441
                        CalculateLimitsFromPoint();
4✔
2442
                else
2443
                        CalculateLimitsFromStation();
1✔
2444
        }
2445
}
24✔
2446
        
2447

2448
void dna_plot::PrintStationDataFile(std::ostream& os, it_vstn_t_const _it_stn)
5,982✔
2449
{
2450
        if (default_limits_) 
5,982✔
2451
        {
2452
                if (_it_stn->initialLatitude < lowerDeg_) 
3,164✔
2453
                        lowerDeg_ = _it_stn->initialLatitude;
62✔
2454
                if (_it_stn->initialLatitude > upperDeg_)
3,164✔
2455
                        upperDeg_ = _it_stn->initialLatitude;
264✔
2456
                if (_it_stn->initialLongitude < leftDeg_) 
3,164✔
2457
                        leftDeg_ = _it_stn->initialLongitude;
223✔
2458
                if (_it_stn->initialLongitude > rightDeg_) 
3,164✔
2459
                        rightDeg_ = _it_stn->initialLongitude;
239✔
2460
        }
2461

2462
        // print longitude and latitude
2463
        os << std::setprecision(10) << std::fixed << _it_stn->initialLongitude << "  " <<
5,982✔
2464
                _it_stn->initialLatitude << std::endl;
5,982✔
2465
}
5,982✔
2466

2467
void dna_plot::PrintStationLabel(std::ostream& os, it_vstn_t_const _it_stn)
467✔
2468
{
2469
        if (_it_stn->unusedStation)
467✔
2470
                return;
×
2471

2472
        // Print longitude, latitude and label
2473
        os << std::setprecision(10) << std::fixed << 
467✔
2474
                _it_stn->initialLongitude << "  " <<                        // E/W
467✔
2475
                _it_stn->initialLatitude << "   ";                                // N/S
467✔
2476

2477
        // Print the label, default is station name (i.e. 200100350)
2478
        std::string label(_it_stn->stationName);
467✔
2479
        
2480
        // plot alternate name?
2481
        if (pprj_->p._plot_alt_name)
467✔
2482
        {
2483
                label = _it_stn->description;                // description (i.e. Acheron PM 35)
148✔
2484
                if (trimstr(label).empty())
296✔
2485
                        label = "_";
×
2486
        }
2487
        os << label;                        
467✔
2488

2489
        // Plot constraints?
2490
        if (pprj_->p._plot_station_constraints)
467✔
2491
                if (_it_stn->stationConst[0] == 'C' || 
293✔
2492
                        _it_stn->stationConst[1] == 'C' || 
148✔
2493
                        _it_stn->stationConst[2] == 'C')
145✔
2494
                                os << " (" << _it_stn->stationConst << ")";
4✔
2495
        os << std::endl;
467✔
2496
}
467✔
2497

2498
void dna_plot::PrintStationLabels()
×
2499
{
2500
        std::ofstream stn_lbl;
×
2501
        try {
×
2502
                // Create stations data file.  Throws runtime_error on failure.
2503
                file_opener(stn_lbl, v_isl_lbl_file_.at(0));
×
2504
        }
NEW
2505
        catch (const std::runtime_error& e) {
×
2506
                SignalExceptionPlot(e.what(), 0, NULL);
×
2507
        }
×
2508

2509
        // initialise a station list and sort on longitude
2510
        vUINT32 stnList(bstBinaryRecords_.size());
×
2511
        it_vUINT32 _it_stn(stnList.begin());
×
2512

2513
        // initialise vector with 0,1,2,...,n-2,n-1,n
2514
        initialiseIncrementingIntegerVector<UINT32>(stnList, static_cast<UINT32>(bstBinaryRecords_.size()));
×
2515

2516
        // sort stations on longitude so labels to the left are placed last
2517
        CompareStnLongitude<station_t, UINT32> stnorderCompareFunc(&bstBinaryRecords_, false);
×
NEW
2518
        std::sort(stnList.begin(), stnList.end(), stnorderCompareFunc);
×
2519

2520
        it_vstn_t _it_bstn;
×
2521

2522
        for (_it_stn=stnList.begin(); _it_stn<stnList.end(); _it_stn++)
×
2523
        {
2524
                _it_bstn = bstBinaryRecords_.begin() + *_it_stn;
×
2525
                
2526
                // print the label
2527
                PrintStationLabel(stn_lbl, _it_bstn);
×
2528
        }
2529

2530
        stn_lbl.close();
×
2531
}
×
2532
        
2533

2534
void dna_plot::PrintStationLabelsBlock(const UINT32& block)
6✔
2535
{        
2536
        UINT32 block_index(block);
6✔
2537
        if (plotBlocks_ && pprj_->p._plot_block_number > 0)
6✔
2538
                block_index = 0;
1✔
2539
        
2540
        std::ofstream isl_lbl;
6✔
2541
        try {
6✔
2542
                // Create stations data file.  Throws runtime_error on failure.
2543
                file_opener(isl_lbl, v_isl_lbl_file_.at(block_index));
6✔
2544
        }
NEW
2545
        catch (const std::runtime_error& e) {
×
2546
                SignalExceptionPlot(e.what(), 0, NULL);
×
2547
        }
×
2548

2549
        // sort ISLs on longitude so labels to the left are placed last
2550
        CompareStnLongitude<station_t, UINT32> stnorderCompareFunc(&bstBinaryRecords_, false);
6✔
2551
        std::sort(v_ISL_.at(block).begin(), v_ISL_.at(block).end(), stnorderCompareFunc);
6✔
2552

2553
        it_vstn_t _it_bstn;
6✔
2554

2555
        for (it_vUINT32 _it_isl(v_ISL_.at(block).begin());
6✔
2556
                _it_isl<v_ISL_.at(block).end(); 
452✔
2557
                ++_it_isl)
446✔
2558
        {
2559
                _it_bstn = bstBinaryRecords_.begin() + *_it_isl;
446✔
2560
                
2561
                // print the label
2562
                PrintStationLabel(isl_lbl, _it_bstn);
446✔
2563
        }
2564

2565
        isl_lbl.close();
6✔
2566
        
2567
        // return to former sort order
2568
        std::sort(v_ISL_.at(block).begin(), v_ISL_.at(block).end());
6✔
2569

2570

2571
        std::ofstream jsl_lbl;
6✔
2572
        try {
6✔
2573
                // Create stations data file.  Throws runtime_error on failure.
2574
                file_opener(jsl_lbl, v_jsl_lbl_file_.at(block_index));
6✔
2575
        }
NEW
2576
        catch (const std::runtime_error& e) {
×
2577
                SignalExceptionPlot(e.what(), 0, NULL);
×
2578
        }
×
2579

2580
        // sort JSLs on longitude so labels to the left are placed last
2581
        std::sort(v_JSL_.at(block).begin(), v_JSL_.at(block).end(), stnorderCompareFunc);
6✔
2582

2583
        for (it_vUINT32 _it_jsl(v_JSL_.at(block).begin());
6✔
2584
                _it_jsl<v_JSL_.at(block).end(); 
27✔
2585
                ++_it_jsl)
21✔
2586
        {
2587
                _it_bstn = bstBinaryRecords_.begin() + *_it_jsl;
21✔
2588
                
2589
                // print the label
2590
                PrintStationLabel(jsl_lbl, _it_bstn);        
21✔
2591
        }
2592
        
2593
        jsl_lbl.close();
6✔
2594

2595
        // return to former sort order
2596
        std::sort(v_JSL_.at(block).begin(), v_JSL_.at(block).end());
6✔
2597
}
6✔
2598
        
2599

2600
void dna_plot::PrintPositionalUncertainty(const UINT32& block)
3✔
2601
{
2602
        UINT32 block_index(block);
3✔
2603
        if (plotBlocks_ && pprj_->p._plot_block_number > 0)
3✔
2604
                block_index = 0;
1✔
2605
        
2606
        std::ofstream stn_apu;
3✔
2607
        try {
3✔
2608
                // Create apu file.  Throws runtime_error on failure.
2609
                file_opener(stn_apu, v_stn_apu_file_.at(block_index));
3✔
2610
        }
NEW
2611
        catch (const std::runtime_error& e) {
×
2612
                SignalExceptionPlot(e.what(), 0, NULL);
×
2613
        }
×
2614

2615
        it_pair_string_vUINT32 _it_stnmap;
3✔
2616
        it_vstn_t_const _it_stn(bstBinaryRecords_.begin());
3✔
2617
        UINT32 precision(10);
3✔
2618

2619
        it_vstnPU_t _it_pu;
3✔
2620

2621
        // Print uncertainty legend, using average xx length.  See LoadPosUncertaintyFile().
2622
        stn_apu << 
3✔
2623
                std::setw(MSR) << std::setprecision(precision) << std::fixed << std::left << uncertainty_legend_long_ << "  " <<
3✔
2624
                std::setw(MSR) << std::setprecision(precision) << std::fixed << std::left << uncertainty_legend_lat_ << "  " << 
3✔
2625
                " 0 0 " <<
2626
                std::setw(MSR) << std::setprecision(4) << std::scientific << std::right << largest_uncertainty_  <<                 // semi-major
3✔
2627
                std::setw(MSR) << std::setprecision(4) << std::scientific << std::right << largest_uncertainty_ <<                        // semi-minor
3✔
2628
                std::setw(MSR) << std::setprecision(2) << std::fixed << std::right << "45.0" << std::endl;                                                // orientation from e-axis
3✔
2629
        
2630
        for (_it_pu=v_stn_pu_.begin();
3✔
2631
                _it_pu!=v_stn_pu_.end();
456✔
2632
                ++_it_pu)
453✔
2633
        {
2634
                _it_stnmap = equal_range(stnsMap_.begin(), stnsMap_.end(), _it_pu->_station, StationNameIDCompareName());
453✔
2635

2636
                // Not in the list? (Unlikely since adjust output will not contain stations not in the map, but test anyway)
2637
                if (_it_stnmap.first == _it_stnmap.second)
453✔
2638
                        continue;
6✔
2639
                
2640
                // no need to plot constrained stations - the uncertainties will be zero!!!        
2641
                // Horizontal only!!!
2642
                if (bstBinaryRecords_.at(_it_stnmap.first->second).stationConst[0] == 'C' &&
447✔
2643
                        bstBinaryRecords_.at(_it_stnmap.first->second).stationConst[1] == 'C')
9✔
2644
                        continue;
6✔
2645

2646
                if (plotBlocks_)
441✔
2647
                        // If this station is not in this block, don't print
2648
                        if (!binary_search(v_parameterStationList_.at(block).begin(), v_parameterStationList_.at(block).end(),
441✔
2649
                                _it_stnmap.first->second))
441✔
2650
                                continue;
146✔
2651

2652
                stn_apu << 
295✔
2653
                        std::setw(MSR) << std::setprecision(precision) << std::fixed << std::left << _it_pu->_longitude << "  " <<
295✔
2654
                        std::setw(MSR) << std::setprecision(precision) << std::fixed << std::left << _it_pu->_latitude << "  " << 
295✔
2655
                        " 0 0 " <<
2656
                        std::setw(MSR) << std::setprecision(4) << std::scientific << std::right << _it_pu->_hzPosU * pprj_->p._pu_ellipse_scale <<
295✔
2657
                        std::setw(MSR) << std::setprecision(4) << std::scientific << std::right << _it_pu->_hzPosU * pprj_->p._pu_ellipse_scale <<
295✔
2658
                        std::setw(MSR) << std::setprecision(1) << std::fixed << std::right << "0." << std::endl;        
453✔
2659
        }
2660
        
2661
        stn_apu.close();
3✔
2662
}
3✔
2663
        
2664

2665
void dna_plot::PrintErrorEllipses(const UINT32& block)
3✔
2666
{        
2667
        UINT32 block_index(block);
3✔
2668
        if (plotBlocks_ && pprj_->p._plot_block_number > 0)
3✔
2669
                block_index = 0;
1✔
2670
        
2671
        std::ofstream stn_err;
3✔
2672
        try {
3✔
2673
                // Create error ellipse file.  Throws runtime_error on failure.
2674
                file_opener(stn_err, v_stn_err_file_.at(block_index));
3✔
2675
        }
NEW
2676
        catch (const std::runtime_error& e) {
×
2677
                SignalExceptionPlot(e.what(), 0, NULL);
×
2678
        }
×
2679

2680
        it_pair_string_vUINT32 _it_stnmap;
3✔
2681
        it_vstn_t_const _it_stn(bstBinaryRecords_.begin());
3✔
2682
        UINT32 precision(10);
3✔
2683

2684
        it_vstnPU_t _it_pu;
3✔
2685

2686
        double ellipse_scale(1.);
3✔
2687

2688
        // The error ellipse legend is printed using the largest uncertainty (semi-major) found, unless
2689
        // positional uncertainty is being printed, in which case the error ellipse is printed using
2690
        // half the size.  This is purely to give the impression that error ellipses are 1 sigma (68%) and
2691
        // positional uncertainty is 95%, or close to 2 sigma.
2692
        if (pprj_->p._plot_positional_uncertainty)
3✔
2693
                ellipse_scale = 2.;
3✔
2694

2695
        // Print uncertainty legend, using average xx length.  See LoadPosUncertaintyFile().
2696
        stn_err << 
3✔
2697
                std::setw(MSR) << std::setprecision(precision) << std::fixed << std::left << uncertainty_legend_long_ << "  " <<
3✔
2698
                std::setw(MSR) << std::setprecision(precision) << std::fixed << std::left << uncertainty_legend_lat_ << "  " << 
3✔
2699
                " 0 0 " <<
2700
                std::setw(MSR) << std::setprecision(4) << std::scientific << std::right << 
3✔
2701
                largest_uncertainty_ / ellipse_scale <<                                         // semi-major
3✔
2702
                std::setw(MSR) << std::setprecision(4) << std::scientific << std::right << 
3✔
2703
                largest_uncertainty_ / 3.0 / ellipse_scale <<                                // semi-minor
3✔
2704
                std::setw(MSR) << std::setprecision(2) << std::fixed << std::right <<
3✔
2705
                "45.0" << std::endl;                                                                                                // orientation from e-axis
3✔
2706
        
2707
        double angle;
3✔
2708

2709
        for (_it_pu=v_stn_pu_.begin();
3✔
2710
                _it_pu!=v_stn_pu_.end();
456✔
2711
                ++_it_pu)
453✔
2712
        {
2713
                _it_stnmap = equal_range(stnsMap_.begin(), stnsMap_.end(), _it_pu->_station, StationNameIDCompareName());
453✔
2714

2715
                // Not in the list? (Unlikely since adjust output will not contain stations not in the map, but test anyway)
2716
                if (_it_stnmap.first == _it_stnmap.second)
453✔
2717
                        continue;
6✔
2718
                
2719
                // no need to plot constrained stations - the uncertainties will be zero!!!        
2720
                // Horizontal only!!!
2721
                if (bstBinaryRecords_.at(_it_stnmap.first->second).stationConst[0] == 'C' &&
447✔
2722
                        bstBinaryRecords_.at(_it_stnmap.first->second).stationConst[1] == 'C')
9✔
2723
                        continue;
6✔
2724

2725
                if (plotBlocks_)
441✔
2726
                        // If this station is not in this block, don't print
2727
                        if (!binary_search(v_parameterStationList_.at(block).begin(), v_parameterStationList_.at(block).end(),
441✔
2728
                                _it_stnmap.first->second))
441✔
2729
                                continue;
146✔
2730

2731
                // reduce error ellipse orientation in terms of
2732
                // positive anti-clockwise direction from e-axis
2733
                if (_it_pu->_orientation > 90.)
295✔
2734
                        angle = -(_it_pu->_orientation - 90.);
189✔
2735
                else
2736
                        angle = DegtoDms(90. - DmstoDeg(_it_pu->_orientation));
106✔
2737

2738
                stn_err << 
295✔
2739
                        std::setw(MSR) << std::setprecision(precision) << std::fixed << std::left << _it_pu->_longitude << "  " <<
295✔
2740
                        std::setw(MSR) << std::setprecision(precision) << std::fixed << std::left << _it_pu->_latitude << "  " << 
295✔
2741
                        " 0 0 " <<
2742
                        std::setw(MSR) << std::setprecision(4) << std::scientific << std::right << _it_pu->_semimMajor * pprj_->p._pu_ellipse_scale <<
295✔
2743
                        std::setw(MSR) << std::setprecision(4) << std::scientific << std::right << _it_pu->_semimMinor * pprj_->p._pu_ellipse_scale <<
295✔
2744
                        std::setw(MSR) << std::setprecision(4) << std::fixed << std::right << angle << std::endl;        
453✔
2745
        }
2746
        
2747
        stn_err.close();
3✔
2748
}
3✔
2749
        
2750

2751
void dna_plot::PrintCorrectionArrows(const UINT32& block)
3✔
2752
{
2753
        UINT32 block_index(block);
3✔
2754
        if (plotBlocks_ && pprj_->p._plot_block_number > 0)
3✔
2755
                block_index = 0;
1✔
2756
        
2757
        std::ofstream stn_cor;
3✔
2758
        try {
3✔
2759
                // Create corrections file.  Throws runtime_error on failure.
2760
                file_opener(stn_cor, v_stn_cor_file_.at(block_index));
3✔
2761
        }
NEW
2762
        catch (const std::runtime_error& e) {
×
2763
                SignalExceptionPlot(e.what(), 0, NULL);
×
2764
        }
×
2765

2766
        it_pair_string_vUINT32 _it_stnmap;
3✔
2767
        it_vstn_t_const _it_stn(bstBinaryRecords_.begin());
3✔
2768
        UINT32 precision(10);
3✔
2769

2770
        it_vstnCor_t _it_cor;
3✔
2771

2772
        // Print correction legend, using average correction length.  See LoadCorrectionsFile().
2773
        stn_cor << 
3✔
2774
                std::setw(MSR) << std::setprecision(precision) << std::fixed << std::left << arrow_legend_long_ << "  " <<
3✔
2775
                std::setw(MSR) << std::setprecision(precision) << std::fixed << std::left << arrow_legend_lat_ << "  " << 
3✔
2776
                std::setw(MSR) << std::setprecision(4) << std::scientific << std::right << average_correction_ <<
3✔
2777
                std::setw(MSR) << std::setprecision(2) << std::fixed << std::right << 0.0 <<
3✔
2778
                " 0 0 0 " << std::endl;
3✔
2779
        
2780
        for (_it_cor=v_stn_corrs_.begin();
3✔
2781
                _it_cor!=v_stn_corrs_.end();
450✔
2782
                ++_it_cor)
447✔
2783
        {
2784
                // Find the id of this station
2785
                _it_stnmap = equal_range(stnsMap_.begin(), stnsMap_.end(), _it_cor->_station, StationNameIDCompareName());
447✔
2786

2787
                // Not in the list? (Unlikely since adjust will not output stations that are not 
2788
                // in the map, but test anyway)
2789
                if (_it_stnmap.first == _it_stnmap.second)
447✔
2790
                        continue;
×
2791
                
2792
                // no need to plot constrained stations - these won't have moved!        
2793
                // Horizontal only!!!
2794
                if (bstBinaryRecords_.at(_it_stnmap.first->second).stationConst[0] == 'C' &&
447✔
2795
                        bstBinaryRecords_.at(_it_stnmap.first->second).stationConst[1] == 'C')
9✔
2796
                        continue;
6✔
2797

2798
                if (plotBlocks_)
441✔
2799
                        // If this station is not in this block, don't print
2800
                        if (!binary_search(v_parameterStationList_.at(block).begin(), v_parameterStationList_.at(block).end(),
441✔
2801
                                _it_stnmap.first->second))
441✔
2802
                                continue;
146✔
2803

2804
                stn_cor << 
295✔
2805
                        std::setw(MSR) << std::setprecision(precision) << std::fixed << std::left << bstBinaryRecords_.at(_it_stnmap.first->second).initialLongitude << "  " <<
295✔
2806
                        std::setw(MSR) << std::setprecision(precision) << std::fixed << std::left << bstBinaryRecords_.at(_it_stnmap.first->second).initialLatitude << "  " << 
295✔
2807
                        std::setw(MSR) << std::setprecision(4) << std::scientific << std::right << _it_cor->_east * pprj_->p._correction_scale <<
295✔
2808
                        std::setw(MSR) << std::setprecision(4) << std::scientific << std::right << _it_cor->_north * pprj_->p._correction_scale <<
295✔
2809
                        " 0 0 0 ";
295✔
2810

2811
                if (pprj_->p._plot_correction_labels)
295✔
2812
                        stn_cor << 
295✔
2813
                                std::setw(HEIGHT) << std::setprecision(3) << std::fixed << std::right << _it_cor->_east << "e," <<
295✔
2814
                                std::setprecision(3) << std::fixed << _it_cor->_north << "n   ";
295✔
2815
                stn_cor << std::endl;        
447✔
2816
        }
2817
        
2818
        stn_cor.close();
3✔
2819
}
3✔
2820
        
2821
void dna_plot::PrintPlateBoundaries(const UINT32& block)
2✔
2822
{
2823
        // Load tectonic plate boundaries file and export
2824
        dna_io_tpb tpb;
2✔
2825

2826
        // Tectonic plate boundaries
2827
        v_string_v_doubledouble_pair global_plates;                                
2✔
2828

2829
        std::stringstream ss;
2✔
2830
        ss << "PrintPlateBoundaries(): An error was encountered when loading tectonic plate information." << std::endl;
2✔
2831

2832
        try {
2✔
2833
                // Load tectonic plate polygons.  Throws runtime_error on failure.
2834
                tpb.load_tpb_file(pprj_->r.tpb_file, global_plates);
2✔
2835
                std::sort(global_plates.begin(), global_plates.end());
1✔
2836
        }
2837
        catch (const std::runtime_error& e) {
1✔
2838
                ss << e.what();
1✔
2839
                throw boost::enable_current_exception(std::runtime_error(ss.str()));
3✔
2840
        }
1✔
2841

2842
        UINT32 block_index(block);
1✔
2843
        if (plotBlocks_ && pprj_->p._plot_block_number > 0)
1✔
2844
                block_index = 0;
×
2845
        
2846
        std::ofstream tectonic_plate;
1✔
2847
        try {
1✔
2848
                // Create corrections file.  Throws runtime_error on failure.
2849
                file_opener(tectonic_plate, v_tectonic_plate_file_.at(block_index));
1✔
2850
        }
NEW
2851
        catch (const std::runtime_error& e) {
×
2852
                SignalExceptionPlot(e.what(), 0, NULL);
×
2853
        }
×
2854

2855
        for_each(global_plates.begin(), global_plates.end(),
1✔
2856
                [&tectonic_plate](const string_v_doubledouble_pair& plate){
56✔
2857
                        tectonic_plate << ">" << std::endl;
56✔
2858

2859
                        for_each(plate.second.begin(), plate.second.end(),
56✔
2860
                        [&tectonic_plate](const doubledouble_pair& coordinate){
12,321✔
2861
                                tectonic_plate << std::fixed << std::setprecision(3) <<
12,321✔
2862
                                        std::setw(10) << std::right << coordinate.first << "," <<
12,321✔
2863
                                        std::setw(10) << std::right << coordinate.second << std::endl;
12,321✔
2864
                        });
12,321✔
2865
                });        
56✔
2866

2867
        tectonic_plate.close();
1✔
2868
}
3✔
2869

2870
// Plots the specified measurement types to individual files
2871
// All other measurement types (_combined_msr_list) are printed to a single file
2872
// This enables colours to be specified for individual measurement types
2873
void dna_plot::PrintMeasurementsDatFilesBlock(const UINT32& block)
6✔
2874
{
2875
        v_msr_file_.at(block).clear();
6✔
2876

2877
        std::string type;
6✔
2878
        std::stringstream ss, filename;
6✔
2879

2880
        std::ofstream msr_file_stream;
6✔
2881
        
2882
        for (UINT16 c=0; c<pprj_->p._separate_msrs.size(); c++)
126✔
2883
        {
2884
                // no measurement for this type?
2885
                if (parsemsrTally_.MeasurementCount(pprj_->p._separate_msrs.at(c)) == 0)
120✔
2886
                        continue;
54✔
2887

2888
                ss.str("");
198✔
2889
                ss << pprj_->p._separate_msrs.at(c);
66✔
2890
                type = ss.str();
66✔
2891
                filename.str("");
198✔
2892
                filename << output_folder_ << FOLDER_SLASH << network_name_ << "_msr_block" << block + 1 << "_" << pprj_->p._separate_msrs.at(c) << ".d";
66✔
2893
                v_msr_def_file_.push_back(filename.str());
66✔
2894
                v_msr_file_.at(block).push_back(string_string_pair(v_msr_def_file_.back(), type));
132✔
2895

2896
                try {
66✔
2897
                        // Create msr data file.  Throws runtime_error on failure.
2898
                        file_opener(msr_file_stream, v_msr_def_file_.back());
66✔
2899
                }
NEW
2900
                catch (const std::runtime_error& e) {
×
2901
                        SignalExceptionPlot(e.what(), 0, NULL);
×
2902
                }
×
2903

2904
                PrintMeasurementsDatFileBlock(block, pprj_->p._separate_msrs.at(c), &msr_file_stream);
66✔
2905

2906
                msr_file_stream.close();
66✔
2907

2908
                // remove this measurement type from the global list
2909
                it_vchar_range = equal_range(_combined_msr_list.begin(), _combined_msr_list.end(), 
198✔
2910
                        pprj_->p._separate_msrs.at(c));
66✔
2911

2912
                if (it_vchar_range.first != it_vchar_range.second)
66✔
2913
                {
2914
                        // found - remove it from the list.  The remaining elements will be printed to a single file
2915
                        _combined_msr_list.erase(it_vchar_range.first);
33✔
2916
                }
2917
        }
2918

2919
        std::vector<char>::const_iterator _it_type;
6✔
2920
        bool printOtherTypes(false);
6✔
2921
        for (_it_type=_combined_msr_list.begin(); _it_type!=_combined_msr_list.end(); ++_it_type)
60✔
2922
        {
2923
                if (parsemsrTally_.MeasurementCount(*_it_type) > 0)
54✔
2924
                {
2925
                        printOtherTypes = true;
2926
                        break;
2927
                }
2928
        }
2929

2930
        // don't bother printing this file if there are no 'other' measurements
2931
        if (!printOtherTypes)
6✔
2932
                return;
6✔
2933

2934
        // now print remaining measurement types to a single file
2935
        filename.str("");
×
2936
        filename << output_folder_ << FOLDER_SLASH << network_name_ << "_msr_block" << block + 1 << "_";
×
2937
        ss.str("");
×
2938
        for (_it_type=_combined_msr_list.begin(); _it_type!=_combined_msr_list.end(); _it_type++)
×
2939
                ss << *_it_type;
×
2940
        filename << ss.str() << ".d";
×
2941
        v_msr_all_file_.push_back(filename.str());
×
2942
        v_msr_file_.at(block).insert(v_msr_file_.at(block).begin(), string_string_pair(v_msr_all_file_.back(), ss.str()));
×
2943

2944
        try {
×
2945
                // Create msr data file.  Throws runtime_error on failure.
2946
                file_opener(msr_file_stream, v_msr_all_file_.back());
×
2947
        }
NEW
2948
        catch (const std::runtime_error& e) {
×
2949
                SignalExceptionPlot(e.what(), 0, NULL);
×
2950
        }
×
2951

2952
        for (_it_type=_combined_msr_list.begin(); _it_type!=_combined_msr_list.end(); _it_type++)
×
2953
                PrintMeasurementsDatFileBlock(block, *_it_type, &msr_file_stream);
×
2954

2955
        msr_file_stream.close();
×
2956

2957
}
12✔
2958

2959

2960
// Plots the specified measurement types to individual files
2961
// All other measurement types (_combined_msr_list) are printed to a single file
2962
// This enables colours to be specified for individual measurement types
2963
void dna_plot::PrintMeasurementsDatFiles()
22✔
2964
{
2965
        _combined_msr_list.clear();
22✔
2966
        _combined_msr_list.push_back('A'); // Horizontal angle
22✔
2967
        _combined_msr_list.push_back('B'); // Geodetic azimuth
22✔
2968
        _combined_msr_list.push_back('C'); // Chord dist
22✔
2969
        _combined_msr_list.push_back('D'); // Direction set
22✔
2970
        _combined_msr_list.push_back('E'); // Ellipsoid arc
22✔
2971
        _combined_msr_list.push_back('G'); // GPS Baseline (treat as single-baseline cluster)
22✔
2972
        _combined_msr_list.push_back('H'); // Orthometric height
22✔
2973
        _combined_msr_list.push_back('I'); // Astronomic latitude
22✔
2974
        _combined_msr_list.push_back('J'); // Astronomic longitude
22✔
2975
        _combined_msr_list.push_back('K'); // Astronomic azimuth
22✔
2976
        _combined_msr_list.push_back('L'); // Level difference
22✔
2977
        _combined_msr_list.push_back('M'); // MSL arc
22✔
2978
        _combined_msr_list.push_back('P'); // Geodetic latitude
22✔
2979
        _combined_msr_list.push_back('Q'); // Geodetic longitude
22✔
2980
        _combined_msr_list.push_back('R'); // Ellipsoidal height
22✔
2981
        _combined_msr_list.push_back('S'); // Slope distance
22✔
2982
        _combined_msr_list.push_back('V'); // Zenith distance
22✔
2983
        _combined_msr_list.push_back('X'); // GPS Baseline cluster
22✔
2984
        _combined_msr_list.push_back('Y'); // GPS point cluster
22✔
2985
        _combined_msr_list.push_back('Z'); // Vertical angle
22✔
2986

2987
        //vector<char>::iterator _it_type(_combined_msr_list.end());
2988
        
2989
        std::string msr_file_name;
22✔
2990
        v_msr_file_.at(0).clear();
22✔
2991

2992
        YClusterStations_.clear();
22✔
2993

2994
        std::string type;
22✔
2995
        std::stringstream ss;
22✔
2996

2997
        std::ofstream msr_file_stream;
22✔
2998

2999
        for (UINT16 c=0; c<pprj_->p._separate_msrs.size(); c++)
450✔
3000
        {
3001
                // no measurement for this type?
3002
                if (parsemsrTally_.MeasurementCount(pprj_->p._separate_msrs.at(c)) == 0)
428✔
3003
                        continue;
18✔
3004

3005
                ss.str("");
1,230✔
3006
                ss << pprj_->p._separate_msrs.at(c);
410✔
3007
                type = ss.str();
410✔
3008
                msr_file_name = output_folder_ + FOLDER_SLASH + network_name_ + "_msr_" + pprj_->p._separate_msrs.at(c) + ".d";
2,870✔
3009
                v_msr_file_.at(0).push_back(string_string_pair(msr_file_name, type));
820✔
3010

3011
                try {
410✔
3012
                        // Create msr data file.  Throws runtime_error on failure.
3013
                        file_opener(msr_file_stream, msr_file_name);
410✔
3014
                }
NEW
3015
                catch (const std::runtime_error& e) {
×
3016
                        SignalExceptionPlot(e.what(), 0, NULL);
×
3017
                }
×
3018

3019
                PrintMeasurementsDatFile(pprj_->p._separate_msrs.at(c), &msr_file_stream);
410✔
3020

3021
                msr_file_stream.close();
410✔
3022

3023
                // remove this measurement type from the global list
3024
                it_vchar_range = equal_range(_combined_msr_list.begin(), _combined_msr_list.end(), 
1,230✔
3025
                        pprj_->p._separate_msrs.at(c));
410✔
3026

3027
                if (it_vchar_range.first != it_vchar_range.second)
410✔
3028
                {
3029
                        // found - remove it from the list.  The remaining elements will be printed to a single file
3030
                        _combined_msr_list.erase(it_vchar_range.first);
410✔
3031
                }
3032
        }
3033

3034
        std::vector<char>::const_iterator _it_type;
22✔
3035
        bool printOtherTypes(false);
22✔
3036
        for (_it_type=_combined_msr_list.begin(); _it_type!=_combined_msr_list.end(); ++_it_type)
38✔
3037
        {
3038
                if (parsemsrTally_.MeasurementCount(*_it_type) > 0)
17✔
3039
                {
3040
                        printOtherTypes = true;
3041
                        break;
3042
                }
3043
        }
3044

3045
        // don't bother printing this file if there are no 'other' measurements
3046
        if (!printOtherTypes)
22✔
3047
                return;
21✔
3048

3049
        // now print remaining measurement types to a single file
3050
        msr_file_name = output_folder_ + FOLDER_SLASH + network_name_ + "_msr_";
4✔
3051
        ss.str("");
3✔
3052
        for (_it_type=_combined_msr_list.begin(); _it_type!=_combined_msr_list.end(); ++_it_type)
15✔
3053
                ss << *_it_type;
14✔
3054
        type = ss.str();
1✔
3055
        msr_file_name.append(type).append(".d");
1✔
3056
        v_msr_file_.at(0).insert(v_msr_file_.at(0).begin(), string_string_pair(msr_file_name, type));
1✔
3057

3058
        try {
1✔
3059
                // Create msr data file.  Throws runtime_error on failure.
3060
                file_opener(msr_file_stream, msr_file_name);
1✔
3061
        }
NEW
3062
        catch (const std::runtime_error& e) {
×
3063
                SignalExceptionPlot(e.what(), 0, NULL);
×
3064
        }
×
3065

3066
        for (_it_type=_combined_msr_list.begin(); _it_type!=_combined_msr_list.end(); _it_type++)
15✔
3067
                PrintMeasurementsDatFile(*_it_type, &msr_file_stream);
14✔
3068

3069
        msr_file_stream.close();
1✔
3070

3071
}
66✔
3072

3073

3074
bool dna_plot::WithinLimits(const double& latitude, const double& longitude)
27,842✔
3075
{
3076
        if (latitude >= lowerDeg_ && latitude <= upperDeg_ &&
27,842✔
3077
                longitude >= leftDeg_ && longitude <= rightDeg_)
11,210✔
3078
                return true;
3079
        else
3080
                return false;
16,789✔
3081
}
3082
        
3083

3084
void dna_plot::PrintMeasurementsDatFileBlock(const UINT32& block, char msrType, std::ofstream* msr_file_stream)
66✔
3085
{
3086
        it_vstn_t _it_stn(bstBinaryRecords_.begin());
66✔
3087
        
3088
        UINT32 precision(10);
66✔
3089
        bool FirstisWithinLimits, SecondisWithinLimits, ThirdisWithinLimits;
66✔
3090

3091
        std::stringstream ss;
66✔
3092
        
3093
        it_vUINT32 _it_block_msr(v_CML_.at(block).begin());
66✔
3094
        vUINT32 msrIndices;
66✔
3095
        it_vmsr_t _it_msr;
66✔
3096

3097
        (*msr_file_stream) << ">" << std::endl;
66✔
3098

3099
        for (_it_block_msr=v_CML_.at(block).begin(); _it_block_msr<v_CML_.at(block).end(); _it_block_msr++)
24,233✔
3100
        {
3101
                _it_msr = bmsBinaryRecords_.begin() + (*_it_block_msr);
24,167✔
3102

3103
                if (msrType != _it_msr->measType)
24,167✔
3104
                        continue;
21,970✔
3105

3106
                if (_it_msr->ignore && !pprj_->p._plot_ignored_msrs)
2,197✔
3107
                        continue;
×
3108

3109
                ss.str("");
6,591✔
3110
                ss.clear();
2,197✔
3111
                FirstisWithinLimits = SecondisWithinLimits = ThirdisWithinLimits = false;
2,197✔
3112
                switch (msrType)
2,197✔
3113
                {
3114
                case 'A':        // Horizontal angles
497✔
3115
                        // Print 3 - 1 - 2
3116
                        //
3117
                        // Third
3118
                        ss << std::setprecision(precision) << std::fixed << bstBinaryRecords_.at(_it_msr->station3).initialLongitude;
497✔
3119
                        ss << "  ";
497✔
3120
                        ss << std::setprecision(precision) << std::fixed << bstBinaryRecords_.at(_it_msr->station3).initialLatitude;
497✔
3121
                        ss << std::endl;
497✔
3122

3123
                        // test if point is within limits of custom defined box
3124
                        if (!default_limits_)
497✔
3125
                                ThirdisWithinLimits = WithinLimits(bstBinaryRecords_.at(_it_msr->station3).initialLatitude, bstBinaryRecords_.at(_it_msr->station3).initialLongitude);
×
3126

3127
                        [[fallthrough]];
573✔
3128

3129
                case 'G': // GPS Baseline
573✔
3130
                case 'X': // GPS Baseline cluster
573✔
3131
                
3132
                        // The following prevents GPS measurements from printing three times (i.e. once per X, Y, Z)
3133
                        if (_it_msr->measStart > xMeas)
573✔
3134
                                continue;
×
3135

3136
                        [[fallthrough]];
2,193✔
3137
                        
3138
                case 'B': // Geodetic azimuth
2,193✔
3139
                case 'D': // Direction set
2,193✔
3140
                case 'K': // Astronomic azimuth
2,193✔
3141
                case 'C': // Chord dist
2,193✔
3142
                case 'E': // Ellipsoid arc
2,193✔
3143
                case 'M': // MSL arc
2,193✔
3144
                case 'S': // Slope distance
2,193✔
3145
                case 'L': // Level difference
2,193✔
3146
                case 'V': // Zenith distance
2,193✔
3147
                case 'Z': // Vertical angle
2,193✔
3148
                        // Get the measurement indices involved in this measurement
3149
                        GetMsrIndices<UINT32>(bmsBinaryRecords_, *_it_block_msr, msrIndices);
2,193✔
3150

3151
                        for (it_vUINT32 msr=msrIndices.begin(); msr!=msrIndices.end(); ++msr)
4,386✔
3152
                        {
3153
                                if (bmsBinaryRecords_.at(*msr).measStart > xMeas)
2,193✔
3154
                                        continue;
×
3155

3156
                                if (!default_limits_)
2,193✔
3157
                                {
3158
                                        FirstisWithinLimits = WithinLimits(
×
3159
                                                bstBinaryRecords_.at(bmsBinaryRecords_.at(*msr).station1).initialLatitude, 
×
3160
                                                bstBinaryRecords_.at(bmsBinaryRecords_.at(*msr).station1).initialLongitude);
×
3161
                                        SecondisWithinLimits = WithinLimits(
×
3162
                                                bstBinaryRecords_.at(bmsBinaryRecords_.at(*msr).station2).initialLatitude, 
×
3163
                                                bstBinaryRecords_.at(bmsBinaryRecords_.at(*msr).station2).initialLongitude);
×
3164

3165
                                        if (!FirstisWithinLimits && !SecondisWithinLimits && !ThirdisWithinLimits)
×
3166
                                                continue;
×
3167
                                }
3168

3169
                                // Third.  If case 'A' was reached before case 'B', ss will be non-empty
3170
                                (*msr_file_stream) << ss.str();
2,193✔
3171
                        
3172
                                // First
3173
                                (*msr_file_stream) << std::setprecision(precision) << std::fixed << bstBinaryRecords_.at(bmsBinaryRecords_.at(*msr).station1).initialLongitude;
2,193✔
3174
                                (*msr_file_stream) << "  ";
2,193✔
3175
                                (*msr_file_stream) << std::setprecision(precision) << std::fixed << bstBinaryRecords_.at(bmsBinaryRecords_.at(*msr).station1).initialLatitude;
2,193✔
3176
                                (*msr_file_stream) << std::endl;
2,193✔
3177
                        
3178
                                // Second
3179
                                (*msr_file_stream) << std::setprecision(precision) << std::fixed << bstBinaryRecords_.at(bmsBinaryRecords_.at(*msr).station2).initialLongitude;
2,193✔
3180
                                (*msr_file_stream) << "  ";
2,193✔
3181
                                (*msr_file_stream) << std::setprecision(precision) << std::fixed << bstBinaryRecords_.at(bmsBinaryRecords_.at(*msr).station2).initialLatitude;
2,193✔
3182
                                (*msr_file_stream) << std::endl << ">" << std::endl;
2,193✔
3183
                        }
3184
                        break;
2,193✔
3185
                
3186
                // single station
3187
                case 'H': // Orthometric height
2✔
3188
                case 'I': // Astronomic latitude
2✔
3189
                case 'J': // Astronomic longitude
2✔
3190
                case 'P': // Geodetic latitude
2✔
3191
                case 'Q': // Geodetic longitude
2✔
3192
                case 'R': // Ellipsoidal height
2✔
3193
                        if (!default_limits_)
2✔
3194
                                if (!WithinLimits(
×
3195
                                        bstBinaryRecords_.at(_it_msr->station1).initialLatitude, 
×
3196
                                        bstBinaryRecords_.at(_it_msr->station1).initialLongitude))
×
3197
                                        continue;
×
3198

3199
                        // First
3200
                        (*msr_file_stream) << std::setprecision(precision) << std::fixed << bstBinaryRecords_.at(_it_msr->station1).initialLongitude;
2✔
3201
                        (*msr_file_stream) << "  ";
2✔
3202
                        (*msr_file_stream) << std::setprecision(precision) << std::fixed << bstBinaryRecords_.at(_it_msr->station1).initialLatitude;
2✔
3203
                        (*msr_file_stream) << std::endl << ">" << std::endl;
24,167✔
3204
                        
3205
                        break;
3206

3207
                case 'Y': // GPS point cluster
2✔
3208
                        
3209
                        // Get the measurement indices involved in this measurement
3210
                        GetMsrIndices<UINT32>(bmsBinaryRecords_, *_it_block_msr, msrIndices);
2✔
3211

3212
                        for (it_vUINT32 msr=msrIndices.begin(); msr!=msrIndices.end(); ++msr)
10✔
3213
                        {
3214
                                if (bmsBinaryRecords_.at(*msr).measStart > xMeas)
8✔
3215
                                        continue;
×
3216

3217
                                if (!default_limits_)
8✔
3218
                                        if (!WithinLimits(
×
3219
                                                bstBinaryRecords_.at(bmsBinaryRecords_.at(*msr).station1).initialLatitude, 
×
3220
                                                bstBinaryRecords_.at(bmsBinaryRecords_.at(*msr).station1).initialLongitude))
×
3221
                                                continue;
×
3222

3223
                                // First
3224
                                (*msr_file_stream) << std::setprecision(precision) << std::fixed << bstBinaryRecords_.at(bmsBinaryRecords_.at(*msr).station1).initialLongitude;
8✔
3225
                                (*msr_file_stream) << "  ";
8✔
3226
                                (*msr_file_stream) << std::setprecision(precision) << std::fixed << bstBinaryRecords_.at(bmsBinaryRecords_.at(*msr).station1).initialLatitude;
8✔
3227
                                (*msr_file_stream) << std::endl << ">" << std::endl;
8✔
3228
                        }
3229
                }
3230
        }
3231

3232
}
66✔
3233
        
3234

3235
void dna_plot::PrintMeasurementsDatFile(char msrType, std::ofstream* msr_file_stream)
424✔
3236
{
3237
        it_vstn_t _it_stn(bstBinaryRecords_.begin());
424✔
3238
        it_vmsr_t _it_msr(bmsBinaryRecords_.begin());
424✔
3239
        
3240
        UINT32 precision(10);
424✔
3241
        bool FirstisWithinLimits, SecondisWithinLimits, ThirdisWithinLimits;
424✔
3242

3243
        std::stringstream ss;
424✔
3244

3245
        (*msr_file_stream) << ">" << std::endl;
424✔
3246
        
3247
        for (_it_msr=bmsBinaryRecords_.begin(); _it_msr!=bmsBinaryRecords_.end(); _it_msr++)
2,689,488✔
3248
        {
3249
                if (msrType != _it_msr->measType)
2,689,064✔
3250
                        continue;
2,554,438✔
3251
                
3252
                if (_it_msr->ignore && !pprj_->p._plot_ignored_msrs)
134,626✔
3253
                        continue;
433✔
3254
                
3255
                ss.str("");
402,579✔
3256
                ss.clear();
134,193✔
3257
                FirstisWithinLimits = SecondisWithinLimits = ThirdisWithinLimits = false;
134,193✔
3258
                switch (msrType)
134,193✔
3259
                {
3260
                case 'A':        // Horizontal angles
4,999✔
3261
                        // Print 3 - 1 - 2
3262
                        //
3263
                        // Third
3264
                        ss << std::setprecision(precision) << std::fixed << bstBinaryRecords_.at(_it_msr->station3).initialLongitude;
4,999✔
3265
                        ss << "  ";
4,999✔
3266
                        ss << std::setprecision(precision) << std::fixed << bstBinaryRecords_.at(_it_msr->station3).initialLatitude;
4,999✔
3267
                        ss << std::endl;
4,999✔
3268

3269
                        // test if point is within limits of custom defined box
3270
                        if (!default_limits_)
4,999✔
3271
                                ThirdisWithinLimits = WithinLimits(bstBinaryRecords_.at(_it_msr->station3).initialLatitude, bstBinaryRecords_.at(_it_msr->station3).initialLongitude);
2,498✔
3272

3273
                        [[fallthrough]];
17,278✔
3274

3275
                case 'G': // GPS Baseline
17,278✔
3276
                case 'X': // GPS Baseline cluster
17,278✔
3277
                
3278
                        // The following prevents GPS measurements from printing three times (i.e. once per X, Y, Z)
3279
                        if (_it_msr->measStart > xMeas)
17,278✔
3280
                                continue;
8,473✔
3281

3282
                        [[fallthrough]];
25,657✔
3283

3284
                case 'B': // Geodetic azimuth
25,657✔
3285
                case 'D': // Direction set
25,657✔
3286
                case 'K': // Astronomic azimuth
25,657✔
3287
                case 'C': // Chord dist
25,657✔
3288
                case 'E': // Ellipsoid arc
25,657✔
3289
                case 'M': // MSL arc
25,657✔
3290
                case 'S': // Slope distance
25,657✔
3291
                case 'L': // Level difference
25,657✔
3292
                case 'V': // Zenith distance
25,657✔
3293
                case 'Z': // Vertical angle
25,657✔
3294

3295
                        if (!default_limits_)
25,657✔
3296
                        {
3297
                                FirstisWithinLimits = WithinLimits(bstBinaryRecords_.at(_it_msr->station1).initialLatitude, bstBinaryRecords_.at(_it_msr->station1).initialLongitude);
12,613✔
3298
                                SecondisWithinLimits = WithinLimits(bstBinaryRecords_.at(_it_msr->station2).initialLatitude, bstBinaryRecords_.at(_it_msr->station2).initialLongitude);
12,613✔
3299

3300
                                if (!FirstisWithinLimits && !SecondisWithinLimits && !ThirdisWithinLimits)
12,613✔
3301
                                        continue;
7,584✔
3302
                        }
3303

3304
                        // Third 
3305
                        // If this measurement is an angle, then ss will contain data for third station
3306
                        // Otherwise, ss will be blank
3307
                        (*msr_file_stream) << ss.str();
18,073✔
3308
                        
3309
                        // First
3310
                        (*msr_file_stream) << std::setprecision(precision) << std::fixed << bstBinaryRecords_.at(_it_msr->station1).initialLongitude;
18,073✔
3311
                        (*msr_file_stream) << "  ";
18,073✔
3312
                        (*msr_file_stream) << std::setprecision(precision) << std::fixed << bstBinaryRecords_.at(_it_msr->station1).initialLatitude;
18,073✔
3313
                        (*msr_file_stream) << std::endl;
18,073✔
3314
                        
3315
                        // Second
3316
                        (*msr_file_stream) << std::setprecision(precision) << std::fixed << bstBinaryRecords_.at(_it_msr->station2).initialLongitude;
18,073✔
3317
                        (*msr_file_stream) << "  ";
18,073✔
3318
                        (*msr_file_stream) << std::setprecision(precision) << std::fixed << bstBinaryRecords_.at(_it_msr->station2).initialLatitude;
18,073✔
3319
                        (*msr_file_stream) << std::endl << ">" << std::endl;
18,073✔
3320
                        break;
3321
                
3322
                // single station
3323
                case 'H': // Orthometric height
280✔
3324
                case 'I': // Astronomic latitude
280✔
3325
                case 'J': // Astronomic longitude
280✔
3326
                case 'P': // Geodetic latitude
280✔
3327
                case 'Q': // Geodetic longitude
280✔
3328
                case 'R': // Ellipsoidal height
280✔
3329
                        
3330
                        if (!default_limits_)
280✔
3331
                        {
3332
                                FirstisWithinLimits = WithinLimits(bstBinaryRecords_.at(_it_msr->station1).initialLatitude, bstBinaryRecords_.at(_it_msr->station1).initialLongitude);
118✔
3333
                                if (!FirstisWithinLimits)
118✔
3334
                                        continue;
78✔
3335
                        }
3336

3337
                        // First
3338
                        (*msr_file_stream) << std::setprecision(precision) << std::fixed << bstBinaryRecords_.at(_it_msr->station1).initialLongitude;
202✔
3339
                        (*msr_file_stream) << "  ";
202✔
3340
                        (*msr_file_stream) << std::setprecision(precision) << std::fixed << bstBinaryRecords_.at(_it_msr->station1).initialLatitude;
202✔
3341
                        (*msr_file_stream) << std::endl << ">" << std::endl;                        
202✔
3342
                        break;
3343

3344
                case 'Y': // GPS point cluster
99,783✔
3345
                        
3346
                        // The following prevents GPS measurements from printing three times (i.e. once per X, Y, Z)
3347
                        if (_it_msr->measStart > xMeas)
99,783✔
3348
                                continue;
98,391✔
3349

3350
                        //// capture first station in the cluster
3351
                        //if (_it_tmp == bmsBinaryRecords_.end())
3352
                        //{
3353
                        //        _it_tmp = _it_msr;
3354
                        //        continue;
3355
                        //}
3356

3357
                        //// Is this a new measurement cluster?
3358
                        //if (_it_tmp->clusterID != _it_msr->clusterID)
3359
                        //{
3360
                        //        _it_tmp = _it_msr;
3361
                        //        continue;
3362
                        //}
3363

3364
                        if (binary_search(YClusterStations_.begin(), YClusterStations_.end(), _it_msr->station1))
1,392✔
3365
                                // already have this one
3366
                                continue;
38✔
3367
                        
3368
                        YClusterStations_.push_back(_it_msr->station1);
1,354✔
3369
                        std::sort(YClusterStations_.begin(), YClusterStations_.end());
1,354✔
3370

3371
                        // First
3372
                        (*msr_file_stream) << std::setprecision(precision) << std::fixed << bstBinaryRecords_.at(_it_msr->station1).initialLongitude;
1,354✔
3373
                        (*msr_file_stream) << "  ";
1,354✔
3374
                        (*msr_file_stream) << std::setprecision(precision) << std::fixed << bstBinaryRecords_.at(_it_msr->station1).initialLatitude;
1,354✔
3375
                        (*msr_file_stream) << std::endl << ">" << std::endl;
2,689,064✔
3376

3377
                }
3378
        }
3379

3380
}
424✔
3381
        
3382

3383
void dna_plot::PrintGMTParameters()
28✔
3384
{
3385
        it_string_pair _it_vpstr(pprj_->p._gmt_params.begin());
28✔
3386

3387
        try {
28✔
3388
                for (; _it_vpstr!=pprj_->p._gmt_params.end(); _it_vpstr++)
140✔
3389
                        gmtbat_file_ << _APP_GMTSET_ << " " << _it_vpstr->first << " " << _it_vpstr->second << std::endl;
112✔
3390
                gmtbat_file_ << std::endl;
28✔
3391
        }
NEW
3392
        catch (const std::ios_base::failure& f) {
×
NEW
3393
                SignalExceptionPlot(static_cast<std::string>(f.what()), 0, "o", &gmtbat_file_);        
×
UNCOV
3394
        }
×
3395
        
3396
}
28✔
3397
        
3398

3399
void dna_plot::LoadNetworkFiles(const project_settings& projectSettings)
31✔
3400
{
3401
        projectSettings_ = projectSettings;
31✔
3402

3403
        _combined_msr_list.clear();
31✔
3404
        MsrTally::FillMsrList(_combined_msr_list);
31✔
3405

3406
        blockCount_ = 1;
31✔
3407
        plotBlocks_ = projectSettings.p._plot_phased_blocks;
31✔
3408
        LoadBinaryFiles();
31✔
3409
        LoadStationMap();
31✔
3410
        if (plotBlocks_)
31✔
3411
                LoadSegmentationFile();
7✔
3412

3413
        // Printing uncertainties?
3414
        if (projectSettings.p._plot_error_ellipses || 
31✔
3415
                projectSettings.p._plot_positional_uncertainty)
29✔
3416
        {
3417
                uncertainty_legend_length_ = 0.5;
2✔
3418
                LoadPosUncertaintyFile();
2✔
3419
        }
3420
        
3421
        // Printing corrections?
3422
        if (projectSettings.p._plot_correction_arrows)
31✔
3423
        {
3424
                arrow_legend_length_ = 3.;
2✔
3425
                if (projectSettings.p._compute_corrections)
2✔
3426
                        ComputeStationCorrections();
2✔
3427
                else
3428
                        LoadCorrectionsFile();
×
3429
        }
3430

3431
        if (plotBlocks_)
31✔
3432
                // Parameter station list is needed for correction arrows
3433
                BuildParameterStationList();
7✔
3434
}
31✔
3435

3436

3437
void dna_plot::LoadBinaryFiles()
31✔
3438
{
3439
        try {
31✔
3440
                // Load binary stations data.  Throws runtime_error on failure.
3441
                dna_io_bst bst;
31✔
3442
                stationCount_ = bst.load_bst_file(projectSettings_.i.bst_file, &bstBinaryRecords_, bst_meta_);
31✔
3443

3444
                // Load binary stations data.  Throws runtime_error on failure.
3445
                dna_io_bms bms;
31✔
3446
                bms.load_bms_file(projectSettings_.i.bms_file, &bmsBinaryRecords_, bms_meta_);
31✔
3447
        }
31✔
NEW
3448
        catch (const std::runtime_error& e) {
×
3449
                SignalExceptionPlot(e.what(), 0, NULL);
×
3450
        }
×
3451

3452
        reference_frame_ = projectSettings_.i.reference_frame;
31✔
3453
        
3454
        try {
31✔
3455
                reference_frame_ = datumFromEpsgString<std::string>(bst_meta_.epsgCode);
93✔
3456
        }
3457
        catch (...) {
×
3458
                // do nothing
3459
        }
×
3460
        
3461
        for_each(
31✔
3462
                bstBinaryRecords_.begin(), 
3463
                bstBinaryRecords_.end(), 
3464
                [this] (station_t& stn) {                        // use lambda expression
6,433✔
3465
                        ReduceStationCoordinates(&stn);
6,433✔
3466
                }
3467
        );
3468

3469
        // Create measurement tally to determine the measurement
3470
        // types that have been supplied
3471
        for_each(
31✔
3472
                bmsBinaryRecords_.begin(), 
3473
                bmsBinaryRecords_.end(), 
3474
                [this] (measurement_t& msr) {                        // use lambda expression
142,792✔
3475
                        
3476
                        switch (msr.measType)
142,792✔
3477
                        {
3478
                        case 'A': // Horizontal angle
6,572✔
3479
                                parsemsrTally_.A++;
6,572✔
3480
                                break;
6,572✔
3481
                        case 'B': // Geodetic azimuth
72✔
3482
                                parsemsrTally_.B++;
72✔
3483
                                break;
72✔
3484
                        case 'C': // Chord dist
46✔
3485
                                parsemsrTally_.C++;
46✔
3486
                                break;
46✔
3487
                        case 'D': // Direction set
403✔
3488
                                if (msr.vectorCount1 > 0)
403✔
3489
                                        parsemsrTally_.D += msr.vectorCount1 - 1;
111✔
3490
                                break;
3491
                        case 'E': // Ellipsoid arc
92✔
3492
                                parsemsrTally_.E++;
92✔
3493
                                break;
92✔
3494
                        case 'G': // GPS Baseline
11,337✔
3495
                                parsemsrTally_.G++;
11,337✔
3496
                                break;
11,337✔
3497
                        case 'H': // Orthometric height
137✔
3498
                                parsemsrTally_.H++;
137✔
3499
                                break;
137✔
3500
                        case 'I': // Astronomic latitude
46✔
3501
                                parsemsrTally_.I++;
46✔
3502
                                break;
46✔
3503
                        case 'J': // Astronomic longitude
46✔
3504
                                parsemsrTally_.J++;
46✔
3505
                                break;
46✔
3506
                        case 'K': // Astronomic azimuth
72✔
3507
                                parsemsrTally_.K++;
72✔
3508
                                break;
72✔
3509
                        case 'L': // Level difference
2,360✔
3510
                                parsemsrTally_.L++;
2,360✔
3511
                                break;
2,360✔
3512
                        case 'M': // MSL arc
118✔
3513
                                parsemsrTally_.M++;
118✔
3514
                                break;
118✔
3515
                        case 'P': // Geodetic latitude
46✔
3516
                                parsemsrTally_.P++;
46✔
3517
                                break;
46✔
3518
                        case 'Q': // Geodetic longitude
46✔
3519
                                parsemsrTally_.Q++;
46✔
3520
                                break;
46✔
3521
                        case 'R': // Ellipsoidal height
46✔
3522
                                parsemsrTally_.R++;
46✔
3523
                                break;
46✔
3524
                        case 'S': // Slope distance
11,474✔
3525
                                parsemsrTally_.S++;
11,474✔
3526
                                break;
11,474✔
3527
                        case 'V': // Zenith distance
7,846✔
3528
                                parsemsrTally_.V++;
7,846✔
3529
                                break;
7,846✔
3530
                        case 'X': // GPS Baseline cluster
1,977✔
3531
                                if (msr.measStart == xMeas)
1,977✔
3532
                                {
3533
                                        if (msr.vectorCount1 == msr.vectorCount2 + 1)
366✔
3534
                                                parsemsrTally_.X += (msr.vectorCount1 * 3);
168✔
3535
                                }
3536
                                break;
3537
                        case 'Y': // GPS point cluster
99,984✔
3538
                                if (msr.measStart == xMeas)
99,984✔
3539
                                {
3540
                                        if (msr.vectorCount1 == msr.vectorCount2 + 1)
1,423✔
3541
                                                parsemsrTally_.Y += (msr.vectorCount1 * 3);
129✔
3542
                                }
3543
                                break;
3544
                        case 'Z': // Vertical angle
72✔
3545
                                parsemsrTally_.Z++;
72✔
3546
                                break;
72✔
3547
                        }
3548
                }
142,792✔
3549
        );
3550

3551
        measurementCount_ = parsemsrTally_.TotalCount();        
31✔
3552

3553
}
31✔
3554

3555

3556
void dna_plot::LoadStationMap()
31✔
3557
{
3558
        try {
31✔
3559
                // Load station map.  Throws runtime_error on failure.
3560
                dna_io_map map;
31✔
3561
                map.load_map_file(projectSettings_.i.map_file, &stnsMap_);
31✔
3562
        }
31✔
NEW
3563
        catch (const std::runtime_error& e) {
×
3564
                SignalExceptionPlot(e.what(), 0, NULL);
×
3565
        }
×
3566
}
31✔
3567
        
3568

3569
//void dna_plot::SortandMapStations()
3570
//{
3571
//        UINT32 stnCount(static_cast<UINT32>(bstBinaryRecords_.size()));
3572
//        stnsMap_.clear();
3573
//        stnsMap_.reserve(stnCount);
3574
//
3575
//        // Create the Station-Name / ID map
3576
//        string_uint32_pair stnID;
3577
//        for (UINT32 stnIndex=0; stnIndex<stnCount; stnIndex++)
3578
//        {
3579
//                stnID.first = bstBinaryRecords_.at(stnIndex).stationName;
3580
//                stnID.second = stnIndex;
3581
//                stnsMap_.push_back(stnID);
3582
//        }
3583
//
3584
//        // sort on station name (i.e. first of the pair)
3585
//        std::sort(stnsMap_.begin(), stnsMap_.end(), StationNameIDCompareName());
3586
//
3587
//        if (stnsMap_.size() < stnCount)
3588
//                SignalExceptionPlot("SortandMapStations(): Could not allocate sufficient memory for the Station map.", 0, NULL);
3589
//}
3590
        
3591

3592
void dna_plot::LoadSegmentationFile()
7✔
3593
{
3594
        vUINT32 v_ContiguousNetList, v_parameterStationCount;
7✔
3595
        try {
7✔
3596
                // Load segmentation file.  Throws runtime_error on failure.
3597
                dna_io_seg seg;
7✔
3598
                seg.load_seg_file(projectSettings_.s.seg_file, 
7✔
3599
                        blockCount_, blockThreshold_, minInnerStns_,
7✔
3600
                        v_ISL_, v_JSL_, v_CML_,
7✔
3601
                        true, &bmsBinaryRecords_,
3602
                        &v_measurementCount_, &v_unknownsCount_, &v_ContiguousNetList,
3603
                        &v_parameterStationCount);
3604
        }
7✔
NEW
3605
        catch (const std::runtime_error& e) {
×
3606
                SignalExceptionPlot(e.what(), 0, NULL);
×
3607
        }
×
3608

3609
        if (projectSettings_.p._plot_block_number > blockCount_)
7✔
3610
        {
NEW
3611
                std::stringstream ss;
×
3612
                ss << 
×
3613
                        "Specified block number (" << projectSettings_.p._plot_block_number << 
×
3614
                        ") exceeds the total number of blocks (" <<
×
NEW
3615
                        blockCount_ << ")." << std::endl;
×
3616
                SignalExceptionPlot(ss.str(), 0, NULL);        
×
3617
        }
×
3618

3619
        v_msr_file_.resize(blockCount_);
7✔
3620
}
7✔
3621
        
3622

3623
// The positional uncertainty file is produced by adjust.
3624
void dna_plot::LoadPosUncertaintyFile()
2✔
3625
{
3626
        // Load corrections file generated by adjust
3627
        std::ifstream apu_file;
2✔
3628
        try {
2✔
3629
                // Load apu file.  Throws runtime_error on failure.
3630
                file_opener(apu_file, projectSettings_.o._apu_file, std::ios::in, ascii, true);
2✔
3631
        }
NEW
3632
        catch (const std::runtime_error& e) {
×
3633
                SignalExceptionPlot(e.what(), 0, NULL);
×
3634
        }
×
3635

3636
        bool fullCovarianceMatrix(false);
2✔
3637
        UINT32 block(0), stn(0), stn_cov, blockstnCount;
2✔
3638
        std::string strLine;
2✔
3639
        stationPosUncertainty_t posUnc;
2✔
3640

3641
        v_stn_pu_.resize(blockCount_);
2✔
3642
        largest_uncertainty_ = 0.0;
2✔
3643

3644
        char line[PRINT_LINE_LENGTH];
2✔
3645
        bool dataBlocks(false);
2✔
3646
        it_pair_string_vUINT32 _it_stnmap;
2✔
3647

3648
        APU_UNITS_UI vcv_units;
2✔
3649
        matrix_2d vcv_cart(3, 3), vcv_local(3, 3);
2✔
3650

3651
        try {
2✔
3652
                
3653
                // read header line
3654
                apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // ------------------------
2✔
3655
                apu_file.ignore(PRINT_LINE_LENGTH, '\n');                //            DYNADJUST POSITIONAL UNCERTAINTY...
2✔
3656
                apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // 
2✔
3657
                apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // Version
2✔
3658
                apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // Build
2✔
3659
                apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // File created
2✔
3660
                apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // File name
2✔
3661
                apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // 
2✔
3662
                apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // PU Confidence interval
2✔
3663
                apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // Error ellipse axes
2✔
3664
                apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // Variances
2✔
3665

3666
                apu_file.getline(line, PRINT_LINE_LENGTH);                // Stations printed in blocks
2✔
3667
                strLine = trimstr(std::string(line));                
6✔
3668
                if (!boost::iequals(strLine.substr(0, 16), "Stations printed"))
4✔
3669
                {
NEW
3670
                        std::stringstream ss;
×
NEW
3671
                        ss << "LoadPosUncertaintyFile(): " << projectSettings_.o._apu_file << " is corrupt." << std::endl;
×
NEW
3672
                        ss << "  Expected to find 'Stations printed in blocks' field." << std::endl;
×
UNCOV
3673
                        SignalExceptionPlot(ss.str(), 0, "i", &apu_file);
×
UNCOV
3674
                }
×
3675
                
3676
                if ((dataBlocks = yesno_uint<bool, std::string>(strLine.substr(PRINT_VAR_PAD))))
4✔
3677
                        v_stn_pu_.resize(bstBinaryRecords_.size());
×
3678
                else
3679
                        v_stn_pu_.reserve(bstBinaryRecords_.size());
2✔
3680

3681
                apu_file.getline(line, PRINT_LINE_LENGTH);                // Variance matrix units
2✔
3682
                strLine = trimstr(std::string(line));
6✔
3683
                if (boost::iequals(strLine.substr(PRINT_VAR_PAD, 3), "XYZ"))
4✔
3684
                        vcv_units = XYZ_apu_ui;
3685
                else
3686
                        vcv_units = ENU_apu_ui;
×
3687
                
3688

3689
                apu_file.getline(line, PRINT_LINE_LENGTH);                // Full covariance matrix
2✔
3690
                strLine = trimstr(std::string(line));
6✔
3691
                if (!boost::iequals(strLine.substr(0, 15), "Full covariance"))
4✔
3692
                {
NEW
3693
                        std::stringstream ss;
×
NEW
3694
                        ss << "LoadPosUncertaintyFile(): " << projectSettings_.o._apu_file << " is corrupt." << std::endl;
×
NEW
3695
                        ss << "  Expected to find 'Full covariance matrix' field." << std::endl;
×
3696
                        SignalExceptionPlot(ss.str(), 0, "i", &apu_file);
×
3697
                }
×
3698
                
3699
                fullCovarianceMatrix = yesno_uint<bool, std::string>(strLine.substr(PRINT_VAR_PAD));
2✔
3700

3701
                // If covariances are printed, then the data will appear in blocks
3702
                if (fullCovarianceMatrix)
2✔
3703
                        dataBlocks = true;
×
3704
                
3705
                apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // ------------------------
2✔
3706
                apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // 
2✔
3707
                apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // Positional uncertainty of ...
2✔
3708
                apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // ------------------------
2✔
3709
                
3710
                for (block=0; block<blockCount_; ++block)
4✔
3711
                {
3712
                        if (dataBlocks)
4✔
3713
                        {
3714
                                blockstnCount = static_cast<UINT32>(v_ISL_.at(block).size() + v_JSL_.at(block).size());
×
3715

3716
                                apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // 
×
3717
                                apu_file.getline(line, PRINT_LINE_LENGTH);                // Block #
×
3718

NEW
3719
                                strLine = trimstr(std::string(line));
×
3720
                                
NEW
3721
                                if (!boost::iequals(strLine.substr(0, 5), "Block"))
×
3722
                                {
NEW
3723
                                        std::stringstream ss;
×
NEW
3724
                                        ss << "LoadPosUncertaintyFile(): " << projectSettings_.o._apu_file << " is corrupt." << std::endl;
×
NEW
3725
                                        ss << "  Expected to read Block data, but found " << strLine << std::endl;
×
3726
                                        SignalExceptionPlot(ss.str(), 0, "i", &apu_file);
×
3727
                                }
×
3728

3729
                                if (LongFromString<UINT32>(strLine.substr(6)) != block + 1)
×
3730
                                {
NEW
3731
                                        std::stringstream ss;
×
NEW
3732
                                        ss << "LoadPosUncertaintyFile(): " << projectSettings_.o._apu_file << " is corrupt." << std::endl;
×
NEW
3733
                                        ss << "  Expected to read data for block " << strLine.substr(6) << ", but found " << strLine << std::endl;
×
3734
                                        SignalExceptionPlot(ss.str(), 0, "i", &apu_file);
×
3735
                                }
×
3736
                        }
3737
                        else
3738
                        {
3739
                                blockstnCount = stationCount_;
4✔
3740
                                apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // 
4✔
3741
                        }
3742
                        
3743
                        apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // Station
4✔
3744
                        apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // ------------------------
2✔
3745
                        
3746
                        for (stn=0; stn<blockstnCount;  ++stn)
300✔
3747
                        {
3748
                                apu_file.getline(line, PRINT_LINE_LENGTH);                // Now the data...
298✔
3749

3750
                                strLine = trimstr(std::string(line));
894✔
3751
                                if (strLine.length() < STATION)
298✔
3752
                                {
3753
                                        if (apu_file.eof())
×
3754
                                                break;                                
3755
                                        continue;
×
3756
                                }
3757

3758
                                posUnc._station =          trimstr(strLine.substr(0, STATION));
596✔
3759
                                posUnc._latitude =          DmstoDeg(DoubleFromString<double>(trimstr(strLine.substr(STATION+PAD2, LAT_EAST))));
596✔
3760
                                posUnc._longitude =   DmstoDeg(DoubleFromString<double>(trimstr(strLine.substr(STATION+PAD2+LAT_EAST, LON_NORTH))));
596✔
3761
                                posUnc._hzPosU =          DoubleFromString<double>(trimstr(strLine.substr(STATION+PAD2+LAT_EAST+LON_NORTH, STAT)));
596✔
3762
                                posUnc._vtPosU =          DoubleFromString<double>(trimstr(strLine.substr(STATION+PAD2+LAT_EAST+LON_NORTH+STAT, STAT)));
596✔
3763
                                posUnc._semimMajor =  DoubleFromString<double>(trimstr(strLine.substr(STATION+PAD2+LAT_EAST+LON_NORTH+STAT+STAT, PREC)));
596✔
3764
                                posUnc._semimMinor =  DoubleFromString<double>(trimstr(strLine.substr(STATION+PAD2+LAT_EAST+LON_NORTH+STAT+STAT+PREC, PREC)));
596✔
3765
                                posUnc._orientation = DoubleFromString<double>(trimstr(strLine.substr(STATION+PAD2+LAT_EAST+LON_NORTH+STAT+STAT+PREC+PREC, PREC)));
596✔
3766
                                posUnc._xx =                  DoubleFromString<double>(trimstr(strLine.substr(STATION+PAD2+LAT_EAST+LON_NORTH+STAT+STAT+PREC+PREC+PREC, MSR)));
596✔
3767
                                posUnc._xy =                  DoubleFromString<double>(trimstr(strLine.substr(STATION+PAD2+LAT_EAST+LON_NORTH+STAT+STAT+PREC+PREC+PREC+MSR, MSR)));
596✔
3768
                                posUnc._xz =                  DoubleFromString<double>(trimstr(strLine.substr(STATION+PAD2+LAT_EAST+LON_NORTH+STAT+STAT+PREC+PREC+PREC+MSR+MSR, MSR)));
596✔
3769

3770
                                // get yy from next row of variance matrix
3771
                                apu_file.getline(line, PRINT_LINE_LENGTH);
298✔
3772
                                strLine = std::string(line);
596✔
3773
                                posUnc._yy = DoubleFromString<double>(trimstr(strLine.substr(STATION+PAD2+LAT_EAST+LON_NORTH+STAT+STAT+PREC+PREC+PREC+MSR, MSR)));
596✔
3774
                                posUnc._yz = DoubleFromString<double>(trimstr(strLine.substr(STATION+PAD2+LAT_EAST+LON_NORTH+STAT+STAT+PREC+PREC+PREC+MSR+MSR, MSR)));
596✔
3775

3776
                                // Get reference of this station in bstBinaryRecords.
3777
                                if (dataBlocks || vcv_units == XYZ_apu_ui)
298✔
3778
                                {
3779
                                        _it_stnmap = equal_range(stnsMap_.begin(), stnsMap_.end(), posUnc._station, StationNameIDCompareName());
298✔
3780

3781
                                        // Not in the list? (Unlikely since adjust output will not contain stations not in the map, but test anyway)
3782
                                        if (_it_stnmap.first == _it_stnmap.second)
298✔
3783
                                                continue;
×
3784
                                }
3785

3786
                                // Calculate vcv in local reference frame
3787
                                if (vcv_units == XYZ_apu_ui)
298✔
3788
                                {
3789
                                        // get yy from next row of variance matrix
3790
                                        apu_file.getline(line, PRINT_LINE_LENGTH);
298✔
3791
                                        strLine = trimstr(std::string(line));
894✔
3792
                                        posUnc._zz = DoubleFromString<double>(trimstr(strLine));
298✔
3793

3794
                                        vcv_cart.put(0, 0, posUnc._xx);
298✔
3795
                                        vcv_cart.put(0, 1, posUnc._xy);
298✔
3796
                                        vcv_cart.put(0, 2, posUnc._xz);
298✔
3797
                                        vcv_cart.put(1, 1, posUnc._yy);
298✔
3798
                                        vcv_cart.put(1, 2, posUnc._yz);
298✔
3799
                                        vcv_cart.put(2, 2, posUnc._zz);
298✔
3800

3801
                                        vcv_cart.filllower();
298✔
3802

3803
                                        // Calculate correlations in local reference frame
3804
                                        PropagateVariances_LocalCart<double>(vcv_cart, vcv_local, 
596✔
3805
                                                bstBinaryRecords_.at(_it_stnmap.first->second).currentLatitude, 
298✔
3806
                                                bstBinaryRecords_.at(_it_stnmap.first->second).currentLongitude, false);
298✔
3807

3808
                                        posUnc._xx = vcv_local.get(0, 0);
298✔
3809
                                        posUnc._xy = vcv_local.get(0, 1);
298✔
3810
                                        posUnc._xz = vcv_local.get(0, 2);
298✔
3811
                                        posUnc._yy = vcv_local.get(1, 1);
298✔
3812
                                        posUnc._yz = vcv_local.get(1, 2);
298✔
3813
                                        posUnc._zz = vcv_local.get(2, 2);
298✔
3814
                                }
3815
                                else
3816
                                        // ENU - don't need up component - ignore last (height) row 
3817
                                        // of variance matrix
3818
                                        apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // ------------------------
×
3819

3820
                                // Data in blocks?  Set the vector element accordingly, otherwise add to the vector
3821
                                if (dataBlocks)
298✔
3822
                                        v_stn_pu_.at(_it_stnmap.first->second) = posUnc;
×
3823
                                else
3824
                                        v_stn_pu_.push_back(posUnc);
298✔
3825

3826
                                if (fabs(posUnc._semimMajor) > largest_uncertainty_)
298✔
3827
                                        largest_uncertainty_ = posUnc._semimMajor;
14✔
3828

3829
                                if (!fullCovarianceMatrix)
298✔
3830
                                        continue;
298✔
3831
                                
3832
                                // skip over covariances
3833
                                for (stn_cov=stn+1; stn_cov<blockstnCount;  ++stn_cov)
×
3834
                                {
3835
                                        // ignore covariance block
3836
                                        apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // ------------------------
×
3837
                                        apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // ------------------------
×
3838
                                        apu_file.ignore(PRINT_LINE_LENGTH, '\n');                // ------------------------
×
3839
                                }
3840
                        }
3841
                }
3842
        }
3843
        catch (const std::ios_base::failure& f) {
2✔
3844
                if (!apu_file.eof())
2✔
3845
                {
NEW
3846
                        std::stringstream ss;
×
NEW
3847
                        ss << "LoadPosUncertaintyFile(): An error was encountered when reading " << projectSettings_.o._apu_file << "." << std::endl << "  " << f.what();
×
3848
                        SignalExceptionPlot(ss.str(), 0, "i", &apu_file);
×
3849
                }
×
3850
        }
2✔
3851

3852
        apu_file.close();
2✔
3853
}
6✔
3854

3855
void dna_plot::ComputeStationCorrection(it_vstn_t_const _it_stn, stationCorrections_t& stnCor,
296✔
3856
        matrix_2d& currentEstimates, matrix_2d& initialEstimates)
3857
{
3858
        // Compute XYZ for current estimates
3859
        GeoToCart<double>(
296✔
3860
                _it_stn->currentLatitude,
296✔
3861
                _it_stn->currentLongitude,
296✔
3862
                _it_stn->currentHeight,
296✔
3863
                currentEstimates.getelementref(0, 0),
296✔
3864
                currentEstimates.getelementref(1, 0),
296✔
3865
                currentEstimates.getelementref(2, 0),
296✔
3866
                datum_.GetEllipsoidRef());
3867

3868
        // Compute XYZ for initial estimates
3869
        GeoToCart<double>(
296✔
3870
                Radians(_it_stn->initialLatitude),
592✔
3871
                Radians(_it_stn->initialLongitude),
592✔
3872
                _it_stn->initialHeight + _it_stn->geoidSep,
592✔
3873
                initialEstimates.getelementref(0, 0),
296✔
3874
                initialEstimates.getelementref(1, 0),
296✔
3875
                initialEstimates.getelementref(2, 0),
296✔
3876
                datum_.GetEllipsoidRef());
3877

3878
        // compute vertical angle
3879
        stnCor._vAngle = VerticalAngle<double>(
592✔
3880
                initialEstimates.get(0, 0),                // X1
296✔
3881
                initialEstimates.get(1, 0),                // Y1
296✔
3882
                initialEstimates.get(2, 0),                // Z1
296✔
3883
                currentEstimates.get(0, 0),                // X2
296✔
3884
                currentEstimates.get(1, 0),                // Y2
296✔
3885
                currentEstimates.get(2, 0),                // Z2
296✔
3886
                _it_stn->currentLatitude,
296✔
3887
                _it_stn->currentLongitude,
296✔
3888
                _it_stn->currentLatitude,
296✔
3889
                _it_stn->currentLongitude,
296✔
3890
                0., 0.,
3891
                &stnCor._east, &stnCor._north, &stnCor._up);
3892

3893
        if (fabs(stnCor._east) < PRECISION_1E5)
296✔
3894
                if (fabs(stnCor._north) < PRECISION_1E5)
4✔
3895
                        if (fabs(stnCor._up) < PRECISION_1E5)
2✔
3896
                                stnCor._vAngle = 0.;
×
3897
        
3898
        // compute horizontal correction
3899
        stnCor._hDistance = magnitude(stnCor._east, stnCor._north);
296✔
3900
                        
3901
        // calculate azimuth
3902
        stnCor._azimuth = Direction<double>(
592✔
3903
                initialEstimates.get(0, 0),                // X1
296✔
3904
                initialEstimates.get(1, 0),                // Y1
296✔
3905
                initialEstimates.get(2, 0),                // Z1
296✔
3906
                currentEstimates.get(0, 0),                // X2
296✔
3907
                currentEstimates.get(1, 0),                // Y2
296✔
3908
                currentEstimates.get(2, 0),                // Z2
296✔
3909
                _it_stn->currentLatitude,
296✔
3910
                _it_stn->currentLongitude,
296✔
3911
                &stnCor._east, &stnCor._north);
3912

3913
        if (fabs(stnCor._east) < PRECISION_1E5)
296✔
3914
                if (fabs(stnCor._north) < PRECISION_1E5)
4✔
3915
                        stnCor._azimuth = 0.;
2✔
3916

3917
        // calculate distances
3918
        stnCor._sDistance = magnitude<double>(
592✔
3919
                initialEstimates.get(0, 0),                // X1
296✔
3920
                initialEstimates.get(1, 0),                // Y1
296✔
3921
                initialEstimates.get(2, 0),                // Z1
296✔
3922
                currentEstimates.get(0, 0),                // X2
296✔
3923
                currentEstimates.get(1, 0),                // Y2
296✔
3924
                currentEstimates.get(2, 0));        // Z2
296✔
3925
}
296✔
3926
        
3927

3928
void dna_plot::ComputeStationCorrections()
2✔
3929
{
3930
        // reserve enough memory for each station
3931
        v_stn_corrs_.reserve(bstBinaryRecords_.size());
2✔
3932

3933
        stationCorrections_t stnCor;
4✔
3934
        matrix_2d currentEstimates(3, 1), initialEstimates(3, 1);
2✔
3935

3936
        average_correction_ = 0.0;
2✔
3937
        UINT32 correction_count(0);
2✔
3938

3939
        // compute corrections for every station in the network
3940
        for (it_vstn_t_const _it_stn=bstBinaryRecords_.begin();
300✔
3941
                _it_stn!=bstBinaryRecords_.end(); 
300✔
3942
                ++_it_stn)
298✔
3943
        {
3944
                // Constrained?  No correction!
3945
                if (_it_stn->stationConst[0] == 'C' && 
306✔
3946
                        _it_stn->stationConst[1] == 'C' && 
298✔
3947
                        _it_stn->stationConst[2] == 'C')
4✔
3948
                {
3949
                        // push a zero correction
3950
                        v_stn_corrs_.push_back(stationCorrections(_it_stn->stationName));
8✔
3951
                        continue;
2✔
3952
                }
3953

3954
                stnCor._station = _it_stn->stationName;
296✔
3955
                ComputeStationCorrection(_it_stn, stnCor,
296✔
3956
                        currentEstimates, initialEstimates);
3957

3958
                average_correction_ += stnCor._hDistance;
296✔
3959
                correction_count++;
296✔
3960

3961
                v_stn_corrs_.push_back(stnCor);
296✔
3962
        }
3963

3964
        // determine average correction length
3965
        average_correction_ /= correction_count;
2✔
3966
}
4✔
3967
        
3968
void dna_plot::BuildParameterStationList()
7✔
3969
{
3970
        if (!plotBlocks_)
7✔
3971
                return;
×
3972

3973
        v_parameterStationList_.resize(blockCount_);
7✔
3974

3975
        vUINT32 vStns;
7✔
3976
        it_vUINT32_const _it_stn;
7✔
3977

3978
        for (UINT32 block(0); block!=blockCount_; ++block)
22✔
3979
        {
3980
                // Form combined stations list
3981
                v_parameterStationList_.at(block) = v_ISL_.at(block);
15✔
3982
                v_parameterStationList_.at(block).insert(v_parameterStationList_.at(block).end(),
30✔
3983
                        v_JSL_.at(block).begin(), v_JSL_.at(block).end());
15✔
3984
                std::sort(v_parameterStationList_.at(block).begin(), v_parameterStationList_.at(block).end());
15✔
3985

3986
        }
3987
}
7✔
3988

3989
// The station corrections file is produced by adjust.  Note that corrections for *all* stations may not 
3990
// be printed, since the user has the option to restrict the output of station corrections using
3991
// horizontal and vertical thresholds.
3992
// Also, the coorctions file may contain a list of stations printed in blocks, or in a contiguous list.
3993
// These options create complexities!
3994
//
3995
// The best way to deal with station corrections is to ignore the cor file and to recalculate corrections
3996
// from the original coordinates in the bst file.
3997
void dna_plot::LoadCorrectionsFile()
×
3998
{
3999
        // Load corrections file generated by adjust
4000
        std::ifstream cor_file;
×
4001
        try {
×
4002
                // Load corrections file.  Throws runtime_error on failure.
NEW
4003
                file_opener(cor_file, projectSettings_.o._cor_file, std::ios::in, ascii, true);
×
4004
        }
NEW
4005
        catch (const std::runtime_error& e) {
×
4006
                SignalExceptionPlot(e.what(), 0, NULL);
×
4007
        }
×
4008

4009
        UINT32 correction_count(0);
×
4010
        UINT32 block(0), stn(0), blockstnCount, corFileBlockCount(blockCount_);
×
NEW
4011
        std::string strLine;
×
4012
        stationCorrections_t stnCor;
×
4013

4014
        average_correction_ = 0.0;
×
4015

4016
        char line[PRINT_LINE_LENGTH];
×
4017
        bool dataBlocks(false);
×
4018
        it_pair_string_vUINT32 _it_stnmap;
×
4019

4020
        try {
×
4021
                
4022
                // read header line
4023
                cor_file.ignore(PRINT_LINE_LENGTH, '\n');                // ------------------------
×
4024
                cor_file.ignore(PRINT_LINE_LENGTH, '\n');                //            DYNADJUST CORRECT...
×
4025
                cor_file.ignore(PRINT_LINE_LENGTH, '\n');                // 
×
4026
                cor_file.ignore(PRINT_LINE_LENGTH, '\n');                // Version
×
4027
                cor_file.ignore(PRINT_LINE_LENGTH, '\n');                // Build
×
4028
                cor_file.ignore(PRINT_LINE_LENGTH, '\n');                // File created
×
4029
                cor_file.ignore(PRINT_LINE_LENGTH, '\n');                // File name
×
4030
                cor_file.ignore(PRINT_LINE_LENGTH, '\n');                // 
×
4031
                cor_file.getline(line, PRINT_LINE_LENGTH);                // Stations printed in blocks
×
4032
                
4033
                // Get the yes/no string and convert to bool
NEW
4034
                strLine = trimstr(std::string(line));
×
NEW
4035
                if (!boost::iequals(strLine.substr(0, 16), "Stations printed"))
×
4036
                {
NEW
4037
                        std::stringstream ss;
×
4038
                        // TODO - make use of Boost current function
4039
                        // http://www.boost.org/doc/libs/1_58_0/boost/current_function.hpp
4040
                        // and if required, print the filename and line number using __FILE__ and __LINE__
4041
                        // https://stackoverflow.com/questions/15305310/predefined-macros-for-function-name-func
NEW
4042
                        ss << "LoadCorrectionsFile(): " << projectSettings_.o._cor_file << " is corrupt." << std::endl;
×
NEW
4043
                        ss << "  Expected to find 'Stations printed in blocks' field." << std::endl;
×
4044
                        SignalExceptionPlot(ss.str(), 0, "i", &cor_file);
×
4045
                }
×
4046

NEW
4047
                if ((dataBlocks = yesno_uint<bool, std::string>(strLine.substr(PRINT_VAR_PAD))))                // Data printed in blocks?
×
4048
                        v_stn_corrs_.resize(bstBinaryRecords_.size());
×
4049
                else
4050
                {
4051
                        v_stn_corrs_.reserve(bstBinaryRecords_.size());
×
4052
                        corFileBlockCount = 1;
4053
                }
4054

4055
                cor_file.ignore(PRINT_LINE_LENGTH, '\n');                // 
×
4056
                cor_file.ignore(PRINT_LINE_LENGTH, '\n');                // Corrections to Stations
×
4057
                cor_file.ignore(PRINT_LINE_LENGTH, '\n');                // ------------------------
×
4058
                
4059
                for (block=0; block<corFileBlockCount; ++block)
×
4060
                {
4061
                        if (dataBlocks)
×
4062
                        {
4063
                                blockstnCount = static_cast<UINT32>(v_ISL_.at(block).size() + v_JSL_.at(block).size());
×
4064

4065
                                cor_file.ignore(PRINT_LINE_LENGTH, '\n');                // 
×
4066
                                cor_file.getline(line, PRINT_LINE_LENGTH);                // Block #
×
4067

NEW
4068
                                strLine = trimstr(std::string(line));
×
4069
                                
NEW
4070
                                if (!boost::iequals(strLine.substr(0, 5), "Block"))
×
4071
                                {
NEW
4072
                                        std::stringstream ss;
×
NEW
4073
                                        ss << "LoadCorrectionsFile(): " << projectSettings_.o._cor_file << " is corrupt." << std::endl;
×
NEW
4074
                                        ss << "  Expected to read Block data, but found " << strLine << std::endl;
×
4075
                                        SignalExceptionPlot(ss.str(), 0, "i", &cor_file);
×
4076
                                }
×
4077

4078
                                if (LongFromString<UINT32>(strLine.substr(6)) != block + 1)
×
4079
                                {
NEW
4080
                                        std::stringstream ss;
×
NEW
4081
                                        ss << "LoadCorrectionsFile(): " << projectSettings_.o._cor_file << " is corrupt." << std::endl;
×
NEW
4082
                                        ss << "  Expected to read data for block " << strLine.substr(6) << ", but found " << strLine << std::endl;
×
4083
                                        SignalExceptionPlot(ss.str(), 0, "i", &cor_file);
×
4084
                                }
×
4085
                        }
4086
                        else
4087
                        {
4088
                                blockstnCount = stationCount_;
×
4089
                                cor_file.ignore(PRINT_LINE_LENGTH, '\n');                // 
×
4090
                        }
4091
                        
4092
                        cor_file.ignore(PRINT_LINE_LENGTH, '\n');                // Station
×
4093
                        cor_file.ignore(PRINT_LINE_LENGTH, '\n');                // ------------------------
×
4094

4095
                        for (stn=0; stn<blockstnCount;  ++stn)
×
4096
                        {
4097
                                cor_file.getline(line, PRINT_LINE_LENGTH);                // Now the data...
×
4098

NEW
4099
                                strLine = trimstr(std::string(line));
×
4100
                                if (strLine.length() < STATION)
×
4101
                                {
4102
                                        if (cor_file.eof())
×
4103
                                                break;                                
4104
                                        continue;
×
4105
                                }
4106

4107
                                //// print...
4108
                                //// station and constraint
4109
                                //os << std::setw(STATION) << std::left << bstBinaryRecords_.at(stn).stationName << std::setw(PAD2) << " ";
4110
                                //// data
4111
                                //os << std::setw(MSR) << std::right << FormatDmsString(RadtoDms(azimuth), 4, true, false) << 
4112
                                //        std::setw(MSR) << std::right << FormatDmsString(RadtoDms(vertical_angle), 4, true, false) << 
4113
                                //        std::setw(MSR) << std::setprecision(PRECISION_MTR_STN) << std::fixed << std::right << slope_distance << 
4114
                                //        std::setw(MSR) << std::setprecision(PRECISION_MTR_STN) << std::fixed << std::right << horiz_distance << 
4115
                                //        std::setw(HEIGHT) << std::setprecision(PRECISION_MTR_STN) << std::fixed << std::right << local_12e << 
4116
                                //        std::setw(HEIGHT) << std::setprecision(PRECISION_MTR_STN) << std::fixed << std::right << local_12n << 
4117
                                //        std::setw(HEIGHT) << std::setprecision(PRECISION_MTR_STN) << std::fixed << std::right << local_12up << std::endl;
4118

4119
                                stnCor._station   = trimstr(strLine.substr(0, STATION));
×
4120
                                stnCor._azimuth   = ParseDmsString<double>(trimstr(strLine.substr(STATION+PAD2, MSR)), " ");
×
4121
                                stnCor._vAngle          = ParseDmsString<double>(trimstr(strLine.substr(STATION+PAD2+MSR, MSR)), " ");
×
4122
                                stnCor._sDistance = DoubleFromString<double>(trimstr(strLine.substr(STATION+PAD2+MSR+MSR, MSR)));
×
4123
                                stnCor._hDistance = DoubleFromString<double>(trimstr(strLine.substr(STATION+PAD2+MSR+MSR+MSR, MSR)));
×
4124
                                stnCor._east      = DoubleFromString<double>(trimstr(strLine.substr(STATION+PAD2+MSR+MSR+MSR+MSR, HEIGHT)));
×
4125
                                stnCor._north     = DoubleFromString<double>(trimstr(strLine.substr(STATION+PAD2+MSR+MSR+MSR+MSR+HEIGHT, HEIGHT)));
×
4126
                                stnCor._up        = DoubleFromString<double>(trimstr(strLine.substr(STATION+PAD2+MSR+MSR+MSR+MSR+HEIGHT+HEIGHT, HEIGHT)));
×
4127

4128

4129
                                // Get reference of this station in bstBinaryRecords.
4130
                                if (dataBlocks)
×
4131
                                {
4132
                                        _it_stnmap = equal_range(stnsMap_.begin(), stnsMap_.end(), stnCor._station, StationNameIDCompareName());
×
4133

4134
                                        // Not in the list? (Unlikely since adjust output will not contain stations not in the map, but test anyway)
4135
                                        if (_it_stnmap.first == _it_stnmap.second)
×
4136
                                                continue;
×
4137
                
4138
                                        v_stn_corrs_.at(_it_stnmap.first->second) = stnCor;
×
4139
                                }
4140
                                else
4141
                                        v_stn_corrs_.push_back(stnCor);
×
4142

4143
                                average_correction_ += stnCor._hDistance;
×
4144
                                correction_count++;
×
4145
                        }
4146
                }
4147
        }
NEW
4148
        catch (const std::ios_base::failure& f) {
×
4149
                if (!cor_file.eof())
×
4150
                {
NEW
4151
                        std::stringstream ss;
×
NEW
4152
                        ss << "LoadCorrectionsFile(): An error was encountered when reading " << projectSettings_.o._cor_file << "." << std::endl << "  " << f.what();
×
4153
                        SignalExceptionPlot(ss.str(), 0, "i", &cor_file);
×
4154
                }
×
4155
        }
×
4156

4157
        // determine average correction length
4158
        average_correction_ /= correction_count;
×
4159

4160
        cor_file.close();
×
4161
}
×
4162
        
4163

4164
// Name:                                SignalExceptionPlot
4165
// Purpose:                                Closes all files (if file pointers are passed in) and throws runtime_error
4166
// Called by:                        Any
4167
// Calls:                                runtime_error()
NEW
4168
void dna_plot::SignalExceptionPlot(const std::string& msg, const int& line_no, const char *streamType, ...)
×
4169
{
UNCOV
4170
        plotStatus_ = PLOT_EXCEPTION_RAISED;
×
4171

UNCOV
4172
        if (streamType == NULL)
×
4173
                throw NetPlotException(msg, line_no);
×
4174

UNCOV
4175
        std::ofstream* ofsDynaML;
×
UNCOV
4176
        std::ifstream* ifsbinaryFile;
×
4177

UNCOV
4178
        va_list argptr; 
×
UNCOV
4179
        va_start(argptr, streamType);
×
4180

UNCOV
4181
        while (*streamType != '\0')
×
4182
        {
4183
                //ifstream
UNCOV
4184
                if (*streamType == 'i' )
×
4185
                {
UNCOV
4186
                        ifsbinaryFile = va_arg(argptr, std::ifstream*);
×
UNCOV
4187
                        ifsbinaryFile->close();
×
4188
                }
4189
                //ofstream
UNCOV
4190
                if (*streamType == 'o' )
×
4191
                {
4192
                        ofsDynaML = va_arg(argptr, std::ofstream*);
×
4193
                        ofsDynaML->close();
×
4194
                }
UNCOV
4195
                streamType++;
×
4196
        }
4197

UNCOV
4198
        va_end(argptr);
×
4199

UNCOV
4200
        throw NetPlotException(msg, line_no);
×
4201
}
4202

4203

4204
//void dna_plot::PrintGMTPlotCoords(vdnaStnPtr* vStations, vdnaMsrPtr* vMeasurements, ostream& osStn, ostream& osStn2, ostream& osMsr)
4205
//{
4206
//        _it_vdnastnptr _it_stn(vStations->begin());
4207
//        vdnaMsrPtr::iterator _it_msr(vMeasurements->begin());
4208
//        
4209
//        // Print station coords
4210
//        for (; _it_stn!=vStations->end(); _it_stn++)
4211
//                _it_stn->get()->coutStationData(osStn, osStn2, GMT_OUT);
4212
//
4213
//        //v_string_uint32_pair::iterator _it_stnmap(stnsMap_.begin());
4214
//
4215
//        UINT32 precision;
4216
//        _COORD_TYPE_ ctType;
4217
//
4218
//        std::vector<CDnaDirection>* vdirns;
4219
//        std::vector<CDnaGpsBaseline>* vgpsBsls;
4220
//
4221
//        for (; _it_msr!=vMeasurements->end(); _it_msr++)
4222
//        {
4223
//                switch (_it_msr->get()->GetTypeC())
4224
//                {
4225
//                case 'A':        // Horizontal angles
4226
//                        // Print 3 - 1 - 2
4227
//                        //
4228
//                        // Third
4229
//                        it_stnmap_range = equal_range(stnsMap_.begin(), stnsMap_.end(), 
4230
//                                _it_msr->get()->GetTarget2(), StationNameIDCompareName());
4231
//
4232
//                        if (it_stnmap_range.first == it_stnmap_range.second)
4233
//                        {
4234
//                                std::cout << _it_msr->get()->GetTarget2() << " is not in the list of network stations.";
4235
//                                continue;
4236
//                        }
4237
//                        precision = 3;
4238
//                        if ((ctType = vStations->at(it_stnmap_range.first->second)->GetMyCoordTypeC()) == LLH_type_i)
4239
//                                precision = 10;
4240
//
4241
//                        osMsr << std::setprecision(precision) << std::fixed << 
4242
//                                (ctType == LLH_type_i ? 
4243
//                                        Degrees(vStations->at(it_stnmap_range.first->second)->GetYAxis()) :
4244
//                                        vStations->at(it_stnmap_range.first->second)->GetYAxis());
4245
//                        osMsr << "  ";
4246
//                        osMsr << std::setprecision(precision) << std::fixed << 
4247
//                                (ctType == LLH_type_i ? 
4248
//                                        Degrees(vStations->at(it_stnmap_range.first->second)->GetXAxis()) :
4249
//                                        vStations->at(it_stnmap_range.first->second)->GetXAxis());
4250
//                        osMsr << std::endl;
4251
//                case 'B': // Geodetic azimuth
4252
//                case 'K': // Astronomic azimuth
4253
//                case 'C': // Chord dist
4254
//                case 'E': // Ellipsoid arc
4255
//                case 'M': // MSL arc
4256
//                case 'S': // Slope distance
4257
//                case 'L': // Level difference
4258
//                case 'V': // Zenith distance
4259
//                case 'Z': // Vertical angle
4260
//                        // First
4261
//                        it_stnmap_range = equal_range(stnsMap_.begin(), stnsMap_.end(), 
4262
//                                _it_msr->get()->GetFirst(), StationNameIDCompareName());
4263
//
4264
//                        if (it_stnmap_range.first == it_stnmap_range.second)
4265
//                        {
4266
//                                std::cout << _it_msr->get()->GetFirst() << " is not in the list of network stations.";
4267
//                                continue;
4268
//                        }
4269
//                        precision = 3;
4270
//                        if ((ctType = vStations->at(it_stnmap_range.first->second)->GetMyCoordTypeC()) == LLH_type_i)
4271
//                                precision = 10;
4272
//
4273
//                        osMsr << std::setprecision(precision) << std::fixed << (ctType == LLH_type_i ? Degrees(vStations->at(it_stnmap_range.first->second)->GetYAxis()): vStations->at(it_stnmap_range.first->second)->GetYAxis());
4274
//                        osMsr << "  ";
4275
//                        osMsr << std::setprecision(precision) << std::fixed << (ctType == LLH_type_i ? Degrees(vStations->at(it_stnmap_range.first->second)->GetXAxis()): vStations->at(it_stnmap_range.first->second)->GetXAxis());
4276
//                        osMsr << std::endl;
4277
//                        
4278
//                        // Second
4279
//                        it_stnmap_range = equal_range(stnsMap_.begin(), stnsMap_.end(), 
4280
//                                _it_msr->get()->GetTarget(), StationNameIDCompareName());
4281
//
4282
//                        if (it_stnmap_range.first == it_stnmap_range.second)
4283
//                        {
4284
//                                std::cout << _it_msr->get()->GetTarget() << " is not in the list of network stations.";
4285
//                                continue;
4286
//                        }
4287
//                        precision = 3;
4288
//                        if ((ctType = vStations->at(it_stnmap_range.first->second)->GetMyCoordTypeC()) == LLH_type_i)
4289
//                                precision = 10;
4290
//
4291
//                        osMsr << std::setprecision(precision) << std::fixed << (ctType == LLH_type_i ? Degrees(vStations->at(it_stnmap_range.first->second)->GetYAxis()): vStations->at(it_stnmap_range.first->second)->GetYAxis());
4292
//                        osMsr << "  ";
4293
//                        osMsr << std::setprecision(precision) << std::fixed << (ctType == LLH_type_i ? Degrees(vStations->at(it_stnmap_range.first->second)->GetXAxis()): vStations->at(it_stnmap_range.first->second)->GetXAxis());
4294
//                        osMsr << std::endl << "#" << std::endl;
4295
//                        break;
4296
//                case 'D': // Direction set
4297
//                        vdirns = _it_msr->get()->GetDirections_ptr();
4298
//                        PrintGMTPlotCoords_D(vStations, vdirns, osMsr);
4299
//                        break;
4300
//                case 'G': // GPS Baseline
4301
//                case 'X': // GPS Baseline cluster
4302
//                        vgpsBsls = _it_msr->get()->GetBaselines_ptr();
4303
//                        PrintGMTPlotCoords_GX(vStations, vgpsBsls, osMsr);
4304
//                        break;
4305
//                }
4306
//        }
4307
//}
4308
//
4309
//
4310
//void dna_plot::PrintGMTPlotCoords_D(vdnaStnPtr* vStations, std::vector<CDnaDirection>* vDirections, ostream& osMsr)
4311
//{
4312
//        std::vector<CDnaDirection>::iterator _it_dirn(vDirections->begin());
4313
//        //v_string_uint32_pair::iterator _it_stnmap(stnsMap_.begin());
4314
//
4315
//        UINT32 precision;
4316
//        _COORD_TYPE_ ctType;
4317
//
4318
//        for (; _it_dirn!=vDirections->end(); _it_dirn++)
4319
//        {
4320
//                // First
4321
//                it_stnmap_range = equal_range(stnsMap_.begin(), stnsMap_.end(), 
4322
//                        _it_dirn->GetFirst(), StationNameIDCompareName());
4323
//
4324
//                if (it_stnmap_range.first == it_stnmap_range.second)
4325
//                {
4326
//                        std::cout << _it_dirn->GetFirst() << " is not in the list of network stations.";
4327
//                        continue;
4328
//                }
4329
//                precision = 3;
4330
//                if ((ctType = vStations->at(it_stnmap_range.first->second)->GetMyCoordTypeC()) == LLH_type_i)
4331
//                        precision = 10;
4332
//
4333
//                osMsr << std::setprecision(precision) << std::fixed << (ctType == LLH_type_i ? Degrees(vStations->at(it_stnmap_range.first->second)->GetYAxis()): vStations->at(it_stnmap_range.first->second)->GetYAxis());
4334
//                osMsr << "  ";
4335
//                osMsr << std::setprecision(precision) << std::fixed << (ctType == LLH_type_i ? Degrees(vStations->at(it_stnmap_range.first->second)->GetXAxis()): vStations->at(it_stnmap_range.first->second)->GetXAxis());
4336
//                osMsr << std::endl;
4337
//
4338
//                // Second
4339
//                it_stnmap_range = equal_range(stnsMap_.begin(), stnsMap_.end(), 
4340
//                        _it_dirn->GetTarget(), StationNameIDCompareName());
4341
//
4342
//                if (it_stnmap_range.first == it_stnmap_range.second)
4343
//                {
4344
//                        std::cout << _it_dirn->GetTarget() << " is not in the list of network stations.";
4345
//                        continue;
4346
//                }
4347
//                precision = 3;
4348
//                if ((ctType = vStations->at(it_stnmap_range.first->second)->GetMyCoordTypeC()) == LLH_type_i)
4349
//                        precision = 10;
4350
//
4351
//                osMsr << std::setprecision(precision) << std::fixed << (ctType == LLH_type_i ? Degrees(vStations->at(it_stnmap_range.first->second)->GetYAxis()): vStations->at(it_stnmap_range.first->second)->GetYAxis());
4352
//                osMsr << "  ";
4353
//                osMsr << std::setprecision(precision) << std::fixed << (ctType == LLH_type_i ? Degrees(vStations->at(it_stnmap_range.first->second)->GetXAxis()): vStations->at(it_stnmap_range.first->second)->GetXAxis());
4354
//                osMsr << std::endl << "#" << std::endl;
4355
//        }
4356
//}
4357
//
4358
//
4359
//void dna_plot::PrintGMTPlotCoords_GX(vdnaStnPtr* vStations, std::vector<CDnaGpsBaseline>* vGPSBaselines, ostream& osMsr)
4360
//{
4361
//        std::vector<CDnaGpsBaseline>::iterator _it_bsl(vGPSBaselines->begin());
4362
//        //v_string_uint32_pair::iterator _it_stnmap(stnsMap_.begin());
4363
//
4364
//        UINT32 precision;
4365
//        _COORD_TYPE_ ctType;
4366
//
4367
//        for (; _it_bsl!=vGPSBaselines->end(); _it_bsl++)
4368
//        {
4369
//                // First
4370
//                it_stnmap_range = equal_range(stnsMap_.begin(), stnsMap_.end(), 
4371
//                        _it_bsl->GetFirst(), StationNameIDCompareName());
4372
//
4373
//                if (it_stnmap_range.first == it_stnmap_range.second)
4374
//                {
4375
//                        std::cout << _it_bsl->GetFirst() << " is not in the list of network stations.";
4376
//                        continue;
4377
//                }
4378
//                precision = 3;
4379
//                if ((ctType = vStations->at(it_stnmap_range.first->second)->GetMyCoordTypeC()) == LLH_type_i)
4380
//                        precision = 10;
4381
//
4382
//                osMsr << std::setprecision(precision) << std::fixed << (ctType == LLH_type_i ? Degrees(vStations->at(it_stnmap_range.first->second)->GetYAxis()): vStations->at(it_stnmap_range.first->second)->GetYAxis());
4383
//                osMsr << "  ";
4384
//                osMsr << std::setprecision(precision) << std::fixed << (ctType == LLH_type_i ? Degrees(vStations->at(it_stnmap_range.first->second)->GetXAxis()): vStations->at(it_stnmap_range.first->second)->GetXAxis());
4385
//                osMsr << std::endl;
4386
//
4387
//                // Second
4388
//                it_stnmap_range = equal_range(stnsMap_.begin(), stnsMap_.end(), 
4389
//                        _it_bsl->GetTarget(), StationNameIDCompareName());
4390
//
4391
//                if (it_stnmap_range.first == it_stnmap_range.second)
4392
//                {
4393
//                        std::cout << _it_bsl->GetTarget() << " is not in the list of network stations.";
4394
//                        continue;
4395
//                }
4396
//                precision = 3;
4397
//                if ((ctType = vStations->at(it_stnmap_range.first->second)->GetMyCoordTypeC()) == LLH_type_i)
4398
//                        precision = 10;
4399
//
4400
//                osMsr << std::setprecision(precision) << std::fixed << (ctType == LLH_type_i ? Degrees(vStations->at(it_stnmap_range.first->second)->GetYAxis()): vStations->at(it_stnmap_range.first->second)->GetYAxis());
4401
//                osMsr << "  ";
4402
//                osMsr << std::setprecision(precision) << std::fixed << (ctType == LLH_type_i ? Degrees(vStations->at(it_stnmap_range.first->second)->GetXAxis()): vStations->at(it_stnmap_range.first->second)->GetXAxis());
4403
//                osMsr << std::endl << "#" << std::endl;
4404
//        }
4405
//}
4406

4407

4408

4409
void dna_plot::ReduceStationCoordinates(station_t* stationRecord)
6,433✔
4410
{
4411
        stationRecord->initialLatitude = Degrees(stationRecord->initialLatitude);
6,433✔
4412
        stationRecord->initialLongitude = Degrees(stationRecord->initialLongitude);
6,433✔
4413
}
6,433✔
4414

4415
void dna_plot::NormaliseScale(double& scale)
25✔
4416
{
4417
        if (scale > 5000000. && scale < 10000000.)
25✔
4418
                scale = 5000000.;
×
4419
        else if (scale > 1250000.)
25✔
4420
                scale = 1500000.;
14✔
4421
        else if (scale > 1000000.)
11✔
4422
                scale = 1250000.;
×
4423
        else if (scale > 750000.)
11✔
4424
                scale = 1000000.;
×
4425
        else if (scale > 500000.)
11✔
4426
                scale = 750000.;
×
4427
        else if (scale > 350000.)
11✔
4428
                scale = 500000.;
3✔
4429
        else if (scale > 250000.)
8✔
4430
                scale = 350000.;
×
4431
        else if (scale > 200000.)
8✔
4432
                scale = 250000.;
×
4433
        else if (scale > 150000.)
8✔
4434
                scale = 200000.;
×
4435
        else if (scale > 100000.)
8✔
4436
                scale = 150000.;
×
4437
        else if (scale > 75000.)
8✔
4438
                scale = 100000.;
×
4439
        else if (scale > 50000.)
8✔
4440
                scale = 75000.;
×
4441
        else if (scale > 35000.)
8✔
4442
                scale = 50000.;
×
4443
        else if (scale > 25000.)
8✔
4444
                scale = 35000.;
×
4445
        else if (scale > 10000.)
8✔
4446
                scale = 25000.;
5✔
4447
        else if (scale > 7500.)
3✔
4448
                scale = 10000.;
×
4449
        else if (scale > 5000.)
3✔
4450
                scale = 7500.;
×
4451
        else if (scale > 2500.)
3✔
4452
                scale = 5000.;
×
4453
        else if (scale > 1000.)
3✔
4454
                scale = 2500.;
2✔
4455
        else if (scale > 500.)
1✔
4456
                scale = 1000.;
×
4457
        else
4458
                scale = 500.;
1✔
4459
}
25✔
4460

4461
void dna_plot::NormaliseScaleBar(double& scale_bar_width)
25✔
4462
{
4463
        if (scale_bar_width > 1.)
25✔
4464
                scale_bar_width = floor(scale_bar_width);
22✔
4465

4466
        if (scale_bar_width > 10000)
25✔
4467
                scale_bar_width -= (int)scale_bar_width % 10000;
4✔
4468
        else if (scale_bar_width > 1000)
21✔
4469
                scale_bar_width -= (int)scale_bar_width % 1000;
10✔
4470
        else if (scale_bar_width > 100)
11✔
4471
                scale_bar_width -= (int)scale_bar_width % 100;
×
4472
        else if (scale_bar_width > 10)
11✔
4473
                scale_bar_width -= (int)scale_bar_width % 10;
3✔
4474
        else if (scale_bar_width > 5)
8✔
4475
                scale_bar_width -= (int)scale_bar_width % 5;
×
4476
        else if (scale_bar_width > 1)
8✔
4477
                scale_bar_width -= (int)scale_bar_width % 1;
4478
        else if (scale_bar_width > 0.5)
4✔
4479
                scale_bar_width = 0.5;
1✔
4480
        else if (scale_bar_width > 0.25)
3✔
4481
                scale_bar_width = 0.25;
2✔
4482
        
4483
        else if (scale_bar_width > 0.1)
1✔
4484
                scale_bar_width = 0.1;
×
4485
        else if (scale_bar_width > 0.075)
1✔
4486
                scale_bar_width = 0.075;
×
4487
        else if (scale_bar_width > 0.05)
1✔
4488
                scale_bar_width = 0.05;
×
4489
        else if (scale_bar_width > 0.025)
1✔
4490
                scale_bar_width = 0.025;
×
4491
        
4492
        else if (scale_bar_width > 0.01)
1✔
4493
                scale_bar_width = 0.01;
1✔
4494
        else if (scale_bar_width > 0.0075)
×
4495
                scale_bar_width = 0.0075;
×
4496
        else if (scale_bar_width > 0.005)
×
4497
                scale_bar_width = 0.005;
×
4498
        else if (scale_bar_width > 0.0025)
×
4499
                scale_bar_width = 0.0025;
×
4500
        
4501
        else if (scale_bar_width > 0.0001)
×
4502
                scale_bar_width = 0.0001;
×
4503
        else if (scale_bar_width > 0.00075)
×
4504
                scale_bar_width = 0.00075;
×
4505
        else if (scale_bar_width > 0.0005)
×
4506
                scale_bar_width = 0.0005;
×
4507
        else if (scale_bar_width > 0.00025)
×
4508
                scale_bar_width = 0.00025;
×
4509
        
4510
}
25✔
4511

4512

4513
void dna_plot::NormaliseGraticule(double& graticule_width_, UINT32& graticule_width_precision)
25✔
4514
{
4515
        double graticule = graticule_width_ * 3600.0;        // convert to seconds
25✔
4516
        if (graticule > 1.)
25✔
4517
                graticule = floor(graticule);
24✔
4518
        else
4519
                graticule_width_precision = 16;
1✔
4520

4521
        if (graticule > 7200)                        // 2 degrees
25✔
4522
                graticule -= (int)graticule % 7200;
14✔
4523
        else if (graticule > 3600)                // 1 degrees
11✔
4524
                graticule -= (int)graticule % 3600;
×
4525
        else if (graticule > 1800)                // 30 minutes
11✔
4526
                graticule -= (int)graticule % 1800;
3✔
4527
        else if (graticule > 900)                // 15 minutes
8✔
4528
                graticule -= (int)graticule % 900;
1✔
4529
        else if (graticule > 600)                // 10 minutes
7✔
4530
                graticule -= (int)graticule % 600;
×
4531
        else if (graticule > 300)                // 5 minutes
7✔
4532
                graticule -= (int)graticule % 300;
×
4533
        else if (graticule > 60)                // 1 minute
7✔
4534
                graticule -= (int)graticule % 60;
4✔
4535
        else if (graticule > 30)                // 30 seconds
3✔
4536
                graticule -= (int)graticule % 30;
×
4537
        else if (graticule > 15)                // 15 seconds
3✔
4538
                graticule -= (int)graticule % 15;
×
4539
        else if (graticule > 10)                // 10 seconds
3✔
4540
                graticule -= (int)graticule % 10;
×
4541
        else if (graticule > 5)                        // 5 seconds
3✔
4542
                graticule -= (int)graticule % 5;
2✔
4543
        else if (graticule > 1)                        // 5 seconds
1✔
4544
                graticule -= (int)graticule % 1;
4545
        else if (graticule > 0.5)                // .5 seconds
1✔
4546
                graticule = 0.5;
4547
        else if (graticule > 0.25)                // .25 seconds
×
4548
                graticule = 0.25;
×
4549

4550

4551
        // convert to degrees
4552
        graticule_width_ = graticule / 3600.;
25✔
4553
}
25✔
4554

4555
void dna_plot::SelectCoastlineResolution(const double& dDimension, std::string& coastResolution, plot_settings* plotCriteria)
25✔
4556
{
4557
        plotCriteria->_coasline_resolution = low;
25✔
4558
        coastResolution = "l";
25✔
4559
        
4560
        if (dDimension < 900000)
25✔
4561
        {
4562
                plotCriteria->_coasline_resolution = full;
11✔
4563
                coastResolution = "f";
11✔
4564
                return;
11✔
4565
        }
4566
        if (dDimension < 2000000)
14✔
4567
        {
4568
                coastResolution = "h";
×
4569
                plotCriteria->_coasline_resolution = high;
×
4570
                return;
×
4571
        }
4572
        if (dDimension < 9000000)
14✔
4573
        {
4574
                plotCriteria->_coasline_resolution = intermediate;
10✔
4575
                coastResolution = "i";
10✔
4576
        }        
4577
}
4578

4579
}        // namespace mathcomp
4580
}        // namespace dynadjust
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