1 //*******************************************************************
2 //
3 // License: See top level LICENSE.txt file.
4 //
5 // DESCRIPTION:
6 // This class maintains the relationship between a local space rectangular
7 // (LSR) coordinate system and the earth-centered, earth-fixed (ECEF) system.
8 //
9 // SOFTWARE HISTORY:
10 //
11 // 09Aug2001 Oscar Kramer (okramer@imagelinks.com)
12 // Initial coding.
13 //
14 //*****************************************************************************
15 // $Id: ossimLsrSpace.cpp 17593 2010-06-17 19:07:26Z dburken $
16
17 #include <ossim/base/ossimLsrSpace.h>
18 #include <ossim/base/ossimCommon.h>
19 #include <ossim/base/ossimGpt.h>
20 #include <ossim/base/ossimColumnVector3d.h>
21 #include <ossim/base/ossimEcefVector.h>
22
23 using namespace std;
24
25
26 //*****************************************************************************
27 // CONSTRUCTOR: ossimLsrSpace(origin, x_dir, y_dir, int)
28 //
29 // Constructs the space given origin, and X and Y ECEF directions. The int
30 // argument is a place holder only and not used.
31 //
32 //*****************************************************************************
ossimLsrSpace(const ossimEcefPoint & origin,const ossimEcefVector & x_dir_ecf_vec,const ossimEcefVector & y_dir_ecf_vec,int)33 ossimLsrSpace::ossimLsrSpace(const ossimEcefPoint& origin,
34 const ossimEcefVector& x_dir_ecf_vec,
35 const ossimEcefVector& y_dir_ecf_vec,
36 int /* z_not_provided_space_holder */)
37 : theOrigin (origin)
38 {
39 //***
40 // Compute the remaining axis given first two:
41 //***
42 ossimColumnVector3d xdir (x_dir_ecf_vec.data().unit());
43 ossimColumnVector3d ydir (y_dir_ecf_vec.data().unit());
44 ossimColumnVector3d zdir (xdir.cross(ydir));
45
46 //***
47 // Fill the rotation matrix:
48 //***
49 theLsrToEcefRotMatrix = ossimMatrix3x3::create(xdir[0], ydir[0], zdir[0],
50 xdir[1], ydir[1], zdir[1],
51 xdir[2], ydir[2], zdir[2]);
52 }
53
54 //*****************************************************************************
55 // CONSTRUCTOR: ossimLsrSpace
56 //
57 // Constructs the space given origin, and X and Z ECEF directions. The int
58 // argument is a place holder only and not used.
59 //
60 //*****************************************************************************
ossimLsrSpace(const ossimEcefPoint & origin,const ossimEcefVector & x_dir_ecf_vec,int,const ossimEcefVector & z_dir_ecf_vec)61 ossimLsrSpace::ossimLsrSpace(const ossimEcefPoint& origin,
62 const ossimEcefVector& x_dir_ecf_vec,
63 int /* y_not_provided_space_holder */,
64 const ossimEcefVector& z_dir_ecf_vec)
65 : theOrigin (origin)
66 {
67 //***
68 // Compute the remaining axis given first two:
69 //***
70 ossimColumnVector3d xdir (x_dir_ecf_vec.data().unit());
71 ossimColumnVector3d zdir (z_dir_ecf_vec.data().unit());
72 ossimColumnVector3d ydir (zdir.cross(xdir));
73
74 //***
75 // Fill the rotation matrix:
76 //***
77 theLsrToEcefRotMatrix = ossimMatrix3x3::create(xdir[0], ydir[0], zdir[0],
78 xdir[1], ydir[1], zdir[1],
79 xdir[2], ydir[2], zdir[2]);
80 }
81
82 //*****************************************************************************
83 // CONSTRUCTOR: ossimLsrSpace
84 //
85 // Constructs the space given origin, and Y and Z ECEF directions. The int
86 // argument is a place holder only and not used.
87 //
88 //*****************************************************************************
ossimLsrSpace(const ossimEcefPoint & origin,int,const ossimEcefVector & y_dir_ecf_vec,const ossimEcefVector & z_dir_ecf_vec)89 ossimLsrSpace::ossimLsrSpace(const ossimEcefPoint& origin,
90 int /* x_not_provided_space_holder */,
91 const ossimEcefVector& y_dir_ecf_vec,
92 const ossimEcefVector& z_dir_ecf_vec)
93 : theOrigin (origin)
94 {
95 //***
96 // Compute the remaining axis given first two:
97 //***
98 ossimColumnVector3d ydir (y_dir_ecf_vec.data().unit());
99 ossimColumnVector3d zdir (z_dir_ecf_vec.data().unit());
100 ossimColumnVector3d xdir (ydir.cross(zdir));
101
102 //***
103 // Fill the rotation matrix:
104 //***
105 theLsrToEcefRotMatrix = ossimMatrix3x3::create(xdir[0], ydir[0], zdir[0],
106 xdir[1], ydir[1], zdir[1],
107 xdir[2], ydir[2], zdir[2]);
108 }
109
110 //*****************************************************************************
111 // CONSTRUCTORS: ossimLsrSpace(ossimGpt, y_azimuth)
112 //
113 // This constructor sets up a local coordinate system centered at the
114 // specified groundpoint, with the Z-axis normal to the ellipsoid and the
115 // Y-axis rotated clockwise from north by the y_azimuth. This angle defaults
116 // to 0, producing an East-North-Up system.
117 //
118 //*****************************************************************************
ossimLsrSpace(const ossimGpt & origin,const double & y_azimuth)119 ossimLsrSpace::ossimLsrSpace(const ossimGpt& origin,
120 const double& y_azimuth)
121 {
122 //***
123 // Convert ground point origin to ECEF coordinates:
124 //***
125 theOrigin = ossimEcefPoint(origin);
126
127 //***
128 // Establish the component vectors for ENU system::
129 //***
130 double sin_lat = ossim::sind(origin.lat);
131 double cos_lat = ossim::cosd(origin.lat);
132 double sin_lon = ossim::sind(origin.lon);
133 double cos_lon = ossim::cosd(origin.lon);
134
135 ossimColumnVector3d E (-sin_lon,
136 cos_lon,
137 0.0);
138 ossimColumnVector3d N (-sin_lat*cos_lon,
139 -sin_lat*sin_lon,
140 cos_lat);
141 ossimColumnVector3d U (E.cross(N));
142
143 //
144 // Fill rotation matrix with these components, rotated about the Z axis
145 // by the azimuth indicated:
146 //
147 if (std::abs(y_azimuth) > FLT_EPSILON)
148 {
149 double cos_azim = ossim::cosd(y_azimuth);
150 double sin_azim = ossim::sind(y_azimuth);
151 ossimColumnVector3d X (cos_azim*E - sin_azim*N);
152 ossimColumnVector3d Y (sin_azim*E + cos_azim*N);
153 ossimColumnVector3d Z (X.cross(Y));
154
155 theLsrToEcefRotMatrix
156 = ossimMatrix3x3::create(X[0], Y[0], Z[0],
157 X[1], Y[1], Z[1],
158 X[2], Y[2], Z[2]);
159 }
160 else
161 {
162 //***
163 // No azimuth rotation, so simplify:
164 //***
165 theLsrToEcefRotMatrix = ossimMatrix3x3::create(E[0], N[0], U[0],
166 E[1], N[1], U[1],
167 E[2], N[2], U[2]);
168 }
169 }
170
171 //*****************************************************************************
172 // OPERATOR: ==
173 //*****************************************************************************
operator ==(const ossimLsrSpace & that) const174 bool ossimLsrSpace::operator == (const ossimLsrSpace& that) const
175 {
176 if (theOrigin != that.origin())
177 return false;
178
179 if (theLsrToEcefRotMatrix != that.theLsrToEcefRotMatrix)
180 return false;
181
182 return true;
183 }
184
185 //*****************************************************************************
186 // OPERATOR: =
187 //*****************************************************************************
operator =(const ossimLsrSpace & space)188 const ossimLsrSpace& ossimLsrSpace::operator = (const ossimLsrSpace& space)
189 {
190 theOrigin = space.theOrigin;
191 theLsrToEcefRotMatrix = space.theLsrToEcefRotMatrix;
192 return *this;
193 }
194
195 //*****************************************************************************
196 // STATIC METHOD: lsrSpaceErrorMessage()
197 //
198 // Convenience method accessible to all owners of an ossimLsrSpace for
199 // displaying an error message when LSR spaces do not match between
200 // objects. All operations between LSR objects must be in a common space.
201 //
202 //*****************************************************************************
lsrSpaceErrorMessage(ostream & os)203 ostream& ossimLsrSpace::lsrSpaceErrorMessage(ostream& os)
204 {
205 os<<"ossimLsrSpace ERROR: An operation was attempted between two LSR \n"
206 <<" objects with differing LSR spaces. This is an illegal condition.\n"
207 <<" Please check the data and/or report the error to OSSIM development."
208 << std::endl;
209
210 return os;
211 }
212
213 //*****************************************************************************
214 // METHOD: print()
215 //
216 // Dumps contents to stream for debug purposes. Defaults to cout.
217 //
218 //*****************************************************************************
print(ostream & stream) const219 void ossimLsrSpace::print(ostream& stream) const
220 {
221 stream << "(ossimLsrSpace)"
222 << "\n theOrigin = " << theOrigin
223 << "\n theLsrToEcefRotMatrix = \n" << theLsrToEcefRotMatrix << std::endl;
224 }
225
226