otbOGRIOHelper.cxx 46.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
20

21
#include "otbOGRIOHelper.h"
22

23
#include "otbMacro.h"
24
#include "ogrsf_frmts.h"
25
#include "otbOGR.h"
26
#include "otbStopwatch.h"
27

28
namespace otb
29
{
30

31
void
32
OGRIOHelper
33
::ConvertGeometryToPointNode(const OGRGeometry * ogrGeometry, DataNodePointerType node) const
34 35 36
{
  OGRPoint * ogrPoint = (OGRPoint *) ogrGeometry;

37
  if (ogrPoint == nullptr)
OTB Bot's avatar
OTB Bot committed
38 39 40
    {
    itkGenericExceptionMacro(<< "Failed to convert OGRGeometry to OGRPoint");
    }
41 42 43

  PointType otbPoint;
  otbPoint.Fill(0);
44 45
  otbPoint[0] = static_cast<DataNodeType::PrecisionType>(ogrPoint->getX());
  otbPoint[1] = static_cast<DataNodeType::PrecisionType>(ogrPoint->getY());
46 47 48

  if (DataNodeType::Dimension > 2)
    {
OTB Bot's avatar
OTB Bot committed
49 50 51 52
    if (PointType::PointDimension != 3)
      {
      itkGenericExceptionMacro(<< "OTB vector data can't contain the OGR information (2D instead of 2.5D)");
      }
53
    otbPoint[2] = static_cast<DataNodeType::PrecisionType>(ogrPoint->getZ());
54 55 56 57 58
    }

  node->SetPoint(otbPoint);
}

59

60
void
61
OGRIOHelper
62
::ConvertGeometryToLineNode(const OGRGeometry * ogrGeometry, DataNodePointerType node) const
63
{
OTB Bot's avatar
OTB Bot committed
64
  OGRLineString * ogrLine = (OGRLineString *) ogrGeometry;
65

66
  if (ogrLine == nullptr)
OTB Bot's avatar
OTB Bot committed
67 68 69
    {
    itkGenericExceptionMacro(<< "Failed to convert OGRGeometry to OGRLine");
    }
70 71 72

  LinePointerType line = LineType::New();

OTB Bot's avatar
OTB Bot committed
73
  OGRPoint * ogrTmpPoint = (OGRPoint *) OGRGeometryFactory::createGeometry(wkbPoint);
74

OTB Bot's avatar
OTB Bot committed
75 76
  for (int pIndex = 0; pIndex < ogrLine->getNumPoints(); ++pIndex)
    {
77

OTB Bot's avatar
OTB Bot committed
78
    ogrLine->getPoint(pIndex, ogrTmpPoint);
79

80
    LineType::VertexType vertex;
81 82 83 84 85 86

    vertex[0] = ogrTmpPoint->getX();
    vertex[1] = ogrTmpPoint->getY();

    if (DataNodeType::Dimension > 2)
      {
OTB Bot's avatar
OTB Bot committed
87 88 89 90 91
      if (LineType::VertexType::PointDimension != 3)
        {
        itkGenericExceptionMacro(<< "OTB vector data can't contain the OGR information (2D instead of 2.5D)");
        }
      vertex[2] = ogrTmpPoint->getZ();
92 93 94
      }

    line->AddVertex(vertex);
OTB Bot's avatar
OTB Bot committed
95
    }
96
  OGRGeometryFactory::destroyGeometry(ogrTmpPoint);
97 98 99 100

  node->SetLine(line);
}

101

102
void
103
OGRIOHelper
104
::ConvertGeometryToPolygonNode(const OGRGeometry * ogrGeometry, DataNodePointerType node) const
105
{
OTB Bot's avatar
OTB Bot committed
106
  OGRPolygon * ogrPolygon = (OGRPolygon *) ogrGeometry;
107

108
  if (ogrPolygon == nullptr)
OTB Bot's avatar
OTB Bot committed
109 110 111
    {
    itkGenericExceptionMacro(<< "Failed to convert OGRGeometry to OGRPolygon");
    }
112

OTB Bot's avatar
OTB Bot committed
113
  OGRPoint *      ogrTmpPoint = (OGRPoint *) OGRGeometryFactory::createGeometry(wkbPoint);
OTB Bot's avatar
OTB Bot committed
114
  OGRLinearRing * ogrRing = ogrPolygon->getExteriorRing();
115 116 117

  PolygonPointerType extRing = PolygonType::New();

OTB Bot's avatar
OTB Bot committed
118 119 120
  for (int pIndex = 0; pIndex < ogrRing->getNumPoints(); ++pIndex)
    {
    ogrRing->getPoint(pIndex, ogrTmpPoint);
121
    PolygonType::VertexType vertex;
122 123 124 125 126
    vertex[0] = ogrTmpPoint->getX();
    vertex[1] = ogrTmpPoint->getY();

    if (DataNodeType::Dimension > 2)
      {
OTB Bot's avatar
OTB Bot committed
127 128 129 130 131
      if (PolygonType::VertexType::PointDimension != 3)
        {
        itkGenericExceptionMacro(<< "OTB vector data can't contain the OGR information (2D instead of 2.5D)");
        }
      vertex[2] = ogrTmpPoint->getZ();
132 133 134
      }

    extRing->AddVertex(vertex);
OTB Bot's avatar
OTB Bot committed
135
    }
136 137 138

  PolygonListPointerType intRings = PolygonListType::New();

OTB Bot's avatar
OTB Bot committed
139 140
  for (int intRingIndex = 0; intRingIndex < ogrPolygon->getNumInteriorRings(); ++intRingIndex)
    {
141 142
    PolygonPointerType ring = PolygonType::New();
    ogrRing = ogrPolygon->getInteriorRing(intRingIndex);
OTB Bot's avatar
OTB Bot committed
143 144 145
    for (int pIndex = 0; pIndex < ogrRing->getNumPoints(); ++pIndex)
      {
      ogrRing->getPoint(pIndex, ogrTmpPoint);
146
      PolygonType::VertexType vertex;
147 148 149 150 151

      vertex[0] = ogrTmpPoint->getX();
      vertex[1] = ogrTmpPoint->getY();
      if (DataNodeType::Dimension > 2)
        {
OTB Bot's avatar
OTB Bot committed
152 153 154 155 156
        if (PolygonType::VertexType::PointDimension != 3)
          {
          itkGenericExceptionMacro(<< "OTB vector data can't contain the OGR information (2D instead of 2.5D)");
          }
        vertex[2] = ogrTmpPoint->getZ();
157 158
        }
      ring->AddVertex(vertex);
OTB Bot's avatar
OTB Bot committed
159
      }
160
    intRings->PushBack(ring);
OTB Bot's avatar
OTB Bot committed
161
    }
162

163
  OGRGeometryFactory::destroyGeometry(ogrTmpPoint);
164 165 166

  node->SetPolygonExteriorRing(extRing);
  node->SetPolygonInteriorRings(intRings);
167
}
OTB Bot's avatar
OTB Bot committed
168

169

170
OGRIOHelper
171
::OGRIOHelper()
172 173 174
{
  otb::ogr::Drivers::Init();
}
175

176 177

OGRIOHelper
178 179 180
::~OGRIOHelper()
{}

181 182

void OGRIOHelper
OTB Bot's avatar
OTB Bot committed
183
::ConvertOGRLayerToDataTreeNode(OGRLayer * layer, InternalTreeNodeType * documentPtr) const
184 185 186 187 188 189
{
  /** Temporary pointer to store the feature */
  OGRFeature * feature;

  layer->ResetReading();

OTB Bot's avatar
OTB Bot committed
190
  unsigned int   counter = 0;
191
  otb::Stopwatch chrono = otb::Stopwatch::StartNew();
192

193
  while ((feature = layer->GetNextFeature()) != nullptr)
OTB Bot's avatar
OTB Bot committed
194
    {
195

OTB Bot's avatar
OTB Bot committed
196
    // A pointer to the current multi-geometry
197
    InternalTreeNodeType::Pointer multiPtr;
198 199 200 201

    /** Temporary geometry container */
    OGRGeometry * geometry = feature->GetGeometryRef();

202
    if (geometry == nullptr)
203
      {
204 205 206 207 208 209 210 211
      OGRFeature::DestroyFeature(feature);
      ++counter;
      continue;
      }

    otb::VectorDataKeywordlist kwl;
    for (int fieldNum = 0; fieldNum < feature->GetFieldCount(); ++fieldNum)
      {
212
      if (ogr::version_proxy::IsFieldSetAndNotNull(feature, fieldNum))
213
        {
214
        kwl.AddField(feature->GetFieldDefnRef(fieldNum), feature->GetRawFieldRef(fieldNum));
215
        }
216
      }
217

218 219 220 221
    switch (geometry->getGeometryType())
      {
      case wkbPoint:
      {
222
      InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
223 224 225 226 227 228 229 230 231 232 233 234 235
      DataNodePointerType dataNode = DataNodeType::New();
      ConvertGeometryToPointNode(geometry, dataNode);
      newNode->Set(dataNode);
      //Reach the DataNode inside the tree node
      itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary();
      itk::EncapsulateMetaData<VectorDataKeywordlist>(dict,
                                                      MetaDataKey::VectorDataKeywordlistKey,
                                                      kwl);
      documentPtr->AddChild(newNode);
      break;
      }
      case wkbPoint25D:
      {
236
      InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
237 238 239 240 241 242 243 244 245 246 247 248 249
      DataNodePointerType dataNode = DataNodeType::New();
      ConvertGeometryToPointNode(geometry, dataNode);
      newNode->Set(dataNode);
      //Reach the DataNode inside the tree node
      itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary();
      itk::EncapsulateMetaData<VectorDataKeywordlist>(dict,
                                                      MetaDataKey::VectorDataKeywordlistKey,
                                                      kwl);
      documentPtr->AddChild(newNode);
      break;
      }
      case wkbLineString:
      {
250
      InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
251 252 253 254 255 256 257 258 259 260 261 262 263
      DataNodePointerType dataNode = DataNodeType::New();
      ConvertGeometryToLineNode(geometry, dataNode);
      newNode->Set(dataNode);
      //Reach the DataNode inside the tree node
      itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary();
      itk::EncapsulateMetaData<VectorDataKeywordlist>(dict,
                                                      MetaDataKey::VectorDataKeywordlistKey,
                                                      kwl);
      documentPtr->AddChild(newNode);
      break;
      }
      case wkbLineString25D:
      {
264
      InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
265 266 267 268 269 270 271 272 273 274 275 276 277
      DataNodePointerType dataNode = DataNodeType::New();
      ConvertGeometryToLineNode(geometry, dataNode);
      newNode->Set(dataNode);
      //Reach the DataNode inside the tree node
      itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary();
      itk::EncapsulateMetaData<VectorDataKeywordlist>(dict,
                                                      MetaDataKey::VectorDataKeywordlistKey,
                                                      kwl);
      documentPtr->AddChild(newNode);
      break;
      }
      case wkbPolygon:
      {
278
      InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
279 280 281 282 283 284 285 286 287 288 289 290 291
      DataNodePointerType dataNode = DataNodeType::New();
      ConvertGeometryToPolygonNode(geometry, dataNode);
      newNode->Set(dataNode);
      //Reach the DataNode inside the tree node
      itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary();
      itk::EncapsulateMetaData<VectorDataKeywordlist>(dict,
                                                      MetaDataKey::VectorDataKeywordlistKey,
                                                      kwl);
      documentPtr->AddChild(newNode);
      break;
      }
      case wkbPolygon25D:
      {
292
      InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
      DataNodePointerType dataNode = DataNodeType::New();
      ConvertGeometryToPolygonNode(geometry, dataNode);
      newNode->Set(dataNode);
      //Reach the DataNode inside the tree node
      itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary();
      itk::EncapsulateMetaData<VectorDataKeywordlist>(dict,
                                                      MetaDataKey::VectorDataKeywordlistKey,
                                                      kwl);
      documentPtr->AddChild(newNode);
      break;
      }
      case wkbMultiPoint:
      {

      DataNodePointerType multi = DataNodeType::New();
      multi->SetNodeType(FEATURE_MULTIPOINT);
      multiPtr = InternalTreeNodeType::New();
      multiPtr->Set(multi);
      documentPtr->AddChild(multiPtr);

      OGRMultiPoint * ogrMulti = (OGRMultiPoint *) geometry;

      for (int geoIndex = 0; geoIndex < ogrMulti->getNumGeometries(); ++geoIndex)
316
        {
317
        InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
318
        DataNodePointerType dataNode = DataNodeType::New();
319
        ConvertGeometryToPointNode(ogrMulti->getGeometryRef(geoIndex), dataNode);
320
        newNode->Set(dataNode);
321 322 323 324
        itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary();
        itk::EncapsulateMetaData<VectorDataKeywordlist>(dict,
                                                        MetaDataKey::VectorDataKeywordlistKey,
                                                        kwl);
325
        multiPtr->AddChild(newNode);
326
        }
327 328 329 330 331 332 333 334 335 336 337 338 339 340
      break;
      }
      case wkbMultiPoint25D:
      {
      DataNodePointerType multi = DataNodeType::New();
      multi->SetNodeType(FEATURE_MULTIPOINT);

      multiPtr = InternalTreeNodeType::New();
      multiPtr->Set(multi);
      documentPtr->AddChild(multiPtr);

      OGRMultiPoint * ogrMulti = (OGRMultiPoint *) geometry;

      for (int geoIndex = 0; geoIndex < ogrMulti->getNumGeometries(); ++geoIndex)
341
        {
342
        InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
343
        DataNodePointerType dataNode = DataNodeType::New();
344
        ConvertGeometryToPointNode(ogrMulti->getGeometryRef(geoIndex), dataNode);
345
        newNode->Set(dataNode);
346 347 348 349
        itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary();
        itk::EncapsulateMetaData<VectorDataKeywordlist>(dict,
                                                        MetaDataKey::VectorDataKeywordlistKey,
                                                        kwl);
350
        multiPtr->AddChild(newNode);
351
        }
352 353 354 355 356 357 358 359 360 361 362 363 364 365
      break;
      }
      case wkbMultiLineString:
      {
      DataNodePointerType multi = DataNodeType::New();
      multi->SetNodeType(FEATURE_MULTILINE);

      multiPtr = InternalTreeNodeType::New();
      multiPtr->Set(multi);
      documentPtr->AddChild(multiPtr);

      OGRMultiLineString * ogrMulti = (OGRMultiLineString *) geometry;

      for (int geoIndex = 0; geoIndex < ogrMulti->getNumGeometries(); ++geoIndex)
366
        {
367
        InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
368
        DataNodePointerType dataNode = DataNodeType::New();
369
        ConvertGeometryToLineNode(ogrMulti->getGeometryRef(geoIndex), dataNode);
370
        newNode->Set(dataNode);
371 372 373 374
        itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary();
        itk::EncapsulateMetaData<VectorDataKeywordlist>(dict,
                                                        MetaDataKey::VectorDataKeywordlistKey,
                                                        kwl);
375
        multiPtr->AddChild(newNode);
376
        }
377 378 379 380 381 382 383 384 385 386 387 388 389 390
      break;
      }
      case wkbMultiLineString25D:
      {
      DataNodePointerType multi = DataNodeType::New();
      multi->SetNodeType(FEATURE_MULTILINE);

      multiPtr = InternalTreeNodeType::New();
      multiPtr->Set(multi);
      documentPtr->AddChild(multiPtr);

      OGRMultiLineString * ogrMulti = (OGRMultiLineString *) geometry;

      for (int geoIndex = 0; geoIndex < ogrMulti->getNumGeometries(); ++geoIndex)
391
        {
392
        InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
393
        DataNodePointerType dataNode = DataNodeType::New();
394
        ConvertGeometryToLineNode(ogrMulti->getGeometryRef(geoIndex), dataNode);
395
        newNode->Set(dataNode);
396 397 398 399
        itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary();
        itk::EncapsulateMetaData<VectorDataKeywordlist>(dict,
                                                        MetaDataKey::VectorDataKeywordlistKey,
                                                        kwl);
400
        multiPtr->AddChild(newNode);
401
        }
402 403 404 405 406 407 408 409 410 411 412 413 414 415
      break;
      }
      case wkbMultiPolygon:
      {
      DataNodePointerType multi = DataNodeType::New();
      multi->SetNodeType(FEATURE_MULTIPOLYGON);

      multiPtr = InternalTreeNodeType::New();
      multiPtr->Set(multi);
      documentPtr->AddChild(multiPtr);

      OGRMultiPolygon * ogrMulti = (OGRMultiPolygon *) geometry;

      for (int geoIndex = 0; geoIndex < ogrMulti->getNumGeometries(); ++geoIndex)
416
        {
417
        InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
418
        DataNodePointerType dataNode = DataNodeType::New();
419
        ConvertGeometryToPolygonNode(ogrMulti->getGeometryRef(geoIndex), dataNode);
420
        newNode->Set(dataNode);
421 422 423 424
        itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary();
        itk::EncapsulateMetaData<VectorDataKeywordlist>(dict,
                                                        MetaDataKey::VectorDataKeywordlistKey,
                                                        kwl);
425
        multiPtr->AddChild(newNode);
426
        }
427 428 429 430 431 432 433 434 435 436 437 438 439 440
      break;
      }
      case wkbMultiPolygon25D:
      {
      DataNodePointerType multi = DataNodeType::New();
      multi->SetNodeType(FEATURE_MULTIPOLYGON);

      multiPtr = InternalTreeNodeType::New();
      multiPtr->Set(multi);
      documentPtr->AddChild(multiPtr);

      OGRMultiPolygon * ogrMulti = (OGRMultiPolygon *) geometry;

      for (int geoIndex = 0; geoIndex < ogrMulti->getNumGeometries(); ++geoIndex)
441
        {
442
        InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
443
        DataNodePointerType dataNode = DataNodeType::New();
444
        ConvertGeometryToPolygonNode(ogrMulti->getGeometryRef(geoIndex), dataNode);
445
        newNode->Set(dataNode);
446 447 448 449
        itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary();
        itk::EncapsulateMetaData<VectorDataKeywordlist>(dict,
                                                        MetaDataKey::VectorDataKeywordlistKey,
                                                        kwl);
450
        multiPtr->AddChild(newNode);
451
        }
452 453 454 455 456 457
      break;
      }
      case wkbGeometryCollection:
      {
      DataNodePointerType multi = DataNodeType::New();
      multi->SetNodeType(FEATURE_COLLECTION);
458

459 460 461
      multiPtr = InternalTreeNodeType::New();
      multiPtr->Set(multi);
      documentPtr->AddChild(multiPtr);
462

463
      OGRGeometryCollection * ogrMulti = (OGRGeometryCollection *) geometry;
464

465 466 467 468 469
      for (int geoIndex = 0; geoIndex < ogrMulti->getNumGeometries(); ++geoIndex)
        {
        switch (ogrMulti->getGeometryRef(geoIndex)->getGeometryType())
          {
          case wkbPoint:
470
          {
471
          InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
472 473 474
          DataNodePointerType dataNode = DataNodeType::New();
          ConvertGeometryToPointNode(ogrMulti->getGeometryRef(geoIndex), dataNode);
          newNode->Set(dataNode);
475 476 477 478
          itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary();
          itk::EncapsulateMetaData<VectorDataKeywordlist>(dict,
                                                          MetaDataKey::VectorDataKeywordlistKey,
                                                          kwl);
479
          multiPtr->AddChild(newNode);
480
          break;
481
          }
482
          case wkbPoint25D:
483
          {
484
          InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
485 486 487
          DataNodePointerType dataNode = DataNodeType::New();
          ConvertGeometryToPointNode(ogrMulti->getGeometryRef(geoIndex), dataNode);
          newNode->Set(dataNode);
488 489 490 491
          itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary();
          itk::EncapsulateMetaData<VectorDataKeywordlist>(dict,
                                                          MetaDataKey::VectorDataKeywordlistKey,
                                                          kwl);
492
          multiPtr->AddChild(newNode);
493
          break;
494
          }
495
          case wkbLineString:
496
          {
497
          InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
498 499 500
          DataNodePointerType dataNode = DataNodeType::New();
          ConvertGeometryToLineNode(ogrMulti->getGeometryRef(geoIndex), dataNode);
          newNode->Set(dataNode);
501 502 503 504
          itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary();
          itk::EncapsulateMetaData<VectorDataKeywordlist>(dict,
                                                          MetaDataKey::VectorDataKeywordlistKey,
                                                          kwl);
505
          multiPtr->AddChild(newNode);
506
          break;
507
          }
508
          case wkbLineString25D:
509
          {
510
          InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
511 512 513
          DataNodePointerType dataNode = DataNodeType::New();
          ConvertGeometryToLineNode(ogrMulti->getGeometryRef(geoIndex), dataNode);
          newNode->Set(dataNode);
514 515 516 517
          itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary();
          itk::EncapsulateMetaData<VectorDataKeywordlist>(dict,
                                                          MetaDataKey::VectorDataKeywordlistKey,
                                                          kwl);
518
          multiPtr->AddChild(newNode);
519
          break;
520
          }
521
          case wkbPolygon:
522
          {
523
          InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
524 525 526
          DataNodePointerType dataNode = DataNodeType::New();
          ConvertGeometryToPolygonNode(ogrMulti->getGeometryRef(geoIndex), dataNode);
          newNode->Set(dataNode);
527 528 529 530
          itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary();
          itk::EncapsulateMetaData<VectorDataKeywordlist>(dict,
                                                          MetaDataKey::VectorDataKeywordlistKey,
                                                          kwl);
531
          multiPtr->AddChild(newNode);
532
          break;
533
          }
534
          case wkbPolygon25D:
535
          {
536
          InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
537 538 539
          DataNodePointerType dataNode = DataNodeType::New();
          ConvertGeometryToPolygonNode(ogrMulti->getGeometryRef(geoIndex), dataNode);
          newNode->Set(dataNode);
540 541 542 543
          itk::MetaDataDictionary& dict = newNode->Get()->GetMetaDataDictionary();
          itk::EncapsulateMetaData<VectorDataKeywordlist>(dict,
                                                          MetaDataKey::VectorDataKeywordlistKey,
                                                          kwl);
544
          multiPtr->AddChild(newNode);
545
          break;
546
          }
547
          default:
548
          {
549
          otbWarningMacro( << "Geometry type not found: " << ogrMulti->getGeometryRef(geoIndex)->getGeometryType());
550 551
          break;
          }
OTB Bot's avatar
OTB Bot committed
552
          }
553
        }
554 555 556 557 558 559
      break;
      }
      case wkbGeometryCollection25D:
      {
      DataNodePointerType multi = DataNodeType::New();
      multi->SetNodeType(FEATURE_COLLECTION);
OTB Bot's avatar
OTB Bot committed
560

561 562 563
      multiPtr = InternalTreeNodeType::New();
      multiPtr->Set(multi);
      documentPtr->AddChild(multiPtr);
OTB Bot's avatar
OTB Bot committed
564

565
      OGRGeometryCollection * ogrMulti = (OGRGeometryCollection *) geometry;
OTB Bot's avatar
OTB Bot committed
566

567 568 569
      for (int geoIndex = 0; geoIndex < ogrMulti->getNumGeometries(); ++geoIndex)
        {
        switch (ogrMulti->getGeometryRef(geoIndex)->getGeometryType())
570
          {
571 572
          case wkbPoint:
          {
573
          InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
574 575
          DataNodePointerType dataNode = DataNodeType::New();
          ConvertGeometryToPointNode(ogrMulti->getGeometryRef(geoIndex), dataNode);
576
          newNode->Set(dataNode);
577 578 579 580 581
          multiPtr->AddChild(newNode);
          break;
          }
          case wkbPoint25D:
          {
582
          InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
583 584
          DataNodePointerType dataNode = DataNodeType::New();
          ConvertGeometryToPointNode(ogrMulti->getGeometryRef(geoIndex), dataNode);
585
          newNode->Set(dataNode);
586 587 588 589 590
          multiPtr->AddChild(newNode);
          break;
          }
          case wkbLineString:
          {
591
          InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
592 593
          DataNodePointerType dataNode = DataNodeType::New();
          ConvertGeometryToLineNode(ogrMulti->getGeometryRef(geoIndex), dataNode);
594
          newNode->Set(dataNode);
595 596 597 598 599
          multiPtr->AddChild(newNode);
          break;
          }
          case wkbLineString25D:
          {
600
          InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
601 602
          DataNodePointerType dataNode = DataNodeType::New();
          ConvertGeometryToLineNode(ogrMulti->getGeometryRef(geoIndex), dataNode);
603
          newNode->Set(dataNode);
604 605 606 607 608
          multiPtr->AddChild(newNode);
          break;
          }
          case wkbPolygon:
          {
609
          InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
610 611
          DataNodePointerType dataNode = DataNodeType::New();
          ConvertGeometryToPolygonNode(ogrMulti->getGeometryRef(geoIndex), dataNode);
612
          newNode->Set(dataNode);
613 614 615 616 617
          multiPtr->AddChild(newNode);
          break;
          }
          case wkbPolygon25D:
          {
618
          InternalTreeNodeType::Pointer newNode = InternalTreeNodeType::New();
619 620
          DataNodePointerType dataNode = DataNodeType::New();
          ConvertGeometryToPolygonNode(ogrMulti->getGeometryRef(geoIndex), dataNode);
621
          newNode->Set(dataNode);
622
          multiPtr->AddChild(newNode);
623 624 625 626
          break;
          }
          default:
          {
627
          otbWarningMacro( << "Geometry type not found: " << ogrMulti->getGeometryRef(geoIndex)->getGeometryType());
628 629
          break;
          }
OTB Bot's avatar
OTB Bot committed
630
          }
631
        }
632
      break;
OTB Bot's avatar
OTB Bot committed
633
      }
634 635
      default:
      {
636
      otbWarningMacro("Geometry not handled: " << geometry->getGeometryName());
637 638 639 640
      break;
      }
      }

641

OTB Bot's avatar
OTB Bot committed
642
    OGRFeature::DestroyFeature(feature);
643
    ++counter;
OTB Bot's avatar
OTB Bot committed
644
    } //end While feature
645 646

  chrono.Stop();
OTB Bot's avatar
OTB Bot committed
647
  otbMsgDevMacro(
648
    << layer->GetFeatureCount() << " features read, total processing time " << chrono.GetElapsedMilliseconds() << " ms");
649
}
OTB Bot's avatar
OTB Bot committed
650

651 652

unsigned int OGRIOHelper
OTB Bot's avatar
OTB Bot committed
653
::ProcessNodeWrite(InternalTreeNodeType * source,
654
                   GDALDataset * m_DataSource,
655
                   OGRGeometryCollection * ogrCollection,
OTB Bot's avatar
OTB Bot committed
656
                   OGRLayer * ogrCurrentLayer,
657
                   OGRSpatialReference * oSRS)
658
{
659
  unsigned int kept = 0;
660
  bool fieldsAddedToOGRLayer = false;
661
  // Get the children list from the input node
662
  typedef InternalTreeNodeType::ChildrenListType ChildrenListType;
663 664 665
  ChildrenListType children = source->GetChildrenList();

  // For each child
666
  for (ChildrenListType::iterator it = children.begin(); it != children.end(); ++it)
OTB Bot's avatar
OTB Bot committed
667
    {
668
    DataNodePointerType dataNode = (*it)->Get();
669
    //otbMsgDevMacro(<< "Type of node " << dataNode->GetNodeType() << " id " << dataNode->GetNodeId());
670
    ++kept;
671 672 673 674

    // Get the kwl
    otb::VectorDataKeywordlist kwl;
    itk::ExposeMetaData<VectorDataKeywordlist>(dataNode->GetMetaDataDictionary(),
675 676
                                               MetaDataKey::VectorDataKeywordlistKey,
                                               kwl);
677

678
    // Create the field once
679
    if (ogrCurrentLayer != nullptr && !fieldsAddedToOGRLayer)
680
      {
OTB Bot's avatar
OTB Bot committed
681
      // Take into account the fields stored in the
682
      // vectordatakeywordlist
OTB Bot's avatar
OTB Bot committed
683
      for (unsigned int fieldIdx  = 0; fieldIdx < kwl.GetNumberOfFields(); fieldIdx++)
684
        {
685 686
        if ( std::string(kwl.GetNthField(fieldIdx).first->GetNameRef()) != "FID" )
          {
687
          otbMsgDevMacro(<< " CreateField '" << kwl.GetNthField(fieldIdx).first->GetNameRef() << "'");
688 689 690 691 692
          if (ogrCurrentLayer->CreateField(kwl.GetNthField(fieldIdx).first) != OGRERR_NONE )
            {
            itkExceptionMacro(<< "Failed to create Field "<<kwl.GetNthField(fieldIdx).first->GetNameRef());
            }
          }
693 694 695 696
         else
          {
          otbMsgDevMacro(<< "WARNING: Skipping OGR field 'FID'");
          }
697
        }
698 699 700 701 702 703 704
      // While no feature are added to the layer (in case of multiple
      // folders added to the document) continue test for adding
      // fields to the ogrCurrentLayer
      if ( kwl.GetNumberOfFields() > 0 || ogrCurrentLayer->GetFeatureCount() > 0)
        {
        fieldsAddedToOGRLayer = true;
        }
705 706
      }

707 708
    switch (dataNode->GetNodeType())
      {
OTB Bot's avatar
OTB Bot committed
709
      case ROOT:
710 711 712
      {
      break;
      }
OTB Bot's avatar
OTB Bot committed
713
      case DOCUMENT:
714
      {
715 716
      ogrCurrentLayer = m_DataSource->CreateLayer(dataNode->GetNodeId(), oSRS, wkbUnknown, nullptr);
      if (ogrCurrentLayer == nullptr)
717
        {
718 719
        //itkExceptionMacro(<<"Failed to create layer "<<dataNode->GetNodeId());
        std::cout << "Failed to create layer " << dataNode->GetNodeId() << std::endl;
720
        }
721 722 723 724 725
      else
        {
        // New OGRLayer, set the flag to false
        fieldsAddedToOGRLayer = false;
        }
726 727 728
      ProcessNodeWrite(*it, m_DataSource, ogrCollection, ogrCurrentLayer, oSRS);
      break;
      }
OTB Bot's avatar
OTB Bot committed
729
      case FOLDER:
730 731 732 733
      {
      ProcessNodeWrite(*it, m_DataSource, ogrCollection, ogrCurrentLayer, oSRS);
      break;
      }
OTB Bot's avatar
OTB Bot committed
734
      case FEATURE_POINT:
735 736 737 738 739 740 741
      {
      //Build the ogrObject
      OGRPoint ogrPoint;
      ogrPoint.setX(dataNode->GetPoint()[0]);
      ogrPoint.setY(dataNode->GetPoint()[1]);

      if (DataNodeType::Dimension > 2)
OTB Bot's avatar
OTB Bot committed
742
        {
743 744
        ogrPoint.setZ(dataNode->GetPoint()[2]);
        }
745

746
      //Save it in the structure
747
      if (ogrCollection == nullptr)
748 749 750
        {
        OGRFeature *ogrFeature;
        ogrFeature = OGRFeature::CreateFeature(ogrCurrentLayer->GetLayerDefn());
751

752
        // Add the fields to the features
753
        for (unsigned int i  = 0; i < kwl.GetNumberOfFields(); ++i)
754
          {
OTB Bot's avatar
OTB Bot committed
755
          // Get the key of the Nth OGRFieldRefn
756
          const char * key = kwl.GetNthField(i).first->GetNameRef();
757

758
          if (std::string(key) != "FID")
759 760 761 762
            {
            // Edit the value of the field and add it to the current feature
            ogrFeature->SetField(ogrFeature->GetFieldIndex(key) , kwl.GetFieldAsString(key).c_str());
            }
763
          }
764

765
//        ogrFeature->SetField("Name", dataNode->GetNodeId());
766
        ogrFeature->SetGeometry(&ogrPoint);
767

768
        if (ogrCurrentLayer->CreateFeature(ogrFeature) != OGRERR_NONE)
769
          {
770 771
          itkExceptionMacro(<< "Failed to create feature in shapefile.");
          //std::cout << "Failed to create feature in shapefile."
772 773
          }

774
        OGRFeature::DestroyFeature(ogrFeature);
OTB Bot's avatar
OTB Bot committed
775
        }
776
      else
777
        {
778 779 780 781 782 783 784 785 786 787
        ogrCollection->addGeometry(&ogrPoint);
        }

      break;
      }
      case FEATURE_LINE:
      {
      //Build the ogrObject
      OGRLineString              ogrLine;
      VertexListConstPointerType vertexList = dataNode->GetLine()->GetVertexList();
788

789
      VertexListType::ConstIterator vIt = vertexList->Begin();
790

791 792 793 794 795 796
      while (vIt != vertexList->End())
        {
        OGRPoint ogrPoint;
        ogrPoint.setX(vIt.Value()[0]);
        ogrPoint.setY(vIt.Value()[1]);
        if (DataNodeType::Dimension > 2)
797
          {
798
          ogrPoint.setZ(vIt.Value()[2]);
799
          }
800 801 802 803 804
        ogrLine.addPoint(&ogrPoint);
        ++vIt;
        }

      //Save it in the structure
805
      if (ogrCollection == nullptr)
806 807 808
        {
        OGRFeature *ogrFeature;
        ogrFeature = OGRFeature::CreateFeature(ogrCurrentLayer->GetLayerDefn());
809

810
        // Add the fields to the features
811
        for (unsigned int i  = 0; i < kwl.GetNumberOfFields(); ++i)
OTB Bot's avatar
OTB Bot committed
812
          {
OTB Bot's avatar
OTB Bot committed
813
          // Get the key of the Nth OGRFieldRefn
814 815 816 817
          const char * key = kwl.GetNthField(i).first->GetNameRef();
          // Edit the value of the field and add it to the current feature
          ogrFeature->SetField(ogrFeature->GetFieldIndex(key) , kwl.GetFieldAsString(key).c_str());
          }
818

819
//        ogrFeature->SetField("Name", dataNode->GetNodeId());
820
        ogrFeature->SetGeometry(&ogrLine);
821

822
        if (ogrCurrentLayer->CreateFeature(ogrFeature) != OGRERR_NONE)
823
          {
824
          itkExceptionMacro(<< "Failed to create feature in shapefile.");
825 826
          }

827 828
        OGRFeature::DestroyFeature(ogrFeature);

829
        }
830
      else
831
        {
832 833 834 835 836 837 838
        ogrCollection->addGeometry(&ogrLine);
        }

      break;
      }
      case FEATURE_POLYGON:
      {
OTB Bot's avatar
OTB Bot committed
839

840 841 842 843
      //Build the ogrObject
      OGRPolygon *               ogrPolygon = (OGRPolygon *) OGRGeometryFactory::createGeometry(wkbPolygon);
      OGRLinearRing *            ogrExternalRing = (OGRLinearRing *) OGRGeometryFactory::createGeometry(wkbLinearRing);
      VertexListConstPointerType vertexList = dataNode->GetPolygonExteriorRing()->GetVertexList();
OTB Bot's avatar
OTB Bot committed
844

845
      VertexListType::ConstIterator vIt = vertexList->Begin();
846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865

      while (vIt != vertexList->End())
        {
        OGRPoint ogrPoint;
        ogrPoint.setX(vIt.Value()[0]);
        ogrPoint.setY(vIt.Value()[1]);
        if (DataNodeType::Dimension > 2)
          {
          ogrPoint.setZ(vIt.Value()[2]);
          }

        ogrExternalRing->addPoint(&ogrPoint);
        ++vIt;
        }
      ogrPolygon->addRing(ogrExternalRing);
      // Close the polygon
      ogrPolygon->closeRings();
      OGRGeometryFactory::destroyGeometry(ogrExternalRing);

      // Retrieving internal rings as well
866
      for (PolygonListType::Iterator pIt = dataNode->GetPolygonInteriorRings()->Begin();
867 868 869 870 871
           pIt != dataNode->GetPolygonInteriorRings()->End(); ++pIt)
        {
        OGRLinearRing * ogrInternalRing = (OGRLinearRing *) OGRGeometryFactory::createGeometry(wkbLinearRing);
        vertexList = pIt.Get()->GetVertexList();
        vIt = vertexList->Begin();
872

OTB Bot's avatar
OTB Bot committed
873
        while (vIt != vertexList->End())
874
          {
OTB Bot's avatar
OTB Bot committed
875 876 877 878
          OGRPoint ogrPoint;
          ogrPoint.setX(vIt.Value()[0]);
          ogrPoint.setY(vIt.Value()[1]);
          if (DataNodeType::Dimension > 2)
879
            {
OTB Bot's avatar
OTB Bot committed
880
            ogrPoint.setZ(vIt.Value()[2]);
881
            }
882
          ogrInternalRing->addPoint(&ogrPoint);
OTB Bot's avatar
OTB Bot committed
883
          ++vIt;
884
          }
885 886 887
        ogrPolygon->addRing(ogrInternalRing);
        OGRGeometryFactory::destroyGeometry(ogrInternalRing);
        }
OTB Bot's avatar
OTB Bot committed
888

889
      //Save it in the structure
890
      if (ogrCollection == nullptr)
OTB Bot's avatar
OTB Bot committed
891
        {
892 893
        OGRFeature *ogrFeature;
        ogrFeature = OGRFeature::CreateFeature(ogrCurrentLayer->GetLayerDefn());
894

895
        // Add the fields to the features
896
        for (unsigned int i  = 0; i < kwl.GetNumberOfFields(); ++i)
897
          {
OTB Bot's avatar
OTB Bot committed
898
          // Get the key of the Nth OGRFieldRefn
899 900 901 902
          const char * key = kwl.GetNthField(i).first->GetNameRef();
          // Edit the value of the field and add it to the current feature
          ogrFeature->SetField(ogrFeature->GetFieldIndex(key) , kwl.GetFieldAsString(key).c_str());
          }
903

904
        ogrFeature->SetGeometry(ogrPolygon);
905

906
        if (ogrCurrentLayer->CreateFeature(ogrFeature) != OGRERR_NONE)
OTB Bot's avatar
OTB Bot committed
907
          {
908
          itkExceptionMacro(<< "Failed to create feature in shapefile.");
OTB Bot's avatar
OTB Bot committed
909
          }
910

911 912 913 914 915
        OGRFeature::DestroyFeature(ogrFeature);
        }
      else
        {
        ogrCollection->addGeometry(ogrPolygon);
OTB Bot's avatar
OTB Bot committed
916
        }
917 918 919 920

      OGRGeometryFactory::destroyGeometry(ogrPolygon);
      break;
      }
OTB Bot's avatar
OTB Bot committed
921
      case FEATURE_MULTIPOINT:
922
      {
923
      if (ogrCollection != nullptr)
924 925 926
        {
        itkExceptionMacro(<< "Problem while creating multipoint.");
        }
927

928 929
      OGRMultiPoint* ogrMultiPoint = (OGRMultiPoint*) OGRGeometryFactory::createGeometry(wkbMultiPoint);
      OGRFeature *   ogrFeature;
930

931
      ogrFeature = OGRFeature::CreateFeature(ogrCurrentLayer->GetLayerDefn());
932
//      ogrFeature->SetField("Name", dataNode->GetNodeId());
933 934
      ogrFeature->GetDefnRef()->SetGeomType(wkbMultiPoint);
      ogrFeature->SetGeometry(ogrMultiPoint);
935

936 937 938
      if (ogrCurrentLayer->CreateFeature(ogrFeature) != OGRERR_NONE)
        {
        itkExceptionMacro(<< "Failed to create feature in shapefile.");
939
        }
940 941 942 943

      ProcessNodeWrite(*it, m_DataSource, ogrCollection, ogrCurrentLayer, oSRS);
      break;
      }
OTB Bot's avatar
OTB Bot committed
944
      case FEATURE_MULTILINE:
945
      {
946
      if (ogrCollection != nullptr)
947
        {
948 949
        itkExceptionMacro(<< "Problem while creating multiline.");
        }
950

951
      // Instantiate a new  ogrMultiLineString feature
952 953
      OGRMultiLineString* ogrMultiLineString = (OGRMultiLineString*) OGRGeometryFactory::createGeometry(
        wkbMultiLineString);
954

955
      OGRFeature *ogrFeature;
956

957
      ogrFeature = OGRFeature::CreateFeature(ogrCurrentLayer->GetLayerDefn());
958
//      ogrFeature->SetField("Name", dataNode->GetNodeId());
959 960
      ogrFeature->GetDefnRef()->SetGeomType(wkbMultiLineString);
      ogrFeature->SetGeometry(ogrMultiLineString);
961

962 963 964
      if (ogrCurrentLayer->CreateFeature(ogrFeature) != OGRERR_NONE)
        {
        itkExceptionMacro(<< "Failed to create feature in shapefile.");
965
        }
966 967 968
      ProcessNodeWrite(*it, m_DataSource, ogrCollection, ogrCurrentLayer, oSRS);
      break;
      }
OTB Bot's avatar
OTB Bot committed
969
      case FEATURE_MULTIPOLYGON:
970
      {
971
      if (ogrCollection != nullptr)
OTB Bot's avatar
OTB Bot committed
972
        {
973 974
        itkExceptionMacro(<< "Problem while creating multipolygon.");
        }
975

976
      // Instantiate a new multipolygon feature
977 978
      OGRMultiPolygon* ogrMultiPolygon = (OGRMultiPolygon*) OGRGeometryFactory::createGeometry(wkbMultiPolygon);
      OGRFeature *     ogrFeature;
979

980
      ogrFeature = OGRFeature::CreateFeature(ogrCurrentLayer->GetLayerDefn());
981
//      ogrFeature->SetField("Name", dataNode->GetNodeId());
982 983
      ogrFeature->GetDefnRef()->SetGeomType(wkbMultiPolygon);
      ogrFeature->SetGeometry(ogrMultiPolygon);
984

985 986 987
      if (ogrCurrentLayer->CreateFeature(ogrFeature) != OGRERR_NONE)
        {
        itkExceptionMacro(<< "Failed to create feature in shapefile.");
988
        }
989 990 991
      ProcessNodeWrite(*it, m_DataSource, ogrCollection, ogrCurrentLayer, oSRS);
      break;
      }
OTB Bot's avatar
OTB Bot committed
992
      case FEATURE_COLLECTION:
993
      {
994
      if (ogrCollection != nullptr)
995
        {
996 997
        itkExceptionMacro(<< "Problem while creating collection.");
        }
998

999 1000
      OGRGeometryCollection* ogrCollectionGeometry = (OGRGeometryCollection*) OGRGeometryFactory::createGeometry(
        wkbGeometryCollection);
1001

1002
      OGRFeature *ogrFeature;
1003

1004
      ogrFeature = OGRFeature::CreateFeature(ogrCurrentLayer->GetLayerDefn());
1005
//      ogrFeature->SetField("Name", dataNode->GetNodeId());
1006 1007
      ogrFeature->GetDefnRef()->SetGeomType(wkbGeometryCollection);
      ogrFeature->SetGeometry(ogrCollectionGeometry);
1008

1009 1010 1011
      if (ogrCurrentLayer->CreateFeature(ogrFeature) != OGRERR_NONE)
        {
        itkExceptionMacro(<< "Failed to create feature in shapefile.");
1012
        }
1013 1014 1015 1016

      ProcessNodeWrite(*it, m_DataSource, ogrCollection, ogrCurrentLayer, oSRS);
      break;
      }
1017 1018
      }
    }
OTB Bot's avatar
OTB Bot committed
1019

1020
  return kept;
1021 1022 1023 1024 1025 1026 1027 1028

}

/**
 * They may be several OGRLayers in this tree node.
 * Return a vector of OGRLayer
 **/
std::vector<OGRLayer*> OGRIOHelper
OTB Bot's avatar
OTB Bot committed
1029
::ConvertDataTreeNodeToOGRLayers(InternalTreeNodeType * source,
1030
                                 GDALDataset * inMemoryDataSource,
1031 1032 1033
                                 OGRLayer* ogrCurrentLayer,
                                 OGRSpatialReference * oSRS)
{
1034

1035
  // Create the in memory datasource if NULL
1036
  if (inMemoryDataSource == nullptr)
1037 1038
    {
    const char * driverName = "Memory";
1039
    GDALDriver * ogrDriver = GetGDALDriverManager()->GetDriverByName(driverName);
1040
    inMemoryDataSource = ogr::version_proxy::Create(ogrDriver,"tempDataSource");
1041 1042 1043
    }

  std::vector<OGRLayer*>  ogrLayerVector;
1044
  //unsigned int kept = 0;
1045
  bool fieldsAddedToOGRLayer = false;
1046 1047 1048 1049 1050 1051 1052 1053
  // Get the children list from the input node
  typedef InternalTreeNodeType::ChildrenListType ChildrenListType;
  ChildrenListType children = source->GetChildrenList();

  // For each child
  for (ChildrenListType::iterator it = children.begin(); it != children.end(); ++it)
    {
    DataNodePointerType dataNode = (*it)->Get();
1054

1055 1056 1057 1058 1059
    // Get the kwl
    otb::VectorDataKeywordlist kwl;
    itk::ExposeMetaData<VectorDataKeywordlist>(dataNode->GetMetaDataDictionary(),
                                               MetaDataKey::VectorDataKeywordlistKey,
                                               kwl);
1060

1061
    // Create the field once
1062
    if (ogrCurrentLayer != nullptr && !fieldsAddedToOGRLayer)
1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080
      {
      // Take into account the fields stored in the
      // vectordatakeywordlist
      for (unsigned int fieldIdx  = 0; fieldIdx < kwl.GetNumberOfFields(); fieldIdx++)
        {
        if ( std::string(kwl.GetNthField(fieldIdx).first->GetNameRef()) != "FID" )
          {
          otbMsgDevMacro(<< " CreateField '" << kwl.GetNthField(fieldIdx).first->GetNameRef() << "'");
          if (ogrCurrentLayer->CreateField(kwl.GetNthField(fieldIdx).first) != OGRERR_NONE )
            {
            itkExceptionMacro(<< "Failed to create Field "<<kwl.GetNthField(fieldIdx).first->GetNameRef());
            }
          }
         else
          {
          otbMsgDevMacro(<< "WARNING: Skipping OGR field 'FID'");
          }
        }
1081
      fieldsAddedToOGRLayer = true;
1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092
      }

    switch (dataNode->GetNodeType())
      {
      case ROOT:
      {
      break;
      }
      case DOCUMENT:
      {
      ogrCurrentLayer = inMemoryDataSource->CreateLayer(dataNode->GetNodeId(), oSRS,
1093 1094
                                      wkbUnknown, nullptr);
      if (ogrCurrentLayer == nullptr)
1095 1096 1097
        {
        std::cout << "Failed to create layer " << dataNode->GetNodeId() << std::endl;
        }
1098 1099 1100 1101 1102
      else
        {
        // New OGRLayer, set the flag to false
        fieldsAddedToOGRLayer = false;
        }
1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126
      ogrLayerVector.push_back(ogrCurrentLayer);
      ConvertDataTreeNodeToOGRLayers(*it, inMemoryDataSource, ogrCurrentLayer, oSRS);
      break;
      }
      case FOLDER:
      {
      ConvertDataTreeNodeToOGRLayers(*it, inMemoryDataSource, ogrCurrentLayer, oSRS);
      break;
      }
      case FEATURE_POINT:
      {
      //Build the ogrObject
      OGRPoint ogrPoint;
      ogrPoint.setX(dataNode->GetPoint()[0]);
      ogrPoint.setY(dataNode->GetPoint()[1]);

      if (DataNodeType::Dimension > 2)
        {
        ogrPoint.setZ(dataNode->GetPoint()[2]);
        }

      //Save it in the structure
      OGRFeature *ogrFeature;
      ogrFeature = OGRFeature::CreateFeature(ogrCurrentLayer->GetLayerDefn());
1127

1128 1129 1130 1131 1132
      // Add the fields to the features
      for (unsigned int i  = 0; i < kwl.GetNumberOfFields(); ++i)
        {
        // Get the key of the Nth OGRFieldRefn
        const char * key = kwl.GetNthField(i).first->GetNameRef();
1133

1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245
        if (std::string(key) != "FID")
          {
          // Edit the value of the field and add it to the current feature
          ogrFeature->SetField(ogrFeature->GetFieldIndex(key) , kwl.GetFieldAsString(key).c_str());
          }
        }
      ogrFeature->SetGeometry(&ogrPoint);

      if (ogrCurrentLayer->CreateFeature(ogrFeature) != OGRERR_NONE)
        {
        itkExceptionMacro(<< "Failed to create feature in shapefile.");
        }

      OGRFeature::DestroyFeature(ogrFeature);
      break;
      }
      case FEATURE_LINE:
      {
      //Build the ogrObject
      OGRLineString              ogrLine;
      VertexListConstPointerType vertexList = dataNode->GetLine()->GetVertexList();

      VertexListType::ConstIterator vIt = vertexList->Begin();

      while (vIt != vertexList->End())
        {
        OGRPoint ogrPoint;
        ogrPoint.setX(vIt.Value()[0]);
        ogrPoint.setY(vIt.Value()[1]);
        if (DataNodeType::Dimension > 2)
          {
          ogrPoint.setZ(vIt.Value()[2]);
          }
        ogrLine.addPoint(&ogrPoint);
        ++vIt;
        }

      //Save it in the structure
      OGRFeature *ogrFeature;
      ogrFeature = OGRFeature::CreateFeature(ogrCurrentLayer->GetLayerDefn());

      // Add the fields to the features
      for (unsigned int i  = 0; i < kwl.GetNumberOfFields(); ++i)
        {
        // Get the key of the Nth OGRFieldRefn
        const char * key = kwl.GetNthField(i).first->GetNameRef();
        // Edit the value of the field and add it to the current feature
        ogrFeature->SetField(ogrFeature->GetFieldIndex(key) , kwl.GetFieldAsString(key).c_str());
        }
      ogrFeature->SetGeometry(&ogrLine);

      if (ogrCurrentLayer->CreateFeature(ogrFeature) != OGRERR_NONE)
        {
        itkExceptionMacro(<< "Failed to create feature in shapefile.");
        }

      OGRFeature::DestroyFeature(ogrFeature);
      break;
      }
      case FEATURE_POLYGON:
      {
      //Build the ogrObject
      OGRPolygon *