//--------------------------------------------------------- bool CSG_PointCloud::_Save(const CSG_String &File_Name) { CSG_File Stream; SG_UI_Msg_Add(CSG_String::Format(SG_T("%s: %s..."), _TL("Save point cloud"), File_Name.c_str()), true); CSG_String sFile_Name = SG_File_Make_Path(NULL, File_Name, SG_T("spc")); if( Stream.Open(sFile_Name, SG_FILE_W, true) == false ) { SG_UI_Msg_Add(_TL("failed"), false, SG_UI_MSG_STYLE_FAILURE); SG_UI_Msg_Add_Error(_TL("unable to create file.")); return( false ); } int i, iBuffer, nPointBytes = m_nPointBytes - 1; Stream.Write((void *)PC_FILE_VERSION, 6); Stream.Write(&nPointBytes , sizeof(int)); Stream.Write(&m_nFields , sizeof(int)); for(i=0; i<m_nFields; i++) { Stream.Write(&m_Field_Type[i], sizeof(TSG_Data_Type)); iBuffer = (int)m_Field_Name[i]->Length(); if( iBuffer >= 1024 - 1 ) iBuffer = 1024 - 1; Stream.Write(&iBuffer, sizeof(int)); Stream.Write((void *)m_Field_Name[i]->b_str(), sizeof(char), iBuffer); } _Set_Shape(m_Shapes_Index); for(i=0; i<Get_Count() && SG_UI_Process_Set_Progress(i, Get_Count()); i++) { Stream.Write(m_Points[i] + 1, nPointBytes); } Set_Modified(false); Set_File_Name(sFile_Name, true); Save_MetaData(File_Name); Get_Projection().Save(SG_File_Make_Path(NULL, File_Name, SG_T("prj")), SG_PROJ_FMT_WKT); SG_UI_Msg_Add(_TL("okay"), false, SG_UI_MSG_STYLE_SUCCESS); SG_UI_Process_Set_Ready(); 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_Export::On_Execute(void) { bool bBinary; int zField; float v[3]; CSG_String File; CSG_File Stream; CSG_TIN *pTIN; pTIN = Parameters("TIN") ->asTIN(); File = Parameters("FILE") ->asString(); zField = Parameters("ZFIELD") ->asInt(); bBinary = Parameters("BINARY") ->asInt() == 1; if( !Stream.Open(File, SG_FILE_W, bBinary) ) { return( false ); } //----------------------------------------------------- if( bBinary ) { char *sHeader = (char *)SG_Calloc(80, sizeof(char)); DWORD nFacets = pTIN->Get_Triangle_Count(); WORD nBytes = 0; Stream.Write(sHeader , sizeof(char), 80); Stream.Write(&nFacets, sizeof(DWORD)); SG_Free(sHeader); //------------------------------------------------- for(int iTriangle=0; iTriangle<pTIN->Get_Triangle_Count(); iTriangle++) { CSG_TIN_Triangle *pTriangle = pTIN->Get_Triangle(iTriangle); Get_Normal(pTriangle, zField, v); Stream.Write(v, sizeof(float), 3); // facet normal for(int iNode=0; iNode<3; iNode++) { CSG_TIN_Node *pNode = pTriangle->Get_Node(iNode); v[0] = (float)pNode->Get_X(); v[1] = (float)pNode->Get_Y(); v[2] = (float)pNode->asDouble(zField); Stream.Write(v, sizeof(float), 3); } Stream.Write(&nBytes, sizeof(WORD)); } } //----------------------------------------------------- else // ASCII { Stream.Printf(SG_T("solid %s\n"), SG_File_Get_Name(File, false).c_str()); for(int iTriangle=0; iTriangle<pTIN->Get_Triangle_Count(); iTriangle++) { CSG_TIN_Triangle *pTriangle = pTIN->Get_Triangle(iTriangle); Get_Normal(pTriangle, zField, v); Stream.Printf(SG_T(" facet normal %.4f %.4f %.4f\n"), v[0], v[1], v[2]); Stream.Printf(SG_T(" outer loop\n")); for(int iNode=0; iNode<3; iNode++) { CSG_TIN_Node *pNode = pTriangle->Get_Node(iNode); v[0] = (float)pNode->Get_X(); v[1] = (float)pNode->Get_Y(); v[2] = (float)pNode->asDouble(zField); Stream.Printf(SG_T(" vertex %.4f %.4f %.4f\n"), v[0], v[1], v[2]); } Stream.Printf(SG_T(" endloop\n")); Stream.Printf(SG_T(" endfacet\n")); } Stream.Printf(SG_T("endsolid %s\n"), SG_File_Get_Name(File, false).c_str()); } return( true ); }
//--------------------------------------------------------- bool CSG_Grid::_Save_Binary(CSG_File &Stream, int xA, int yA, int xN, int yN, TSG_Data_Type File_Type, bool bFlip, bool bSwapBytes) { char *Line, *pValue; int x, y, i, ix, iy, dy, axBytes, nxBytes, nValueBytes; //----------------------------------------------------- if( Stream.is_Open() && m_System.is_Valid() && m_Type != SG_DATATYPE_Undefined ) { Set_File_Type(GRID_FILE_FORMAT_Binary); if( bFlip ) { y = yA + yN - 1; dy = -1; } else { y = yA; dy = 1; } //------------------------------------------------- if( File_Type == SG_DATATYPE_Bit ) { nxBytes = xN / 8 + 1; if( m_Type == File_Type && m_Memory_Type == GRID_MEMORY_Normal && xA % 8 == 0 ) { axBytes = xA / 8; for(iy=0; iy<yN && SG_UI_Process_Set_Progress(iy, yN); iy++, y+=dy) { Stream.Write((char *)m_Values[y] + axBytes, sizeof(char), nxBytes); } } else { Line = (char *)SG_Malloc(nxBytes); for(iy=0; iy<yN && SG_UI_Process_Set_Progress(iy, yN); iy++, y+=dy) { for(ix=0, x=xA, pValue=Line; ix<xN; pValue++) { for(i=0; i<8 && ix<xN; i++, ix++, x++) { *pValue = asChar(x, y) != 0.0 ? *pValue | m_Bitmask[i] : *pValue & (~m_Bitmask[i]); } } Stream.Write(Line, sizeof(char), nxBytes); } SG_Free(Line); } } //------------------------------------------------- else { nValueBytes = SG_Data_Type_Get_Size(File_Type); nxBytes = xN * nValueBytes; if( m_Type == File_Type && m_Memory_Type == GRID_MEMORY_Normal && !bSwapBytes ) { axBytes = xA * nValueBytes; for(iy=0; iy<yN && SG_UI_Process_Set_Progress(iy, yN); iy++, y+=dy) { Stream.Write((char *)m_Values[y] + axBytes, sizeof(char), nxBytes); } } else { Line = (char *)SG_Malloc(nxBytes); for(iy=0; iy<yN && SG_UI_Process_Set_Progress(iy, yN); iy++, y+=dy) { for(ix=0, x=xA, pValue=Line; ix<xN; ix++, x++, pValue+=nValueBytes) { switch( File_Type ) { default: break; case SG_DATATYPE_Byte: *(BYTE *)pValue = asChar (x, y); break; case SG_DATATYPE_Char: *(char *)pValue = asChar (x, y); break; case SG_DATATYPE_Word: *(WORD *)pValue = asShort (x, y); break; case SG_DATATYPE_Short: *(short *)pValue = asShort (x, y); break; case SG_DATATYPE_DWord: *(DWORD *)pValue = asInt (x, y); break; case SG_DATATYPE_Int: *(int *)pValue = asInt (x, y); break; case SG_DATATYPE_Float: *(float *)pValue = asFloat (x, y); break; case SG_DATATYPE_Double: *(double *)pValue = asDouble (x, y); break; } if( bSwapBytes ) { _Swap_Bytes(pValue, nValueBytes); } } Stream.Write(Line, sizeof(char), nxBytes); } SG_Free(Line); } } //------------------------------------------------- SG_UI_Process_Set_Ready(); return( true ); } return( false ); }
void CSimulateVariableWind::CreateReport(){ CSG_String sReportFile, sFile; int i; if (Parameters("REPORTFILE")->asString() != NULL){ sReportFile = Parameters("REPORTFILE")->asString(); CalculateReportParameters(); char cDate[81]; time_t curTime; tm * timeinfo; time(&curTime); timeinfo = gmtime(&curTime); // std::locale spanish("esp"); // std::locale::global(spanish); strftime(cDate, 80, "%#x", timeinfo); sFile += "\t\t\t SIMULACIÓN realizada el "; sFile += cDate; sFile += "\n\t\t =============================================================================="; sFile += "\n\n\t Parámetros de entrada\n"; sFile += "\t --------------------------------\n\n"; sFile += "\t\t Modelos de combustible (por area) \n: "; for (i = 0; i < 12; i++){ if (m_pAreaByFuelModel[i]){ sFile += "\t\t\t * "; sFile += SG_Get_String(i + 1, 0) + " : " + SG_Get_String(m_pAreaByFuelModel[i]) + " ha\n"; }//if }//for sFile += "\t\t Humedad de los combustibles muertos (1 h): "; sFile += SG_Get_String(m_fDeadFuelMoisture) + " %\n"; sFile += "\t\t Velocidad del viento a media llama: \n" ; for(i = 0; i < m_iWindSpdGrids; i++){ sFile += "\t\t\t * "; sFile += SG_Get_String(i * m_fInterval, 0) + " min: " + SG_Get_String(m_pMeanWindSpd[i]) + "Km/h\n"; }//for sFile += "\t\t Dirección del vector viento, desde el norte geográfico: \n"; for(i = 0; i < m_iWindDirGrids; i++){ sFile += "\t\t\t * "; sFile += SG_Get_String(i * m_fInterval, 0) + " min: " + SG_Get_String(m_pMeanWindDir[i]) + "º\n"; }//for sFile += "\t\t Pendiente del terreno media: "; sFile += SG_Get_String(m_fSlope) + " %\n"; sFile += "\t\t Orientación del terreno: "; sFile += SG_Get_String(m_fAspect) + "º\n"; sFile += "\t\t Foco de partida: X = "; sFile += SG_Get_String(Parameters("COORDX")->asDouble(), 0) + " / Y = " + SG_Get_String(Parameters("COORDY")->asDouble(), 0) + "\n"; sFile += "\t\t Tiempo de simulación: 3.0 h"; sFile += "\n\n\t Resultado de la simulación\n"; sFile += "\t --------------------------------\n\n"; sFile += "\t\t Velocidad de propagación: "; sFile += SG_Get_String(m_fMeanSpeed) + " m/min\n"; sFile += "\t\t Calor por unidad de area: "; sFile += SG_Get_String(m_fHeatPerUnitArea) + " kJ/m^2\n"; //revisar unidades!! sFile += "\t\t Intensidad de la línea de fuego: "; sFile += SG_Get_String(m_fIntensity) + " kCal/m\n"; sFile += "\t\t Longitud de la llama: "; sFile += SG_Get_String(m_fFlameHeight) + " m\n"; sFile += "\t\t Intensidad de reacción: "; sFile += SG_Get_String(m_fReactionIntensity) + " kCal/m2\n"; sFile += "\t\t Velocidad efectiva del viento: "; sFile += SG_Get_String(m_fEffectiveWind / KMH2FTMIN) + " Km/h\n"; sFile += "\t\t Dirección de máxima propagación, desde el norte geográfico: "; sFile += SG_Get_String(m_fMaxSpreadDir) + "º\n"; sFile += "\t\t Area: "; sFile += SG_Get_String(m_fArea / 10000) + " ha\n"; sFile += "\t\t Perímetro: "; sFile += SG_Get_String(m_fPerimeter) + "m\n"; //Razón Longitud/Ancho: 1.9 sFile += "\t\t Distancia de propagación hacia delante: "; sFile += SG_Get_String(m_fFrontDistance) + " m\n"; sFile += "\t\t Distancia de propagación hacia atrás: "; sFile += SG_Get_String(m_fRearDistance) + " m\n"; CSG_File file; if( file.Open(sReportFile, SG_FILE_W, false) ) { file.Write(sFile); } }//if }//method
//--------------------------------------------------------- bool CWRF_Export::Save(const CSG_String &Directory, CSG_Parameter_Grid_List *pGrids) { //----------------------------------------------------- // 00001-00600.00001-00600 // 01234567890123456789012 int xOffset = m_Index.m_TILE_BDR + (int)(0.5 + (Get_XMin() - m_Index.m_KNOWN_LON) / Get_Cellsize()); int yOffset = m_Index.m_TILE_BDR + (int)(0.5 + (Get_YMin() - m_Index.m_KNOWN_LAT) / Get_Cellsize()); CSG_String Name = SG_File_Get_Name(Directory, true); Name.Printf(SG_T("%05d-%05d.%05d-%05d"), xOffset + 1, xOffset + m_Index.m_TILE_X, yOffset + 1, yOffset + m_Index.m_TILE_Y); //----------------------------------------------------- CSG_File Stream; if( !Stream.Open(SG_File_Make_Path(Directory, Name), SG_FILE_W) ) { Error_Set(_TL("data file could not be openend")); return( false ); } //----------------------------------------------------- char *pLine, *pValue; int x, y, nBytes_Line; nBytes_Line = Get_NX() * m_Index.m_WORDSIZE; pLine = (char *)SG_Malloc(nBytes_Line); //----------------------------------------------------- for(int z=0; z<pGrids->Get_Count() && Process_Get_Okay(); z++) { CSG_Grid *pGrid = pGrids->asGrid(z); //------------------------------------------------- for(y=0; y<pGrid->Get_NY() && !Stream.is_EOF() && Set_Progress(y, pGrid->Get_NY()); y++) { int yy = m_Index.m_ROW_ORDER == VAL_TOP_BOTTOM ? pGrid->Get_NY() - 1 - y : y; for(x=0, pValue=pLine; x<pGrid->Get_NX(); x++, pValue+=m_Index.m_WORDSIZE) { if( m_Index.m_SIGNED ) { switch( m_Index.m_WORDSIZE ) { case 1: *((signed char *)pValue) = (signed char )pGrid->asInt(x, yy); break; case 2: *((signed short *)pValue) = (signed short )pGrid->asInt(x, yy); break; case 4: *((signed int *)pValue) = (signed int )pGrid->asInt(x, yy); break; } } else { switch( m_Index.m_WORDSIZE ) { case 1: *((unsigned char *)pValue) = (unsigned char )pGrid->asInt(x, yy); break; case 2: *((unsigned short *)pValue) = (unsigned short)pGrid->asInt(x, yy); break; case 4: *((unsigned int *)pValue) = (unsigned int )pGrid->asInt(x, yy); break; } } if( m_Index.m_ENDIAN == VAL_ENDIAN_BIG ) { SG_Swap_Bytes(pValue, m_Index.m_WORDSIZE); } } Stream.Write(pLine, sizeof(char), nBytes_Line); } } //----------------------------------------------------- SG_Free(pLine); return( true ); }