Example #1
0
void  CPtsRecordBase::ConvertVarFieldOffsetsToPointers
                                 (U32 cbActualTotalRecordSize)
{

BOOL           fHaveVarData;     // does our record have actual data?
CharVarField * pVarField;
U32            i;


   //  do we have variable field data, or are we a "truncated" record
   //  with just our fixed header part?
   fHaveVarData = (cbActualTotalRecordSize == TotalRecSize());

   //  we only allow all variable length fields, or none.
   assert ((cbActualTotalRecordSize == size) || fHaveVarData);

   if (VarFieldCount() > 0)
      {
      //  may have offset varfields, so change them into pointers
	  pVarField = VarField(0);

      for (i = 0;  i < VarFieldCount();  i ++)
         {
         if (fHaveVarData)
            {
            //  got vardata, but is descriptor converted to pointer form yet?
            if (! pVarField->IsPointerForm ())
               {
               //  nope, let's convert descriptor to pointer form.

               //  offset should be somewhere within our record data, or it
			   //  could be an empty var field (jlo)
               assert ((pVarField->Size()==0) ||
                       ((pVarField->Offset() >= size) &&
                        (pVarField->Offset() <=
                           (cbActualTotalRecordSize - pVarField->Size()))));
     
               //  varfield's data should also be four-byte aligned:
               assert (pVarField->Offset() == RoundSize (pVarField->Offset()));
     
               if ((pVarField->Offset() >= size) &&
                   (pVarField->Offset() <=
                           (cbActualTotalRecordSize - pVarField->Size())))
                  {
                  //  got varfield data, so make an honest varfield pointer
                  pVarField->ChangeOffsetToPointer (this);
                  }
               else
                  {
                  //  this is either an empty var field, or it has an invalid offset.  
                  //  either way, set to be empty. (jlo)
                  pVarField->Set (NULL, 0);
                  }
               }
            }
         else
            {
            //  for now, we mark a phantom by setting its ptr to zero,
            //  while leaving its data size value intact.
            pVarField->SetOffset (0);
            }
		 // jlo - advance to next pVarField
         pVarField++;

         }
      }

   //  all done
   return;

}  /* end of CPtsRecordBase::ConvertVarFieldOffsetsToPointers */
    void processSerie(GeoVectorSerie& Serie)
    {
      QString IndexStr = "init";

      openfluid::base::SimulationStatus::SimulationStage CurrentStage =
          OPENFLUID_GetCurrentStage();

      bool OKToWrite = false;

      if (CurrentStage == openfluid::base::SimulationStatus::INITIALIZERUN)
      {
        OKToWrite = Serie.WhenMode == GeoVectorSerie::WHENINIT ||
                    Serie.WhenMode == GeoVectorSerie::WHENCONTINUOUS;

      }
      else if (CurrentStage == openfluid::base::SimulationStatus::RUNSTEP)
      {
        if (Serie.WhenMode == GeoVectorSerie::WHENCONTINUOUS)
        {
          openfluid::core::TimeIndex_t CurrentIndex = OPENFLUID_GetCurrentTimeIndex();
          IndexStr = QString("%1").arg(CurrentIndex);

          if (Serie.LatestContinuousIndex + Serie.WhenContinuousDelay < CurrentIndex)
          {
            OKToWrite = true;
            Serie.LatestContinuousIndex = CurrentIndex;
          }
        }
      }
      else if (CurrentStage == openfluid::base::SimulationStatus::FINALIZERUN)
      {
        IndexStr = "final";
        OKToWrite = Serie.WhenMode == GeoVectorSerie::WHENCONTINUOUS ||
                    Serie.WhenMode == GeoVectorSerie::WHENFINAL;
      }
      else
      {
        OPENFLUID_LogWarning("Internal stage error when processing geographic series");
        return;
      }


      if (OKToWrite)
      {
        std::string FullFilePath =
            m_OutputPath + "/" + QString(QString::fromStdString(Serie.OutfilePattern).arg(IndexStr)).toStdString();


        GDALDriver_COMPAT* Driver = GDALGetDriverByName_COMPAT(m_GDALFormat.c_str());

        if (openfluid::tools::Filesystem::isFile(FullFilePath))
        {
          // deletion of an existing file or files set
          GDALDelete_COMPAT(Driver,FullFilePath.c_str());
        }

        GDALDataset_COMPAT* CreatedFile = GDALCreate_COMPAT(Driver,FullFilePath.c_str());

        std::string CreatedLayerName = QFileInfo(QString::fromStdString(FullFilePath)).completeBaseName().toStdString();

        OGRLayer* CreatedLayer = CreatedFile->CreateLayer(CreatedLayerName.c_str(),nullptr,
                                                          Serie.GeoLayer->GetLayerDefn()->GetGeomType(),
                                                          nullptr);

        OGRFieldDefn IDField("OFLD_ID",OFTInteger);
        CreatedLayer->CreateField(&IDField);


        GeoVectorSerie::VariablesSet_t::const_iterator itV;
        GeoVectorSerie::VariablesSet_t::const_iterator itVb = Serie.VariablesSet.begin();
        GeoVectorSerie::VariablesSet_t::const_iterator itVe = Serie.VariablesSet.end();

        for (itV = itVb; itV != itVe; ++itV)
        {
          std::string FieldName = (*itV).second;

          OGRFieldDefn VarField(FieldName.c_str(),OFTReal);
          VarField.SetWidth(24);
          VarField.SetPrecision(15);

          CreatedLayer->CreateField(&VarField);
        }


        OGRFeature* SourceFeature;
        openfluid::core::SpatialUnit* UU;

        Serie.GeoLayer->ResetReading();
        while ((SourceFeature = Serie.GeoLayer->GetNextFeature()) != nullptr)
        {
          int SourceID = SourceFeature->GetFieldAsInteger(Serie.OFLDIDFieldIndex);

          UU = OPENFLUID_GetUnit(Serie.UnitsClass,SourceID);

          if (UU)
          {
            CreatedLayer->GetLayerDefn();

            OGRFeature* CreatedFeature = OGRFeature::CreateFeature(CreatedLayer->GetLayerDefn());

            CreatedFeature->SetGeometry(SourceFeature->GetGeometryRef()->clone());
            CreatedFeature->SetField("OFLD_ID",SourceID);


            for (itV = itVb; itV != itVe; ++itV)
            {
              std::string VarName = (*itV).first;
              std::string FieldName = (*itV).second;
              openfluid::core::DoubleValue CreatedValue = 0.0;
              bool IsValueCreated = false;

              if (FieldName.empty())
                FieldName = VarName;

              openfluid::core::IndexedValue VarValue;

              if (OPENFLUID_IsVariableExist(UU,VarName))
              {
                OPENFLUID_GetLatestVariable(UU,VarName,VarValue);

                if (VarValue.value()->isDoubleValue()) // OpenFLUID value is double
                {
                  CreatedValue = VarValue.value()->asDoubleValue();
                  IsValueCreated = true;
                }
                else if (VarValue.value()->convert(CreatedValue)) // OpenFLUID value can be converted to double
                {
                  IsValueCreated = true;
                }
                else
                {
                  QString Msg = QString("Variable %1 on unit %2#%3 is not a double or a compatible type")
                                .arg(VarName.c_str()).arg(UU->getClass().c_str()).arg(UU->getID());
                  OPENFLUID_LogWarning(Msg.toStdString());
                }
              }
              else
              {
                QString Msg = QString("Variable %1 does not exist on unit %2#%3")
                              .arg(VarName.c_str()).arg(UU->getClass().c_str()).arg(UU->getID());
                OPENFLUID_LogWarning(Msg.toStdString());
              }

              if (IsValueCreated) // OpenFLUID value is written to GIS file only if it is double or converted to double
                CreatedFeature->SetField(FieldName.c_str(),CreatedValue);
            }

            if (CreatedLayer->CreateFeature(CreatedFeature) != OGRERR_NONE)
            {
              QString Msg = QString("Feature for unit %1#%2 cannot be created")
                            .arg(UU->getClass().c_str()).arg(UU->getID());
              OPENFLUID_LogWarning(Msg.toStdString());
            }


            OGRFeature::DestroyFeature(CreatedFeature);
          }
        }
        GDALClose_COMPAT(CreatedFile);
      }
    }