• 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

78.53
/dynadjust/include/measurement_types/dnastation.cpp
1
//============================================================================
2
// Name         : dnastation.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 CDnaStation implementation file
21
//============================================================================
22

23
#include <include/measurement_types/dnastation.hpp>
24
#include <include/parameters/dnaepsg.hpp>
25
#include <include/exception/dnaexception.hpp>
26

27
using namespace dynadjust::epsg;
28
using namespace dynadjust::datum_parameters;
29
using namespace dynadjust::exception;
30

31
namespace dynadjust {
32
namespace measurements {
33

34
// Comparison functions
35
// m_strName
36
bool operator<(const CDnaStation& left, const CDnaStation& right)
×
37
{
38
        return left.m_strName < right.m_strName;
×
39
}
40

41
bool operator<(const boost::shared_ptr<CDnaStation>& left, const boost::shared_ptr<CDnaStation>& right)
52,972✔
42
{
43
        return left.get()->m_strName < right.get()->m_strName;
52,972✔
44
}
45

46
CAStationList::CAStationList()
8,921✔
47
        : availMsrCount_ (0)
8,921✔
48
        , assocMsrCount_ (0)
8,921✔
49
        , amlStnIndex_ (0)
8,921✔
50
        , validStation_(VALID_STATION)
8,921✔
51
{
52
}
8,921✔
53

54
CAStationList::CAStationList(bool validStation)
43✔
55
        : availMsrCount_ (0)
43✔
56
        , assocMsrCount_ (0)
43✔
57
        , amlStnIndex_ (0)
43✔
58
        , validStation_(validStation ? VALID_STATION : INVALID_STATION)
43✔
59
{
60
}
43✔
61

62
CAStationList::~CAStationList()
15,856✔
63
{
64

65
}
15,856✔
66

67
// move constructor
68
CAStationList::CAStationList(const CAStationList&& s)
×
69
{
70
        availMsrCount_ = s.availMsrCount_;
×
71
        assocMsrCount_ = s.assocMsrCount_;
×
72
        amlStnIndex_ = s.amlStnIndex_;
×
73
        validStation_ = s.validStation_;
×
74
}
×
75

76

77
// move assignment operator
78
CAStationList& CAStationList::operator =(CAStationList&& rhs)
×
79
{
80
        // check for assignment to self!
81
        if (this == &rhs)
×
82
                return *this;
83

84
        availMsrCount_ = rhs.availMsrCount_;
×
85
        assocMsrCount_ = rhs.assocMsrCount_;
×
86
        amlStnIndex_ = rhs.amlStnIndex_;
×
87
        validStation_ = rhs.validStation_;
×
88

89
        return *this;
×
90
}
91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106
//<CDnaStation>//
107
CDnaStation::CDnaStation(const std::string& referenceframe, const std::string& epoch)
7,267✔
108
        : m_strName(""), m_strOriginalName("")
7,267✔
109
        , m_dXAxis(0.), m_dYAxis(0.), m_dZAxis(0.), m_dHeight(0.)
7,267✔
110
        , m_dStdDevX(0.), m_dStdDevY(0.), m_dStdDevZ(0.), m_dStdDevHt(0.)
7,267✔
111
        , m_strConstraints("FFF"), m_strType(""), m_strHemisphereZone(""), m_strDescription(""), m_strComment("")
7,267✔
112
        , m_cLatConstraint('F'), m_cLonConstraint('F'), m_cHtConstraint('F')
7,267✔
113
        , m_ctType(LLH_type_i), m_ctTypeSupplied(LLH_type_i), m_htType(ORTHOMETRIC_type_i)
7,267✔
114
        , m_dcurrentLatitude(0.), m_dcurrentLongitude(0.), m_dcurrentHeight(0.)
7,267✔
115
        , m_fgeoidSep(0.), m_dmeridianDef(0.), m_dverticalDef(0.)
7,267✔
116
        , m_lfileOrder(0), m_lnameOrder(0)
7,267✔
117
        , m_zone(0), m_unusedStation(INVALID_STATION)
7,267✔
118
        , m_referenceFrame(referenceframe), m_epoch(epoch)
7,267✔
119
        , m_constraintType(free_3D)
14,534✔
120
{
121
        m_epsgCode = epsgStringFromName<std::string>(referenceframe);
7,267✔
122
}
7,267✔
123

124
CDnaStation::~CDnaStation()
12,044✔
125
{
126
}
66,242✔
127

128
// copy constructors
129
CDnaStation::CDnaStation(const CDnaStation& newStation)
6✔
130
{
131
        m_strName = newStation.m_strName;
6✔
132
        m_strOriginalName = newStation.m_strOriginalName;
6✔
133
        m_strConstraints = newStation.m_strConstraints;
6✔
134
        m_strType = newStation.m_strType;
6✔
135
        m_dXAxis = newStation.m_dXAxis;
6✔
136
        m_dYAxis = newStation.m_dYAxis;
6✔
137
        m_dZAxis = newStation.m_dZAxis;
6✔
138
        m_dHeight = newStation.m_dHeight;
6✔
139
        m_dStdDevX = newStation.m_dStdDevX;
6✔
140
        m_dStdDevY = newStation.m_dStdDevY;
6✔
141
        m_dStdDevZ = newStation.m_dStdDevZ;
6✔
142
        m_dStdDevHt = newStation.m_dStdDevHt;
6✔
143
        m_strHemisphereZone = newStation.m_strHemisphereZone;
6✔
144
        m_strDescription = newStation.m_strDescription;
6✔
145
        m_cLatConstraint = newStation.m_cLatConstraint;
6✔
146
        m_cLonConstraint = newStation.m_cLonConstraint;
6✔
147
        m_cHtConstraint = newStation.m_cHtConstraint;
6✔
148
        m_strComment = newStation.m_strComment;
6✔
149

150
        m_ctTypeSupplied = newStation.m_ctTypeSupplied;
6✔
151
        m_ctType = newStation.m_ctType;
6✔
152
        m_htType = newStation.m_htType;
6✔
153

154
        m_dcurrentLatitude = newStation.m_dcurrentLatitude;
6✔
155
        m_dcurrentLongitude = newStation.m_dcurrentLongitude;
6✔
156
        m_dcurrentHeight = newStation.m_dcurrentHeight;
6✔
157
        m_fgeoidSep = newStation.m_fgeoidSep;
6✔
158
        m_dmeridianDef = newStation.m_dmeridianDef;
6✔
159
        m_dverticalDef = newStation.m_dverticalDef;
6✔
160
        m_lfileOrder = newStation.m_lfileOrder;
6✔
161
        m_lnameOrder = newStation.m_lnameOrder;
6✔
162
        m_zone = newStation.m_zone;
6✔
163
        m_unusedStation = newStation.m_unusedStation;
6✔
164

165
        m_referenceFrame = newStation.m_referenceFrame;
6✔
166
        m_epsgCode = newStation.m_epsgCode;
6✔
167
        m_epoch = newStation.m_epoch;
6✔
168

169
        m_constraintType = newStation.m_constraintType;
6✔
170
}
6✔
171

172
CDnaStation::CDnaStation(const std::string& strName, const std::string& strConstraints, 
21✔
173
        const std::string& strType, const double& dXAxis, const double& dYAxis, const double& dZAxis,
174
        const double& dHeight, const std::string& strHemisphereZone, const std::string& strDescription, 
175
        const std::string& strComment)
21✔
176
{
177
        m_strName = strName;
21✔
178

179
        m_strOriginalName = "";
21✔
180
        
181
        SetConstraints(strConstraints);
21✔
182
        SetCoordType(strType);
21✔
183

184
        m_dXAxis = dXAxis;
21✔
185
        m_dYAxis = dYAxis;
21✔
186
        m_dZAxis = dZAxis;
21✔
187
        m_dHeight = dHeight;
21✔
188

189
        m_dStdDevX = PRECISION_1E5;
21✔
190
        m_dStdDevY = PRECISION_1E5;
21✔
191
        m_dStdDevZ = PRECISION_1E5;
21✔
192
        m_dStdDevHt = PRECISION_1E4;
21✔
193

194
        if (strHemisphereZone.empty())
21✔
195
                m_zone = 0;
21✔
196
        else
197
                SetHemisphereZone(strHemisphereZone);
×
198

199
        m_strDescription = strDescription;
21✔
200
        m_strComment = strComment;
21✔
201
        m_unusedStation = INVALID_STATION;
21✔
202

203
        m_dcurrentLatitude = 0.;
21✔
204
        m_dcurrentLongitude = 0.;
21✔
205
        m_dcurrentHeight = 0.;
21✔
206
        m_fgeoidSep = 0.;
21✔
207
        m_dmeridianDef = 0.;
21✔
208
        m_dverticalDef = 0.;
21✔
209

210
        m_referenceFrame = DEFAULT_DATUM;
21✔
211
        m_epsgCode = DEFAULT_EPSG_S;
21✔
212
        m_epoch = "";
21✔
213
}
21✔
214

215
CDnaStation& CDnaStation::operator =(const CDnaStation& rhs)
×
216
{
217
        // check for assignment to self!
218
        if (this == &rhs)
×
219
                return *this;
220

221
        m_strName = rhs.m_strName;
×
222
        m_strConstraints = rhs.m_strConstraints;
×
223
        m_strType = rhs.m_strType;
×
224
        m_dXAxis = rhs.m_dXAxis;
×
225
        m_dYAxis = rhs.m_dYAxis;
×
226
        m_dZAxis = rhs.m_dZAxis;
×
227
        m_dHeight = rhs.m_dHeight;
×
228
        m_strHemisphereZone = rhs.m_strHemisphereZone;
×
229
        m_strDescription = rhs.m_strDescription;
×
230
        m_cLatConstraint = rhs.m_cLatConstraint;
×
231
        m_cLonConstraint = rhs.m_cLonConstraint;
×
232
        m_cHtConstraint = rhs.m_cHtConstraint;
×
233
        m_strComment = rhs.m_strComment;
×
234

235
        m_ctTypeSupplied = rhs.m_ctTypeSupplied;
×
236
        m_ctType = rhs.m_ctType;
×
237
        m_htType = rhs.m_htType;
×
238

239
        // measurement file extras
240
        m_dStdDevX = rhs.m_dStdDevX;
×
241
        m_dStdDevY = rhs.m_dStdDevY;
×
242
        m_dStdDevHt = rhs.m_dStdDevHt;
×
243

244
        m_dcurrentLatitude = rhs.m_dcurrentLatitude;
×
245
        m_dcurrentLongitude = rhs.m_dcurrentLongitude;
×
246
        m_dcurrentHeight = rhs.m_dcurrentHeight;
×
247
        m_fgeoidSep = rhs.m_fgeoidSep;
×
248
        m_dmeridianDef = rhs.m_dmeridianDef;
×
249
        m_dverticalDef = rhs.m_dverticalDef;
×
250
        m_lfileOrder = rhs.m_lfileOrder;
×
251
        m_lnameOrder = rhs.m_lnameOrder;
×
252
        m_zone = rhs.m_zone;
×
253

254
        m_unusedStation = rhs.m_unusedStation;
×
255

256
        m_referenceFrame = rhs.m_referenceFrame;
×
257
        m_epsgCode = rhs.m_epsgCode;
×
258
        m_epoch = rhs.m_epoch;
×
259

260
        m_constraintType = rhs.m_constraintType;
×
261
        
262
        return *this;
×
263
}
264

265

266
void CDnaStation::SetConstraints(const std::string& sConstraints)
8,152✔
267
{
268
        // capture string, trim whitespace
269
        m_strConstraints = trimstr(sConstraints);
8,152✔
270
        
271
        // No string provided?  Fill with FFF
272
        if (sConstraints.empty())
8,152✔
273
                m_strConstraints = "FFF";
×
274

275
        // Greater than 3 characters?  Trim to 3 characters
276
        if (m_strConstraints.length() > 3)
8,152✔
277
                m_strConstraints = m_strConstraints.substr(0, 3);
×
278
        
279
        // Less than 3 characters?  Pad with 'F'
280
        if (m_strConstraints.length() < 3)
8,152✔
281
                m_strConstraints.append(size_t(3 - m_strConstraints.length()), 'F');
×
282
        
283
        m_cLatConstraint = (char)(*m_strConstraints.substr(0, 1).c_str());
8,152✔
284
        m_cLonConstraint = (char)(*m_strConstraints.substr(1, 1).c_str());
8,152✔
285
        m_cHtConstraint = (char)(*m_strConstraints.substr(2, 1).c_str());
8,152✔
286

287
        // Free in all 3 dimensions
288
        if (boost::iequals(m_strConstraints, "FFF"))
8,152✔
289
                m_constraintType = free_3D;
7,927✔
290
        // Constrained in all 3 dimensions
291
        else if (boost::iequals(m_strConstraints, "CCC"))
225✔
292
                m_constraintType = constrained_3D;
72✔
293
        // Horizontal or 2D adjustment
294
        else if (boost::iequals(m_strConstraints, "FFC"))
153✔
295
                m_constraintType = free_2D;
61✔
296
        // Vertical or 1D adjustment
297
        else if (boost::iequals(m_strConstraints, "CCF"))
92✔
298
                m_constraintType = free_1D;
46✔
299
        else
300
                m_constraintType = custom_constraint;
46✔
301
}
8,152✔
302
        
303

304
void CDnaStation::SetCoordType(const std::string& sType) {
8,152✔
305
        m_strType = trimstr(sType);
8,152✔
306
        m_ctTypeSupplied = m_ctType = GetMyCoordTypeC();        
8,152✔
307
}
8,152✔
308

309
// X, Easting, Latitude
310
void CDnaStation::SetXAxis(const std::string& str)
7,139✔
311
{
312
        switch (m_ctType)
7,139✔
313
        {
314
        case LLH_type_i:
608✔
315
        case LLh_type_i:
608✔
316
                FromDmsString(&m_dXAxis, trimstr(str));
608✔
317
                m_dXAxis = Radians(m_dXAxis);
608✔
318
                break;
608✔
319
        default:
6,531✔
320
                // All other types will be converted by dna_import::ReduceStations_LLH()
321
                DoubleFromString(m_dXAxis, trimstr(str));
13,062✔
322
        }
323
}
7,139✔
324

325

326
// Y, Northing, Longitude
327
void CDnaStation::SetYAxis(const std::string& str)
7,139✔
328
{
329
        switch (m_ctType)
7,139✔
330
        {
331
        case LLH_type_i:
608✔
332
        case LLh_type_i:
608✔
333
                FromDmsString(&m_dYAxis, trimstr(str));
608✔
334
                m_dYAxis = Radians(m_dYAxis);
608✔
335
                break;
608✔
336
        default:
6,531✔
337
                DoubleFromString(m_dYAxis, trimstr(str));
13,062✔
338
        }
339
}
7,139✔
340

341

342
// Z
343
void CDnaStation::SetZAxis(const std::string& str)
259✔
344
{
345
        DoubleFromString(m_dZAxis, trimstr(str));
259✔
346
}
259✔
347

348

349
// Height
350
void CDnaStation::SetHeight(const std::string& str)
6,943✔
351
{
352
        if (GetMyCoordTypeC() == XYZ_type_i)
6,943✔
353
                SetZAxis(str);
63✔
354
        else
355
                DoubleFromString(m_dHeight, trimstr(str));
13,760✔
356
}
6,943✔
357

358
// Hemisphere zone
359
void CDnaStation::SetHemisphereZone(const std::string& sHemisphereZone)
6,924✔
360
{
361
        m_strHemisphereZone = trimstr(sHemisphereZone);
6,924✔
362
        if (m_strHemisphereZone.empty())
6,924✔
363
                return;
364
        if (isdigit(m_strHemisphereZone.substr(0).c_str()[0]))                                        // is the first character a decimal digit?
12,544✔
365
                m_zone = LongFromString<UINT32>(m_strHemisphereZone.substr(0));                // extract zone from first position
12,516✔
366
        else
367
                m_zone = LongFromString<UINT32>(m_strHemisphereZone.substr(1));                // extract zone after hemisphere
28✔
368
}
369

370
// Reduce from Cartesian or Projection to Geographic
371
// m_dXAxis always contains X, Easting and Latitude
372
// m_dYAxis always contains Y, Northing and Longitude
373
void CDnaStation::ReduceStations_LLH(const CDnaEllipsoid* m_eEllipsoid, const CDnaProjection* m_pProjection)
7,163✔
374
{
375
        switch (m_ctType)
7,163✔
376
        {
377
        case XYZ_type_i:
283✔
378
                // Convert from cartesian to geographic (radians)
379
                CartToGeo<double>(m_dXAxis, m_dYAxis, m_dZAxis, &m_dXAxis, &m_dYAxis, &m_dHeight, m_eEllipsoid);
283✔
380
                m_dZAxis= 0.;
283✔
381
                m_htType = ELLIPSOIDAL_type_i;
283✔
382

383
                // Force the current type to be geographic (ellipsoid height).  
384
                // The user-supplied type is retained in m_ctTypeSupplied
385
                m_ctType = LLh_type_i;
283✔
386
                m_strType = LLh_type;
283✔
387
                break;
283✔
388
        case UTM_type_i:
6,272✔
389
                // Convert from projection to geographic (radians)
390
                GridToGeo<double, UINT32>(m_dXAxis, m_dYAxis, m_zone, &m_dXAxis, &m_dYAxis, 
6,272✔
391
                        m_eEllipsoid->GetSemiMajor(), m_eEllipsoid->GetInverseFlattening(),                // ellipsoid parameters
6,272✔
392
                        m_pProjection->GetFalseEasting(), m_pProjection->GetFalseNorthing(),        // projection parameters
6,272✔
393
                        m_pProjection->GetCentralScaleFactor(), m_pProjection->GetLongCentralMeridianZone1(), 
6,272✔
394
                        m_pProjection->GetZoneWidth());
6,272✔
395

396
                // Force the current type to be geographic (orthometric height).
397
                // The user-supplied type is retained in m_ctTypeSupplied
398
                m_ctType = LLH_type_i;
6,272✔
399
                m_strType = LLH_type;
6,272✔
400
                break;
6,272✔
401
        default:
402
                break;
403
        }
404
}
7,163✔
405

406
// Reduce from Geographic or Projection to Cartesian
407
// m_dXAxis always contains X, Easting and Latitude
408
// m_dYAxis always contains Y, Northing and Longitude
409
void CDnaStation::ReduceStations_XYZ(const CDnaEllipsoid* m_eEllipsoid, const CDnaProjection* m_pProjection)
3✔
410
{
411
        switch (m_ctType)
3✔
412
        {
413
        case UTM_type_i:
×
414
                // Convert from projection to geographic (radians)
415
                GridToGeo<double, UINT32>(m_dXAxis, m_dYAxis, m_zone, &m_dXAxis, &m_dYAxis, 
×
416
                        m_eEllipsoid->GetSemiMajor(), m_eEllipsoid->GetInverseFlattening(),        // ellipsoid parameters
×
417
                        m_pProjection->GetFalseEasting(), m_pProjection->GetFalseNorthing(),        // projection parameters
×
418
                        m_pProjection->GetCentralScaleFactor(), m_pProjection->GetLongCentralMeridianZone1(), 
×
419
                        m_pProjection->GetZoneWidth());
×
420
                [[fallthrough]];
3✔
421
        case LLH_type_i:
3✔
422
        case LLh_type_i:
3✔
423
                m_dcurrentLatitude = m_dXAxis;
3✔
424
                m_dcurrentLongitude = m_dYAxis;
3✔
425
                m_dcurrentHeight = m_dHeight;
3✔
426
                if (m_ctType == LLH_type_i)
3✔
427
                        m_dcurrentHeight += m_fgeoidSep;
3✔
428
                // Convert from geographic (radians) to cartesian
429
                // Assumes height is ellipsoidal
430
                GeoToCart<double>(m_dcurrentLatitude, m_dcurrentLongitude, m_dcurrentHeight, &m_dXAxis, &m_dYAxis, &m_dZAxis, m_eEllipsoid);
3✔
431
                break;
3✔
432
        default:
433
                break;
434
        }
435

436
        // Force the current type to be geographic.  The user-supplied type is retained in m_ctTypeSupplied
437
        m_ctType = XYZ_type_i;
3✔
438
        m_strType = XYZ_type;
3✔
439
}
3✔
440

441
bool CDnaStation::IsValidConstraint(const std::string& sConst)
4✔
442
{
443
        if (boost::iequals(sConst, "CCC"))
4✔
444
                return true;
445
        if (boost::iequals(sConst, "CCF"))
1✔
446
                return true;
447
        if (boost::iequals(sConst, "CFF"))
1✔
448
                return true;
449
        if (boost::iequals(sConst, "FFF"))
1✔
450
                return true;
451
        if (boost::iequals(sConst, "FFC"))
1✔
452
                return true;
453
        if (boost::iequals(sConst, "FCC"))
1✔
454
                return true;
455
        if (boost::iequals(sConst, "FCF"))
1✔
456
                return true;
457
        if (boost::iequals(sConst, "CFC"))
1✔
458
                return true;
×
459
        return false;
460
}
461
        
462

463
_COORD_TYPE_ CDnaStation::GetCoordTypeC(const std::string& sType)
23,112✔
464
{
465
        // case insensitive
466
        if (boost::iequals(sType, XYZ_type))
23,112✔
467
                return XYZ_type_i;
468
        else if (boost::iequals(sType, UTM_type))
20,766✔
469
                return UTM_type_i;                                // height is assumed to be orthometric
470
        else if (boost::iequals(sType, ENU_type))
3,007✔
471
                return ENU_type_i;
472

473
        // case sensitive
474
        else if (boost::equals(sType, LLh_type))
3,007✔
475
                return LLh_type_i;                                // ellipsoid height
476
        
477
        // default
478
        else if (boost::equals(sType, LLH_type))
2,868✔
479
                return LLH_type_i;                                        // orthometric height (default)
480

481
        // If this point is reached, sType is an unknown coordinate type, so throw!
NEW
482
        std::stringstream ss;
×
NEW
483
        ss << "  '" << sType << "' is not a recognised coordinate type." << std::endl;
×
NEW
484
        throw boost::enable_current_exception(std::runtime_error(ss.str()));
×
485

486
        return LLH_type_i;
487
}
×
488

489

490
_COORD_TYPE_ CDnaStation::GetMyCoordTypeC() const
20,962✔
491
{
492
        return GetCoordTypeC(m_strType);
20,962✔
493
}
494

495

NEW
496
_HEIGHT_SYSTEM_ CDnaStation::GetHeightSystemC(const std::string& sType) const
×
497
{
498
        if (sType.compare(ELLIPSOIDAL_type) == 0)
×
499
                return ELLIPSOIDAL_type_i;
×
500
        return ORTHOMETRIC_type_i;                // default
501
}
502

503

504
_HEIGHT_SYSTEM_ CDnaStation::GetMyHeightSystemC() const
×
505
{
506
        if (m_strType.compare(LLh_type) == 0)
×
507
                return ELLIPSOIDAL_type_i;
×
508
        return ORTHOMETRIC_type_i;        // default
509
}
510

511
// SetHeightSystem called by void Height_pimpl::system(const ::std::string& system)
512
// where system is an attribute of the element Height (either "ellipsoidal" or "orthometric")
NEW
513
void CDnaStation::SetHeightSystem(const std::string& sType)
×
514
{
515
        SetHeightSystem(GetHeightSystemC(sType));
×
516
}
×
517
        
518
void CDnaStation::SetHeightSystem(const HEIGHT_SYSTEM& type_i)
×
519
{
520
        m_htType = type_i;
×
521

522
        switch (m_htType)
×
523
        {
524
        case ELLIPSOIDAL_type_i:
×
525
                // Convert to orthometric
526
                if (m_ctType == LLH_type_i)
×
527
                        m_ctType = LLh_type_i;
×
528
                if (m_strType.compare(LLH_type))
×
529
                        m_strType = LLh_type;
×
530
                break;
531
        case ORTHOMETRIC_type_i:
×
532
                // Convert to ellipsoidal
533
                if (m_ctType == LLh_type_i)
×
534
                        m_ctType = LLH_type_i;
×
535
                if (m_strType.compare(LLh_type))
×
536
                        m_strType = LLH_type;
×
537
                break;
538
        }
539
}
×
540

541
//void CDnaStation::coutStationData(std::ostream &os, ostream &os2, const UINT16& uType) const
542
//{
543
//        UINT32 precision = 3;
544
//        if (m_ctType == LLH_type_i)
545
//                precision = 10;
546
//        std::stringstream ss;
547
//        std::string str;
548
//        size_t dot;
549
//
550
//        switch (uType)
551
//        {
552
//        case DNA_COUT:
553
//        case GEOLAB_COUT:
554
//                
555
//                os << "+ " << std::setw(16) << m_strName;
556
//                os << std::setw(4) << m_strConstraints;
557
//                os << std::setw(4) << m_strType;
558
//                os << std::setw(20) << std::setprecision(precision) << std::fixed << (m_ctType == LLH_type_i ? RadtoDms(m_dXAxis): m_dXAxis);
559
//                os << std::setw(20) << std::setprecision(precision) << std::fixed << (m_ctType == LLH_type_i ? RadtoDmsL(m_dYAxis): m_dYAxis);
560
//                //os << std::setw(16) << vStations[s].GetZAxis();
561
//                os << std::setw(13) << std::setprecision(4) << std::fixed << m_dHeight;
562
//                //os << std::setw(10) << vStations[s].GetRedHeight();
563
//                os << std::setw(5) << m_strHemisphereZone;
564
//                os << std::setw(6) << m_lnameOrder;
565
//                os << std::setw(19) << m_strDescription;
566
//                //os << std::setw(10) << vStations[s].GetComment();
567
//                os << std::endl;
568
//                break;
569
//        case NEWGAN_COUT:
570
//                os << std::setw(3) << "4";
571
//                os << std::right << std::setw(12) << m_strName;
572
//                os << " ";
573
//                os << std::left << std::setw(23) << m_strDescription.substr(0, 23);
574
//                ss.str("");
575
//                ss << std::setprecision(precision) << std::fixed << (m_ctType == LLH_type_i ? RadtoDms(m_dXAxis): m_dXAxis);
576
//                str = trimstr(ss.str());
577
//                dot = str.find(".");
578
//                str.replace(dot, 1, " ");
579
//                str.insert(dot+5, ".");
580
//                if (m_dXAxis < 0)
581
//                {
582
//                        str.replace(0, 1, " ");                // replace negative sign
583
//                        str = trimstr(str);
584
//                        os << std::left << "S" << std::setw(precision + 4) << std::right << str;
585
//                }
586
//                else
587
//                        os << std::left << "N" << std::setw(precision + 4) << std::right << str;
588
//                
589
//                ss.str("");
590
//                ss << std::setprecision(precision) << std::fixed << (m_ctType == LLH_type_i ? RadtoDmsL(m_dYAxis): m_dYAxis);
591
//                str = trimstr(ss.str());
592
//                dot = str.find(".");
593
//                str.replace(dot, 1, " ");
594
//                str.insert(dot+5, ".");
595
//                if (m_dYAxis < 0)
596
//                {
597
//                        str.replace(0, 1, " ");                // replace negative sign
598
//                        str = trimstr(str);
599
//                        os << std::left << "W" << std::setw(precision + 5) << std::right << str;
600
//                }
601
//                else
602
//                        os << std::left << "E" << std::setw(precision + 5) << std::right << str;
603
//                
604
//                
605
//                os << std::right << std::setw(9) << std::setprecision(3) << std::fixed << m_dHeight;
606
//                os << std::endl;
607
//                break;
608
//        case GMT_OUT:
609
//                os << std::setprecision(precision) << std::fixed << (m_ctType == LLH_type_i ? DegreesL(m_dYAxis): m_dYAxis);
610
//                os << "  ";
611
//                os << std::setprecision(precision) << std::fixed << (m_ctType == LLH_type_i ? Degrees(m_dXAxis): m_dXAxis);
612
//                os << std::endl;
613
//
614
//                os2 << std::setprecision(precision) << std::fixed << (m_ctType == LLH_type_i ? DegreesL(m_dYAxis): m_dYAxis);
615
//                os2 << "  ";
616
//                os2 << std::setprecision(precision) << std::fixed << (m_ctType == LLH_type_i ? Degrees(m_dXAxis): m_dXAxis);
617
//                os2 << "  6 0 0 LM " << m_strName << std::endl;                
618
//                break;
619
//        }
620
//        
621
//
622
//}
623

624

625
void CDnaStation::WriteBinaryStn(std::ofstream* binary_stream, const UINT16 bUnused)
6,892✔
626
{
627
        station_t stationRecord;
6,892✔
628
        strcpy(stationRecord.stationName, m_strName.substr(0, STN_NAME_WIDTH).c_str());
6,892✔
629
        strcpy(stationRecord.stationNameOrig, m_strOriginalName.substr(0, STN_NAME_WIDTH).c_str());
6,892✔
630
        strcpy(stationRecord.stationConst, m_strConstraints.substr(0, STN_CONST_WIDTH).c_str());
6,892✔
631
        strcpy(stationRecord.stationType, m_strType.substr(0, STN_TYPE_WIDTH).c_str());
6,892✔
632

633
        stationRecord.suppliedStationType = m_ctTypeSupplied;
6,892✔
634

635
        switch (m_ctTypeSupplied)
6,892✔
636
        {
637
        case LLH_type_i:
6,614✔
638
        case UTM_type_i:
6,614✔
639
                stationRecord.suppliedHeightRefFrame = ORTHOMETRIC_type_i;
6,614✔
640
                break;
6,614✔
641
        default:
642
                break;
643
        }
644

645
        stationRecord.initialLatitude = m_dXAxis;
6,892✔
646
        if (fabs(m_dcurrentLatitude - 0.) < PRECISION_1E15)
6,892✔
647
                stationRecord.currentLatitude = m_dXAxis;
6,781✔
648
        else
649
                stationRecord.currentLatitude = m_dcurrentLatitude;
111✔
650
        
651
        stationRecord.initialLongitude = m_dYAxis;
6,892✔
652
        if (fabs(m_dcurrentLongitude - 0.) < PRECISION_1E15)
6,892✔
653
                stationRecord.currentLongitude = m_dYAxis;
6,781✔
654
        else
655
                stationRecord.currentLongitude = m_dcurrentLongitude;
111✔
656

657
        stationRecord.initialHeight = m_dHeight;        
6,892✔
658
        if (fabs(m_dcurrentHeight - 0.) < PRECISION_1E15)
6,892✔
659
                stationRecord.currentHeight = m_dHeight;
6,632✔
660
        else
661
                stationRecord.currentHeight = m_dcurrentHeight;
260✔
662
                
663
        stationRecord.geoidSep = m_fgeoidSep;
6,892✔
664
        stationRecord.meridianDef = m_dmeridianDef;
6,892✔
665
        stationRecord.verticalDef = m_dverticalDef;
6,892✔
666
        stationRecord.zone = m_zone;
6,892✔
667
        strcpy(stationRecord.description, m_strDescription.substr(0, STN_DESC_WIDTH).c_str());
6,892✔
668
        stationRecord.fileOrder = m_lfileOrder;
6,892✔
669
        stationRecord.nameOrder = m_lnameOrder;
6,892✔
670
        stationRecord.unusedStation = bUnused;
6,892✔
671

672
        strcpy(stationRecord.epoch, m_epoch.substr(0, STN_EPOCH_WIDTH).c_str());
6,892✔
673
        strcpy(stationRecord.epsgCode, m_epsgCode.substr(0, STN_EPSG_WIDTH).c_str());
6,892✔
674

675
        binary_stream->write(reinterpret_cast<char *>(&stationRecord), sizeof(station_t));
6,892✔
676
}
6,892✔
677

678

679
void CDnaStation::WriteDNAXMLStnCurrentEstimates(std::ofstream* dna_ofstream, 
883✔
680
        const CDnaEllipsoid* ellipsoid, const CDnaProjection* projection,
681
        INPUT_FILE_TYPE t, const dna_stn_fields* dsw)
682
{
683
        // Get the latest estimates
684
        double lat_east_x(m_dcurrentLatitude);
883✔
685
        double lon_north_y(m_dcurrentLongitude);
883✔
686
        double ht_zone_z(m_dcurrentHeight);
883✔
687

688
        // Write latest station estimates
689
        WriteDNAXMLStn(dna_ofstream,
883✔
690
                ellipsoid, projection,
691
                lat_east_x, lon_north_y, ht_zone_z,
692
                t, dsw);
693
}
883✔
694
        
695

696
void CDnaStation::WriteDNAXMLStnInitialEstimates(std::ofstream* dna_ofstream, 
584✔
697
        const CDnaEllipsoid* ellipsoid, const CDnaProjection* projection,
698
        INPUT_FILE_TYPE t, const dna_stn_fields* dsw)
699
{
700
        // Write initial station estimates
701
        WriteDNAXMLStn(dna_ofstream,
584✔
702
                ellipsoid, projection,
703
                m_dXAxis, m_dYAxis, m_dHeight,
584✔
704
                t, dsw);
705
}
584✔
706

707

708
void CDnaStation::WriteDNAXMLStn(std::ofstream* dna_ofstream,
1,467✔
709
        const CDnaEllipsoid* ellipsoid, const CDnaProjection* projection,
710
        const double& lat_east_x, const double& lon_north_y, const double& ht_zone_z,
711
        INPUT_FILE_TYPE t, const dna_stn_fields* dsw)
712
{
713
        //m_ctTypeSupplied = LLh_type_i;
714

715
        std::string hemisphereZone(m_strHemisphereZone);
1,467✔
716
        std::string coordinateType(LLH_type);
1,467✔
717

718
        switch (m_ctTypeSupplied)
1,467✔
719
        {
720
        case XYZ_type_i:
179✔
721
                coordinateType = XYZ_type;
179✔
722
                break;
723
        case LLh_type_i:
×
724
                coordinateType = LLh_type;
×
725
                break;
726
        case UTM_type_i:
894✔
727
                coordinateType = UTM_type;
894✔
728
                break;
729
        case ENU_type_i:        // Not supported yet, so revert to Lat, Long, Height
×
730
                coordinateType = LLH_type;
×
731
                m_ctTypeSupplied = LLH_type_i;
×
732
                break;
×
733
        case LLH_type_i:
394✔
734
                coordinateType = LLH_type;
394✔
735
                break;
736
        default:
737
                break;
738
        }
739

740
        // Convert height to orthometric?
741
        // Decisions for printing (estimated) station height for various input coordinate types
742
        // and geoid model.  Estimated stations are in LLh.
743
        // h = H + Na
744
        //
745
        // Input Coord type                Geoid loaded?          Geoid not loaded?          Result
746
        // ---------------------------------------------------------------------------------
747
        // LLH                                    ht_z - m_fgeoidSep     ht_z (m_fgeoidSep = 0)     H (orthometric)
748
        // UTM                                        ht_z - m_fgeoidSep     ht_z (m_fgeoidSep = 0)     H (orthometric)
749
        // ENU                                        ht_z - m_fgeoidSep     ht_z (m_fgeoidSep = 0)     H (orthometric)
750
        // LLh                      ht_z                               ht_z                                              h (ellipsoid)
751
        // XYZ                      LLh->XYZ                       LLh->XYZ                                          X, Y, Z
752
        double lat_east_x_mod(lat_east_x);
1,467✔
753
        double lon_north_y_mod(lon_north_y);
1,467✔
754
        double ht_zone_z_mod(ht_zone_z);
1,467✔
755

756
        switch (m_ctTypeSupplied)
1,467✔
757
        {
758
        case LLH_type_i:
1,288✔
759
        case UTM_type_i:
1,288✔
760
                // reduce to orthometric.  
761
                // If geoid hasn't been loaded, m_fgeoidSep will be 0.0
762
                ht_zone_z_mod -= m_fgeoidSep;
1,288✔
763
                break;
1,288✔
764
        default:
765
                break;
766
        }
767

768
        // Convert coordinates to cartesian or utm?
769
        // Convert radians values to degrees, minutes and seconds?
770
        std::stringstream ss;
2,934✔
771
        double zone;
1,467✔
772
        switch (m_ctTypeSupplied)
1,467✔
773
        {
774
        case XYZ_type_i:
179✔
775
                GeoToCart<double>(lat_east_x, lon_north_y, ht_zone_z, 
179✔
776
                        &lat_east_x_mod, &lon_north_y_mod, &ht_zone_z_mod, ellipsoid);
777
                break;
778
        
779
        case UTM_type_i:
894✔
780
                GeoToGrid<double>(lat_east_x, lon_north_y, 
894✔
781
                        &lat_east_x_mod, &lon_north_y_mod, &zone, ellipsoid, projection, true);
782
                
783
                ss << std::fixed << std::setprecision(0) << zone;
894✔
784
                hemisphereZone = ss.str();        
894✔
785
                break;
894✔
786

787
        case LLh_type_i:
394✔
788
        case LLH_type_i:
394✔
789
                lat_east_x_mod = RadtoDms(lat_east_x);
394✔
790
                lon_north_y_mod = RadtoDmsL(lon_north_y);
394✔
791
                break;
394✔
792
        default:
793
                break;
794
        }
795

796
        switch (t)
1,467✔
797
        {
798
        case dna:
701✔
799
        
800
                // Write DNA station file
801
                WriteDNAStn(dna_ofstream, coordinateType,
701✔
802
                        lat_east_x_mod, lon_north_y_mod, ht_zone_z_mod, 
803
                        hemisphereZone, *dsw);
804
                break;
805

806
        case dynaml:
766✔
807

808
                // Write DynAdjust XML station file
809
                WriteDynaMLStn(dna_ofstream, coordinateType,
766✔
810
                        lat_east_x_mod, lon_north_y_mod, ht_zone_z_mod,
811
                        hemisphereZone);
812
                break;
813
        default:
814
                break;
815
        }
816
}
2,934✔
817

818
void CDnaStation::WriteDNAStn(std::ofstream* dna_ofstream, const std::string& coordinateType, 
701✔
819
        const double& lat_east_x, const double& lon_north_y, const double& ht_zone_z,
820
        std::string& hemisphereZone, const dna_stn_fields& dsw)
821
{        
822
        UINT32 LEX_precision(4), LNY_precision(4), HZ_precision(4);        
701✔
823
        
824
        switch (m_ctTypeSupplied)
701✔
825
        {
826
        case LLh_type_i:
142✔
827
        case LLH_type_i:
142✔
828
                LEX_precision = LNY_precision = 10;
142✔
829
                break;
142✔
830
        default:
831
                break;
832
        }
833

834
        (*dna_ofstream) << std::left << std::setw(dsw.stn_name) << m_strName;
701✔
835
        (*dna_ofstream) << std::left << std::setw(dsw.stn_const) << m_strConstraints;
701✔
836
        (*dna_ofstream) << " ";
701✔
837
        (*dna_ofstream) << std::left << std::setw(dsw.stn_type) << coordinateType;
701✔
838
        (*dna_ofstream) << std::right << std::setw(dsw.stn_e_phi_x) << std::setprecision(LEX_precision) << std::fixed << lat_east_x;
701✔
839
        (*dna_ofstream) << std::right << std::setw(dsw.stn_n_lam_y) << std::setprecision(LNY_precision) << std::fixed << lon_north_y;
701✔
840
        (*dna_ofstream) << std::right << std::setw(dsw.stn_ht_z) << std::setprecision(HZ_precision) << std::fixed << ht_zone_z;        
701✔
841
        if (m_ctTypeSupplied == UTM_type_i)
701✔
842
                (*dna_ofstream) << std::right << std::setw(dsw.stn_hemi_zo) << hemisphereZone;
447✔
843
        else
844
                (*dna_ofstream) << std::right << std::setw(dsw.stn_hemi_zo) << " ";
254✔
845
        (*dna_ofstream) << " ";
701✔
846
        (*dna_ofstream) << std::left << m_strDescription << std::endl;
701✔
847
}
701✔
848
        
849

850
void CDnaStation::WriteDynaMLStn(std::ofstream* xml_ofstream, const std::string& coordinateType, 
766✔
851
        const double& lat_east_x, const double& lon_north_y, const double& ht_zone_z,
852
        std::string& hemisphereZone)
853
{
854
        UINT32 LEX_precision(4), LNY_precision(4), HZ_precision(4);
766✔
855
        
856
        // Convert radians values to degrees, minutes and seconds
857
        switch (m_ctTypeSupplied)
766✔
858
        {
859
        case LLh_type_i:
252✔
860
        case LLH_type_i:
252✔
861
                LEX_precision = LNY_precision = 10;
252✔
862
                break;
252✔
863
        default:
864
                break;
865
        }
866
        
867
        (*xml_ofstream) << "  <DnaStation>" << std::endl;
766✔
868
        (*xml_ofstream) << "    <Name>" << m_strName << "</Name>" << std::endl;
766✔
869
        (*xml_ofstream) << "    <Constraints>" << m_strConstraints << "</Constraints>" << std::endl;
766✔
870
        (*xml_ofstream) << "    <Type>" << coordinateType << "</Type>" << std::endl;
766✔
871
        (*xml_ofstream) << "    <StationCoord>" << std::endl;
766✔
872
        (*xml_ofstream) << "      <Name>" << m_strName << "</Name>" << std::endl;
766✔
873
        (*xml_ofstream) << "      <XAxis>" << std::setprecision(LEX_precision) << std::fixed << lat_east_x << "</XAxis>" << std::endl;
766✔
874
        (*xml_ofstream) << "      <YAxis>" << std::setprecision(LNY_precision) << std::fixed << lon_north_y << "</YAxis>" << std::endl;
766✔
875
        (*xml_ofstream) << "      <Height>" << std::setprecision(HZ_precision) << std::fixed << ht_zone_z << "</Height>" << std::endl;
766✔
876
        
877
        // Convert radians values to degrees, minutes and seconds
878
        if (m_ctTypeSupplied == UTM_type_i)
766✔
879
                (*xml_ofstream) << "      <HemisphereZone>" << hemisphereZone << "</HemisphereZone>" << std::endl;
447✔
880
        
881
        (*xml_ofstream) << "    </StationCoord>" << std::endl;
766✔
882
        (*xml_ofstream) << "    <Description>"  << m_strDescription << "</Description>" << std::endl;
766✔
883
        (*xml_ofstream) << "  </DnaStation>" << std::endl;
766✔
884
}
766✔
885
        
886

887
void CDnaStation::WriteGeoidfile(std::ofstream* geo_ofstream)
×
888
{
NEW
889
        (*geo_ofstream) << std::setw(44) << std::left << m_strName <<
×
NEW
890
                std::setw(15) << std::setprecision(3) << std::fixed << std::left << m_fgeoidSep <<
×
NEW
891
                std::setw(10) << std::setprecision(3) << std::fixed << std::right << m_dmeridianDef <<
×
NEW
892
                std::setw(10) << std::setprecision(3) << std::fixed << std::right << m_dverticalDef << std::endl;
×
UNCOV
893
}
×
894
        
895

896
void CDnaStation::SetStationRec(const station_t& stationRecord)
992✔
897
{
898
        SetName(stationRecord.stationName);
1,984✔
899
        SetOriginalName(stationRecord.stationNameOrig);
1,984✔
900
        SetConstraints(stationRecord.stationConst);
1,984✔
901
        SetCoordType(stationRecord.stationType);
1,984✔
902
        
903
        switch (stationRecord.suppliedStationType)
992✔
904
        {
905
        case UTM_type_i:
669✔
906
                m_ctTypeSupplied = UTM_type_i;
669✔
907
                break;
669✔
908
        case XYZ_type_i:
127✔
909
                m_ctTypeSupplied = XYZ_type_i;
127✔
910
                break;
127✔
911
        case ENU_type_i:
×
912
                m_ctTypeSupplied = ENU_type_i;
×
913
                break;
×
914
        case LLh_type_i:
×
915
                m_ctTypeSupplied = LLh_type_i;
×
916
                break;
×
917
        default:
196✔
918
        case LLH_type_i:
196✔
919
                m_ctTypeSupplied = LLH_type_i;
196✔
920
                break;
196✔
921
        }
922
        
923
        m_dXAxis = stationRecord.initialLatitude;
992✔
924
        m_dYAxis = stationRecord.initialLongitude;
992✔
925
        m_dHeight = stationRecord.initialHeight;
992✔
926
        m_dcurrentLatitude = stationRecord.currentLatitude;
992✔
927
        m_dcurrentLongitude = stationRecord.currentLongitude;
992✔
928
        m_dcurrentHeight = stationRecord.currentHeight;
992✔
929
        m_fgeoidSep = stationRecord.geoidSep;
992✔
930
        m_dmeridianDef = stationRecord.meridianDef;
992✔
931
        m_dverticalDef = stationRecord.verticalDef;
992✔
932
        m_zone = stationRecord.zone;
992✔
933
        if (stationRecord.initialLatitude < 0.)
992✔
934
                m_strHemisphereZone = "S";
959✔
935
        else
936
                m_strHemisphereZone = "N";
33✔
937
        char zone[3];
992✔
938
        sprintf(zone, "%d", m_zone);
992✔
939
        m_strHemisphereZone += zone;
992✔
940
        SetDescription(stationRecord.description);
1,984✔
941
        m_lfileOrder = stationRecord.fileOrder;
992✔
942
        m_lnameOrder = stationRecord.nameOrder;
992✔
943
        m_unusedStation = (stationRecord.unusedStation == VALID_STATION ? true : false);
992✔
944

945
        m_epoch = stationRecord.epoch;
992✔
946
        m_epsgCode = stationRecord.epsgCode;
992✔
947
        m_referenceFrame = datumFromEpsgCode<std::string, UINT32>(LongFromString<UINT32>(m_epsgCode));
992✔
948
}
992✔
949

950
std::string CDnaStation::CoordinateName(const char& c)
463✔
951
{
952
        switch (c)
463✔
953
        {
954
        case 'P':
71✔
955
                return "Latitude";
71✔
956
        case 'L':
71✔
957
                return "Longitude";
71✔
958
        case 'H':
63✔
959
                return "H(Ortho)";
63✔
960
        case 'h':
63✔
961
                return "h(Ellipse)";
63✔
962
        case 'E':
4✔
963
                return "Easting";
4✔
964
        case 'N':
4✔
965
                return "Northing";
4✔
966
        case 'z':
4✔
967
                return "Zone";
4✔
968
        case 'X':
61✔
969
                return "X";
61✔
970
        case 'Y':
61✔
971
                return "Y";
61✔
972
        case 'Z':
61✔
973
                return "Z";
61✔
974
        }
975
        return "";
×
976
}
977

978
}        // namespace measurements
979
}        // 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

© 2026 Coveralls, Inc