otbDEMHandler.cxx 7.51 KB
Newer Older
1 2
/*=========================================================================

3 4 5 6
  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$
7 8


9
  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
10
  See OTBCopyright.txt for details.
11 12


13 14
     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15
     PURPOSE.  See the above copyright notices for more information.
16 17

=========================================================================*/
Romain Garrigues's avatar
Romain Garrigues committed
18
#include "otbDEMHandler.h"
19 20
#include "otbMacro.h"

21 22
#include <cassert>

23
#if defined(__GNUC__) || defined(__clang__)
24 25 26
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Woverloaded-virtual"
27
#pragma GCC diagnostic ignored "-Wshadow"
28 29 30 31 32 33
#include "ossim/elevation/ossimElevManager.h"
#include "ossim/base/ossimGeoidManager.h"
#include "ossim/base/ossimFilename.h"
#include "ossim/base/ossimDirectory.h"
#include "ossim/base/ossimGeoidEgm96.h"
#include "ossim/base/ossimRefPtr.h"
34
#include <ossim/elevation/ossimImageElevationDatabase.h>
35 36 37 38 39 40 41 42 43 44 45 46
#pragma GCC diagnostic pop
#else
#include "ossim/elevation/ossimElevManager.h"
#include "ossim/base/ossimGeoidManager.h"
#include "ossim/base/ossimFilename.h"
#include "ossim/base/ossimDirectory.h"
#include "ossim/base/ossimGeoidEgm96.h"
#include "ossim/base/ossimRefPtr.h"
#include <ossim/elevation/ossimImageElevationDatabase.h>
#endif


47

48
namespace otb
49
{
Julien Michel's avatar
Julien Michel committed
50 51
/** Initialize the singleton */
DEMHandler::Pointer DEMHandler::m_Singleton = NULL;
52

53
DEMHandler::Pointer DEMHandler::Instance()
54
{
55
  if(m_Singleton.GetPointer() == NULL)
56
    {
57 58 59 60 61 62 63
    m_Singleton = itk::ObjectFactory<Self>::Create();

    if(m_Singleton.GetPointer() == NULL)
      {
      m_Singleton = new DEMHandler;
      }
    m_Singleton->UnRegister();
64
    }
65

66 67 68
  return m_Singleton;
}

69
DEMHandler
OTB Bot's avatar
OTB Bot committed
70
::DEMHandler() :
71 72
  m_GeoidFile(""),
  m_DefaultHeightAboveEllipsoid(0)
73
{
74 75
  assert( ossimElevManager::instance()!=NULL );

76
  ossimElevManager::instance()->setDefaultHeightAboveEllipsoid(m_DefaultHeightAboveEllipsoid);
77
  // Force geoid fallback
78
  ossimElevManager::instance()->setUseGeoidIfNullFlag(true);
79
}
80

81 82 83 84
void
DEMHandler
::OpenDEMDirectory(const char* DEMDirectory)
{
85 86
  assert( ossimElevManager::instance()!=NULL );

87
  ossimFilename ossimDEMDir( DEMDirectory );
88

89
  if (!ossimElevManager::instance()->loadElevationPath(ossimDEMDir))
OTB Bot's avatar
OTB Bot committed
90
    {
91 92 93 94 95 96 97
    // In ossim elevation database factory code, the
    // ossimImageElevationDatabase is explicitly disabled by a #if 0
    // guard, because it causes problem when loading ossim related
    // application. Therefore, we explicitly call
    // ossimImageElevationDatabase here to allow for general elevation
    // images support.
    ossimRefPtr<ossimElevationDatabase> imageElevationDatabase = new ossimImageElevationDatabase;
98

99 100 101 102 103 104 105
    if(!imageElevationDatabase->open(DEMDirectory))
      {
      itkExceptionMacro("Failed to open DEM Directory: " << ossimDEMDir);
      }
    else
      {
      otbMsgDevMacro(<< "DEM directory contains general elevation image files: " << ossimDEMDir);
106
      ossimElevManager::instance()->addDatabase(imageElevationDatabase.get());
107
      }
OTB Bot's avatar
OTB Bot committed
108
    }
109
}
110

111 112 113 114 115 116 117 118 119 120 121

void
DEMHandler
::ClearDEMs()
{
  assert( ossimElevManager::instance()!=NULL );

  ossimElevManager::instance()->clear();
}


122 123 124 125 126 127 128
void
DEMHandler
::OpenDEMDirectory(const std::string& DEMDirectory)
{
  OpenDEMDirectory(DEMDirectory.c_str());
}

129 130 131 132
bool
DEMHandler
::IsValidDEMDirectory(const char* DEMDirectory)
{
133 134
  assert( ossimElevManager::instance()!=NULL );

135
  //Try to load elevation source
136
  bool result = ossimElevManager::instance()->loadElevationPath(DEMDirectory);
137

138 139 140 141 142 143 144 145
  if (!result)
    {
      // we explicitly call ossimImageElevationDatabase here to allow for general elevation
      // images support and test the open method to check if the directory .
      ossimRefPtr<ossimElevationDatabase> imageElevationDatabase = new ossimImageElevationDatabase;
      result = imageElevationDatabase->open(DEMDirectory);
    }
  return result;
146 147
}

148
bool
149 150 151
DEMHandler
::OpenGeoidFile(const char* geoidFile)
{
152
  if ((ossimGeoidManager::instance()->findGeoidByShortName("geoid1996")) == 0)
OTB Bot's avatar
OTB Bot committed
153 154 155
    {
    otbMsgDevMacro(<< "Opening geoid: " << geoidFile);
    ossimFilename           geoid(geoidFile);
156
    ossimRefPtr<ossimGeoid> geoidPtr = new ossimGeoidEgm96(geoid);
157
    if (geoidPtr->getErrorStatus() == ossimErrorCodes::OSSIM_OK)
OTB Bot's avatar
OTB Bot committed
158
      {
159
      // Ossim does not allow retrieving the geoid file path
160 161
      // We therefore must keep it on our side
      m_GeoidFile = geoidFile;
OTB Bot's avatar
OTB Bot committed
162 163 164
      otbMsgDevMacro(<< "Geoid successfully opened");
      ossimGeoidManager::instance()->addGeoid(geoidPtr);
      geoidPtr.release();
165 166 167

      // The previous flag will be ignored if
      // defaultHeightAboveEllipsoid is not NaN
168 169
      assert( ossimElevManager::instance()!=NULL );

170
      ossimElevManager::instance()->setDefaultHeightAboveEllipsoid(ossim::nan());
171

172
      return true;
OTB Bot's avatar
OTB Bot committed
173
      }
174
    else
OTB Bot's avatar
OTB Bot committed
175 176
      {
      otbMsgDevMacro(<< "Failure opening geoid");
177
      geoidPtr.release();
178 179 180 181

      itkExceptionMacro( << "Failed to open geoid file: '" << geoidFile << "'" );

      return false;
OTB Bot's avatar
OTB Bot committed
182
      }
183
    }
184 185

  return false;
186 187
}

188
bool
189 190 191
DEMHandler
::OpenGeoidFile(const std::string& geoidFile)
{
192
  return OpenGeoidFile(geoidFile.c_str());
193 194
}

195 196
double
DEMHandler
197
::GetHeightAboveMSL(double lon, double lat) const
198
{
OTB Bot's avatar
OTB Bot committed
199
  double   height;
200
  ossimGpt ossimWorldPoint;
201

202 203
  ossimWorldPoint.lon = lon;
  ossimWorldPoint.lat = lat;
204 205 206

  assert( ossimElevManager::instance()!=NULL );

207
  height = ossimElevManager::instance()->getHeightAboveMSL(ossimWorldPoint);
208

209 210
  return height;
}
211

212 213
double
DEMHandler
214 215 216 217 218 219 220 221
::GetHeightAboveMSL(const PointType& geoPoint) const
{
  return GetHeightAboveMSL(geoPoint[0], geoPoint[1]);
}

double
DEMHandler
::GetHeightAboveEllipsoid(double lon, double lat) const
222
{
OTB Bot's avatar
OTB Bot committed
223
  double   height;
224
  ossimGpt ossimWorldPoint;
225

226 227
  ossimWorldPoint.lon = lon;
  ossimWorldPoint.lat = lat;
228 229 230

  assert( ossimElevManager::instance()!=NULL );

231
  height = ossimElevManager::instance()->getHeightAboveEllipsoid(ossimWorldPoint);
232

233 234
  return height;
}
235

236 237 238 239 240 241 242
double
DEMHandler
::GetHeightAboveEllipsoid(const PointType& geoPoint) const
{
  return GetHeightAboveEllipsoid(geoPoint[0], geoPoint[1]);
}

243 244 245 246
void
DEMHandler
::SetDefaultHeightAboveEllipsoid(double h)
{
247
  // Ossim does not allow retrieving the default height above
248
  // ellipsoid We therefore must keep it on our side
Julien Michel's avatar
Julien Michel committed
249
  m_DefaultHeightAboveEllipsoid = h;
250 251 252

  assert( ossimElevManager::instance()!=NULL );

253
  ossimElevManager::instance()->setDefaultHeightAboveEllipsoid(h);
254 255
}

256 257 258 259
double
DEMHandler
::GetDefaultHeightAboveEllipsoid() const
{
260
  // Ossim does not allow retrieving the default height above
261 262 263 264
  // ellipsoid We therefore must keep it on our side
  return m_DefaultHeightAboveEllipsoid;
}

265 266 267 268 269 270 271 272 273
unsigned int
DEMHandler
::GetDEMCount() const
{
  assert( ossimElevManager::instance()!=NULL );

  return ossimElevManager::instance()->getNumberOfElevationDatabases();
}

274 275 276 277
std::string DEMHandler::GetDEMDirectory(unsigned int idx) const
{
  std::string demDir = "";

278
  if(ossimElevManager::instance()->getNumberOfElevationDatabases() > 0)
279
    {
280 281
    assert( ossimElevManager::instance()!=NULL );

282
    demDir = ossimElevManager::instance()->getElevationDatabase(idx)->getConnectionString().string();
283 284 285 286 287 288
    }
  return demDir;
}

std::string DEMHandler::GetGeoidFile() const
{
289
  // Ossim does not allow retrieving the geoid file path
290 291 292 293
  // We therefore must keep it on our side
  return m_GeoidFile;
}

294 295
void
DEMHandler
296
::PrintSelf(std::ostream& os, itk::Indent indent) const
297
{
OTB Bot's avatar
OTB Bot committed
298
  Superclass::PrintSelf(os, indent);
299 300
  os << indent << "DEMHandler" << std::endl;
}
301 302

} // namespace otb