//--------------------------------------------------------- bool CSG_PointCloud::Assign(CSG_Data_Object *pObject) { if( pObject && pObject->is_Valid() && pObject->Get_ObjectType() == Get_ObjectType() ) { Destroy(); CSG_PointCloud *pPointCloud = (CSG_PointCloud *)pObject; Get_History() = pPointCloud->Get_History(); for(int iField=0; iField<pPointCloud->m_nFields; iField++) { _Add_Field(pPointCloud->m_Field_Name[iField]->c_str(), pPointCloud->m_Field_Type[iField]); } for(int iPoint=0; iPoint<pPointCloud->Get_Count(); iPoint++) { if( _Inc_Array() ) { memcpy(m_Points[iPoint] + 1, pPointCloud->m_Points[iPoint] + 1, m_nPointBytes - 1); } } return( true ); } return( false ); }
//--------------------------------------------------------- bool CPC_Drop_Attribute::On_After_Execution(void) { CSG_PointCloud *pOutput = Parameters("OUTPUT")->asPointCloud(); if( pOutput == NULL ) { pOutput = Parameters("INPUT")->asPointCloud(); } DataObject_Set_Parameter(pOutput, "DISPLAY_VALUE_AGGREGATE", 3); // highest z DataObject_Set_Parameter(pOutput, "METRIC_COLORS" , 12); // number of colors DataObject_Set_Parameter(pOutput, "COLORS_TYPE" , 3); // graduated color DataObject_Set_Parameter(pOutput, "METRIC_ATTRIB" , 2); // z attrib DataObject_Set_Parameter(pOutput, "METRIC_ZRANGE", pOutput->Get_Mean(2) - 2.0 * pOutput->Get_StdDev(2), pOutput->Get_Mean(2) + 2.0 * pOutput->Get_StdDev(2) ); DataObject_Set_Colors(pOutput, 11, SG_COLORS_RAINBOW); if( pOutput == Parameters("INPUT")->asPointCloud() ) { Parameters("OUTPUT")->Set_Value(DATAOBJECT_NOTSET); } return( true ); }
//--------------------------------------------------------- bool CPC_From_Shapes::On_Execute(void) { int zField, iField, nFields, *Fields; CSG_PointCloud *pPoints; CSG_Shapes *pShapes; pShapes = Parameters("SHAPES") ->asShapes(); pPoints = Parameters("POINTS") ->asPointCloud(); zField = Parameters("ZFIELD") ->asInt(); if( !pShapes->is_Valid() ) { return( false ); } //----------------------------------------------------- pPoints->Create(); pPoints->Set_Name(pShapes->Get_Name()); nFields = 0; Fields = new int[pShapes->Get_Field_Count()]; if( Parameters("OUTPUT")->asInt() == 1 ) { for(iField=0, nFields=0; iField<pShapes->Get_Field_Count(); iField++) { if( iField != zField && SG_Data_Type_Get_Size(pShapes->Get_Field_Type(iField)) > 0 ) { Fields[nFields++] = iField; pPoints->Add_Field(pShapes->Get_Field_Name(iField), pShapes->Get_Field_Type(iField)); } } } //----------------------------------------------------- for(int iShape=0; iShape<pShapes->Get_Count() && Set_Progress(iShape, pShapes->Get_Count()); iShape++) { CSG_Shape *pShape = pShapes->Get_Shape(iShape); for(int iPart=0; iPart<pShape->Get_Part_Count(); iPart++) { for(int iPoint=0; iPoint<pShape->Get_Point_Count(iPart); iPoint++) { TSG_Point p = pShape->Get_Point(iPoint, iPart); pPoints->Add_Point(p.x, p.y, zField < 0 ? pShape->Get_Z(iPoint, iPart) : pShape->asDouble(zField)); for(iField=0; iField<nFields; iField++) { pPoints->Set_Value(3 + iField, pShape->asDouble(Fields[iField])); } } } } //----------------------------------------------------- delete [] Fields; return( pPoints->Get_Count() > 0 ); }
bool CSG_PointCloud::Create(const CSG_PointCloud &PointCloud) { if( Assign((CSG_Data_Object *)&PointCloud) ) { Set_Name(PointCloud.Get_Name()); return( true ); } return( false ); }
//--------------------------------------------------------- bool CPoints_View_Module::On_Execute(void) { if( !SG_UI_Get_Window_Main() ) { Message_Add(_TL("point cloud viewer can only be run from graphical user interface")); return( false ); } CSG_PointCloud *pPoints = Parameters("POINTS")->asPointCloud(); if( pPoints->Get_Count() <= 0 ) { Message_Add(_TL("point cloud viewer will not be started, because point cloud has no points")); return( false ); } CPoints_View_Dialog dlg(pPoints); dlg.ShowModal(); return( true ); }
//--------------------------------------------------------- bool CResection::On_Execute(void) { CSG_PointCloud *pPoints; // Input Point Cloud CSG_String fileName; CSG_File *pTabStream = NULL; int n = 6; // Number of unknowns CSG_Vector center(3); CSG_Vector target(3); double c = Parameters("F") ->asDouble(); // Focal Length (mm) double pixWmm = Parameters("W") ->asDouble() / 1000;// Pixel Width (mm) double ppOffsetX = Parameters("ppX") ->asDouble(); // Principal Point Offset X (pixels) double ppOffsetY = Parameters("ppY") ->asDouble(); // Principal Point Offset Y (pixels) pPoints = Parameters("POINTS") ->asPointCloud(); fileName = Parameters("OUTPUT FILE") ->asString(); center[0] = Parameters("Xc") ->asDouble(); center[1] = Parameters("Yc") ->asDouble(); center[2] = Parameters("Zc") ->asDouble(); target[0] = Parameters("Xt") ->asDouble(); target[1] = Parameters("Yt") ->asDouble(); target[2] = Parameters("Zt") ->asDouble(); int pointCount = pPoints->Get_Point_Count(); bool estPPOffsets = false; if ( Parameters("EST_OFFSETS")->asBool() ) { estPPOffsets = true; n = 8; // Increase number of unknowns by 2 } bool applyDistortions = false; CSG_Vector K(3); if ( Parameters("GIVE_DISTORTIONS")->asBool() ) { applyDistortions = true; K[0] = Parameters("K1") ->asDouble(); K[1] = Parameters("K2") ->asDouble(); K[2] = Parameters("K3") ->asDouble(); } double dxapp = center [0] - target [0]; double dyapp = center [1] - target [1]; double dzapp = center [2] - target [2]; double h_d = sqrt (dxapp * dxapp + dyapp * dyapp + dzapp * dzapp); // Distance between Proj. Center & Target (m) double h_dmm = h_d * 1000; // Convert to mm if( fileName.Length() == 0 ) { SG_UI_Msg_Add_Error(_TL("Please provide an output file name!")); 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); } CSG_Vector rotns = methods::calcRotations(center,target); // Approx. rotations omega, kappa, alpha CSG_String msg = "********* Initial Approximate Values *********"; pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("Rotation Angles:"); pTabStream->Write(SG_T("\n") + msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("Omega:\t") + SG_Get_String(rotns[0],6,false); pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("Kappa:\t") + SG_Get_String(rotns[1],6,false); pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("Alpha:\t") + SG_Get_String(rotns[2],6,false); pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("Projection Center:"); pTabStream->Write(SG_T("\n") + msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("Xc:\t") + SG_Get_String(center[0],4,false); pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("Yc:\t") + SG_Get_String(center[1],4,false); pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("Zc:\t") + SG_Get_String(center[2],4,false); pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); if (estPPOffsets) { msg = SG_T("Principal Point Offsets:"); pTabStream->Write(SG_T("\n") + msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("ppX:\t") + SG_Get_String(ppOffsetX,5,false); pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("ppY:\t") + SG_Get_String(ppOffsetY,5,false); pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); } double itrNo = 0; CSG_Matrix invN; while (true) { // Begin Iterations itrNo++; double omega = rotns[0]; double kappa = rotns[1]; double alpha = rotns[2]; CSG_Matrix R = methods::calcRotnMatrix(rotns); // Rotation Matrix from approximate values CSG_Matrix E(3,3); // [w1;w2;w3] = E * [dw;dk;da] E[0][0] = -1; E[0][1] = E[1][0] = E[2][0] = 0; E[0][2] = sin(kappa); E[1][1] = -cos(omega); E[1][2] = -sin(omega) * cos(kappa); E[2][1] = sin(omega); E[2][2] = -cos(omega) * cos(kappa); CSG_Matrix N(n,n); // Transpose(Design Matrix) * I * Design Matrix CSG_Vector ATL(n); // Transpose(Design Matrix) * I * Shortened obs. vector double SS = 0; double sigma_naught = 0; for (int i = 0; i < pointCount; i++) { CSG_Vector pqs(3); // Approx. pi, qi, si for (int j = 0; j < 3; j++) { pqs[j] = R[j][0] * (pPoints->Get_X(i) - center[0]) + R[j][1] * (pPoints->Get_Y(i) - center[1]) + R[j][2] * (pPoints->Get_Z(i) - center[2]); } double p_i = pqs[0]; double q_i = pqs[1]; double s_i = pqs[2]; double dR = 0; // Undistorted double x_u = c * p_i / q_i; double y_u = c * s_i / q_i; double c_hat = c; if (applyDistortions) { double r2 = x_u * x_u + y_u * y_u; dR = K[0] * r2 + K[1] * r2 * r2 + K[2] * r2 * r2 * r2; c_hat = c * (1 - dR); } // Approx. image coordinates (with distortions) double x_i = (1 - dR) * x_u + ppOffsetX * pixWmm; double z_i = (1 - dR) * y_u + ppOffsetY * pixWmm; // Shortened obervation vector: dxi & dzi double dx_i = pPoints->Get_Attribute(i,0) * pixWmm - x_i; double dz_i = pPoints->Get_Attribute(i,1) * pixWmm - z_i; SS += pow(dx_i,2) + pow(dz_i,2); /* x_i, z_i in [mm] p_i,q_i,s_i in [m] h_d in [m] c, c_hat in [mm] h_dmm in [mm] */ CSG_Matrix L(3,2); // CSG_Matrix takes columns first and rows second CSG_Matrix V(3,3); CSG_Matrix LR(3,2); CSG_Matrix LVE(3,2); L[0][0] = L[1][2] = c_hat / (1000 * q_i); L[0][2] = L[1][0] = 0; L[0][1] = -x_u * (1 - dR) / (1000 * q_i); L[1][1] = -y_u * (1 - dR) / (1000 * q_i); V[0][0] = V[1][1] = V[2][2] = 0; V[0][1] = s_i / h_d; V[0][2] = -q_i / h_d; V[1][0] = -s_i / h_d; V[1][2] = p_i / h_d; V[2][0] = q_i / h_d; V[2][1] = -p_i / h_d; LVE = ( L * V ) * E; LR = L * R; // Design Matrix (J) CSG_Matrix design(n,2); for(int j = 0; j < 2; j++) { for(int k = 0; k < 3; k++) { design[j][k] = LVE[j][k]; design[j][k+3] = -LR[j][k]; } } if ( estPPOffsets ) { design[0][6] = design[1][7] = 1.0; } // Build Normal Matrix for(int j = 0; j < n; j++) { for(int k = 0; k < n; k++) { N[j][k] += (design[0][j] * design[0][k] + design[1][j] * design[1][k]); } } // Build Tranpose (J) * I * (Shortened obs. vector) for (int m=0; m < n; m++) { ATL[m] += design[0][m] * dx_i + design[1][m] * dz_i; } L.Destroy(); V.Destroy(); LR.Destroy(); LVE.Destroy(); pqs.Destroy(); design.Destroy(); } // end looping over observations // Eigen values and Eigen Vectors CSG_Vector eigenVals(n); CSG_Matrix eigenVecs(n,n); SG_Matrix_Eigen_Reduction(N, eigenVecs, eigenVals, true); // One of the Eigen Values is 0 if (std::any_of(eigenVals.cbegin(), eigenVals.cend(), [] (double i) { return i == 0; })) { msg = "The Normal Matrix has a rank defect. Please measure more points."; pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); break; } double mx = *std::max_element(eigenVals.cbegin(), eigenVals.cend()); double mn = *std::min_element(eigenVals.cbegin(), eigenVals.cend()); // Ratio of Smallest to the Biggest Eigen value is too small if ((mn / mx) < pow(10,-12.0)) { msg = SG_T("Condition of the Matrix of Normal Equations:\t") + CSG_String::Format(SG_T(" %13.5e"), mn/mx); pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = "The Normal Matrix is weakly conditioned. Please measure more points."; pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); break; } // Calculate the adjustments double absMax = 0; invN = N.Get_Inverse(); CSG_Vector est_param_incs = invN * ATL; for (int i = 0; i < n; i++) { if (abs(est_param_incs[i]) > absMax) { absMax = abs(est_param_incs[i]); } } if (absMax < thresh) { msg = "Solution has converged."; pTabStream->Write(SG_T("\n") + msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); break; } for (int a = 0; a < 3; a++) { rotns[a] += est_param_incs[a] / h_dmm; // New Approx. rotations omega, kappa, alpha center[a] += est_param_incs[a+3] / 1000; // New Approx. Projection Center } if ( estPPOffsets ) { ppOffsetX += (est_param_incs[6] / pixWmm); // New Approx. Principal Point ppOffsetY += (est_param_incs[7] / pixWmm); } sigma_naught = sqrt(SS / (2 * pointCount - n)); // Writing To Output File & SAGA Console msg = "********* Iteration: " + SG_Get_String(itrNo,0,false) + " *********"; pTabStream->Write(SG_T("\n") + msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = "Sum of Squared Residuals:\t" + SG_Get_String(SS,5,false); pTabStream->Write(SG_T("\n") + msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = "Sigma Naught:\t" + SG_Get_String(sigma_naught,5,false); pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("Condition of the Matrix of Normal Equations:\t") + CSG_String::Format(SG_T(" %13.5e"), mn/mx); pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); R.Destroy(); E.Destroy(); N.Destroy(); ATL.Destroy(); invN.Destroy(); eigenVals.Destroy(); eigenVecs.Destroy(); est_param_incs.Destroy(); } // end of iterations msg = "********* Final Estimated Parameters *********"; pTabStream->Write(SG_T("\n") + msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("Rotation Angles:"); pTabStream->Write(SG_T("\n") + msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("Omega:\t") + SG_Get_String(rotns[0],6,false); pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("Kappa:\t") + SG_Get_String(rotns[1],6,false); pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("Alpha:\t") + SG_Get_String(rotns[2],6,false); pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("Projection Center:"); pTabStream->Write(SG_T("\n") + msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("Xc:\t") + SG_Get_String(center[0],4,false); pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("Yc:\t") + SG_Get_String(center[1],4,false); pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("Zc:\t") + SG_Get_String(center[2],4,false); pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); if (estPPOffsets) { msg = SG_T("Principal Point Offsets:"); pTabStream->Write(SG_T("\n") + msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("ppX:\t") + SG_Get_String(ppOffsetX,5,false); pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); msg = SG_T("ppY:\t") + SG_Get_String(ppOffsetY,5,false); pTabStream->Write(msg + SG_T("\n")); SG_UI_Msg_Add(msg, true); } K.Destroy(); rotns.Destroy(); center.Destroy(); target.Destroy(); pTabStream->Close(); return true; }
//--------------------------------------------------------- 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 CSTL_Import::On_Execute(void) { int Method; DWORD iFacette, nFacettes; TSTL_Point p[3]; CSG_String sFile, sHeader; CSG_File Stream; //----------------------------------------------------- sFile = Parameters("FILE") ->asString(); Method = Parameters("METHOD") ->asInt(); r_sin_x = sin(Parameters("ROT_X")->asDouble() * M_DEG_TO_RAD); r_sin_y = sin(Parameters("ROT_Y")->asDouble() * M_DEG_TO_RAD); r_sin_z = sin(Parameters("ROT_Z")->asDouble() * M_DEG_TO_RAD); r_cos_x = cos(Parameters("ROT_X")->asDouble() * M_DEG_TO_RAD); r_cos_y = cos(Parameters("ROT_Y")->asDouble() * M_DEG_TO_RAD); r_cos_z = cos(Parameters("ROT_Z")->asDouble() * M_DEG_TO_RAD); //----------------------------------------------------- if( !Stream.Open(sFile) ) { return( false ); } if( !Stream.Read(sHeader, 80) ) { return( false ); } Message_Add(sHeader); if( !Stream.Read(&nFacettes, sizeof(nFacettes)) ) { return( false ); } Message_Add(CSG_String::Format(SG_T("%s: %d"), _TL("Number of Facettes"), nFacettes)); //----------------------------------------------------- switch( Method ) { //----------------------------------------------------- case 0: { // Point Cloud CSG_Rect Extent; if( Get_Extent(Stream, Extent, nFacettes) ) { CSG_PRQuadTree Points(Extent); CSG_PointCloud *pPoints = SG_Create_PointCloud(); Parameters("POINTS")->Set_Value(pPoints); pPoints->Set_Name(SG_File_Get_Name(sFile, false)); pPoints->Add_Field((const char *)NULL, SG_DATATYPE_Undefined); for(iFacette=0; iFacette<nFacettes && !Stream.is_EOF() && Set_Progress(iFacette, nFacettes); iFacette++) { if( Read_Facette(Stream, p) ) { for(int i=0; i<3; i++) { if( Points.Add_Point(p[i].x, p[i].y, p[i].z) ) { pPoints->Add_Point(p[i].x, p[i].y, p[i].z); } } } } } break; } //----------------------------------------------------- case 1: { // Point Cloud (centered) CSG_PointCloud *pPoints = SG_Create_PointCloud(); Parameters("POINTS")->Set_Value(pPoints); pPoints->Set_Name(SG_File_Get_Name(sFile, false)); pPoints->Add_Field((const char *)NULL, SG_DATATYPE_Undefined); for(iFacette=0; iFacette<nFacettes && !Stream.is_EOF() && Set_Progress(iFacette, nFacettes); iFacette++) { if( Read_Facette(Stream, p) ) { pPoints->Add_Point( (p[0].x + p[1].x + p[2].x) / 3.0, (p[0].y + p[1].y + p[2].y) / 3.0, (p[0].z + p[1].z + p[2].z) / 3.0 ); } } break; } //----------------------------------------------------- case 2: { // Points CSG_Shapes *pPoints = SG_Create_Shapes(SHAPE_TYPE_Point, SG_File_Get_Name(sFile, false)); pPoints->Add_Field(SG_T("Z"), SG_DATATYPE_Float); Parameters("SHAPES")->Set_Value(pPoints); for(iFacette=0; iFacette<nFacettes && !Stream.is_EOF() && Set_Progress(iFacette, nFacettes); iFacette++) { if( Read_Facette(Stream, p) ) { CSG_Shape *pPoint = pPoints->Add_Shape(); pPoint->Add_Point( (p[0].x + p[1].x + p[2].x) / 3.0, (p[0].y + p[1].y + p[2].y) / 3.0 ); pPoint->Set_Value(0, (p[0].z + p[1].z + p[2].z) / 3.0 ); } } break; } //----------------------------------------------------- case 3: { // Raster CSG_Rect Extent; if( Get_Extent(Stream, Extent, nFacettes) ) { int nx, ny; double d; nx = Parameters("GRID_RES")->asInt(); d = Extent.Get_XRange() / nx; ny = 1 + (int)(Extent.Get_YRange() / d); m_pGrid = SG_Create_Grid(SG_DATATYPE_Float, nx, ny, d, Extent.Get_XMin(), Extent.Get_YMin()); m_pGrid->Set_Name(SG_File_Get_Name(sFile, false)); m_pGrid->Set_NoData_Value(-99999); m_pGrid->Assign_NoData(); Parameters("GRID")->Set_Value(m_pGrid); //--------------------------------------------- for(iFacette=0; iFacette<nFacettes && !Stream.is_EOF() && Set_Progress(iFacette, nFacettes); iFacette++) { if( Read_Facette(Stream, p) ) { TSG_Point_Z Point[3]; for(int i=0; i<3; i++) { Point[i].x = (p[i].x - m_pGrid->Get_XMin()) / m_pGrid->Get_Cellsize(); Point[i].y = (p[i].y - m_pGrid->Get_YMin()) / m_pGrid->Get_Cellsize(); Point[i].z = p[i].z; } Set_Triangle(Point); } } } break; } } //----------------------------------------------------- return( true ); }
//--------------------------------------------------------- bool CPointCloud_From_Text_File::On_Execute(void) { CSG_String fileName; int iField, iType; TSG_Data_Type Type; CSG_String Name, Types, s; CSG_PointCloud *pPoints; CSG_Parameters P; CSG_Parameter *pNode; int xField, yField, zField, nAttribs, max_iField; bool bSkipHeader; char fieldSep; std::vector<int> vCol; std::ifstream tabStream; std::string tabLine; double lines; long cntPt, cntInvalid; double x, y, z, value; //----------------------------------------------------- fileName = Parameters("FILE") ->asString(); xField = Parameters("XFIELD") ->asInt() - 1; yField = Parameters("YFIELD") ->asInt() - 1; zField = Parameters("ZFIELD") ->asInt() - 1; nAttribs = Parameters("ATTRIBS") ->asInt(); bSkipHeader = Parameters("SKIP_HEADER") ->asBool(); switch (Parameters("FIELDSEP")->asInt()) { default: case 0: fieldSep = '\t'; break; case 1: fieldSep = ' '; break; case 2: fieldSep = ','; break; } Types.Printf(SG_T("%s|%s|%s|%s|%s|"), _TL("1 byte integer"), _TL("2 byte integer"), _TL("4 byte integer"), _TL("4 byte floating point"), _TL("8 byte floating point") ); P.Set_Name(_TL("Attribute Field Properties")); for(iField=1; iField<=nAttribs; iField++) { s.Printf(SG_T("NODE_%03d") , iField); pNode = P.Add_Node(NULL, s, CSG_String::Format(SG_T("%d. %s"), iField, _TL("Field")), _TL("")); s.Printf(SG_T("FIELD_%03d"), iField); P.Add_String(pNode, s, _TL("Name"), _TL(""), s); s.Printf(SG_T("COLUMN_%03d"), iField); P.Add_Value(pNode, s, _TL("Attribute is Column ..."), _TL(""), PARAMETER_TYPE_Int, iField+3, 1, true); s.Printf(SG_T("TYPE_%03d") , iField); P.Add_Choice(pNode, s, _TL("Type"), _TL(""), Types, 3); } //----------------------------------------------------- if( nAttribs > 0 ) { if( Dlg_Parameters(&P, _TL("Field Properties")) ) { pPoints = SG_Create_PointCloud(); pPoints->Set_Name(SG_File_Get_Name(fileName, false)); Parameters("POINTS")->Set_Value(pPoints); for(iField=0; iField<nAttribs; iField++) { Name = P(CSG_String::Format(SG_T("FIELD_%03d" ), iField + 1).c_str())->asString(); iType = P(CSG_String::Format(SG_T("TYPE_%03d" ), iField + 1).c_str())->asInt(); vCol.push_back(P(CSG_String::Format(SG_T("COLUMN_%03d"), iField + 1).c_str())->asInt() - 1); switch( iType ) { default: case 0: Type = SG_DATATYPE_Char; break; case 1: Type = SG_DATATYPE_Short; break; case 2: Type = SG_DATATYPE_Int; break; case 3: Type = SG_DATATYPE_Float; break; case 4: Type = SG_DATATYPE_Double; break; } pPoints->Add_Field(Name, Type); } } else return( false ); } else { pPoints = SG_Create_PointCloud(); pPoints->Create(); pPoints->Set_Name(SG_File_Get_Name(fileName, false)); Parameters("POINTS")->Set_Value(pPoints); } max_iField = M_GET_MAX(xField, yField); max_iField = M_GET_MAX(max_iField, zField); for( unsigned int i=0; i<vCol.size(); i++ ) { if( max_iField < vCol.at(i) ) max_iField = vCol.at(i); } // open input stream //--------------------------------------------------------- tabStream.open(fileName.b_str(), std::ifstream::in); if( !tabStream ) { SG_UI_Msg_Add_Error(CSG_String::Format(_TL("Unable to open input file!"))); return (false); } tabStream.seekg(0, std::ios::end); // get length of file lines = (double)tabStream.tellg(); tabStream.seekg(0, std::ios::beg); std::getline(tabStream, tabLine); // as a workaround we assume the number of lines from the length of the first line lines = lines / (double)tabStream.tellg(); if( !bSkipHeader ) { tabStream.clear(); // let's forget we may have reached the EOF tabStream.seekg(0, std::ios::beg); // and rewind to the beginning } // import //--------------------------------------------------------- cntPt = cntInvalid = 0; SG_UI_Process_Set_Text(CSG_String::Format(_TL("Importing data ..."))); while( std::getline(tabStream, tabLine) ) { std::istringstream stream(tabLine); std::vector<std::string> tabCols; std::string tabEntry; if( cntPt%10000 == 0 ) SG_UI_Process_Set_Progress((double)cntPt, lines); cntPt++; while( std::getline(stream, tabEntry, fieldSep) ) // read every column in this line and fill vector { if (tabEntry.length() == 0) continue; tabCols.push_back(tabEntry); } if ((int)tabCols.size() < max_iField - 1 ) { SG_UI_Msg_Add(CSG_String::Format(_TL("WARNING: Skipping misformatted line (%.0f)!"), cntPt), true); cntInvalid++; continue; } x = strtod(tabCols[xField].c_str(), NULL); y = strtod(tabCols[yField].c_str(), NULL); z = strtod(tabCols[zField].c_str(), NULL); pPoints->Add_Point(x, y, z); for( int i=0; i<nAttribs; i++ ) { value = strtod(tabCols.at(vCol.at(i)).c_str(), NULL); pPoints->Set_Attribute(i, value); } } // finalize //--------------------------------------------------------- tabStream.close(); CSG_Parameters sParms; DataObject_Get_Parameters(pPoints, sParms); if (sParms("COLORS_ATTRIB") && sParms("COLORS_TYPE") && sParms("METRIC_COLORS") && sParms("METRIC_ZRANGE") && sParms("COLORS_AGGREGATE")) { sParms("COLORS_AGGREGATE")->Set_Value(3); // highest z sParms("COLORS_TYPE")->Set_Value(2); // graduated color sParms("METRIC_COLORS")->asColors()->Set_Count(255); // number of colors sParms("COLORS_ATTRIB")->Set_Value(2); // z attrib sParms("METRIC_ZRANGE")->asRange()->Set_Range(pPoints->Get_Minimum(2),pPoints->Get_Maximum(2)); DataObject_Set_Parameters(pPoints, sParms); DataObject_Update(pPoints); } if (cntInvalid > 0) SG_UI_Msg_Add(CSG_String::Format(_TL("WARNING: Skipped %d invalid points!"), cntInvalid), true); SG_UI_Msg_Add(CSG_String::Format(_TL("%d points sucessfully imported."), (cntPt-cntInvalid)), true); return( true ); }
//--------------------------------------------------------- bool CPointCloud_From_Text_File::On_Execute(void) { CSG_String fileName; int iField, iType; CSG_String Name, Types, s; CSG_PointCloud *pPoints; CSG_Parameters P; CSG_Parameter *pNode; int xField, yField, zField, nAttribs; bool bSkipHeader; char fieldSep; std::vector<int> vCol; std::ifstream tabStream; std::string tabLine; double lines; long cntPt, cntInvalid; double x, y, z; //----------------------------------------------------- fileName = Parameters("FILE") ->asString(); xField = Parameters("XFIELD") ->asInt() - 1; yField = Parameters("YFIELD") ->asInt() - 1; zField = Parameters("ZFIELD") ->asInt() - 1; bSkipHeader = Parameters("SKIP_HEADER") ->asBool(); switch (Parameters("FIELDSEP")->asInt()) { default: case 0: fieldSep = '\t'; break; case 1: fieldSep = ' '; break; case 2: fieldSep = ','; break; } pPoints = SG_Create_PointCloud(); pPoints->Create(); pPoints->Set_Name(SG_File_Get_Name(fileName, false)); Parameters("POINTS")->Set_Value(pPoints); DataObject_Add(pPoints); //----------------------------------------------------- if (SG_UI_Get_Window_Main()) { nAttribs = Parameters("ATTRIBS") ->asInt(); Types.Printf(SG_T("%s|%s|%s|%s|%s|"), _TL("1 byte integer"), _TL("2 byte integer"), _TL("4 byte integer"), _TL("4 byte floating point"), _TL("8 byte floating point") ); P.Set_Name(_TL("Attribute Field Properties")); for(iField=1; iField<=nAttribs; iField++) { s.Printf(SG_T("NODE_%03d") , iField); pNode = P.Add_Node(NULL, s, CSG_String::Format(SG_T("%d. %s"), iField, _TL("Field")), _TL("")); s.Printf(SG_T("FIELD_%03d"), iField); P.Add_String(pNode, s, _TL("Name"), _TL(""), s); s.Printf(SG_T("COLUMN_%03d"), iField); P.Add_Value(pNode, s, _TL("Attribute is Column ..."), _TL(""), PARAMETER_TYPE_Int, iField+3, 1, true); s.Printf(SG_T("TYPE_%03d") , iField); P.Add_Choice(pNode, s, _TL("Type"), _TL(""), Types, 3); } //----------------------------------------------------- if( nAttribs > 0 ) { if( Dlg_Parameters(&P, _TL("Field Properties")) ) { for(iField=0; iField<nAttribs; iField++) { Name = P(CSG_String::Format(SG_T("FIELD_%03d" ), iField + 1).c_str())->asString(); iType = P(CSG_String::Format(SG_T("TYPE_%03d" ), iField + 1).c_str())->asInt(); vCol.push_back(P(CSG_String::Format(SG_T("COLUMN_%03d"), iField + 1).c_str())->asInt() - 1); pPoints->Add_Field(Name, Get_Data_Type(iType)); } } else return( false ); } } else // CMD { CSG_String sFields, sNames, sTypes; CSG_String token; int iValue; std::vector<int> vTypes; sFields = Parameters("FIELDS")->asString(); sNames = Parameters("FIELDNAMES")->asString(); sTypes = Parameters("FIELDTYPES")->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 < 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_datatypes(sTypes, ";", SG_TOKEN_STRTOK); while( tkz_datatypes.Has_More_Tokens() ) { token = tkz_datatypes.Get_Next_Token(); if( token.Length() == 0 ) break; if( !token.asInt(iValue) ) { SG_UI_Msg_Add_Error(_TL("Error parsing field type: can't convert to number")); return( false ); } vTypes.push_back(iValue); } CSG_String_Tokenizer tkz_datanames(sNames, ";", SG_TOKEN_STRTOK); int iter = 0; while( tkz_datanames.Has_More_Tokens() ) { token = tkz_datanames.Get_Next_Token(); if( token.Length() == 0 ) break; pPoints->Add_Field(token, Get_Data_Type(vTypes.at(iter))); iter++; } if( vCol.size() != vTypes.size() || (int)vCol.size() != iter ) { SG_UI_Msg_Add_Error(CSG_String::Format(_TL("Number of arguments for attribute fields (%d), names (%d) and types (%d) do not match!"), vCol.size(), iter, vTypes.size())); return( false ); } } // open input stream //--------------------------------------------------------- tabStream.open(fileName.b_str(), std::ifstream::in); if( !tabStream ) { SG_UI_Msg_Add_Error(CSG_String::Format(_TL("Unable to open input file!"))); return (false); } tabStream.seekg(0, std::ios::end); // get length of file lines = (double)tabStream.tellg(); tabStream.seekg(0, std::ios::beg); std::getline(tabStream, tabLine); // as a workaround we assume the number of lines from the length of the first line lines = lines / (double)tabStream.tellg(); if( !bSkipHeader ) { tabStream.clear(); // let's forget we may have reached the EOF tabStream.seekg(0, std::ios::beg); // and rewind to the beginning } // import //--------------------------------------------------------- cntPt = cntInvalid = 0; SG_UI_Process_Set_Text(CSG_String::Format(_TL("Importing data ..."))); while( std::getline(tabStream, tabLine) ) { std::istringstream stream(tabLine); std::vector<std::string> tabCols; std::string tabEntry; if( cntPt%10000 == 0 ) { SG_UI_Process_Set_Progress((double)cntPt, lines); } cntPt++; while( std::getline(stream, tabEntry, fieldSep) ) // read every column in this line and fill vector { if (tabEntry.length() == 0) continue; tabCols.push_back(tabEntry); } if ((int)tabCols.size() < (vCol.size() + 3) ) { SG_UI_Msg_Add(CSG_String::Format(_TL("WARNING: Skipping misformatted line: %d!"), cntPt), true); cntInvalid++; continue; } //parse line tokens std::vector<double> fieldValues; fieldValues.resize(vCol.size()); x = strtod(tabCols[xField].c_str(), NULL); y = strtod(tabCols[yField].c_str(), NULL); z = strtod(tabCols[zField].c_str(), NULL); for( int i=0; i<(int)vCol.size(); i++ ) { fieldValues[i] = strtod(tabCols.at(vCol.at(i)).c_str(), NULL); } pPoints->Add_Point(x, y, z); for( int i=0; i<(int)vCol.size(); i++ ) { pPoints->Set_Attribute(i, fieldValues[i]); } } // finalize //--------------------------------------------------------- tabStream.close(); CSG_Parameters sParms; DataObject_Get_Parameters(pPoints, sParms); if (sParms("METRIC_ATTRIB") && sParms("COLORS_TYPE") && sParms("METRIC_COLORS") && sParms("METRIC_ZRANGE") && sParms("DISPLAY_VALUE_AGGREGATE")) { sParms("DISPLAY_VALUE_AGGREGATE")->Set_Value(3); // highest z sParms("COLORS_TYPE")->Set_Value(2); // graduated color sParms("METRIC_COLORS")->asColors()->Set_Count(255); // number of colors sParms("METRIC_ATTRIB")->Set_Value(2); // z attrib sParms("METRIC_ZRANGE")->asRange()->Set_Range(pPoints->Get_Minimum(2),pPoints->Get_Maximum(2)); DataObject_Set_Parameters(pPoints, sParms); DataObject_Update(pPoints); } if (cntInvalid > 0) SG_UI_Msg_Add(CSG_String::Format(SG_T("%s: %d %s"), _TL("WARNING"), cntInvalid, _TL("invalid points have been skipped")), true); SG_UI_Msg_Add(CSG_String::Format(SG_T("%d %s"), (cntPt-cntInvalid), _TL("points have been imported with success")), true); return( true ); }
//--------------------------------------------------------- bool CLAS_Import::On_Execute(void) { CSG_Parameter_PointCloud_List *pPointsList; bool bValidity; CSG_Strings Files; int RGBrange; int cntInvalid = 0; bValidity = Parameters("VALID")->asBool(); RGBrange = Parameters("RGB_RANGE")->asInt(); //----------------------------------------------------- if( !Parameters("FILES")->asFilePath()->Get_FilePaths(Files) ) { return( false ); } //----------------------------------------------------- pPointsList = Parameters("POINTS")->asPointCloudList(); pPointsList ->Del_Items(); for(int i=0; i<Files.Get_Count(); i++) { SG_UI_Msg_Add(CSG_String::Format(_TL("Parsing %s ... "), SG_File_Get_Name(Files[i], true).c_str()), true); std::ifstream ifs; ifs.open(Files[i].b_str(), std::ios::in | std::ios::binary); if( !ifs ) { SG_UI_Msg_Add_Error(CSG_String::Format(_TL("Unable to open LAS file!"))); continue; } //----------------------------------------------------- // Check if LAS version is supported liblas::LASReader *pReader; try { pReader = new liblas::LASReader(ifs); } catch(std::exception &e) { SG_UI_Msg_Add_Error(CSG_String::Format(_TL("LAS header exception: %s"), e.what())); ifs.close(); return( false ); } catch(...) { SG_UI_Msg_Add_Error(CSG_String::Format(_TL("Unknown LAS header exception!"))); ifs.close(); return( false ); } delete (pReader); ifs.clear(); //----------------------------------------------------- liblas::LASReader reader(ifs); liblas::LASHeader const& header = reader.GetHeader(); //----------------------------------------------------- int nFields, iField[VAR_Count]; CSG_PointCloud *pPoints = SG_Create_PointCloud(); pPoints->Set_Name(SG_File_Get_Name(Files[i], false)); nFields = 3; ADD_FIELD("T", VAR_T, _TL("gps-time") , SG_DATATYPE_Double); // SG_DATATYPE_Long ADD_FIELD("i", VAR_i, _TL("intensity") , SG_DATATYPE_Float); // SG_DATATYPE_Word ADD_FIELD("a", VAR_a, _TL("scan angle") , SG_DATATYPE_Float); // SG_DATATYPE_Byte ADD_FIELD("r", VAR_r, _TL("number of the return") , SG_DATATYPE_Int); ADD_FIELD("c", VAR_c, _TL("classification") , SG_DATATYPE_Int); // SG_DATATYPE_Byte ADD_FIELD("u", VAR_u, _TL("user data") , SG_DATATYPE_Double); // SG_DATATYPE_Byte ADD_FIELD("n", VAR_n, _TL("number of returns of given pulse") , SG_DATATYPE_Int); ADD_FIELD("R", VAR_R, _TL("red channel color") , SG_DATATYPE_Int); // SG_DATATYPE_Word ADD_FIELD("G", VAR_G, _TL("green channel color") , SG_DATATYPE_Int); ADD_FIELD("B", VAR_B, _TL("blue channel color") , SG_DATATYPE_Int); ADD_FIELD("e", VAR_e, _TL("edge of flight line flag") , SG_DATATYPE_Char); ADD_FIELD("d", VAR_d, _TL("direction of scan flag") , SG_DATATYPE_Char); ADD_FIELD("p", VAR_p, _TL("point source ID") , SG_DATATYPE_Int); // SG_DATATYPE_Word ADD_FIELD("C", VAR_C, _TL("rgb color") , SG_DATATYPE_Int); //----------------------------------------------------- int iPoint = 0; try { while( reader.ReadNextPoint() ) { if (iPoint % 100000) SG_UI_Process_Set_Progress(iPoint, header.GetPointRecordsCount()); liblas::LASPoint const& point = reader.GetPoint(); if( bValidity ) { if( !point.IsValid() ) { cntInvalid++; continue; } } pPoints->Add_Point(point.GetX(), point.GetY(), point.GetZ()); if( iField[VAR_T] > 0 ) pPoints->Set_Value(iPoint, iField[VAR_T], point.GetTime()); if( iField[VAR_i] > 0 ) pPoints->Set_Value(iPoint, iField[VAR_i], point.GetIntensity()); if( iField[VAR_a] > 0 ) pPoints->Set_Value(iPoint, iField[VAR_a], point.GetScanAngleRank()); if( iField[VAR_r] > 0 ) pPoints->Set_Value(iPoint, iField[VAR_r], point.GetReturnNumber()); if( iField[VAR_c] > 0 ) pPoints->Set_Value(iPoint, iField[VAR_c], point.GetClassification()); if( iField[VAR_u] > 0 ) pPoints->Set_Value(iPoint, iField[VAR_u], point.GetUserData()); if( iField[VAR_n] > 0 ) pPoints->Set_Value(iPoint, iField[VAR_n], point.GetNumberOfReturns()); if( iField[VAR_R] > 0 ) pPoints->Set_Value(iPoint, iField[VAR_R], point.GetColor().GetRed()); if( iField[VAR_G] > 0 ) pPoints->Set_Value(iPoint, iField[VAR_G], point.GetColor().GetGreen()); if( iField[VAR_B] > 0 ) pPoints->Set_Value(iPoint, iField[VAR_B], point.GetColor().GetBlue()); if( iField[VAR_e] > 0 ) pPoints->Set_Value(iPoint, iField[VAR_e], point.GetFlightLineEdge()); if( iField[VAR_d] > 0 ) pPoints->Set_Value(iPoint, iField[VAR_d], point.GetScanDirection()); if( iField[VAR_p] > 0 ) pPoints->Set_Value(iPoint, iField[VAR_p], point.GetPointSourceID()); if( iField[VAR_C] > 0 ) { double r, g, b; r = point.GetColor().GetRed(); g = point.GetColor().GetGreen(); b = point.GetColor().GetBlue(); if (RGBrange == 0) // 16 bit { r = r / 65535 * 255; g = g / 65535 * 255; b = b / 65535 * 255; } pPoints->Set_Value(iPoint, iField[VAR_C], SG_GET_RGB(r, g, b)); } iPoint++; } } catch(std::exception &e) { SG_UI_Msg_Add_Error(CSG_String::Format(_TL("LAS reader exception: %s"), e.what())); ifs.close(); return( false ); } catch(...) { SG_UI_Msg_Add_Error(CSG_String::Format(_TL("Unknown LAS reader exception!"))); ifs.close(); return( false ); } ifs.close(); pPointsList->Add_Item(pPoints); DataObject_Add(pPoints); //----------------------------------------------------- CSG_Parameters sParms; DataObject_Get_Parameters(pPoints, sParms); if (sParms("METRIC_ATTRIB") && sParms("COLORS_TYPE") && sParms("METRIC_COLORS") && sParms("METRIC_ZRANGE") && sParms("DISPLAY_VALUE_AGGREGATE")) { sParms("DISPLAY_VALUE_AGGREGATE")->Set_Value(3); // highest z sParms("COLORS_TYPE")->Set_Value(2); // graduated color sParms("METRIC_COLORS")->asColors()->Set_Count(255); // number of colors sParms("METRIC_ATTRIB")->Set_Value(2); // z attrib sParms("METRIC_ZRANGE")->asRange()->Set_Range(pPoints->Get_Minimum(2),pPoints->Get_Maximum(2)); } DataObject_Set_Parameters(pPoints, sParms); SG_UI_Msg_Add(_TL("okay"), false); } //----------------------------------------------------- if( bValidity && cntInvalid > 0 ) SG_UI_Msg_Add(CSG_String::Format(_TL("WARNING: %d invalid points skipped!"), cntInvalid), true); return( true ); }
//--------------------------------------------------------- bool CPC_Drop_Attribute::On_Execute(void) { //------------------------------------------------- int *Features = (int *)Parameters("FIELDS")->asPointer(); int nFeatures = Parameters("FIELDS")->asInt (); if( !Features || nFeatures <= 0 ) { Error_Set(_TL("You must specify at least one attribute to drop!")); return( false ); } //----------------------------------------------------- CSG_PointCloud *pInput = Parameters("INPUT" )->asPointCloud(); CSG_PointCloud *pOutput = Parameters("OUTPUT")->asPointCloud(), Output; if( !pOutput || pOutput == pInput ) { pOutput = &Output; } pOutput->Create(pInput); //----------------------------------------------------- int i; std::set<int> setCols; std::set<int>::iterator it; setCols.clear(); for(i=0; i<nFeatures; i++) { setCols.insert(Features[i]); } for(i=0, it=setCols.begin(); it!=setCols.end(); i++, it++) { pOutput->Del_Field(*it - i); } //----------------------------------------------------- for(i=0; i<pInput->Get_Point_Count() && SG_UI_Process_Set_Progress(i, pInput->Get_Count()); i++) { pOutput->Add_Point(pInput->Get_X(i), pInput->Get_Y(i), pInput->Get_Z(i)); for(int j=0, k=0; j<pInput->Get_Attribute_Count(); j++, k++) { it = setCols.find(j + 3); if( it != setCols.end() ) { k--; continue; } switch (pInput->Get_Attribute_Type(j)) { default: pOutput->Set_Attribute(k, pInput->Get_Attribute(i, j)); break; case SG_DATATYPE_Date: case SG_DATATYPE_String: CSG_String sAttr; pInput->Get_Attribute(i, j, sAttr); pOutput->Set_Attribute(k, sAttr); break; } } } //----------------------------------------------------- if( pOutput == &Output ) { CSG_MetaData History = pInput->Get_History(); CSG_String Name = pInput->Get_Name (); pInput->Assign(pOutput); pInput->Get_History() = History; pInput->Set_Name(Name); Parameters("OUTPUT")->Set_Value(pInput); } else { pOutput->Fmt_Name("%s [%s]", pInput->Get_Name(), _TL("Dropped Attributes")); } //----------------------------------------------------- return( true ); }
//--------------------------------------------------------- bool CPointCloud_From_Text_File::On_Execute(void) { //----------------------------------------------------- CSG_File Stream; if( !Stream.Open(Parameters("FILE")->asString(), SG_FILE_R, false) ) { Error_Set(_TL("Unable to open input file!")); return( false ); } //----------------------------------------------------- int xField = Parameters("XFIELD")->asInt() - 1; int yField = Parameters("YFIELD")->asInt() - 1; int zField = Parameters("ZFIELD")->asInt() - 1; char Separator; switch( Parameters("SEPARATOR")->asInt() ) { default: Separator = '\t'; break; case 1: Separator = ' '; break; case 2: Separator = ','; break; } //----------------------------------------------------- CSG_String sLine; CSG_Strings Values; if( !Stream.Read_Line(sLine) ) { Error_Set(_TL("Empty file!")); return( false ); } if( Parameters("SKIP_HEADER")->asBool() ) // header contains field names { CSG_String_Tokenizer tokValues(sLine, Separator); // read each field name for later use while( tokValues.Has_More_Tokens() ) { Values += tokValues.Get_Next_Token(); } } else { Stream.Seek_Start(); } //----------------------------------------------------- CSG_PointCloud *pPoints = SG_Create_PointCloud(); pPoints->Set_Name(SG_File_Get_Name(Parameters("FILE")->asString(), false)); Parameters("POINTS")->Set_Value(pPoints); CSG_Array_Int Fields; //----------------------------------------------------- if( SG_UI_Get_Window_Main() ) { CSG_Parameters &Fields = *Parameters("FIELDSPECS")->asParameters(); int nFields = Fields.Get_Count() / 2; CSG_String Names, Types; for(int iField=0; iField<nFields; iField++) { Names += CSG_String::Format("%s;", Fields(CSG_String::Format("NAME%03d", iField))->asString()); Types += CSG_String::Format("%d;", Fields(CSG_String::Format("TYPE%03d", iField))->asInt ()); } Parameters("FIELDNAMES")->Set_Value(Names); Parameters("FIELDTYPES")->Set_Value(Types); } { TSG_Data_Type Type = SG_DATATYPE_Float; // default CSG_String_Tokenizer tokFields(Parameters("FIELDS" )->asString(), ";"); CSG_String_Tokenizer tokTypes (Parameters("FIELDTYPES")->asString(), ";"); CSG_String_Tokenizer tokNames (Parameters("FIELDNAMES")->asString(), ";"); while( tokFields.Has_More_Tokens() ) { int iField; if( !tokFields.Get_Next_Token().asInt(iField) || iField < 1 ) { Error_Set(_TL("Error parsing attribute field index")); return( false ); } Fields += iField - 1; CSG_String Name; if( tokNames.Has_More_Tokens() ) { Name = tokNames.Get_Next_Token(); Name.Trim(true); Name.Trim(false); } if( Name.is_Empty() ) { if( iField - 1 < Values.Get_Count() ) { Name = Values[iField - 1]; } else { Name.Printf("FIELD%02d", iField); } } if( tokTypes.Has_More_Tokens() ) { Get_Data_Type(Type, tokTypes.Get_Next_Token()); } pPoints->Add_Field(Name, Type); } } //----------------------------------------------------- Process_Set_Text(_TL("Importing data ...")); int nLines = 0; sLong Length = Stream.Length(); while( Stream.Read_Line(sLine) ) { nLines++; if( pPoints->Get_Count() % 10000 == 0 && !Set_Progress((double)Stream.Tell(), (double)Length) ) { return( true ); // user break } //------------------------------------------------- CSG_String_Tokenizer tokValues(sLine, Separator); Values.Clear(); while( tokValues.Has_More_Tokens() ) // read every column in this line and fill vector { Values += tokValues.Get_Next_Token(); } //------------------------------------------------- double x, y, z; if( xField >= Values.Get_Count() || !Values[xField].asDouble(x) || yField >= Values.Get_Count() || !Values[yField].asDouble(y) || zField >= Values.Get_Count() || !Values[zField].asDouble(z) ) { Message_Fmt("\n%s: %s [%d]", _TL("Warning"), _TL("Skipping misformatted line"), nLines); continue; } pPoints->Add_Point(x, y, z); //------------------------------------------------- for(int iAttribute=0; iAttribute<pPoints->Get_Attribute_Count(); iAttribute++) { if( Fields[iAttribute] >= Values.Get_Count() ) { pPoints->Set_NoData(3 + iAttribute); } else switch( pPoints->Get_Attribute_Type(iAttribute) ) { case SG_DATATYPE_String: pPoints->Set_Attribute(iAttribute, Values[Fields[iAttribute]]); break; default: { double Value; if( Values[Fields[iAttribute]].asDouble(Value) ) { pPoints->Set_Attribute(iAttribute, Value); } else { pPoints->Set_NoData(3 + iAttribute); } } break; } } } //----------------------------------------------------- DataObject_Set_Parameter(pPoints, "DISPLAY_VALUE_AGGREGATE", 3); // highest z DataObject_Set_Parameter(pPoints, "COLORS_TYPE" , 3); // graduated colors DataObject_Set_Parameter(pPoints, "METRIC_ATTRIB" , 2); // z attrib DataObject_Set_Parameter(pPoints, "METRIC_ZRANGE", pPoints->Get_Minimum(2), pPoints->Get_Maximum(2)); DataObject_Update(pPoints); //----------------------------------------------------- if( nLines > pPoints->Get_Count() ) { Message_Add(" ", true); Message_Fmt("%s: %d %s", _TL("Warning"), nLines - pPoints->Get_Count(), _TL("invalid points have been skipped")); } Message_Add(" ", true); Message_Fmt("%d %s", pPoints->Get_Count(), _TL("points have been imported with success")); 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 ); }