//--------------------------------------------------------- bool CPointcloud_To_Text_File::On_Execute(void) { CSG_PointCloud *pPoints; CSG_String fileName; CSG_File *pTabStream = NULL; bool bWriteHeader; CSG_String fieldSep; CSG_Parameters P; CSG_Parameter *pNode; CSG_String s; std::vector<int> vCol, vPrecision; //----------------------------------------------------- pPoints = Parameters("POINTS") ->asPointCloud(); fileName = Parameters("FILE") ->asString(); bWriteHeader = Parameters("WRITE_HEADER")->asBool(); switch (Parameters("FIELDSEP")->asInt()) { default: case 0: fieldSep = "\t"; break; case 1: fieldSep = " "; break; case 2: fieldSep = ","; break; } if( fileName.Length() == 0 ) { SG_UI_Msg_Add_Error(_TL("Please provide an output file name!")); return( false ); } if (SG_UI_Get_Window_Main()) { P.Set_Name(_TL("Check the fields to export")); for(int iField=0; iField<pPoints->Get_Field_Count(); iField++) { s.Printf(SG_T("NODE_%03d") , iField + 1); pNode = P.Add_Node(NULL, s, CSG_String::Format(_TL("%d. %s"), iField + 1, _TL("Field")), _TL("")); s.Printf(SG_T("FIELD_%03d"), iField); P.Add_Value(pNode, s, CSG_String::Format(SG_T("%s"), pPoints->Get_Field_Name(iField)), _TL(""), PARAMETER_TYPE_Bool, false); s.Printf(SG_T("PRECISION_%03d"), iField); P.Add_Value(pNode, s, _TL("Decimal Precision"), _TL(""), PARAMETER_TYPE_Int, 2.0, 0.0, true); } //----------------------------------------------------- if( Dlg_Parameters(&P, _TL("Field Properties")) ) { vCol.clear(); vPrecision.clear(); for(int iField=0; iField<pPoints->Get_Field_Count(); iField++) { if( P(CSG_String::Format(SG_T("FIELD_%03d" ), iField).c_str())->asBool() ) { vCol.push_back(iField); vPrecision.push_back(P(CSG_String::Format(SG_T("PRECISION_%03d" ), iField).c_str())->asInt()); } } } else return( false ); } else // CMD { CSG_String sFields, sPrecision; CSG_String token; int iValue; sFields = Parameters("FIELDS")->asString(); sPrecision = Parameters("PRECISIONS")->asString(); CSG_String_Tokenizer tkz_fields(sFields, ";", SG_TOKEN_STRTOK); while( tkz_fields.Has_More_Tokens() ) { token = tkz_fields.Get_Next_Token(); if( token.Length() == 0 ) break; if( !token.asInt(iValue) ) { SG_UI_Msg_Add_Error(_TL("Error parsing attribute fields: can't convert to number")); return( false ); } iValue -= 1; if( iValue < 0 || iValue > pPoints->Get_Field_Count() - 1 ) { SG_UI_Msg_Add_Error(_TL("Error parsing attribute fields: field index out of range")); return( false ); } else vCol.push_back(iValue); } CSG_String_Tokenizer tkz_precisons(sPrecision.c_str(), ";", SG_TOKEN_STRTOK); while( tkz_precisons.Has_More_Tokens() ) { token = tkz_precisons.Get_Next_Token(); if( token.Length() == 0 ) break; if( !token.asInt(iValue) ) { SG_UI_Msg_Add_Error(_TL("Error parsing attribute fields: can't convert to number")); return( false ); } vPrecision.push_back(iValue); } } if( vCol.size() == 0 ) { SG_UI_Msg_Add_Error(_TL("Please provide at least one column to export!")); return( false ); } if( vCol.size() != vPrecision.size() ) { SG_UI_Msg_Add_Error(_TL("Number of fields and precisions must be equal!")); return( false ); } //----------------------------------------------------- pTabStream = new CSG_File(); if( !pTabStream->Open(fileName, SG_FILE_W, false) ) { SG_UI_Msg_Add_Error(CSG_String::Format(_TL("Unable to open output file %s!"), fileName.c_str())); delete (pTabStream); return (false); } if( bWriteHeader ) { CSG_String sHeader; for(size_t i=0; i<vCol.size(); i++) { sHeader += CSG_String::Format(SG_T("%s"), pPoints->Get_Field_Name(vCol.at(i))); if( i < vCol.size()-1 ) sHeader += fieldSep.c_str(); } sHeader += SG_T("\n"); pTabStream->Write(sHeader); } for(int iPoint=0; iPoint<pPoints->Get_Count() && Set_Progress(iPoint, pPoints->Get_Count()); iPoint++) { CSG_String sLine; for(size_t i=0; i<vCol.size(); i++) { switch (pPoints->Get_Field_Type(vCol.at(i))) { case SG_DATATYPE_Double: case SG_DATATYPE_Float: sLine += SG_Get_String(pPoints->Get_Value(iPoint, vCol.at(i)), vPrecision.at(i), false); break; default: sLine += CSG_String::Format(SG_T("%d"), (int)pPoints->Get_Value(iPoint, vCol.at(i))); break; } if( i < vCol.size()-1 ) sLine += fieldSep.c_str(); } sLine += SG_T("\n"); pTabStream->Write(sLine); } pTabStream->Close(); delete (pTabStream); return( true ); }
//--------------------------------------------------------- bool CPointCloud_Create_SPCVF::On_Execute(void) { CSG_Strings sFiles; CSG_String sFileInputList, sFileName; int iMethodPaths; CSG_MetaData SPCVF; CSG_Projection projSPCVF; double dNoData; std::vector<TSG_Data_Type> vFieldTypes; std::vector<CSG_String> vFieldNames; double dBBoxXMin = std::numeric_limits<int>::max(); double dBBoxYMin = std::numeric_limits<int>::max(); double dBBoxXMax = std::numeric_limits<int>::min(); double dBBoxYMax = std::numeric_limits<int>::min(); int iSkipped = 0, iEmpty = 0; int iDatasetCount = 0; double dPointCount = 0.0; double dZMin = std::numeric_limits<double>::max(); double dZMax = -std::numeric_limits<double>::max(); //----------------------------------------------------- sFileName = Parameters("FILENAME")->asString(); iMethodPaths = Parameters("METHOD_PATHS")->asInt(); sFileInputList = Parameters("INPUT_FILE_LIST")->asString(); //----------------------------------------------------- if( !Parameters("FILES")->asFilePath()->Get_FilePaths(sFiles) && sFileInputList.Length() <= 0 ) { SG_UI_Msg_Add_Error(_TL("Please provide some input files!")); return( false ); } //----------------------------------------------------- if( sFiles.Get_Count() <= 0 ) { CSG_Table *pTable = new CSG_Table(); if( !pTable->Create(sFileInputList, TABLE_FILETYPE_Text_NoHeadLine) ) { SG_UI_Msg_Add_Error(_TL("Input file list could not be opened!")); delete( pTable ); return( false ); } sFiles.Clear(); for (int i=0; i<pTable->Get_Record_Count(); i++) { sFiles.Add(pTable->Get_Record(i)->asString(0)); } delete( pTable ); } //----------------------------------------------------- SPCVF.Set_Name(SG_T("SPCVFDataset")); SPCVF.Add_Property(SG_T("Version"), SG_T("1.1")); switch( iMethodPaths ) { default: case 0: SPCVF.Add_Property(SG_T("Paths"), SG_T("absolute")); break; case 1: SPCVF.Add_Property(SG_T("Paths"), SG_T("relative")); break; } //----------------------------------------------------- CSG_MetaData *pSPCVFHeader = SPCVF.Add_Child( SG_T("Header")); CSG_MetaData *pSPCVFFiles = pSPCVFHeader->Add_Child( SG_T("Datasets")); CSG_MetaData *pSPCVFPoints = pSPCVFHeader->Add_Child( SG_T("Points")); CSG_MetaData *pSRS = pSPCVFHeader->Add_Child( SG_T("SRS")); CSG_MetaData *pSPCVFBBox = pSPCVFHeader->Add_Child( SG_T("BBox")); CSG_MetaData *pSPCVFZStats = pSPCVFHeader->Add_Child( SG_T("ZStats")); CSG_MetaData *pSPCVFNoData = pSPCVFHeader->Add_Child( SG_T("NoData")); CSG_MetaData *pSPCVFAttr = pSPCVFHeader->Add_Child( SG_T("Attributes")); CSG_MetaData *pSPCVFDatasets = NULL; //----------------------------------------------------- for(int i=0; i<sFiles.Get_Count() && Set_Progress(i, sFiles.Get_Count()); i++) { CSG_PointCloud *pPC = SG_Create_PointCloud(sFiles[i]); //----------------------------------------------------- if( i==0 ) // first dataset determines projection, NoData value and table structure { projSPCVF = pPC->Get_Projection(); dNoData = pPC->Get_NoData_Value(); pSPCVFNoData->Add_Property(SG_T("Value"), dNoData); pSPCVFAttr->Add_Property(SG_T("Count"), pPC->Get_Field_Count()); for(int iField=0; iField<pPC->Get_Field_Count(); iField++) { vFieldTypes.push_back(pPC->Get_Field_Type(iField)); vFieldNames.push_back(pPC->Get_Field_Name(iField)); CSG_MetaData *pSPCVFField = pSPCVFAttr->Add_Child(CSG_String::Format(SG_T("Field_%d"), iField + 1)); pSPCVFField->Add_Property(SG_T("Name"), pPC->Get_Field_Name(iField)); pSPCVFField->Add_Property(SG_T("Type"), gSG_Data_Type_Identifier[pPC->Get_Field_Type(iField)]); } if( projSPCVF.is_Okay() ) { pSRS->Add_Property(SG_T("Projection"), projSPCVF.Get_Name()); pSRS->Add_Property(SG_T("WKT"), projSPCVF.Get_WKT()); } else { pSRS->Add_Property(SG_T("Projection"), SG_T("Undefined Coordinate System")); } pSPCVFDatasets = SPCVF.Add_Child(SG_T("Datasets")); } else // validate projection, NoData value and table structure { bool bSkip = false; if( pPC->Get_Field_Count() != (int)vFieldTypes.size() ) { bSkip = true; } if( !bSkip && projSPCVF.is_Okay() ) { if ( !pPC->Get_Projection().is_Okay() || SG_STR_CMP(pPC->Get_Projection().Get_WKT(), projSPCVF.Get_WKT()) ) { bSkip = true; } } if( !bSkip ) { for(int iField=0; iField<pPC->Get_Field_Count(); iField++) { if( pPC->Get_Field_Type(iField) != vFieldTypes.at(iField) ) { bSkip = true; break; } if( SG_STR_CMP(pPC->Get_Field_Name(iField), vFieldNames.at(iField)) ) { bSkip = true; break; } } } if( bSkip ) { SG_UI_Msg_Add(CSG_String::Format(_TL("Skipping dataset %s because of incompatibility with the first input dataset!"), sFiles[i].c_str()), true); delete( pPC ); iSkipped++; continue; } } //----------------------------------------------------- if( pPC->Get_Point_Count() <= 0 ) { delete( pPC ); iEmpty++; continue; } //----------------------------------------------------- CSG_MetaData *pDataset = pSPCVFDatasets->Add_Child(SG_T("PointCloud")); CSG_String sFilePath; switch( iMethodPaths ) { default: case 0: sFilePath = SG_File_Get_Path_Absolute(sFiles.Get_String(i)); break; case 1: sFilePath = SG_File_Get_Path_Relative(SG_File_Get_Path(sFileName), sFiles.Get_String(i)); break; } sFilePath.Replace(SG_T("\\"), SG_T("/")); pDataset->Add_Property(SG_T("File"), sFilePath); pDataset->Add_Property(SG_T("Points"), pPC->Get_Point_Count()); pDataset->Add_Property(SG_T("ZMin"), pPC->Get_ZMin()); pDataset->Add_Property(SG_T("ZMax"), pPC->Get_ZMax()); //----------------------------------------------------- CSG_MetaData *pBBox = pDataset->Add_Child(SG_T("BBox")); pBBox->Add_Property(SG_T("XMin"), pPC->Get_Extent().Get_XMin()); pBBox->Add_Property(SG_T("YMin"), pPC->Get_Extent().Get_YMin()); pBBox->Add_Property(SG_T("XMax"), pPC->Get_Extent().Get_XMax()); pBBox->Add_Property(SG_T("YMax"), pPC->Get_Extent().Get_YMax()); if( dBBoxXMin > pPC->Get_Extent().Get_XMin() ) dBBoxXMin = pPC->Get_Extent().Get_XMin(); if( dBBoxYMin > pPC->Get_Extent().Get_YMin() ) dBBoxYMin = pPC->Get_Extent().Get_YMin(); if( dBBoxXMax < pPC->Get_Extent().Get_XMax() ) dBBoxXMax = pPC->Get_Extent().Get_XMax(); if( dBBoxYMax < pPC->Get_Extent().Get_YMax() ) dBBoxYMax = pPC->Get_Extent().Get_YMax(); iDatasetCount += 1; dPointCount += pPC->Get_Point_Count(); if( dZMin > pPC->Get_ZMin() ) dZMin = pPC->Get_ZMin(); if( dZMax < pPC->Get_ZMax() ) dZMax = pPC->Get_ZMax(); delete( pPC ); } //----------------------------------------------------- pSPCVFBBox->Add_Property(SG_T("XMin"), dBBoxXMin); pSPCVFBBox->Add_Property(SG_T("YMin"), dBBoxYMin); pSPCVFBBox->Add_Property(SG_T("XMax"), dBBoxXMax); pSPCVFBBox->Add_Property(SG_T("YMax"), dBBoxYMax); pSPCVFFiles->Add_Property(SG_T("Count"), iDatasetCount); pSPCVFPoints->Add_Property(SG_T("Count"), CSG_String::Format(SG_T("%.0f"), dPointCount)); pSPCVFZStats->Add_Property(SG_T("ZMin"), dZMin); pSPCVFZStats->Add_Property(SG_T("ZMax"), dZMax); //----------------------------------------------------- if( !SPCVF.Save(sFileName) ) { SG_UI_Msg_Add_Error(CSG_String::Format(_TL("Unable to save %s file!"), sFileName.c_str())); return( false ); } //----------------------------------------------------- if( iSkipped > 0 ) { SG_UI_Msg_Add(CSG_String::Format(_TL("WARNING: %d dataset(s) skipped because of incompatibilities!"), iSkipped), true); } if( iEmpty > 0 ) { SG_UI_Msg_Add(CSG_String::Format(_TL("WARNING: %d dataset(s) skipped because they are empty!"), iEmpty), true); } SG_UI_Msg_Add(CSG_String::Format(_TL("SPCVF successfully created from %d dataset(s)."), iDatasetCount), true); //----------------------------------------------------- return( true ); }