1 //----------------------------------------------------------------------------
2 //
3 // License: LGPL
4 //
5 // See LICENSE.txt file in the top level directory for more details.
6 //
7 //----------------------------------------------------------------------------
8 // $Id: ossimQuickbirdRpcHeader.cpp 9094 2006-06-13 19:12:40Z dburken $
9
10 #include <ossim/support_data/ossimQuickbirdRpcHeader.h>
11 #include <ossim/base/ossimRegExp.h>
12 #include <iostream>
13 #include <fstream>
14 #include <algorithm>
15 #include <iterator>
16 #include <ossim/base/ossimXmlDocument.h>
17
18 using namespace std;
19
operator <<(std::ostream & out,const ossimQuickbirdRpcHeader & data)20 std::ostream& operator << (std::ostream& out,
21 const ossimQuickbirdRpcHeader& data)
22 {
23 out << "theSatId = " << data.theSatId << std::endl
24 << "theBandId = " << data.theBandId << std::endl
25 << "theSpecId = " << data.theSpecId << std::endl
26 << "theErrBias = " << data.theErrBias << std::endl
27 << "theLineOffset = " << data.theLineOffset << std::endl
28 << "theSampOffset = " << data.theSampOffset << std::endl
29 << "theLatOffset = " << data.theLatOffset << std::endl
30 << "theLonOffset = " << data.theLonOffset << std::endl
31 << "theHeightOffset = " << data.theHeightOffset << std::endl
32 << "theLineScale = " << data.theLineScale << std::endl
33 << "theSampScale = " << data.theSampScale << std::endl
34 << "theLatScale = " << data.theLatScale << std::endl
35 << "theLonScale = " << data.theLonScale << std::endl
36 << "theHeightScale = " << data.theHeightScale << std::endl;
37
38 out << "lineNumCoef = " << std::endl;
39 std::copy(data.theLineNumCoeff.begin(),
40 data.theLineNumCoeff.end(),
41 std::ostream_iterator<double>(out, "\n"));
42 out << "lineDenCoef = " << std::endl;
43 std::copy(data.theLineDenCoeff.begin(),
44 data.theLineDenCoeff.end(),
45 std::ostream_iterator<double>(out, "\n"));
46 out << "sampNumCoef = " << std::endl;
47 std::copy(data.theSampNumCoeff.begin(),
48 data.theSampNumCoeff.end(),
49 std::ostream_iterator<double>(out, "\n"));
50 out << "sampDenCoef = " << std::endl;
51 std::copy(data.theSampDenCoeff.begin(),
52 data.theSampDenCoeff.end(),
53 std::ostream_iterator<double>(out, "\n"));
54
55 return out;
56 }
57
58
ossimQuickbirdRpcHeader()59 ossimQuickbirdRpcHeader::ossimQuickbirdRpcHeader()
60 : theErrBias(0),
61 theErrRand(0),
62 theLineOffset(0),
63 theSampOffset(0),
64 theLatOffset(0),
65 theLonOffset(0),
66 theHeightOffset(0),
67 theLineScale(0),
68 theSampScale(0),
69 theLatScale(0),
70 theLonScale(0),
71 theHeightScale(0)
72 {
73 }
74
open(const ossimFilename & file)75 bool ossimQuickbirdRpcHeader::open(const ossimFilename& file)
76 {
77 theFilename = file;
78
79 if (theFilename.ext().upcase() == "XML")
80 return parseXml();
81
82 std::ifstream in(file.c_str(), std::ios::in|std::ios::binary);
83
84 char test[64];
85
86 in.read((char*)test, 63);
87 test[63] = '\0';
88 in.seekg(0);
89 ossimString line = test;
90 line = line.upcase();
91
92 if(parseNameValue(line))
93 {
94 theErrorStatus = ossimErrorCodes::OSSIM_OK;
95 getline(in, line);
96 while((in)&&(theErrorStatus == ossimErrorCodes::OSSIM_OK))
97 {
98 line = line.upcase();
99 if(line.contains("LINENUMCOEF"))
100 {
101 if(!readCoeff(in, theLineNumCoeff))
102 {
103 setErrorStatus();
104 break;
105 }
106 }
107 else if(line.contains("LINEDENCOEF"))
108 {
109 if(!readCoeff(in, theLineDenCoeff))
110 {
111 setErrorStatus();
112 break;
113 }
114 }
115 else if(line.contains("SAMPNUMCOEF"))
116 {
117 if(!readCoeff(in, theSampNumCoeff))
118 {
119 setErrorStatus();
120 break;
121 }
122 }
123 else if(line.contains("SAMPDENCOEF"))
124 {
125 if(!readCoeff(in, theSampDenCoeff))
126 {
127 setErrorStatus();
128 break;
129 }
130 }
131 else if(!parseNameValue(line))
132 {
133 setErrorStatus();
134 break;
135 }
136 getline(in,
137 line);
138 }
139 }
140 else
141 {
142 setErrorStatus();
143 }
144 return (theErrorStatus == ossimErrorCodes::OSSIM_OK);
145 }
146
parseXml()147 bool ossimQuickbirdRpcHeader::parseXml ()
148 {
149 ossimXmlDocument document;
150 if (!document.openFile(theFilename))
151 return false;
152
153 ossimRefPtr<ossimXmlNode> root = document.getRoot();
154 ossimRefPtr<ossimXmlNode> rpcNode = root->findFirstNode("RPB");
155 if (!rpcNode)
156 return false;
157
158 ossimString dataString;
159 bool success = false; // Assume we're gonna screw this up...
160 while (1)
161 {
162 theSatId = rpcNode->getChildTextValue("SATID");
163 if (theSatId.empty())
164 break;
165
166 theBandId = rpcNode->getChildTextValue("BANDID");
167 if (theBandId.empty())
168 break;
169
170 theSpecId = rpcNode->getChildTextValue("SPECID");
171 if (theSpecId.empty())
172 break;
173
174 rpcNode = rpcNode->findFirstNode("IMAGE");
175 if (!rpcNode)
176 break;
177
178 dataString = rpcNode->getChildTextValue("ERRBIAS");
179 if (dataString.empty())
180 break;
181 theErrBias = dataString.toDouble();
182
183 dataString = rpcNode->getChildTextValue("ERRRAND");
184 if (dataString.empty())
185 break;
186 theErrRand = dataString.toDouble();
187
188 dataString = rpcNode->getChildTextValue("LINEOFFSET");
189 if (dataString.empty())
190 break;
191 theLineOffset = dataString.toInt();
192
193 dataString = rpcNode->getChildTextValue("SAMPOFFSET");
194 if (dataString.empty())
195 break;
196 theSampOffset = dataString.toInt();
197
198 dataString = rpcNode->getChildTextValue("LATOFFSET");
199 if (dataString.empty())
200 break;
201 theLatOffset = dataString.toDouble();
202
203 dataString = rpcNode->getChildTextValue("LONGOFFSET");
204 if (dataString.empty())
205 break;
206 theLonOffset = dataString.toDouble();
207
208 dataString = rpcNode->getChildTextValue("HEIGHTOFFSET");
209 if (dataString.empty())
210 break;
211 theHeightOffset = dataString.toDouble();
212
213 dataString = rpcNode->getChildTextValue("LINESCALE");
214 if (dataString.empty())
215 break;
216 theLineScale = dataString.toDouble();
217
218 dataString = rpcNode->getChildTextValue("SAMPSCALE");
219 if (dataString.empty())
220 break;
221 theSampScale = dataString.toDouble();
222
223 dataString = rpcNode->getChildTextValue("LATSCALE");
224 if (dataString.empty())
225 break;
226 theLatScale = dataString.toDouble();
227
228 dataString = rpcNode->getChildTextValue("LONGSCALE");
229 if (dataString.empty())
230 break;
231 theLonScale = dataString.toDouble();
232
233 dataString = rpcNode->getChildTextValue("HEIGHTSCALE");
234 if (dataString.empty())
235 break;
236 theHeightScale = dataString.toDouble();
237
238 vector<ossimString> ln, ld, sn, sd;
239 rpcNode->getChildTextValue("LINENUMCOEFList/LINENUMCOEF").split(ln, " ", true);
240 rpcNode->getChildTextValue("LINEDENCOEFList/LINEDENCOEF").split(ld, " ", true);
241 rpcNode->getChildTextValue("SAMPNUMCOEFList/SAMPNUMCOEF").split(sn, " ", true);
242 rpcNode->getChildTextValue("SAMPDENCOEFList/SAMPDENCOEF").split(sd, " ", true);
243 if ( (ln.size() != 20) || (ld.size() != 20) || (sn.size() != 20) || (sd.size() != 20))
244 break;
245
246 for (int i=0; i<20; ++i)
247 {
248 theLineNumCoeff.emplace_back(ln[i].toDouble());
249 theLineDenCoeff.emplace_back(ld[i].toDouble());
250 theSampNumCoeff.emplace_back(sn[i].toDouble());
251 theSampDenCoeff.emplace_back(sd[i].toDouble());
252 }
253 success = true; // Well waddaya know!
254 }
255 return success;
256 }
257
readCoeff(std::istream & in,std::vector<double> & coeff)258 bool ossimQuickbirdRpcHeader::readCoeff(std::istream& in,
259 std::vector<double>& coeff)
260 {
261 coeff.clear();
262 bool done = false;
263 ossimString line;
264 while(!in.eof()&&!in.bad()&&!done)
265 {
266 getline(in,
267 line);
268 line.trim();
269 line.trim(',');
270 if(line.contains(");"))
271 {
272 done = true;
273 line.trim(';');
274 line.trim(')');
275 }
276 coeff.push_back(line.toDouble());
277 }
278 return done;
279 }
isGlobal() const280 bool ossimQuickbirdRpcHeader::isGlobal() const
281 {
282 ossimRegExp regex("R[0-9]*C[0-9]*");
283
284 return !regex.find(theFilename.c_str());
285 }
286
parseNameValue(const ossimString & line)287 bool ossimQuickbirdRpcHeader::parseNameValue(const ossimString& line)
288 {
289 bool result = true;
290 ossimString lineCopy = line;
291
292 if(lineCopy.contains("SATID"))
293 {
294 theSatId = lineCopy.after("\"");
295 theSatId = theSatId.before("\"");
296 }
297 else if(lineCopy.contains("BANDID"))
298 {
299 theBandId = lineCopy.after("\"");
300 theBandId = theBandId.before("\"");
301 }
302 else if(lineCopy.contains("SPECID"))
303 {
304 theSpecId = lineCopy.after("\"");
305 theSpecId = theSpecId.before("\"");
306 }
307 else if(lineCopy.contains("BEGIN_GROUP"))
308 {
309 }
310 else if(lineCopy.contains("ERRBIAS"))
311 {
312 lineCopy = lineCopy.after("=");
313 theErrBias = lineCopy.before(";").toDouble();
314 }
315 else if(lineCopy.contains("ERRRAND"))
316 {
317 lineCopy = lineCopy.after("=");
318 theErrRand = lineCopy.before(";").toDouble();
319 }
320 else if(lineCopy.contains("LINEOFFSET"))
321 {
322 lineCopy = lineCopy.after("=");
323 theLineOffset = lineCopy.before(";").toInt();
324 }
325 else if(lineCopy.contains("SAMPOFFSET"))
326 {
327 lineCopy = lineCopy.after("=");
328 theSampOffset = lineCopy.before(";").toInt();
329 }
330 else if(lineCopy.contains("LATOFFSET"))
331 {
332 lineCopy = lineCopy.after("=");
333 theLatOffset = lineCopy.before(";").toDouble();
334 }
335 else if(lineCopy.contains("LONGOFFSET"))
336 {
337 lineCopy = lineCopy.after("=");
338 theLonOffset = lineCopy.before(";").toDouble();
339 }
340 else if(lineCopy.contains("HEIGHTOFFSET"))
341 {
342 lineCopy = lineCopy.after("=");
343 theHeightOffset = lineCopy.before(";").toDouble();
344 }
345 else if(lineCopy.contains("LINESCALE"))
346 {
347 lineCopy = lineCopy.after("=");
348 theLineScale = lineCopy.before(";").toDouble();
349 }
350 else if(lineCopy.contains("SAMPSCALE"))
351 {
352 lineCopy = lineCopy.after("=");
353 theSampScale = lineCopy.before(";").toDouble();
354 }
355 else if(lineCopy.contains("LATSCALE"))
356 {
357 lineCopy = lineCopy.after("=");
358 theLatScale = lineCopy.before(";").toDouble();
359 }
360 else if(lineCopy.contains("LONGSCALE"))
361 {
362 lineCopy = lineCopy.after("=");
363 theLonScale = lineCopy.before(";").toDouble();
364 }
365 else if(lineCopy.contains("HEIGHTSCALE"))
366 {
367 lineCopy = lineCopy.after("=");
368 theHeightScale = lineCopy.before(";").toDouble();
369 }
370 else if(lineCopy.contains("END_GROUP"))
371 {
372 }
373 else if(lineCopy.contains("END"))
374 {
375 }
376 else
377 {
378 result = false;
379 }
380
381 return result;
382 }
383