-
Notifications
You must be signed in to change notification settings - Fork 0
/
DgGeoSphRF.cpp
146 lines (112 loc) · 4.21 KB
/
DgGeoSphRF.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
////////////////////////////////////////////////////////////////////////////////
//
// DgGeoSphRF.cpp: DgGeoSphRF class implementation
//
// Version 6.1 - Kevin Sahr, 5/23/13
//
////////////////////////////////////////////////////////////////////////////////
#include "DgGeoSphRF.h"
#include "DgIDGG.h"
#include "DgConstants.h"
#include "DgPolygon.h"
// these are initialized here but will get set again when the datum is created
long double DgGeoSphRF::earthRadiusKM_ = DEFAULT_RADIUS_KM;
long double DgGeoSphRF::icosaEdgeRads_ = M_ATAN2;
long double DgGeoSphRF::icosaEdgeDegs_ = icosaEdgeRads_ * M_180_PI;
long double DgGeoSphRF::icosaEdgeKM_ = icosaEdgeRads_ * earthRadiusKM_;
long double DgGeoSphRF::totalAreaKM_ =
4.0L * dgM_PI * earthRadiusKM_ * earthRadiusKM_;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void
DgGeoSphRF::densify (DgPolygon& p, long double maxDist, bool rads)
{
if (maxDist <= 0) return;
const DgGeoSphRF* gs = dynamic_cast<const DgGeoSphRF*>(&p.rf());
if (gs == 0) report("DgGeoSphRF::densify() with non-CCRF", DgBase::Fatal);
if (!rads) maxDist *= dgM_PI_180;
DgPolygon densVerts(*gs);
vector<DgAddressBase*>& v0 = p.addressVec();
vector<DgAddressBase*>& v1 = densVerts.addressVec();
// for each edge
for (unsigned long i = 0; i < v0.size(); i++)
{
DgGeoCoord p1 = dynamic_cast< DgAddress<DgGeoCoord>& >(*v0[i]).address();
DgGeoCoord p2 = dynamic_cast< DgAddress<DgGeoCoord>& >(
*v0[(i + 1) % v0.size()]).address();
// add the first point
v1.push_back(new DgAddress<DgGeoCoord>(p1));
while (DgGeoCoord::gcDist(p1, p2) > maxDist)
{
DgGeoCoord p3 = travelGC(p1, maxDist, azimuth(p1, p2));
v1.push_back(new DgAddress<DgGeoCoord>(p3));
p1 = p3;
}
// p2 should get pushed next time
}
// now replace the original with the densified version
p = densVerts;
} // void DgGeoSphRF::densify
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
DgGeoCoord
DgGeoSphRF::midPoint (const DgGeoCoord& p1, const DgGeoCoord& p2)
/*
Return midpoint of great circle connecting two points.
Works by calling Lian Song's routine GCmidpoint.
*/
{
GeoCoord pp1, pp2;
pp1.lon = p1.lon();
pp1.lat = p1.lat();
pp2.lon = p2.lon();
pp2.lat = p2.lat();
GeoCoord ans = GCmidpoint(pp1, pp2);
return DgGeoCoord(ans.lon, ans.lat);
} // DgGeoCoord DgGeoSphRF::midPoint
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
long double
DgGeoSphRF::azimuth (const DgGeoCoord& p1, const DgGeoCoord& p2,
bool returnRads)
/*
Return azimuth from p1 to p2.
Works by calling Lian Song's routine Azimuth.
*/
{
GeoCoord pp1, pp2;
pp1.lon = p1.lon();
pp1.lat = p1.lat();
pp2.lon = p2.lon();
pp2.lat = p2.lat();
long double ans = Azimuth(pp1, pp2);
if (!returnRads) ans *= M_180_PI;
return ans;
} // long double DgGeoSphRF::azimuth
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
DgGeoCoord
DgGeoSphRF::travelGC (const DgGeoCoord& p0, long double distance, long double azimuth,
bool inputRads)
/*
Return point that is distance from p0 along azimuth.
Works by calling Lian Song's routine Azimuth.
*/
{
GeoCoord pp0;
pp0.lon = p0.lon();
pp0.lat = p0.lat();
if (!inputRads)
{
distance *= dgM_PI_180;
azimuth *= dgM_PI_180;
}
GeoCoord ans = GCdaz(pp0, distance, azimuth);
return DgGeoCoord(ans.lon, ans.lat);
} // long double DgGeoSphRF::azimuth
////////////////////////////////////////////////////////////////////////////////
DgGeoSphDegRF::DgGeoSphDegRF (const DgGeoSphRF& geoRFin, const string& nameIn)
: DgContCartRF (geoRFin.network(), nameIn), geoRF_ (geoRFin)
{
new DgDegConverter(geoRFin, *this);
}