otbOGRLayerWrapper.cxx 13.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$


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


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

=========================================================================*/

/*===========================================================================*/
/*===============================[ Includes ]================================*/
/*===========================================================================*/
22

23
#include <cassert>
OTB Bot's avatar
STYLE  
OTB Bot committed
24
#include <boost/bind.hpp>
25
#include <boost/foreach.hpp>
26 27

#ifdef __GNUC__
28 29
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
30
#include "gdal_priv.h"// GDALDataset
31
#pragma GCC diagnostic pop
32
#else
33
#include "gdal_priv.h" // GDALDataset
34
#endif
35

36 37
#include "otbOGRDataSourceWrapper.h"

38
/*===========================================================================*/
39
/*======================[ Construction & Destruction ]=======================*/
40 41
/*===========================================================================*/
namespace  { // Anonymous namespace
Luc Hermitte's avatar
Luc Hermitte committed
42
  /**\ingroup GeometryInternals
43 44
   * Deleter for \c boost::shared_ptr<> that doesn't delete.
   * This is required for \c OGRLayer s that belong to \c OGRDataSource.
Luc Hermitte's avatar
Luc Hermitte committed
45
   * \internal Unlike OGR, works as a no-op on null geometries.
46 47 48 49 50
   */
  struct LeaveAloneDeleter
    {
    void operator()(OGRLayer*) const {}
    };
OTB Bot's avatar
STYLE  
OTB Bot committed
51
} // Anonymous namespace
52 53


54 55 56
otb::ogr::Layer::Layer(OGRLayer* layer, bool modifiable)
:   m_Layer(layer, LeaveAloneDeleter())
  , m_Modifiable(modifiable)
57 58 59
#if 0
  , m_DataSource(datasource)
#endif
60 61 62
{
}

63
otb::ogr::Layer::Layer(OGRLayer* layer, GDALDataset& sourceInChargeOfLifeTime, bool modifiable)
64 65
:   m_Layer(layer,  boost::bind(&OGRDataSource::ReleaseResultSet, boost::ref(sourceInChargeOfLifeTime), _1))
  , m_Modifiable(modifiable)
66 67 68 69 70
{
  assert(layer && "A null OGRlayer cannot belong to an OGRDataSource" );
  // OGR always refuses "delete 0". *sigh*
}

71 72 73
/*===========================================================================*/
/*===============================[ Features ]================================*/
/*===========================================================================*/
74 75
int otb::ogr::Layer::GetFeatureCount(bool doForceComputation) const
{
76
  assert(m_Layer && "Can't ask the features count on an invalid layer");
77 78 79
  return m_Layer->GetFeatureCount(doForceComputation);
}

80 81 82
otb::ogr::Feature otb::ogr::Layer::GetNextFeature()
{
  assert(m_Layer && "OGRLayer not initialized");
83 84
  OGRFeature * f = m_Layer->GetNextFeature();
  return f;
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
}

otb::ogr::Layer::iterator otb::ogr::Layer::begin()
{
  assert(m_Layer && "OGRLayer not initialized");
  m_Layer->ResetReading();
  return iterator(*this);
}

otb::ogr::Layer::const_iterator otb::ogr::Layer::cbegin() const
{
  assert(m_Layer && "OGRLayer not initialized");
  m_Layer->ResetReading();
  return const_iterator(*const_cast <Layer*>(this));
}

Luc Hermitte's avatar
Luc Hermitte committed
101
otb::ogr::Layer::iterator otb::ogr::Layer::start_at(size_t index)
102 103 104 105 106 107
{
  assert(m_Layer && "OGRLayer not initialized");
  m_Layer->SetNextByIndex(index);
  return iterator(*this);
}

Luc Hermitte's avatar
Luc Hermitte committed
108
otb::ogr::Layer::const_iterator otb::ogr::Layer::cstart_at(size_t index) const
109 110 111 112 113 114
{
  assert(m_Layer && "OGRLayer not initialized");
  m_Layer->SetNextByIndex(index);
  return const_iterator(*const_cast <Layer*>(this));
}

115 116 117
void otb::ogr::Layer::CreateFeature(Feature feature)
{
  assert(m_Layer && "OGRLayer not initialized");
118 119 120 121 122 123 124

  if (!m_Modifiable)
    {
    itkGenericExceptionMacro(<< "Cannot create a new feature in the layer <"
      <<GetName()<<">: layer is not modifiable");
    }

Luc Hermitte's avatar
Luc Hermitte committed
125 126 127
  const OGRErr res = m_Layer->CreateFeature(&feature.ogr());
  if (res != OGRERR_NONE)
    {
Luc Hermitte's avatar
Luc Hermitte committed
128
    itkGenericExceptionMacro(<< "Cannot create a new feature in the layer <"
129
      <<GetName()<<">: " << CPLGetLastErrorMsg());
Luc Hermitte's avatar
Luc Hermitte committed
130
    }
131 132 133 134 135
}

void otb::ogr::Layer::DeleteFeature(long nFID)
{
  assert(m_Layer && "OGRLayer not initialized");
136 137 138 139 140 141 142

  if (!m_Modifiable)
    {
    itkGenericExceptionMacro(<< "Cannot create a new feature in the layer <"
      <<GetName()<<">: layer is not modifiable");
    }

Luc Hermitte's avatar
Luc Hermitte committed
143 144 145
  const OGRErr res = m_Layer->DeleteFeature(nFID);
  if (res != OGRERR_NONE)
    {
Luc Hermitte's avatar
Luc Hermitte committed
146
    itkGenericExceptionMacro(<< "Cannot delete the feature <"<<nFID<<"> in the layer <"
147
      <<GetName()<<">: " << CPLGetLastErrorMsg());
Luc Hermitte's avatar
Luc Hermitte committed
148
    }
149 150 151 152 153
}

otb::ogr::Feature otb::ogr::Layer::GetFeature(long nFID)
{
  assert(m_Layer && "OGRLayer not initialized");
Luc Hermitte's avatar
Luc Hermitte committed
154 155 156 157
  if (nFID == OGRNullFID)
    {
    itkGenericExceptionMacro(<< "Invalid feature null id GetFeature() in the layer <"<<GetName()<<">.");
    }
158 159
  const Feature feat = m_Layer->GetFeature(nFID);
  return feat;
160 161 162 163 164
}

void otb::ogr::Layer::SetFeature(Feature feature)
{
  assert(m_Layer && "OGRLayer not initialized");
165 166 167 168 169 170 171

  if (!m_Modifiable)
    {
    itkGenericExceptionMacro(<< "Cannot create a new feature in the layer <"
      <<GetName()<<">: layer is not modifiable");
    }

Luc Hermitte's avatar
Luc Hermitte committed
172 173 174
  const OGRErr res = m_Layer->SetFeature(&feature.ogr());
  if (res != OGRERR_NONE)
    {
Luc Hermitte's avatar
Luc Hermitte committed
175
    itkGenericExceptionMacro(<< "Cannot update a feature in the layer <"
176
      <<GetName()<<">: " << CPLGetLastErrorMsg());
Luc Hermitte's avatar
Luc Hermitte committed
177
    }
178 179 180 181 182
}

/*===========================================================================*/
/*=================================[ Misc ]==================================*/
/*===========================================================================*/
183 184 185
std::string otb::ogr::Layer::GetName() const
{
  assert(m_Layer && "null layer");
186
#if GDAL_VERSION_NUM >= 1800
187
  return m_Layer->GetName();
OTB Bot's avatar
STYLE  
OTB Bot committed
188
#else
189 190
  return GetLayerDefn().GetName();
#endif
191 192
}

193
OGREnvelope otb::ogr::Layer::GetExtent(bool force/* = false */) const
194
{
195
  assert(m_Layer && "OGRLayer not initialized");
196 197 198 199
  OGREnvelope sExtent;
  const OGRErr res = m_Layer->GetExtent(&sExtent,force);
  if(res != OGRERR_NONE)
    {
200 201
    itkGenericExceptionMacro(<< "Cannot retrieve extent of layer <"
      <<GetName()<<">: " << CPLGetLastErrorMsg());
202
    }
203 204
  return sExtent;
}
205

206 207 208
void otb::ogr::Layer::GetExtent(double& ulx, double& uly, double& lrx, double& lry, bool force) const
{
  const OGREnvelope sExtent = GetExtent(force);
209 210 211
  ulx = sExtent.MinX;
  uly = sExtent.MinY;
  lrx = sExtent.MaxX;
OTB Bot's avatar
STYLE  
OTB Bot committed
212
  lry = sExtent.MaxY;
213 214
}

215 216 217 218 219 220 221 222 223 224 225
OGRLayer & otb::ogr::Layer::ogr()
{
  assert(m_Layer && "OGRLayer not initialized");
  return *m_Layer;
}

void otb::ogr::Layer::PrintSelf(std::ostream& os, itk::Indent indent) const
{
  os << indent << "+";
  if (m_Layer) // in case for odd reason the layer that should exist can't be found
    {
Luc Hermitte's avatar
Luc Hermitte committed
226
    os << "Layer <" << GetName() << "> of "<< OGRGeometryTypeToName(GetGeomType()) <<"\n";
227 228 229 230 231
    indent = indent.GetNextIndent();
    BOOST_FOREACH(Feature f, *this)
      {
      f.PrintSelf(os, indent);
      }
232 233 234 235 236 237 238
    }
  else
    {
    os << "null Layer\n";
    }
}

239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
/*===========================================================================*/
/*============================[ Spatial Filter ]=============================*/
/*===========================================================================*/

OGRGeometry const* otb::ogr::Layer::GetSpatialFilter() const
{
  assert(m_Layer && "OGRLayer not initialized");
  OGRGeometry* spatialFilter = m_Layer->GetSpatialFilter();
  return spatialFilter;
}

void otb::ogr::Layer::SetSpatialFilter(OGRGeometry const* spatialFilter)
{
  assert(m_Layer && "OGRLayer not initialized");
  // const_cast because OGR is not 100% const-correct
  m_Layer->SetSpatialFilter(const_cast <OGRGeometry*>(spatialFilter));
}

257 258 259 260 261 262 263 264 265 266 267 268 269
void otb::ogr::Layer::SetSpatialFilterRect(
  double dfMinX, double dfMinY, double dfMaxX, double dfMaxY)
{
  assert(m_Layer && "OGRLayer not initialized");
  m_Layer->SetSpatialFilterRect(dfMinX, dfMinY, dfMaxX, dfMaxY);
}

OGRSpatialReference const* otb::ogr::Layer::GetSpatialRef() const
{
  assert(m_Layer && "OGRLayer not initialized");
  return m_Layer->GetSpatialRef();
}

270 271
std::string otb::ogr::Layer::GetProjectionRef() const
{
272
  assert(m_Layer && "OGRLayer not initialized");
273 274
  char * wkt = 0;
  OGRSpatialReference const* srs = GetSpatialRef();
275
  if(srs)
276
    {
277 278 279 280 281
    const OGRErr res = srs->exportToWkt(&wkt);

    if(res !=  OGRERR_NONE)
      {
      itkGenericExceptionMacro(<< "Cannot convert spatial reference to wkt string for layer <"
282
        <<GetName()<<">: " << CPLGetLastErrorMsg());
283
      }
284

285 286 287
    assert(wkt);
    const std::string stringWkt(wkt);
    // According to documentation, argument of exportToWkt() should be freed
288
    CPLFree(wkt);
289
    return stringWkt;
290
    }
291

292
  return "";
293 294
}

295 296 297 298 299 300 301 302 303 304
/*===========================================================================*/
/*==========================[ Feature Definition ]===========================*/
/*===========================================================================*/
OGRFeatureDefn & otb::ogr::Layer::GetLayerDefn() const
{
  assert(m_Layer && "OGRLayer not initialized");
  return *const_cast <OGRLayer*>(m_Layer.get())->GetLayerDefn();
}

void otb::ogr::Layer::CreateField(
305
  FieldDefn const& field, bool bApproxOK/* = true */)
306 307
{
  assert(m_Layer && "OGRLayer not initialized");
308 309 310 311 312 313 314

  if (!m_Modifiable)
    {
    itkGenericExceptionMacro(<< "Cannot create a new field in the layer <"
      <<GetName()<<">: layer is not modifiable");
    }

315
  const OGRErr res = m_Layer->CreateField(&field.ogr(), bApproxOK);
316 317
  if (res != OGRERR_NONE)
    {
Luc Hermitte's avatar
Luc Hermitte committed
318
    itkGenericExceptionMacro(<< "Cannot create a field in the layer <"
319
      <<GetName()<<">: " << CPLGetLastErrorMsg());
320 321 322 323 324 325
    }
}

void otb::ogr::Layer::DeleteField(size_t fieldIndex)
{
  assert(m_Layer && "OGRLayer not initialized");
326 327 328 329 330 331 332

  if (!m_Modifiable)
    {
    itkGenericExceptionMacro(<< "Cannot delete field in the layer <"
      <<GetName()<<">: layer is not modifiable");
    }

333
#if GDAL_VERSION_NUM < 1900
Luc Hermitte's avatar
Luc Hermitte committed
334
  itkGenericExceptionMacro("OGRLayer::DeleteField is not supported by OGR v"
335
    << GDAL_VERSION_NUM << ". Upgrade to a version >= 1.9.0, and recompile OTB.")
336 337 338 339 340
#else
  const OGRErr res = m_Layer->DeleteField(int(fieldIndex));
  if (res != OGRERR_NONE)
    {
    itkGenericExceptionMacro(<< "Cannot delete the "<<fieldIndex << "th field in the layer <"
341
      <<GetName() <<">: " << CPLGetLastErrorMsg());
342 343 344 345 346
    }
#endif
}

void otb::ogr::Layer::AlterFieldDefn(
347
  size_t fieldIndex, FieldDefn const& newFieldDefn, int nFlags)
348 349
{
  assert(m_Layer && "OGRLayer not initialized");
350 351 352 353 354 355 356

  if (!m_Modifiable)
    {
    itkGenericExceptionMacro(<< "Cannot alter field definition in the layer <"
      <<GetName()<<">: layer is not modifiable");
    }

357
#if GDAL_VERSION_NUM < 1900
358
  itkGenericExceptionMacro("OGRLayer::AlterFieldDefn is not supported by OGR v"
359
    << GDAL_VERSION_NUM << ". Upgrade to a version >= 1.9.0, and recompile OTB.")
360
#else
Luc Hermitte's avatar
Luc Hermitte committed
361 362
  const OGRErr res = m_Layer->AlterFieldDefn(
    int(fieldIndex),
363
    &newFieldDefn.ogr(),
Luc Hermitte's avatar
Luc Hermitte committed
364
    nFlags);
365 366 367
  if (res != OGRERR_NONE)
    {
    itkGenericExceptionMacro(<< "Cannot alter the "<<fieldIndex << "th field in the layer <"
368
      <<GetName() <<">: " << CPLGetLastErrorMsg());
369 370 371 372 373 374 375
    }
#endif
}

void otb::ogr::Layer::ReorderField(size_t oldPos, size_t newPos)
{
  assert(m_Layer && "OGRLayer not initialized");
376 377 378 379 380 381 382

  if (!m_Modifiable)
    {
    itkGenericExceptionMacro(<< "Cannot reorder fields in the layer <"
      <<GetName()<<">: layer is not modifiable");
    }

383
#if GDAL_VERSION_NUM < 1900
384
  itkGenericExceptionMacro("OGRLayer::ReorderField is not supported by OGR v"
385
    << GDAL_VERSION_NUM << ". Upgrade to a version >= 1.9.0, and recompile OTB.")
386 387 388 389 390
#else
  const OGRErr res = m_Layer->ReorderField(int(oldPos), int(newPos));
  if (res != OGRERR_NONE)
    {
    itkGenericExceptionMacro(<< "Cannot move the "<<oldPos << "th field to the "
391
      << newPos << "th position in the layer <" <<GetName() <<">: " << CPLGetLastErrorMsg());
392 393 394 395 396 397 398
    }
#endif
}

void otb::ogr::Layer::ReorderFields(int * map)
{
  assert(m_Layer && "OGRLayer not initialized");
399 400 401 402 403 404 405

  if (!m_Modifiable)
    {
    itkGenericExceptionMacro(<< "Cannot reorder fields in the layer <"
      <<GetName()<<">: layer is not modifiable");
    }

406
#if GDAL_VERSION_NUM < 1900
407
  itkGenericExceptionMacro("OGRLayer::ReorderField is not supported by OGR v"
408
    << GDAL_VERSION_NUM << ". Upgrade to a version >= 1.9.0, and recompile OTB.")
409 410 411 412 413
#else
  const OGRErr res = m_Layer->ReorderFields(map);
  if (res != OGRERR_NONE)
    {
    itkGenericExceptionMacro(<< "Cannot reorder the fields of the layer <"
414
      <<GetName() <<">: " << CPLGetLastErrorMsg());
415 416 417
    }
#endif
}
Luc Hermitte's avatar
Luc Hermitte committed
418

Luc Hermitte's avatar
Luc Hermitte committed
419 420 421
void otb::ogr::Layer::SetIgnoredFields(char const** fieldNames)
{
  assert(m_Layer && "OGRLayer not initialized");
422
#if GDAL_VERSION_NUM >= 1900
Luc Hermitte's avatar
Luc Hermitte committed
423 424 425 426
  const OGRErr res = m_Layer->SetIgnoredFields(fieldNames);
  if (res != OGRERR_NONE)
    {
    itkGenericExceptionMacro(<< "Cannot set fields to ignore on the layer <"
427
      <<GetName() <<">: " << CPLGetLastErrorMsg());
Luc Hermitte's avatar
Luc Hermitte committed
428
    }
429 430 431 432
#else
  itkGenericExceptionMacro("OGRLayer::SetIgnoredFields is not supported by OGR v"
    << GDAL_VERSION_NUM << ". Upgrade to a version >= 1.9.0, and recompile OTB.")
#endif
Luc Hermitte's avatar
Luc Hermitte committed
433 434
}

Luc Hermitte's avatar
Luc Hermitte committed
435 436 437 438 439 440 441 442 443
OGRwkbGeometryType otb::ogr::Layer::GetGeomType() const
{
  assert(m_Layer && "OGRLayer not initialized");
#if GDAL_VERSION_NUM < 1800
  return GetLayerDefn().GetGeomType();
#else
  return m_Layer->GetGeomType();
#endif
}
444 445 446 447 448 449

bool otb::ogr::operator==(Layer const& lhs, Layer const& rhs)
{
  const bool equal = lhs.m_Layer.get() == rhs.m_Layer.get();
  return equal;
}