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); } }