void onPrepared() { if (m_Series.empty()) return; std::vector<GeoVectorSerie>::iterator it; // preparation of output directory for series (if any) QDir().mkpath(QString::fromStdString(m_OutputPath)); // preparation of series for (it = m_Series.begin();it!=m_Series.end(); ++it) prepareSerie(*it); // removal of wrong formatted source geovector file for (it=m_Series.begin();it!=m_Series.end(); ) { if ((*it).GeoSource == nullptr) { OPENFLUID_LogWarning("Cannot open geographic source for serie "+(*it).SerieName); closeSerie(*it); it = m_Series.erase(it); } else if ((*it).GeoLayer == nullptr) { OPENFLUID_LogWarning("Cannot open layer in geographic source for serie "+(*it).SerieName); closeSerie(*it); it = m_Series.erase(it); } else if ((*it).OFLDIDFieldIndex < 0) { OPENFLUID_LogWarning("File not found or wrong file format for geographic source for serie "+ (*it).SerieName); closeSerie(*it); it = m_Series.erase(it); } else if ((*it).VariablesSet.empty()) { OPENFLUID_LogWarning("No correct variable name in serie "+(*it).SerieName); closeSerie(*it); it = m_Series.erase(it); } else ++it; } // Update field names if necessary for (it=m_Series.begin();it!=m_Series.end(); ++it) updateFieldNamesUsingFormat((*it).VariablesSet); }
void tryOpenGNUplot() { if (m_TryOpenGNUplot) { openfluid::utils::ExternalProgram GNUPlotProgram = openfluid::utils::ExternalProgram::getRegisteredProgram(openfluid::utils::ExternalProgram::GnuplotProgram); if (GNUPlotProgram.isFound()) { QString PersistOption = " "; if (m_Persistent) PersistOption = " -persist "; QString GNUPlotCommand = QString("\"%1\"%2\"%3\"").arg(GNUPlotProgram.getFullProgramPath()) .arg(PersistOption) .arg(QDir(QString::fromStdString(m_OutputDir)) .absoluteFilePath("script.gnuplot")); QProcess::execute(GNUPlotCommand); } else { OPENFLUID_LogWarning("Cannot find GNUPlot"); } } }
void prepareTempDirectory() { std::string TmpDir; OPENFLUID_GetRunEnvironment("dir.temp",TmpDir); m_TmpDir = openfluid::tools::Filesystem::makeUniqueSubdirectory(TmpDir,m_TmpSubDirRoot); openfluid::tools::Filesystem::makeDirectory(m_TmpDir); if (!openfluid::tools::Filesystem::isDirectory(m_TmpDir)) { OPENFLUID_LogWarning("Cannot initialize temporary directory"); m_OKToGo = false; return; } openfluid::tools::Filesystem::removeDirectory(m_TmpDir+"/"+m_KmzSubDir); openfluid::tools::Filesystem::makeDirectory(m_TmpDir+"/"+m_KmzSubDir); if (!openfluid::tools::Filesystem::isDirectory(m_TmpDir+"/"+m_KmzSubDir)) { OPENFLUID_LogWarning("Cannot initialize kmz temporary directory"); m_OKToGo = false; return; } openfluid::tools::Filesystem::makeDirectory(m_TmpDir+"/"+m_KmzSubDir+"/"+m_KmzDataSubDir); if (!openfluid::tools::Filesystem::isDirectory(m_TmpDir+"/"+m_KmzSubDir+"/"+m_KmzDataSubDir)) { OPENFLUID_LogWarning("Cannot initialize kmz data temporary directory"); m_OKToGo = false; return; } }
void tryOpenGEarth() { if (m_TryOpenGEarth) { openfluid::utils::ExternalProgram GEarthProgram = openfluid::utils::ExternalProgram::getRegisteredProgram( openfluid::utils::ExternalProgram::GoogleEarthProgram); if (GEarthProgram.isFound()) { QString GEarthCommand = QString("%1 %2").arg(GEarthProgram.getFullProgramPath()) .arg(QDir(QString::fromStdString(m_OutputDir)) .absoluteFilePath(QString::fromStdString(m_OutputFileName))); QProcess::execute(GEarthCommand); } else { OPENFLUID_LogWarning("Cannot find Google Earth"); } } }
void initParams(const openfluid::ware::WareParams_t& Params) { openfluid::ware::WareParamsTree ParamsTree; try { ParamsTree.setParams(Params); ParamsTree.root().getChildValue("tryopengnuplot",m_TryOpenGNUplot).toBoolean(m_TryOpenGNUplot); ParamsTree.root().getChildValue("persistent",m_Persistent).toBoolean(m_Persistent); m_Terminal = ParamsTree.root().getChildValue("terminal",m_Terminal); m_Output = ParamsTree.root().getChildValue("output",m_Output); } catch (openfluid::base::FrameworkException& E) { OPENFLUID_RaiseError(E.getMessage()); } if (!ParamsTree.root().hasChild("serie")) OPENFLUID_RaiseError("No serie defined"); if (!ParamsTree.root().hasChild("graph")) OPENFLUID_RaiseError("No graph defined"); for (auto& Serie : ParamsTree.root().child("serie")) { std::string SerieID = Serie.first; SerieInfo SInfo; SInfo.VarName = Serie.second.getChildValue("var",""); SInfo.UnitsClass = Serie.second.getChildValue("unitsclass",""); if (SInfo.UnitsClass == "") { // search for deprecated "unitclass" parameter SInfo.UnitsClass = Serie.second.getChildValue("unitclass",""); } std::string UnitIDStr = Serie.second.getChildValue("unitID",""); SInfo.SourceFile = Serie.second.getChildValue("sourcefile",""); SInfo.Label = Serie.second.getChildValue("label",""); SInfo.Style = Serie.second.getChildValue("style","line"); SInfo.Color = Serie.second.getChildValue("color",""); if (!SInfo.VarName.empty() && !SInfo.UnitsClass.empty() && openfluid::tools::convertString(UnitIDStr,&SInfo.UnitID)) { openfluid::core::SpatialUnit* TmpU; TmpU = mp_SpatialData->spatialUnit(SInfo.UnitsClass,SInfo.UnitID); if (TmpU != NULL) { SInfo.Type = SerieInfo::SERIE_VAR; SInfo.Unit = TmpU; SInfo.SourceFile = SerieID + "_data.gnuplot"; } } else if (!SInfo.SourceFile.empty()) SInfo.Type = SerieInfo::SERIE_FILE; if (SInfo.Type!=SerieInfo::SERIE_UNKNOWN) m_Series[SerieID] = SInfo; else OPENFLUID_LogWarning("Serie " + SerieID + "ignored"); } for (auto& Graph : ParamsTree.root().child("graph")) { std::string GraphID = Graph.first; GraphInfo GInfo; GInfo.Title = Graph.second.getChildValue("title",GraphID); GInfo.Key = Graph.second.getChildValue("key","default"); GInfo.YLabel = Graph.second.getChildValue("ylabel",""); std::vector<std::string> SeriesStr = openfluid::tools::splitString(Graph.second.getChildValue("series",""), ";",false); for (std::vector<std::string>::const_iterator it = SeriesStr.begin();it != SeriesStr.end();++it) { if (m_Series.find(*it) != m_Series.end()) GInfo.Series.push_back(&(m_Series[*it])); } if (!GInfo.Series.empty()) m_Graphs[GraphID] = GInfo; else OPENFLUID_LogWarning("Graph " + GraphID + "ignored"); } }
void onPrepared() { if (!m_OKToGo) return; if (!m_PlotProgram.isFound()) { OPENFLUID_LogWarning("Required GNUplot program not found"); m_OKToGo = false; return; } std::ostringstream TmpOSS; TmpOSS << ((OPENFLUID_GetEndDate().diffInSeconds(OPENFLUID_GetBeginDate())) / 2); m_PlotXTics = TmpOSS.str(); prepareTempDirectory(); if (!m_OKToGo) return; openfluid::tools::Filesystem::removeDirectory(m_TmpDir+"/"+m_GNUPlotSubDir); openfluid::tools::Filesystem::makeDirectory(m_TmpDir+"/"+m_GNUPlotSubDir); if (!openfluid::tools::Filesystem::isDirectory(m_TmpDir+"/"+m_GNUPlotSubDir)) { OPENFLUID_LogWarning("Cannot initialize gnuplot temporary directory"); m_OKToGo = false; return; } // initialize data files for (std::list<KmlSerieInfo>::iterator it=m_KmlSeriesInfos.begin();it!=m_KmlSeriesInfos.end();++it) { if ((*it).VarsListStr == "*") { (*it).VarsList = mp_SpatialData->spatialUnits((*it).UnitsClass)->list()->front().variables()->getVariablesNames(); } else { openfluid::tools::tokenizeString((*it).VarsListStr,(*it).VarsList,";"); } if ((*it).VarsList.empty()) { OPENFLUID_LogWarning("Variable list is empty"); m_OKToGo = false; return; } for (std::map<openfluid::core::UnitID_t,KmlUnitInfoExtra>::iterator it2=(*it).UnitsInfos.begin(); it2!=(*it).UnitsInfos.end(); ++it2) { if ((*it2).second.IsPlotted) { std::string DataFilename = buildFilePath(m_TmpDir+"/"+m_GNUPlotSubDir, (*it).UnitsClass,(*it2).second.UnitID, "","dat"); (*it2).second.DataFile = new std::ofstream(DataFilename.c_str()); (*((*it2).second.DataFile)) << "#" << DataFilename << "\n"; } } } }
void initParams(const openfluid::ware::WareParams_t& Params) { openfluid::ware::WareParamsTree ParamsTree; try { ParamsTree.setParams(Params); } catch (openfluid::base::FrameworkException& E) { OPENFLUID_LogWarning(E.getMessage()); m_OKToGo = false; return; } OGRRegisterAll(); OPENFLUID_GetRunEnvironment("dir.input",m_InputDir); OPENFLUID_GetRunEnvironment("dir.output",m_OutputDir); // general try { m_Title = ParamsTree.root().getChildValue("title",m_Title); m_OutputFileName = ParamsTree.root().getChildValue("kmzfilename",m_OutputFileName); ParamsTree.root().getChildValue("tryopengearth",m_TryOpenGEarth).toBoolean(m_TryOpenGEarth); if (!ParamsTree.root().hasChild("layers")) { OPENFLUID_LogWarning("No layer defined"); m_OKToGo = false; return; } for (auto& Layer : ParamsTree.root().child("layers")) { KmlSerieInfo KSI; KSI.UnitsClass = Layer.second.getChildValue("unitsclass",""); if (KSI.UnitsClass == "") { // search for deprecated "unitclass" parameter KSI.UnitsClass = Layer.second.getChildValue("unitclass",""); } KSI.VarsListStr = Layer.second.getChildValue("varslist","*"); // TODO Manage selection of plotted spatial units Layer.second.getChildValue("linewidth",1).toInteger(KSI.LineWidth); KSI.DefaultColor = Layer.second.getChildValue("defaultcolor","ffffffff"); KSI.PlottedColor = Layer.second.getChildValue("plottedcolor","ff0000ff"); KSI.SourceIsDatastore = (Layer.second.getChildValue("source","file").get() == "datastore"); if (KSI.SourceIsDatastore) return; else { KSI.SourceFilename = Layer.second.getChildValue("sourcefile",""); if (KSI.SourceFilename.empty()) { OPENFLUID_LogWarning("wrong sourcefile format"); m_OKToGo = false; return; } KSI.SourceFilename = m_InputDir + "/" + KSI.SourceFilename; } if (transformVectorLayerToKmlGeometry(KSI)) { m_KmlSeriesInfos.push_back(KSI); } } } catch (openfluid::base::FrameworkException& E) { OPENFLUID_LogWarning(E.getMessage()); m_OKToGo = false; return; } m_OKToGo = true; m_KmzSubDir = m_OutputFileName + "_kmz-dir"; m_GNUPlotSubDir = m_OutputFileName + "_gnuplot-dir"; }
void writeKmlFile(const std::string& DocFilePath) { std::ofstream KmlFile(DocFilePath.c_str()); KmlFile << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; KmlFile << "<kml xmlns=\"http://www.opengis.net/kml/2.2\" " "xmlns:gx=\"http://www.google.com/kml/ext/2.2\" " "xmlns:kml=\"http://www.opengis.net/kml/2.2\" xmlns:atom=\"http://www.w3.org/2005/Atom\">\n"; KmlFile << "<Document>\n"; KmlFile << " <name>" << m_Title << "</name>\n"; KmlFile << " <open>1</open>\n"; for (std::list<KmlSerieInfo>::iterator it=m_KmlSeriesInfos.begin();it!=m_KmlSeriesInfos.end();++it) { std::string TmpStyleID = (*it).UnitsClass +"_style"; if ((*((*it).UnitsInfos.begin())).second.GeometryType == wkbPolygon) { KmlFile << " <Style id=\"" << TmpStyleID << "\"><PolyStyle><color>"<< (*it).DefaultColor << "</color><outline>1</outline></PolyStyle></Style>\n"; KmlFile << " <Style id=\"" << TmpStyleID << "_plotted\"><PolyStyle><color>"<< (*it).PlottedColor << "</color></PolyStyle><outline>1</outline></Style>\n"; } else if ((*((*it).UnitsInfos.begin())).second.GeometryType == wkbLineString) { KmlFile << " <Style id=\"" << TmpStyleID << "\"><LineStyle><color>"<< (*it).DefaultColor << "</color><width>" << (*it).LineWidth << "</width></LineStyle><PolyStyle><fill>0</fill></PolyStyle></Style>\n"; KmlFile << " <Style id=\"" << TmpStyleID << "_plotted\"><LineStyle><color>" << (*it).PlottedColor << "</color><width>" << (*it).LineWidth << "</width></LineStyle><PolyStyle><fill>0</fill></PolyStyle></Style>\n"; } else { OPENFLUID_LogWarning("Unsupported geometry format in source geometry file"); m_OKToGo = false; return; } KmlFile << " <Folder>\n"; KmlFile << " <name>" << (*it).UnitsClass << "</name>\n"; for (std::map<openfluid::core::UnitID_t,KmlUnitInfoExtra>::iterator it2=(*it).UnitsInfos.begin(); it2!=(*it).UnitsInfos.end(); ++it2) { KmlFile << " <Placemark>\n"; KmlFile << " <name>" << (*it).UnitsClass << " " << (*it2).second.UnitID << "</name>\n"; KmlFile << " <description>\n<![CDATA[\n"; KmlFile << "Unit class: " << (*it).UnitsClass << "<br/>\n"; KmlFile << "Unit ID: " << (*it2).second.UnitID << "<br/>\n"; KmlFile << "<br/>\n"; if ((*it2).second.IsPlotted) { KmlFile << "<img src=\"" << buildFilePath(m_KmzDataSubDir,(*it).UnitsClass, (*it2).second.UnitID,"","png") << "\"/>\n"; } KmlFile << "\n]]>\n </description>\n"; if ((*it2).second.IsPlotted) { KmlFile << " <styleUrl>#" << TmpStyleID << "_plotted</styleUrl>\n"; } else { KmlFile << " <styleUrl>#" << TmpStyleID << "</styleUrl>\n"; } if ((*it2).second.GeometryType == wkbPolygon) { KmlFile << "<Polygon><tessellate>1</tessellate><outerBoundaryIs><LinearRing><coordinates>" << (*it2).second.CoordsStr << "</coordinates></LinearRing></outerBoundaryIs></Polygon>\n"; } else if ((*it2).second.GeometryType == wkbLineString) { KmlFile << "<LineString><tessellate>1</tessellate><coordinates>" << (*it2).second.CoordsStr << "</coordinates></LineString>\n"; } else { OPENFLUID_LogWarning("Unsupported geometry format in source geometry file"); m_OKToGo = false; return; } KmlFile << " </Placemark>\n"; } KmlFile << " </Folder>\n"; } KmlFile << "</Document>\n"; KmlFile << "</kml>\n"; KmlFile.close(); }
void initParams(const openfluid::ware::WareParams_t& Params) { openfluid::ware::WareParamsTree ParamsTree; try { ParamsTree.setParams(Params); } catch (openfluid::base::FrameworkException& E) { OPENFLUID_RaiseError(E.getMessage()); } // checking of mandatory parameters if (!ParamsTree.root().hasChild("format")) { OPENFLUID_LogWarning("Missing GDAL format for output files"); return; } if (!ParamsTree.root().hasChild("format")) { OPENFLUID_LogWarning("No serie defined"); return; } // process of format parameter m_GDALFormat = ParamsTree.root().getChildValue("format",""); openfluid::utils::GDALDriversFilesExts_t ValidVectorDrivers = openfluid::utils::getOGRFilesDriversForOpenFLUID(); if (ValidVectorDrivers.find(m_GDALFormat) == ValidVectorDrivers.end()) { OPENFLUID_LogWarning("Unsupported GDAL format for output files"); return; } std::string OutfileExt = ValidVectorDrivers[m_GDALFormat].FilesExts.front(); // process of parameter for optional output subdirectory std::string OutSeriesSubdir = ParamsTree.root().getChildValue("outsubdir",""); // get paths for input dataset and output directory OPENFLUID_GetRunEnvironment("dir.input",m_InputPath); OPENFLUID_GetRunEnvironment("dir.output",m_OutputPath); if (!OutSeriesSubdir.empty()) m_OutputPath += "/"+OutSeriesSubdir; for (auto& Serie : ParamsTree.root().child("geoserie")) { GeoVectorSerie::WhenModeCases Mode = GeoVectorSerie::WHENCONTINUOUS; openfluid::core::Duration_t ContinuousDelay = 1; std::string SerieName = Serie.first; std::string GeoSourceFilename = Serie.second.getChildValue("sourcefile",""); std::string VarsString = Serie.second.getChildValue("vars",""); openfluid::core::UnitsClass_t UnitsClass = Serie.second.getChildValue("unitsclass",""); std::string WhenModeString = Serie.second.getChildValue("when",""); if (GeoSourceFilename.empty()) OPENFLUID_LogWarning("Missing geographic source filename for serie "+SerieName); else if (UnitsClass.empty()) OPENFLUID_LogWarning("Missing units class for serie "+SerieName); else if (VarsString.empty()) OPENFLUID_LogWarning("Missing variables list for serie "+SerieName); else { GeoVectorSerie::VariablesSet_t VarsSet = convertParamToVariableSet(VarsString); if (VarsSet.empty()) OPENFLUID_LogWarning("Format error in variables list for serie "+SerieName); else { if (setWhenModeFromParam(WhenModeString,Mode,ContinuousDelay)) { // everything's OK, add the serie to the active series set m_Series.push_back(GeoVectorSerie(SerieName, m_InputPath + "/" + GeoSourceFilename, UnitsClass,VarsSet, OutfileExt, Mode,ContinuousDelay)); } else OPENFLUID_LogWarning("Format error in whenmode for serie "+SerieName); } } } }
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); } }
bool transformVectorLayerToKmlGeometry(KmlLayerInfo<T>& LayerInfo) { // TODO manage when data are coming from datastore GDALDataset_COMPAT* DataSource; OGRLayer *Layer; OGRFeature *Feature; DataSource = GDALOpenRO_COMPAT(LayerInfo.SourceFilename.c_str()); if( DataSource == nullptr ) { OPENFLUID_LogWarning("Cannot open shapefile "+LayerInfo.SourceFilename+". This Kml output is ignored."); return false; } std::string LayerName = openfluid::tools::Filesystem::basename(LayerInfo.SourceFilename); Layer = DataSource->GetLayerByName(LayerName.c_str()); if (Layer == nullptr) { OPENFLUID_LogWarning("Cannot open shapefile layer from " + LayerInfo.SourceFilename + ". This Kml output is ignored."); return false; } int OfldIDFieldIndex = Layer->GetLayerDefn()->GetFieldIndex("OFLD_ID"); if (OfldIDFieldIndex < 0) { OPENFLUID_LogWarning("Cannot find OFLD_ID attribute in " + LayerInfo.SourceFilename + ". This Kml output is ignored."); return false; } Layer->ResetReading(); while((Feature = Layer->GetNextFeature()) != nullptr) { openfluid::core::UnitID_t UnitID = Feature->GetFieldAsInteger(OfldIDFieldIndex); if (OPENFLUID_IsUnitExist(LayerInfo.UnitsClass,UnitID)) { OGRGeometry *Geometry; Geometry = Feature->GetGeometryRef(); std::stringstream CoordSS; CoordSS << std::fixed << std::setprecision(12); T KUI; KUI.UnitID = UnitID; if (Geometry != nullptr) { if (Geometry->getGeometryType() != wkbPolygon && Geometry->getGeometryType() != wkbLineString) { OPENFLUID_LogWarning("Unsupported geometry type in " + LayerInfo.SourceFilename + ". This Kml output is ignored."); return false; } KUI.GeometryType = Geometry->getGeometryType(); // polygons if (Geometry->getGeometryType() == wkbPolygon) { OGRLinearRing* Ring; Ring = ((OGRPolygon*)(Geometry))->getExteriorRing(); int NumPoints = Ring->getNumPoints()-1; for (int i=0;i<NumPoints;i++) { OGRPoint *Point = new OGRPoint(); Ring->getPoint(i,Point); CoordSS << " " << Point->getX() << "," << Point->getY(); delete Point; } // close the polygon if (NumPoints > 0) { OGRPoint *Point = new OGRPoint(); Ring->getPoint(0,Point); CoordSS << " " << Point->getX() << "," << Point->getY(); delete Point; } } // line strings if (Geometry->getGeometryType() == wkbLineString) { OGRLineString* LineString; LineString = (OGRLineString*)(Geometry); int NumPoints = LineString->getNumPoints(); for (int i=0;i<NumPoints;i++) { OGRPoint *Point = new OGRPoint(); LineString->getPoint(i,Point); CoordSS << " " << Point->getX() << "," << Point->getY(); delete Point; } } KUI.CoordsStr = CoordSS.str(); LayerInfo.UnitsInfos[UnitID] = KUI; } else { OPENFLUID_LogWarning("Wrong geometry reference in " + LayerInfo.SourceFilename + ". This Kml output is ignored."); return false; } } OGRFeature::DestroyFeature(Feature); } GDALClose_COMPAT(DataSource); return true; }