OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimNitfProjectionFactory.cpp
Go to the documentation of this file.
1 //---
2 // License: MIT
3 //
4 // Description:
5 //
6 // Contains class definition for ossimNitfProjectionFactory.
7 //---
8 // $Id$
9 
11 #include <ossim/base/ossimDms.h>
12 #include <ossim/base/ossimGpt.h>
16 #include <ossim/base/ossimTrace.h>
29 #include <fstream>
30 #include <cmath>
31 
32 // Define Trace flags for use within this file:
33 static ossimTrace traceDebug(ossimString("ossimNitfProjectionFactory:debug"));
34 
36 
38 {
39 }
40 
42 {
43 }
44 
46 {
47  if(!theInstance)
48  {
50  }
51 
52  return theInstance;
53 }
54 
57  ossim_uint32 entryIdx)const
58 {
59  static const char MODULE[]="ossimNitfProjectionFactory::createProjection";
60  if (traceDebug())
61  {
63  << MODULE << " DEBUG:"
64  << "\nfilename: " << filename
65  << "\nentryIdx: " << entryIdx
66  << std::endl;
67  }
68 
69  // See if there is an external geomtry.
70  ossimProjection* result = createProjectionFromGeometryFile(filename, entryIdx);
71  if (result)
72  {
73  return result;
74  }
75 
76  if(!isNitf(filename))
77  {
78  return result; // result is NULL
79  }
80 
82  if (!nitf->parseFile(filename))
83  {
84  return result; // result is NULL
85  }
86 
87  long imageIndex = static_cast<long>(entryIdx);
88  if ( imageIndex > (nitf->getHeader()->getNumberOfImages()-1) )
89  {
90  return result;
91  }
92 
93  ossimRefPtr<ossimNitfImageHeader> imageHeader = nitf->getNewImageHeader(imageIndex);
94  {
95  if (!imageHeader)
96  {
97  return result;
98  }
99  }
100 
101  result = createProjectionFromHeaders(nitf->getHeader(),
102  imageHeader.get());
103  if (traceDebug())
104  {
105  ossimString coordinateSystem = imageHeader->getCoordinateSystem();
107  << MODULE << " DEBUG:"
108  << "\ncoordinateSysetm: " << coordinateSystem
109  << std::endl;
110  }
111 
112  return result;
113 }
114 
115 
118  const char* /* prefix */) const
119 {
120  return 0;
121 }
122 
125 {
126  return 0;
127 }
128 
131 {
132  return (ossimObject*)createProjection(typeName);
133 }
134 
137  const char* prefix)const
138 {
139  return createProjection(kwl, prefix);
140 }
141 
142 void ossimNitfProjectionFactory::getTypeNameList(std::vector<ossimString>& /* typeList */)const
143 {
144 
145 }
146 
148 {
149  ossimNitfTileSource* nitfTileSource = dynamic_cast<ossimNitfTileSource*> (handler);
150  ossimProjection* result = 0;
151  if(nitfTileSource)
152  {
153  if(!result)
154  {
155  ossimNitfImageHeader* imageHeader = nitfTileSource->getCurrentImageHeader();
156  if(imageHeader)
157  {
158  result = createProjectionFromHeaders(nitfTileSource->getFileHeader(),imageHeader);
159  }
160  }
161  }
162  else if(isNitf(handler->getFilename()))
163  {
164  result = createProjection(handler->getFilename(), handler->getCurrentEntry());
165  }
166  return result;
167 }
168 
170 {
171  std::ifstream in(filename.c_str(), ios::in|ios::binary);
172 
173  if(in)
174  {
175  char nitfFile[4];
176  in.read((char*)nitfFile, 4);
177  ossimString s(nitfFile, nitfFile+4);
178  if ( (s == "NITF") || (s == "NSIF") )
179  {
180  return true;
181  }
182  }
183 
184  return false;
185 }
186 
188  ossimNitfFileHeader* fileHeader, ossimNitfImageHeader* imageHeader)const
189 {
190  ossimProjection* result = 0;
191  ossimString version = fileHeader->getVersion();
192  ossimString coordinateSystem = imageHeader->getCoordinateSystem();
193 
194  // Note in version 2.0 ICORDS with 'N' == NONE. In 2.1 it is UTM North:
195  if (coordinateSystem == "G" || coordinateSystem == "D")
196  {
197  result = makeGeographic(imageHeader, coordinateSystem);
198  }
199  else if( (coordinateSystem == "S") || (coordinateSystem == "U") ||
200  ( version != "02.00" && (coordinateSystem == "N") ) )
201  {
202  result = makeUtm(imageHeader, coordinateSystem);
203  }
204  return result;
205 }
206 
208  const ossimNitfImageHeader* hdr,
209  const ossimString& coordinateSysetm) const
210 {
211  ossimProjection* proj = 0;
212 
213  if (hdr)
214  {
215  // To hold corner points.
216  std::vector<ossimGpt> gpts(0);
217  std::vector<ossimGpt> geolobPts(0);
218  std::vector<ossimGpt> blockaPts(0);
219  std::vector<ossimGpt> igeoloPts(0);
220 
221  //---
222  // Look for points from the GEOLOB tag if geographic coordinate
223  // system. This has an origin and scale with good precision.
224  //
225  // NOTES:
226  // 1) More precise than the BLOCKA
227  // 2) Making an assumption this is not present if rotated.
228  // Might need to test for rotation in BLOCKA and IGEOLO
229  // 3) GEOLOB points are always rectangular as they are derived
230  // from a single origin.
231  //---
232  getGeolobPoints(hdr, geolobPts);
233 
234  //---
235  // Look for points from the BLOCKA tag. This may or may not be present.
236  // If present since it has six digit precision use it for the points.
237  //---
238  getBlockaPoints(hdr, blockaPts);
239 
240  if ( blockaPts.empty() )
241  {
242  // Least precise IGEOLO field:
243  ossimString geographicLocation = hdr->getGeographicLocation();
244  if ( geographicLocation.size() )
245  {
246  if (traceDebug())
247  {
249  << "ossimNitfProjectionFactory::makeGeographic DEBUG:"
250  << "\ngeographicLocation: " << geographicLocation
251  << std::endl;
252  }
253 
254  if (coordinateSysetm == "G")
255  {
256  //---
257  // If coord system is G then format is:
258  // Lat = ddmmssX
259  // where d is degrees and m is minutes
260  // and s is seconds and X is either N (North) or S (South).
261  // Lon = dddmmssX
262  // where d is degrees and m is minutes
263  // and s is seconds and X is either N (North) or S (South).
264  //---
265  parseGeographicString(geographicLocation, igeoloPts);
266  }
267  else if (coordinateSysetm == "D")
268  {
269  //---
270  // If coor system is D then format is:
271  // +-dd.ddd +-dd.ddd four times where + is northern hemispher and
272  // - is souther hemisphere for lat and longitude
273  // + is easting and - is westing.
274  //---
275  parseDecimalDegreesString(geographicLocation, igeoloPts);
276  }
277 
278  } // matches: if ( geographicLocation.size() )
279 
280  } // matches: if ( getBlockaPoints(hdr, gpts) == false )
281 
282  bool isSkewedFlag = false;
283  if ( blockaPts.size() )
284  {
285  isSkewedFlag = isSkewed(blockaPts);
286  if ( (isSkewedFlag == false) && geolobPts.size() )
287  {
288  gpts = geolobPts; // Not skewed and have more accurate geolob points.
289  }
290  else
291  {
292  gpts = blockaPts;
293  }
294  }
295  else if ( igeoloPts.size() )
296  {
297  isSkewedFlag = isSkewed(igeoloPts);
298  if ( (isSkewedFlag == false) && geolobPts.size() )
299  {
300  gpts = geolobPts; // Not skewed and have more accurate geolob points.
301  }
302  else
303  {
304  gpts = igeoloPts;
305  }
306  }
307 
308  if (gpts.size() == 4)
309  {
310  ossimDpt scaleTest;
311  computeScaleInDecimalDegrees(hdr, gpts, scaleTest);
312 
313  //---
314  // Getting very small value above 1.0 when dividing; hence the .000001.
315  // Code calling arc cosine function in makeEquDistant(...) clamps to 1.0.
316  //---
317  if ( !isSkewedFlag && (ossim::abs(scaleTest.y/scaleTest.x) <= 1.000001))
318  {
319  proj = makeEuiDistant(hdr, gpts);
320  }
321  else
322  {
323  // Image is rotated. Make a Bilinear.
324  proj = makeBilinear(hdr, gpts);
325  }
326  }
327 
328  if (traceDebug() && proj)
329  {
331  << "ossimNitfProjectionFactory::makeGeographic DEBUG:"
332  << "\nUpper left corner: " << gpts[0]
333  << "\nUpper right corner: " << gpts[1]
334  << "\nLower right corner: " << gpts[2]
335  << "\nLower left corner: " << gpts[3] << "\n";
337  }
338 
339  } // matches: if (hdr)
340 
341  return proj;
342 }
343 
345  const ossimNitfImageHeader* hdr,
346  const ossimString& coordinateSystem) const
347 {
348  ossimProjection* proj = 0;
349  bool isBilinear = false;
350  if (hdr)
351  {
352  ossimString geographicLocation = hdr->getGeographicLocation();
353 
354  if ( geographicLocation.size() )
355  {
356  std::vector<ossimDpt> utmPoints;
357  ossim_uint32 zone;
358  ossimDpt scale;
359  char hemisphere = 'N';
360 
361  bool status = true;
362  if ( coordinateSystem == "U")
363  {
364  // Sets zone, hemisphere and utmPoints. Returns true on success.
365  status = parseMgrsString(geographicLocation, zone, hemisphere, utmPoints);
366  }
367  else
368  {
369  // Sets zone and utmPoints. Void return...
370  parseUtmString(geographicLocation, zone, utmPoints);
371  if(coordinateSystem == "S")
372  {
373  hemisphere = 'S';
374  }
375  }
376 
377  if ( status )
378  {
379  if ( traceDebug() )
380  {
381  std::string s;
382  s.push_back(hemisphere);
384  << "ossimNitfProjectionFactory::makeUtm DEBUG"
385  << "\ngeo string: " << geographicLocation
386  << "\nutm zone: " << zone
387  << "\nhemisphere: " << hemisphere
388  << std::endl;
389  for (ossim_uint32 i=0; i<utmPoints.size(); ++i)
390  {
392  << "utmPoints[" << utmPoints[i] << std::endl;
393  }
394  }
395 
397  uproj->setHemisphere(hemisphere);
398  uproj->setZone(zone);
399 
400  if(isSkewed(utmPoints))
401  {
402  std::vector<ossimGpt> gpts;
403 
404  // Try blocka points first as they are more accurate.
405  if ( getBlockaPoints(hdr, gpts) == false )
406  {
407  ossimGpt ul = uproj->inverse(utmPoints[0]);
408  ossimGpt ur = uproj->inverse(utmPoints[1]);
409  ossimGpt lr = uproj->inverse(utmPoints[2]);
410  ossimGpt ll = uproj->inverse(utmPoints[3]);
411  gpts.push_back(ul);
412  gpts.push_back(ur);
413  gpts.push_back(lr);
414  gpts.push_back(ll);
415  }
416 
417  //---
418  // Make a bilinear either from our skewed utm points or the points from the blocka
419  // tag.
420  //---
421  proj = makeBilinear(hdr, gpts);
422  if(proj) scale = proj->getMetersPerPixel();
423  isBilinear = true;
424  uproj = 0; // Done with utm projeciton
425 
426  }
427  else
428  {
429  computeScaleInMeters(hdr, utmPoints, scale);
430 
431  //---
432  // Assign our projection to the return "proj".
433  // Use ossimRefPtr::release the so we don't delete proj when uproj
434  // goes out of scope.
435  //---
436  proj = uproj.release();
437  }
438 
439  if( (scale.hasNans() == false)&&(!isBilinear) )
440  {
441  //---
442  // Get the tie point.
443  //
444  // Look for the the BLOCKA tag which may or may not be present.
445  // This has six digit precision in decimal degrees which equates to
446  // about 0.11 meters (at equator) as compared to 1.0 accuaracy of the
447  // IGEOLO field.
448  //---
449  ossimDpt tie;
450  std::vector<ossimGpt> gpts;
451  if ( getBlockaPoints(hdr, gpts) )
452  {
453  if (traceDebug())
454  {
456  << "ossimNitfProjectionFactory::makeUtm DEBUG:"
457  << "\nTie point from blocka: " << gpts[0]
458  << endl;
459  }
460 
461  tie = proj->forward(gpts[0]);
462  tie.x += scale.x/2.0;
463  tie.y -= scale.y/2.0;
464  }
465  else
466  {
467  tie.x = utmPoints[0].x + scale.x/2.0;
468  tie.y = utmPoints[0].y - scale.y/2.0;
469  }
470 
471  if (traceDebug())
472  {
474  << "ossimNitfProjectionFactory::makeUtm DEBUG:"
475  << "\nTie point: " << tie
476  << "\nScale: " << scale
477  << endl;
478  }
479 
480  // Set the tie and scale.
481  ossimMapProjection* mproj = dynamic_cast<ossimMapProjection*>(proj);
482  if ( mproj )
483  {
484  mproj->setUlEastingNorthing(tie);
485  mproj->setMetersPerPixel(scale);
486  }
487  else // cannot cast
488  {
489  if ( proj )
490  {
491  delete proj;
492  proj = 0;
493  }
494  }
495  }
496  else if(isBilinear)
497  {
498  // blank
499  }
500  else // Scale has nans
501  {
502  if ( proj )
503  {
504  delete proj;
505  proj = 0;
506  }
507  }
508 
509  } // matches: if (status)
510 
511  } // matches: if ( geographicLocation.size() )
512 
513  } // matches: if (hdr)
514 
515  return proj;
516 }
517 
519  ossim_uint32& zone,
520  char& hemisphere,
521  std::vector<ossimDpt>& utmPoints)const
522 {
523  bool result = false; // Start false.
524 
525  //---
526  // From spec:
527  // UTM expressed in MGRS use the format zzBJKeeeeennnnn (15 characters).
528  // Assumption Zone and hemisphere same for all corners.
529  //---
530  if ( mgrsLocationString.size() >= 60 )
531  {
532  // Split the location string into four separate ones.
533  std::vector<std::string> mgrsStr(4); // Corner strings.
534  mgrsStr[0] = mgrsLocationString.substr(0, 15);
535  mgrsStr[1] = mgrsLocationString.substr(15, 15);
536  mgrsStr[2] = mgrsLocationString.substr(30, 15);
537  mgrsStr[3] = mgrsLocationString.substr(45, 15);
538 
539  utmPoints.resize(4);
540  long z = 0;
541  ossim_float64 e=0.0;
542  ossim_float64 n=0.0;
543 
544  result = true; // Set to true.
545 
546 
547  //---
548  // Convert each string to Easting Northing. This also sets zone hemisphere.
549  // Method takes long for zone.
550  //---
551  for (ossim_uint32 i = 0; i < 4; ++i)
552  {
553  if ( Convert_OSSIM_MGRS_To_UTM(mgrsStr[i].c_str(), &z, &hemisphere, &e, &n) == 0 )
554  {
555  utmPoints[i].x = e;
556  utmPoints[i].y = n;
557  }
558  else
559  {
560  result = false; // Geotrans code errored on string.
561  break;
562  }
563  }
564  if (result) zone = static_cast<ossim_uint32>(z); // Set the zone.
565  }
566 
567  return result;
568 }
569 
571  const ossimNitfImageHeader* hdr,
572  const std::vector<ossimGpt>& gpts) const
573 {
574  ossimEquDistCylProjection* proj = 0;
575 
576  // Get the scale.
577  ossimDpt scale;
578  computeScaleInDecimalDegrees(hdr, gpts, scale);
579 
580  if (scale.hasNans())
581  {
582  return proj;
583  }
584  // Make the projection.
585  proj = new ossimEquDistCylProjection();
586 
587  if ( scale.x )
588  {
589  ossimGpt origin = proj->getOrigin();
590 
591  //---
592  // ossimEquDistCylProjection uses the origin_latitude for meters per pixel (gsd)
593  // computation. So is not set in tiff tags, compute to achieve the proper
594  // horizontal scaling.
595  //---
596  ossim_float64 x = (scale.y/scale.x);
597  if ( x > 1.0 ) x = 1.0; // Limit to domain of arc cosine function.
598  origin.lat = ossim::acosd(x);
599 
600  proj->setOrigin(origin);
601  }
602 
603  // Shift the tie to the center of the pixel.
604  ossimGpt tiePoint;
605  tiePoint.latd(gpts[0].latd() - (scale.y/2.0));
606  tiePoint.lond(gpts[0].lond() + (scale.x/2.0));
607 
608  // Set the tie points.
609  proj->setUlTiePoints(tiePoint);
610 
611  // Set the scale.
612  proj->setDecimalDegreesPerPixel(scale);
613 
614  return proj;
615 }
616 
618  const ossimNitfImageHeader* hdr,
619  const std::vector<ossimGpt>& gpts) const
620 {
621  double rows = hdr->getNumberOfRows();
622  double cols = hdr->getNumberOfCols();
623 
624  ossimDpt ul(0.0, 0.0);
625  ossimDpt ur(cols-1.0, 0.0);
626  ossimDpt lr(cols-1.0, rows-1.0);
627  ossimDpt ll(0.0, rows-1.0);
628 
630  try
631  {
632  proj = new ossimBilinearProjection(ul,
633  ur,
634  lr,
635  ll,
636  gpts[0],
637  gpts[1],
638  gpts[2],
639  gpts[3]);
640  }
641  catch(...)
642  {
643  proj = 0;
644  }
645 
646  return proj.release();
647 }
648 
650  const std::vector<ossimGpt>& gpts) const
651 {
652 
653  return !( (gpts[0].latd() == gpts[1].latd()) &&
654  (gpts[2].latd() == gpts[3].latd()) &&
655  (gpts[0].lond() == gpts[3].lond()) &&
656  (gpts[1].lond() == gpts[2].lond()) );
657 
658 }
659 
661  const std::vector<ossimDpt>& dpts) const
662 {
663  return !( (dpts[0].y == dpts[1].y) &&
664  (dpts[2].y == dpts[3].y) &&
665  (dpts[0].x == dpts[3].x) &&
666  (dpts[1].x == dpts[2].x) );
667 
668 }
669 
671  const ossimNitfImageHeader* hdr,
672  std::vector<ossimGpt>& gpts) const
673 {
674  if (!hdr)
675  {
676  return false;
677  }
678 
680  hdr->getTagData(ossimString("BLOCKA"));
681 
682  if (!tag)
683  {
684  if (traceDebug())
685  {
687  << "ossimNitfProjectionFactory::getBlockaPoints DEBUG:"
688  << "\nBLOCKA tag not found."
689  << std::endl;
690  }
691  return false;
692  }
693 
694  if (gpts.size())
695  {
696  gpts.clear();
697  }
698 
699  ossimNitfBlockaTag* blockaTag = PTR_CAST(ossimNitfBlockaTag, tag.get());
700  if (!blockaTag)
701  {
702  return false;
703  }
704 
705  ossimDpt dpt;
706  ossimGpt gpt;
707 
708  // Get the upper left or first row first column.
709  blockaTag->getFrfcLoc(dpt);
710  gpt.latd(dpt.y);
711  gpt.lond(dpt.x);
712  gpts.push_back(gpt);
713 
714  // Get the upper right or first row last column.
715  blockaTag->getFrlcLoc(dpt);
716  gpt.latd(dpt.y);
717  gpt.lond(dpt.x);
718  gpts.push_back(gpt);
719 
720  // Get the lower right or last row last column.
721  blockaTag->getLrlcLoc(dpt);
722  gpt.latd(dpt.y);
723  gpt.lond(dpt.x);
724  gpts.push_back(gpt);
725 
726  // Get the lower left or last row first column.
727  blockaTag->getLrfcLoc(dpt);
728  gpt.latd(dpt.y);
729  gpt.lond(dpt.x);
730  gpts.push_back(gpt);
731 
732  if (traceDebug())
733  {
735  << "ossimNitfProjectionFactory::getBlockaPoints DEBUG:"
736  << std::endl;
737  for (int i=0; i<4; ++i)
738  {
740  << "gpt[" << i << "] " << gpts[i] << std::endl;
741  }
742  }
743 
744  return true;
745 }
746 
748  const ossimNitfImageHeader* hdr,
749  std::vector<ossimGpt>& gpts) const
750 {
751  static const char MODULE[] = "ossimNitfProjectionFactory::getGeolobPoints";
752  if (traceDebug())
753  {
755  << MODULE << " entered...\n";
756  }
757  bool result = false;
758 
759  gpts.clear();
760 
761  if ( hdr )
762  {
764  if ( tag.valid() )
765  {
766  ossimNitfGeolobTag* geolob = dynamic_cast<ossimNitfGeolobTag*>(tag.get());
767  if ( geolob )
768  {
769  ossimDpt gsd( geolob->getDegreesPerPixelLon(), geolob->getDegreesPerPixelLat() );
770  if ( (gsd.x > 0.0 ) && (gsd.y > 0.0) )
771  {
772  ossim_int32 rows = hdr->getNumberOfRows();
773  ossim_int32 cols = hdr->getNumberOfCols();
774  if ( (rows > 0) && (cols > 0) )
775  {
776  ossimGpt gpt(0.0, 0.0, 0.0);
777  ossimDpt origin( geolob->getLso(), geolob->getPso() );
778 
779  if (traceDebug())
780  {
782  << "origin: " << origin
783  << "\ngsd: " << gsd << "\n";
784  }
785 
786  // Note: Edge to edge here as origin is shifted makeEuiDistant method.
787  // UL:
788  gpt.latd(origin.y);
789  gpt.lond(origin.x);
790  gpts.push_back(gpt);
791 
792  // UR:
793  gpt.latd(origin.y);
794  gpt.lond(origin.x + cols*gsd.x);
795  gpts.push_back(gpt);
796 
797  // LR:
798  gpt.latd(origin.y - rows*gsd.y);
799  gpt.lond(origin.x + cols*gsd.x);
800  gpts.push_back(gpt);
801 
802  // LL:
803  gpt.latd(origin.y - rows*gsd.y);
804  gpt.lond(origin.x);
805  gpts.push_back(gpt);
806 
807  result = true;
808  }
809  }
810  }
811  }
812  else if (traceDebug())
813  {
815  << "No GEOLOB tag found.\n";
816  }
817  }
818 
819  if (traceDebug())
820  {
822  << MODULE << " exit status: " << (result?"true":"false") << "\n";
823  }
824 
825  return result;
826 }
827 
829  const ossimNitfImageHeader* hdr,
830  const std::vector<ossimGpt>& gpts,
831  ossimDpt& scale) const
832 {
833  if ( !hdr || isSkewed(gpts))
834  {
835  scale.makeNan();
836  return;
837  }
838  ossimIrect imageRect = hdr->getImageRect();
839 
840  //---
841  // Calculate the scale. This assumes that the corner points are for the
842  // edge of the corner pixels, not the center of the corner pixels.
843  //---
844  double longitudeSize = 0.0;
845  double latitudeSize = 0.0;
846  if ( (gpts[1].lond() < 0.0) && (gpts[0].lond() >= 0) )
847  {
848  //---
849  // Upper right negative(Western), upper left positive (Eastern).
850  // Crossing date line maybe???
851  //---
852  longitudeSize = (gpts[1].lond() + 360.0) - gpts[0].lond();
853  }
854  else
855  {
856  longitudeSize = gpts[1].lond() - gpts[0].lond();
857  }
858 
859  latitudeSize = gpts[0].latd() - gpts[2].latd();
860 
861  double rows = imageRect.height();
862  double cols = imageRect.width();
863 // double rows = hdr->getNumberOfRows();
864 // double cols = hdr->getNumberOfCols();
865 
866  if (!rows || !cols)
867  {
868  scale.makeNan();
869  return;
870  }
871  scale.y = latitudeSize / rows;
872  scale.x = longitudeSize / cols;
873 }
874 
876  const ossimNitfImageHeader* hdr,
877  const std::vector<ossimDpt>& dpts,
878  ossimDpt& scale) const
879 {
880  if ( !hdr || isSkewed(dpts))
881  {
882  scale.makeNan();
883  return;
884  }
885  ossimIrect imageRect = hdr->getImageRect();
886 
887  //---
888  // Calculate the scale. This assumes that the corner points are for the
889  // edge of the corner pixels, not the center of the corner pixels.
890  //---
891  double eastingSize = 0.0;
892  double northingSize = 0.0;
893 
894  eastingSize = fabs(dpts[1].x - dpts[0].x);
895  northingSize = fabs(dpts[0].y - dpts[3].y);
896 
897  double rows = imageRect.height();//hdr->getNumberOfRows();
898  double cols = imageRect.width();//hdr->getNumberOfCols();
899 
900  if (!rows || !cols)
901  {
902  scale.makeNan();
903  return;
904  }
905  scale.y = northingSize / rows;
906  scale.x = eastingSize / cols;
907 }
908 
910  ossim_uint32& zone,
911  std::vector<ossimDpt>& utmPoints)const
912 {
913  ossim_uint32 idx = 0;
914  ossimString z;
915  ossimString east;
916  ossimString north;
917 
918 
919  z = ossimString(utmLocation.begin() + idx,
920  utmLocation.begin() + idx + 2);
921  idx += 2;
922  east = ossimString(utmLocation.begin() + idx,
923  utmLocation.begin() + idx + 6);
924  idx += 6;
925  north = ossimString(utmLocation.begin() + idx,
926  utmLocation.begin() + idx + 7);
927  idx += 7;
928 
929  utmPoints.push_back(ossimDpt(east.toDouble(),
930  north.toDouble()));
931 
932  z = ossimString(utmLocation.begin() + idx,
933  utmLocation.begin() + idx + 2);
934  idx += 2;
935  east = ossimString(utmLocation.begin() + idx,
936  utmLocation.begin() + idx + 6);
937  idx += 6;
938  north = ossimString(utmLocation.begin() + idx,
939  utmLocation.begin() + idx + 7);
940  idx += 7;
941  utmPoints.push_back(ossimDpt(east.toDouble(),
942  north.toDouble()));
943 
944  z = ossimString(utmLocation.begin() + idx,
945  utmLocation.begin() + idx + 2);
946  idx += 2;
947  east = ossimString(utmLocation.begin() + idx,
948  utmLocation.begin() + idx + 6);
949  idx += 6;
950  north = ossimString(utmLocation.begin() + idx,
951  utmLocation.begin() + idx + 7);
952  idx += 7;
953  utmPoints.push_back(ossimDpt(east.toDouble(),
954  north.toDouble()));
955 
956  z = ossimString(utmLocation.begin() + idx,
957  utmLocation.begin() + idx + 2);
958  idx += 2;
959  east = ossimString(utmLocation.begin() + idx,
960  utmLocation.begin() + idx + 6);
961  idx += 6;
962  north = ossimString(utmLocation.begin() + idx,
963  utmLocation.begin() + idx + 7);
964  idx += 7;
965  utmPoints.push_back(ossimDpt(east.toDouble(),
966  north.toDouble()));
967 
968  zone = z.toUInt32();
969 }
970 
971 
973  const ossimString& geographicLocation, std::vector<ossimGpt>& gpts) const
974 {
975  gpts.clear();
976 
977  if (geographicLocation.size() != 60)
978  {
979  return;
980  }
981 
982  std::string::size_type geo_index = 0;
983  for (int i=0; i<4; ++i)
984  {
985  //---
986  // We have to split up the geographicLocation string for the dms class.
987  //
988  // geographicLocation = ddmmssXdddmmssX (four times).
989  // "dd mm ss X" has a string length of 10
990  // "ddd mm ss X" has a string length of 11
991  //---
992  std::string::size_type lat_index = 0;
993  std::string::size_type lon_index = 0;
994  const char SPACE = ' ';
995  ossimString latString(10, SPACE);
996  ossimString lonString(11, SPACE);
997 
998  // degrees latitude
999  latString[lat_index++] = geographicLocation[geo_index++];
1000  latString[lat_index++] = geographicLocation[geo_index++];
1001  ++lat_index;
1002 
1003  // minutes latitude
1004  latString[lat_index++] = geographicLocation[geo_index++];
1005  latString[lat_index++] = geographicLocation[geo_index++];
1006  ++lat_index;
1007 
1008  // seconds latitude
1009  latString[lat_index++] = geographicLocation[geo_index++];
1010  latString[lat_index++] = geographicLocation[geo_index++];
1011  ++lat_index;
1012 
1013  // hemisphere
1014  latString[lat_index++] = geographicLocation[geo_index++];
1015 
1016  // degrees longitude
1017  lonString[lon_index++] = geographicLocation[geo_index++];
1018  lonString[lon_index++] = geographicLocation[geo_index++];
1019  lonString[lon_index++] = geographicLocation[geo_index++];
1020  ++lon_index;
1021 
1022  // minutes longitude
1023  lonString[lon_index++] = geographicLocation[geo_index++];
1024  lonString[lon_index++] = geographicLocation[geo_index++];
1025  ++lon_index;
1026 
1027  // seconds longitude
1028  lonString[lon_index++] = geographicLocation[geo_index++];
1029  lonString[lon_index++] = geographicLocation[geo_index++];
1030  ++lon_index;
1031 
1032  // hemisphere
1033  lonString[lon_index++] = geographicLocation[geo_index++];
1034 
1035  // Convert to decimal degrees using the dms class.
1036  ossimGpt gpt;
1037  ossimDms dms(0.0);
1038  dms.setLatFlag(true);
1039  if ( ! dms.setDegrees(latString.c_str()) )
1040  {
1041  gpts.clear();
1042  return;
1043  }
1044  gpt.latd(dms.getDegrees());
1045 
1046  dms.setLatFlag(false);
1047  if ( ! dms.setDegrees(lonString.c_str()) )
1048  {
1049  gpts.clear();
1050  return;
1051  }
1052  gpt.lond(dms.getDegrees());
1053 
1054  gpts.push_back(gpt);
1055 
1056  if (traceDebug())
1057  {
1059  << "ossimNitfProjectionFactory::parseGeographicString DEBUG:"
1060  << "\nground point[" << i << "]: " << gpt
1061  << std::endl;
1062  }
1063  }
1064 }
1065 
1067  std::vector<ossimGpt>& gpts) const
1068 {
1069  const char* bufPtr = geographicLocation.c_str();
1070 
1071 
1072  ossimString ulLat(bufPtr,
1073  bufPtr + 7);
1074  bufPtr+=7;
1075  ossimString ulLon(bufPtr,
1076  bufPtr+8);
1077  bufPtr+=8;
1078  ossimString urLat(bufPtr,
1079  bufPtr + 7);
1080  bufPtr+=7;
1081  ossimString urLon(bufPtr,
1082  bufPtr+8);
1083  bufPtr+=8;
1084  ossimString lrLat(bufPtr,
1085  bufPtr + 7);
1086  bufPtr+=7;
1087  ossimString lrLon(bufPtr,
1088  bufPtr+8);
1089  bufPtr+=8;
1090  ossimString llLat(bufPtr,
1091  bufPtr + 7);
1092  bufPtr+=7;
1093  ossimString llLon(bufPtr,
1094  bufPtr+8);
1095 
1096  gpts.push_back(ossimGpt(ulLat.toDouble(), ulLon.toDouble()));
1097  gpts.push_back(ossimGpt(urLat.toDouble(), urLon.toDouble()));
1098  gpts.push_back(ossimGpt(lrLat.toDouble(), lrLon.toDouble()));
1099  gpts.push_back(ossimGpt(llLat.toDouble(), llLon.toDouble()));
1100 
1101  if (traceDebug())
1102  {
1104  << "ossimNitfProjectionFactory::parseDecimalDegreesString DEBUG:"
1105  << "\nground point[" << 0 << "]: " << gpts[0]
1106  << "\nground point[" << 1 << "]: " << gpts[1]
1107  << "\nground point[" << 2 << "]: " << gpts[2]
1108  << "\nground point[" << 3 << "]: " << gpts[3]
1109  << std::endl;
1110  }
1111 }
1112 
1114 {
1115 }
1116 
1118 {
1119  return *this;
1120 }
ossim_uint32 x
virtual ossimGpt inverse(const ossimDpt &eastingNorthing) const
Will take a point in meters and convert it to ground.
virtual const char * getVersion() const =0
void computeScaleInDecimalDegrees(const ossimNitfImageHeader *hdr, const std::vector< ossimGpt > &gpts, ossimDpt &scale) const
Computes the scale in decimal degrees with scale.x being longitude, y being latitude.
ossimProjection * createProjectionFromGeometryFile(const ossimFilename &imageFile, ossim_uint32 entryIdx) const
This method takes the filename and tries to find an external ".geom" file.
virtual ossim_int32 getNumberOfRows() const =0
ossimString getFrlcLoc() const
ossimNitfImageHeader * getNewImageHeader(ossim_uint32 imageNumber) const
ossimString getFrfcLoc() const
virtual ossimString getCoordinateSystem() const =0
ossim_float64 getDegreesPerPixelLon() const
Gets degrees per pixel in lonitude direction from BRV field.
double lond() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:97
Represents serializable keyword/value map.
ossim_uint32 y
std::basic_ifstream< char > ifstream
Class for char input file streams.
Definition: ossimIosFwd.h:44
bool valid() const
Definition: ossimRefPtr.h:75
virtual ~ossimNitfProjectionFactory()
destructor
void parseUtmString(const ossimString &utmLocation, ossim_uint32 &zone, std::vector< ossimDpt > &utmPoints) const
virtual std::ostream & print(std::ostream &out) const
Outputs theErrorStatus as an ossimErrorCode and an ossimString.
ossimProjection * makeGeographic(const ossimNitfImageHeader *hdr, const ossimString &coordinateSysetm) const
double y
Definition: ossimDpt.h:165
ossim_uint32 height() const
Definition: ossimIrect.h:487
ossimProjection * makeBilinear(const ossimNitfImageHeader *hdr, const std::vector< ossimGpt > &gpts) const
T abs(const T &value)
Definition: ossimCommon.h:138
double acosd(double x)
Definition: ossimCommon.h:264
virtual ossimObject * createObject(const ossimString &typeName) const
Creates an object given a type name.
virtual void setDecimalDegreesPerPixel(const ossimDpt &gsd)
ossim_uint32 toUInt32() const
double latd() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:87
#define SPACE
Definition: vpfio.h:25
static ossimNitfProjectionFactory * theInstance
ossimString getLrfcLoc() const
virtual void setMetersPerPixel(const ossimDpt &gsd)
ossim_float64 getPso() const
Gets the PSO field(Latitude Origin).
ossimProjection * makeEuiDistant(const ossimNitfImageHeader *hdr, const std::vector< ossimGpt > &gpts) const
void push_back(char c)
Equivalent to insert(end(), c).
Definition: ossimString.h:905
double ossim_float64
bool parseMgrsString(const ossimString &mgrsLocationString, ossim_uint32 &zone, char &hemisphere, std::vector< ossimDpt > &utmPoints) const
Gets UTM points, zone and hemisphere from IGEOLO field when ICORDS files = U which is UTM expressed i...
virtual void setUlEastingNorthing(const ossimDpt &ulEastingNorthing)
virtual const ossimFilename & getFilename() const
Returns the filename.
virtual ossimIrect getImageRect() const =0
std::string::size_type size() const
Definition: ossimString.h:405
os2<< "> n<< " > nendobj n
std::string::iterator begin()
Definition: ossimString.h:420
virtual ossimDpt getMetersPerPixel() const =0
static ossimNitfProjectionFactory * instance()
METHOD: instance()
const ossimNitfFileHeader * getHeader() const
unsigned int ossim_uint32
virtual ossim_int32 getNumberOfCols() const =0
ossimNitfProjectionFactory()
Private constructor, users must go through instance() method.
bool setDegrees(const std::string &value)
setDegrees(char*).
Definition: ossimDms.cpp:79
double toDouble() const
#define PTR_CAST(T, p)
Definition: ossimRtti.h:321
T * release()
Definition: ossimRefPtr.h:93
virtual ossim_uint32 getCurrentEntry() const
virtual void setOrigin(const ossimGpt &origin)
double getDegrees() const
Definition: ossimDms.h:71
ossimProjection * createProjectionFromHeaders(ossimNitfFileHeader *fileHeader, ossimNitfImageHeader *imageHeader) const
const ossimNitfImageHeader * getCurrentImageHeader() const
virtual ossimString getGeographicLocation() const =0
void computeScaleInMeters(const ossimNitfImageHeader *hdr, const std::vector< ossimDpt > &dpts, ossimDpt &scale) const
Computes the scale in meters with scale.x being easting, y being northing.
ossim_uint32 width() const
Definition: ossimIrect.h:500
ossimString getLrlcLoc() const
bool hasNans() const
Definition: ossimDpt.h:67
ossim_float64 getLso() const
Gets the LSO field(Longitude Origin).
const ossimGpt & getOrigin() const
void setZone(const ossimGpt &ground)
OSSIM_DLL long Convert_OSSIM_MGRS_To_UTM(const char *MGRS, long *Zone, char *Hemisphere, double *Easting, double *Northing)
ossimNitfProjectionFactory & operator=(const ossimNitfProjectionFactory &rhs)
Private operator = to hide from use.
return status
const ossimNitfFileHeader * getFileHeader() const
bool getGeolobPoints(const ossimNitfImageHeader *hdr, std::vector< ossimGpt > &gpts) const
This class defines an abstract Handler which all image handlers(loaders) should derive from...
virtual ossimDpt forward(const ossimGpt &wp) const
bool isNitf(const ossimFilename &filename) const
void parseDecimalDegreesString(const ossimString &geographicLocation, std::vector< ossimGpt > &gpts) const
Parses Decimal degree stream.
ossimDms & setLatFlag(bool latFlag)
Definition: ossimDms.h:89
bool isSkewed(const std::vector< ossimGpt > &gpts) const
double x
Definition: ossimDpt.h:164
ossimRefPtr< ossimNitfRegisteredTag > getTagData(const ossimString &tagName)
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string&#39;s contents...
Definition: ossimString.h:396
bool getBlockaPoints(const ossimNitfImageHeader *hdr, std::vector< ossimGpt > &gpts) const
virtual void setUlTiePoints(const ossimGpt &gpt)
std::string substr(std::string::size_type pos=0, std::string::size_type n=std::string::npos) const
Equivalent to basic_string(*this, pos, n).
Definition: ossimString.h:910
bool parseFile(const ossimFilename &file)
ossim_float64 lat
Definition: ossimGpt.h:265
ossim_float64 getDegreesPerPixelLat() const
Gets degrees per pixel in latitude direction from BRV field.
void parseGeographicString(const ossimString &geographicLocation, std::vector< ossimGpt > &gpts) const
Parses geographic stream.
virtual void getTypeNameList(std::vector< ossimString > &typeList) const
This should return the type name of all objects in all factories.
void setHemisphere(const ossimGpt &ground)
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
void makeNan()
Definition: ossimDpt.h:65
ossimProjection * makeUtm(const ossimNitfImageHeader *hdr, const ossimString &coordinateSysetm) const
int ossim_int32
virtual ossimProjection * createProjection(const ossimFilename &filename, ossim_uint32 entryIdx) const
virtual ossim_int32 getNumberOfImages() const =0