1 //----------------------------------------------------------------------------
2 //
3 // License: LGPL
4 //
5 // See LICENSE.txt file in the top level directory for more details.
6 //
7 // Author: David Burken
8 //
9 // Description: Utility class for global nitf methods.
10 //
11 //----------------------------------------------------------------------------
12 // $Id: ossimNitfCommon.cpp 17978 2010-08-24 16:17:00Z dburken $
13
14 #include <cstring> /* for memcpy */
15 #include <sstream>
16 #include <iomanip>
17 #include <sstream>
18 #include <stdexcept>
19 #include <iostream>
20 #include <ossim/support_data/ossimNitfCommon.h>
21 #include <ossim/base/ossimDms.h>
22 #include <ossim/base/ossimDpt.h>
23 #include <ossim/base/ossimIrect.h>
24 #include <ossim/base/ossimNotify.h>
25 #include <ossim/base/ossimTrace.h>
26
27 static const ossimTrace traceDebug(ossimString("ossimNitfCommon:debug"));
28
29
ossimNitfCommon()30 ossimNitfCommon::ossimNitfCommon(){}
31
~ossimNitfCommon()32 ossimNitfCommon::~ossimNitfCommon(){}
33
convertToScientificString(const ossim_float64 & aValue,ossim_uint32 size)34 ossimString ossimNitfCommon::convertToScientificString(
35 const ossim_float64& aValue,
36 ossim_uint32 size)
37 {
38 // Precision cannot hit 0 for this to work...
39 if ( ((aValue < 0.0) && (size < 8)) ||
40 ((aValue >= 0.0) && (size < 7)) )
41 {
42 if (traceDebug())
43 {
44 ossimNotify(ossimNotifyLevel_DEBUG)
45 << "ossimNitfCommon::convertToScientificString DEBUG:"
46 << "\nsize range error!"
47 << std::endl;
48 }
49 return ossimString();
50 }
51
52 //--
53 // Set the precision to account for size with 1.xxxxxE+01
54 //---
55 ossim_uint32 precision = size - 6;
56
57 if (aValue < 0.0)
58 {
59 --precision;
60 }
61
62 std::ostringstream s1;
63 s1 << std::setiosflags(std::ios_base::scientific|std::ios_base::internal)
64 << std::setfill('0')
65 // << setw(size)
66 << std::setprecision(precision)
67 << aValue;
68
69 ossimString result = s1.str();
70
71 // Upcase the "e".
72 result.upcase();
73
74 if (traceDebug())
75 {
76 if (result.size() != size)
77 {
78 ossimNotify(ossimNotifyLevel_DEBUG)
79 << "ossimNitfCommon::convertToScientificString DEBUG:"
80 << "\nIncorrect output size!"
81 << "\nValue: " << aValue
82 << "\nString: " << result
83 << std::endl;
84 }
85 }
86 return result;
87 }
88
convertToDoubleString(const ossim_float64 & aValue,ossim_uint32 precision,ossim_uint32 size)89 ossimString ossimNitfCommon::convertToDoubleString(
90 const ossim_float64& aValue,
91 ossim_uint32 precision,
92 ossim_uint32 size)
93 {
94 ossim_uint32 width = size;
95
96 std::ostringstream s1;
97 s1 << std::setiosflags(std::ios_base::fixed|
98 std::ios_base::internal)
99 << std::setprecision(precision)
100 << std::setfill('0')
101 << std::setw(width)
102 << aValue;
103
104 ossimString result = s1.str();
105
106 if (traceDebug())
107 {
108 ossimNotify(ossimNotifyLevel_DEBUG)
109 << "ossimNitfCommon::convertToDoubleString DEBUG:"
110 << "\nresult: " << result << std::endl;
111
112 if (result.size() != size)
113 {
114 ossimNotify(ossimNotifyLevel_DEBUG)
115 << "ossimNitfCommon::convertToDoubleString DEBUG:"
116 << "\nIncorrect output size!"
117 << std::endl;
118 }
119 }
120 return result;
121 }
122
convertToUIntString(ossim_uint32 aValue,ossim_uint32 size)123 ossimString ossimNitfCommon::convertToUIntString(ossim_uint32 aValue,
124 ossim_uint32 size)
125 {
126 ossim_uint32 width = size;
127
128 std::ostringstream s1;
129 s1 << std::setiosflags(std::ios_base::fixed|
130 std::ios_base::internal)
131 << std::setfill('0')
132 << std::setw(width)
133 << aValue;
134
135 ossimString result = s1.str();
136
137 if (traceDebug())
138 {
139 if (result.size() != size)
140 {
141 ossimNotify(ossimNotifyLevel_DEBUG)
142 << "ossimNitfCommon::convertToUIntString DEBUG:"
143 << "\nIncorrect output size!"
144 << "\nValue: " << aValue
145 << "\nString: " << result
146 << std::endl;
147 }
148 }
149 return result;
150 }
151
convertToIntString(ossim_int32 aValue,ossim_uint32 size)152 ossimString ossimNitfCommon::convertToIntString(ossim_int32 aValue,
153 ossim_uint32 size)
154 {
155 ossim_uint32 width = size;
156
157 std::ostringstream s1;
158 s1 << std::setiosflags(std::ios_base::fixed|
159 std::ios_base::internal)
160 << std::setfill('0')
161 << std::setw(width)
162 << aValue;
163
164 ossimString result = s1.str();
165
166 if (traceDebug())
167 {
168 if (result.size() != size)
169 {
170 ossimNotify(ossimNotifyLevel_DEBUG)
171 << "ossimNitfCommon::convertToIntString DEBUG:"
172 << "\nIncorrect output size!"
173 << "\nValue: " << aValue
174 << "\nString: " << result
175 << std::endl;
176 }
177 }
178 return result;
179 }
180
convertToDdLatLonLocString(const ossimDpt & pt,ossim_uint32 precision)181 ossimString ossimNitfCommon::convertToDdLatLonLocString(const ossimDpt& pt,
182 ossim_uint32 precision)
183 {
184 ossimString lat;
185 ossimString lon;
186 ossim_uint32 latSize = precision+4; // size = precision + "-33."
187 ossim_uint32 lonSize = precision+5; // size = precision + "-122."
188
189 if (pt.y >= 0.0)
190 {
191 lat = "+";
192 --latSize;
193 }
194 if (pt.x >= 0.0)
195 {
196 lon = "+";
197 --lonSize;
198 }
199 lat += convertToDoubleString(pt.y,
200 precision,
201 latSize);
202 lon += convertToDoubleString(pt.x,
203 precision,
204 lonSize);
205 ossimString result = lat+lon;
206
207 if (traceDebug())
208 {
209 ossimNotify(ossimNotifyLevel_DEBUG)
210 << "ossimNitfCommon::convertToDdLatLonLocString DEBUG:"
211 << "\nresult: " << result
212 << std::endl;
213 }
214
215 return result;
216 }
217
setField(void * fieldDestination,const ossimString & src,std::streamsize width,std::ios_base::fmtflags ioflags,char fill)218 void ossimNitfCommon::setField(void* fieldDestination,
219 const ossimString& src,
220 std::streamsize width,
221 std::ios_base::fmtflags ioflags,
222 char fill)
223 {
224 std::ostringstream out;
225 out << std::setw(width)
226 << std::setfill(fill)
227 << std::setiosflags(ioflags)
228 << src.trim().c_str();
229
230 memcpy(fieldDestination, out.str().c_str(), width);
231 }
232
encodeUtm(ossim_uint32 zone,const ossimDpt & ul,const ossimDpt & ur,const ossimDpt & lr,const ossimDpt & ll)233 ossimString ossimNitfCommon::encodeUtm(
234 ossim_uint32 zone,
235 const ossimDpt& ul,
236 const ossimDpt& ur,
237 const ossimDpt& lr,
238 const ossimDpt& ll)
239 {
240 std::ostringstream out;
241
242 if(zone > 60)
243 {
244 std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nUTM zone greate than 60!";
245 if (traceDebug())
246 {
247 ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
248 }
249 throw std::out_of_range(s);
250 }
251
252 ossim_float64 east = ul.x;
253 ossim_float64 north = ul.y;
254
255 if((ossim_uint32)(east+.5) > 999999)
256 {
257 std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nUpper left easting too large for NITF field!";
258 if (traceDebug())
259 {
260 ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
261 }
262 throw std::out_of_range(s);
263 }
264
265 if((ossim_uint32)(north+.5) > 9999999)
266 {
267 std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nUpper left northing too large for NITF field!";
268 if (traceDebug())
269 {
270 ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
271 }
272 throw std::out_of_range(s);
273 }
274
275 out << std::setw(2)
276 << std::setfill('0')
277 << zone
278 << std::setw(6)
279 << std::setfill('0')
280 <<(ossim_uint32)(east+.5)
281 << std::setw(7)
282 << std::setfill('0')
283 <<(ossim_uint32)(north+.5);
284
285
286 east = ur.x;
287 north = ur.y;
288
289 if((ossim_uint32)(east+.5) > 999999)
290 {
291 std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nUpper right easting too large for NITF field!";
292 if (traceDebug())
293 {
294 ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
295 }
296 throw std::out_of_range(s);
297 }
298
299 if((ossim_uint32)(north+.5) > 9999999)
300 {
301 std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nUpper right northing too large for NITF field!";
302 if (traceDebug())
303 {
304 ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
305 }
306 throw std::out_of_range(s);
307 }
308
309 out << std::setw(2)
310 << std::setfill('0')
311 << zone
312 << std::setw(6)
313 << std::setfill('0')
314 <<(ossim_uint32)(east+.5)
315 << std::setw(7)
316 << std::setfill('0')
317 <<(ossim_uint32)(north+.5);
318 east = lr.x;
319 north = lr.y;
320
321 if((ossim_uint32)(east+.5) > 999999)
322 {
323 std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nLower right easting too large for NITF field!";
324 if (traceDebug())
325 {
326 ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
327 }
328 throw std::out_of_range(s);
329 }
330
331 if((ossim_uint32)(north+.5) > 9999999)
332 {
333 std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nLower right northing too large for NITF field!";
334 if (traceDebug())
335 {
336 ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
337 }
338 throw std::out_of_range(s);
339 }
340
341 out << std::setw(2)
342 << std::setfill('0')
343 << zone
344 << std::setw(6)
345 << std::setfill('0')
346 <<(ossim_uint32)(east+.5)
347 << std::setw(7)
348 << std::setfill('0')
349 <<(ossim_uint32)(north+.5);
350
351 east = ll.x;
352 north = ll.y;
353
354 if((ossim_uint32)(east+.5) > 999999)
355 {
356 std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nLower left easting too large for NITF field!";
357 if (traceDebug())
358 {
359 ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
360 }
361 throw std::out_of_range(s);
362 }
363
364 if((ossim_uint32)(north+.5) > 9999999)
365 {
366 std::string s = "ossimNitfImageHeaderV2_1::encodeUtm: ERROR\nLower left northing too large for NITF field!";
367 if (traceDebug())
368 {
369 ossimNotify(ossimNotifyLevel_WARN) << s << std::endl;
370 }
371 throw std::out_of_range(s);
372 }
373
374 out << std::setw(2)
375 << std::setfill('0')
376 << zone
377 << std::setw(6)
378 << std::setfill('0')
379 <<(ossim_uint32)(east+.5)
380 << std::setw(7)
381 << std::setfill('0')
382 <<(ossim_uint32)(north+.5);
383
384 return out.str().c_str();
385 }
386
encodeGeographicDms(const ossimDpt & ul,const ossimDpt & ur,const ossimDpt & lr,const ossimDpt & ll)387 ossimString ossimNitfCommon::encodeGeographicDms(const ossimDpt& ul,
388 const ossimDpt& ur,
389 const ossimDpt& lr,
390 const ossimDpt& ll)
391 {
392 std::ostringstream out;
393
394 out << ossimDms(ul.y, true).toString("ddmmssC").c_str();
395 out << ossimDms(ul.x, false).toString("dddmmssC").c_str();
396 out << ossimDms(ur.y, true).toString("ddmmssC").c_str();
397 out << ossimDms(ur.x, false).toString("dddmmssC").c_str();
398 out << ossimDms(lr.y, true).toString("ddmmssC").c_str();
399 out << ossimDms(lr.x, false).toString("dddmmssC").c_str();
400 out << ossimDms(ll.y, true).toString("ddmmssC").c_str();
401 out << ossimDms(ll.x, false).toString("dddmmssC").c_str();
402
403 return ossimString(out.str());
404 }
405
encodeGeographicDecimalDegrees(const ossimDpt & ul,const ossimDpt & ur,const ossimDpt & lr,const ossimDpt & ll)406 ossimString ossimNitfCommon::encodeGeographicDecimalDegrees(const ossimDpt& ul,
407 const ossimDpt& ur,
408 const ossimDpt& lr,
409 const ossimDpt& ll)
410 {
411 std::ostringstream out;
412
413 out << (ul.lat >= 0.0?"+":"")
414 << std::setw(6)
415 << std::setfill('0')
416 << std::setprecision(3)
417 << std::setiosflags(std::ios::fixed)
418 << ul.lat
419 << (ul.lon >= 0.0?"+":"")
420 << std::setw(7)
421 << std::setfill('0')
422 << std::setprecision(3)
423 << std::setiosflags(std::ios::fixed)
424 << ul.lon;
425 out << (ur.lat >= 0.0?"+":"")
426 << std::setw(6)
427 << std::setfill('0')
428 << std::setprecision(3)
429 << std::setiosflags(std::ios::fixed)
430 << ur.lat
431 << (ur.lon >= 0.0?"+":"")
432 << std::setw(7)
433 << std::setfill('0')
434 << std::setprecision(3)
435 << std::setiosflags(std::ios::fixed)
436 << ur.lon;
437 out << (lr.lat >= 0.0?"+":"")
438 << std::setw(6)
439 << std::setfill('0')
440 << std::setprecision(3)
441 << std::setiosflags(std::ios::fixed)
442 << lr.lat
443 << (lr.lon >= 0.0?"+":"")
444 << std::setw(7)
445 << std::setfill('0')
446 << std::setprecision(3)
447 << std::setiosflags(std::ios::fixed)
448 << lr.lon;
449 out << (ll.lat >= 0.0?"+":"")
450 << std::setw(6)
451 << std::setfill('0')
452 << std::setprecision(3)
453 << std::setiosflags(std::ios::fixed)
454 << ll.lat
455 << (ll.lon >= 0.0?"+":"")
456 << std::setw(7)
457 << std::setfill('0')
458 << std::setprecision(3)
459 << std::setiosflags(std::ios::fixed)
460 << ll.lon;
461
462 return ossimString(out.str());
463 }
464
getNitfPixelType(ossimScalarType scalarType)465 ossimString ossimNitfCommon::getNitfPixelType(ossimScalarType scalarType)
466 {
467 ossimString pixelType;
468 switch(scalarType)
469 {
470 case OSSIM_UINT8:
471 case OSSIM_USHORT11:
472 case OSSIM_USHORT12:
473 case OSSIM_USHORT13:
474 case OSSIM_USHORT14:
475 case OSSIM_USHORT15:
476 case OSSIM_UINT16:
477 case OSSIM_UINT32:
478 {
479 pixelType = "INT";
480 break;
481 }
482 case OSSIM_SINT16:
483 case OSSIM_SINT32:
484 {
485 pixelType = "SI";
486 break;
487 }
488 case OSSIM_FLOAT:
489 case OSSIM_NORMALIZED_FLOAT:
490 case OSSIM_DOUBLE:
491 case OSSIM_NORMALIZED_DOUBLE:
492 {
493 pixelType = "R";
494 break;
495 }
496 default:
497 {
498 ossimNotify(ossimNotifyLevel_DEBUG)
499 << __FILE__ << ":" << __LINE__
500 << "\nUnhandled scalar type: " << scalarType << std::endl;
501 break;
502 }
503 }
504 return pixelType;
505 }
506
getCompressionRate(const ossimIrect & rect,ossim_uint32 bands,ossimScalarType scalar,ossim_uint64 lengthInBytes)507 ossimString ossimNitfCommon::getCompressionRate(const ossimIrect& rect,
508 ossim_uint32 bands,
509 ossimScalarType scalar,
510 ossim_uint64 lengthInBytes)
511 {
512 ossimString result("");
513
514 ossim_float64 uncompressedSize =
515 ossim::scalarSizeInBytes(scalar) * rect.width() * rect.height() * bands;
516 ossim_float64 bitsPerPix = ossim::getBitsPerPixel(scalar);
517 ossim_float64 rate = ( bitsPerPix *
518 (static_cast<ossim_float64>(lengthInBytes) /
519 uncompressedSize) );
520
521 // Multiply by 100 as there is an implied decimal point.
522 rate *= 100.0;
523
524 // Convert to string with zero precision.
525 ossimString s = ossimString::toString(rate, 0, 4);
526
527 if (s.size())
528 {
529 if (s.size() <= 3)
530 {
531 result = "N";
532 if (s.size() == 3)
533 {
534 result = "0";
535 }
536 else if (s.size() == 2)
537 {
538 result = "00";
539 }
540 result += s;
541 }
542 }
543 return result;
544 }
545
546