//--------------------------------------------------------- double CSG_mRMR::Get_MutualInfo(long v1, long v2) { double mi = -1; // initialized as an illegal value if( !m_Samples[0] ) { SG_UI_Msg_Add_Error("The input data is NULL."); return mi; } if( v1 >= m_nVars || v2 >= m_nVars || v1 < 0 || v2 < 0 ) { SG_UI_Msg_Add_Error("The input variable indexes are invalid (out of range)."); return mi; } //----------------------------------------------------- // copy data int *v1data = new int[m_nSamples]; int *v2data = new int[m_nSamples]; if( !v1data || !v2data ) { SG_UI_Msg_Add_Error("Fail to allocate memory."); return mi; } for(long i=0; i<m_nSamples; i++) { v1data[i] = (int)m_Samples[i][v1]; // the double already been discretized, should be safe now v2data[i] = (int)m_Samples[i][v2]; } //----------------------------------------------------- // compute mutual info long nstate = 3; // always true for DataTable, which was discretized as three states int nstate1 = 0, nstate2 = 0; double *pab = Get_JointProb(v1data, v2data, m_nSamples, nstate, nstate1, nstate2); mi = Get_MutualInfo(pab, nstate1, nstate2); //----------------------------------------------------- // free memory and return DELETE_ARRAY(v1data); DELETE_ARRAY(v2data); DELETE_ARRAY(pab ); return mi; }
//--------------------------------------------------------- bool CSG_mRMR::Get_Memory(int nVars, int nSamples) { Destroy(); //----------------------------------------------------- m_nVars = nVars; if( m_nVars <= 0 ) { SG_UI_Msg_Add_Error("no features"); return( false ); } m_nSamples = nSamples; if( m_nSamples <= 0 ) { SG_UI_Msg_Add_Error("no samples"); return( false ); } //----------------------------------------------------- m_Samples = new double *[m_nSamples]; if( !m_Samples ) { SG_UI_Msg_Add_Error("failed to allocate memory."); return( false ); } m_Samples[0] = new double[m_nSamples * m_nVars]; if( !m_Samples[0] ) { SG_UI_Msg_Add_Error("failed to allocate memory."); return( false ); } return( true ); }
//--------------------------------------------------------- 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 CSG_CRSProjector::_Set_Projection(const CSG_Projection &Projection, void **ppProjection, bool bInverse) { PROJ4_FREE(*ppProjection); //------------------------------------------------- if( (*ppProjection = pj_init_plus(Projection.Get_Proj4())) == NULL ) { SG_UI_Msg_Add_Error(CSG_String::Format(SG_T("Proj4 [%s]: %s"), _TL("initialization"), SG_STR_MBTOSG(pj_strerrno(pj_errno)))); return( false ); } //------------------------------------------------- if( bInverse && ((PJ *)(*ppProjection))->inv == NULL ) { SG_UI_Msg_Add_Error(CSG_String::Format(SG_T("Proj4 [%s]: %s"), _TL("initialization"), _TL("inverse transformation not available"))); return( false ); } return( true ); }
//--------------------------------------------------------- template <class T> void CSG_mRMR::Copy_Vector(T *srcdata, long len, int *desdata, int &nstate) { if (!srcdata || !desdata) { SG_UI_Msg_Add_Error("no points in Copy_Vector()!"); return; } // note: originally I added 0.5 before rounding, however seems the negative numbers and // positive numbers are all rounded towarded 0; hence int(-1+0.5)=0 and int(1+0.5)=1; // This is unwanted because I need the above to be -1 and 1. // for this reason I just round with 0.5 adjustment for positive and negative differently // copy data int minn, maxx; if (srcdata[0] > 0) { maxx = minn = int (srcdata[0] + 0.5); } else { maxx = minn = int (srcdata[0] - 0.5); } long i; int tmp; double tmp1; for (i = 0; i < len; i++) { tmp1 = double (srcdata[i]); tmp = (tmp1 > 0) ? (int) (tmp1 + 0.5) : (int) (tmp1 - 0.5); //round to integers minn = (minn < tmp) ? minn : tmp; maxx = (maxx > tmp) ? maxx : tmp; desdata[i] = tmp; // printf("%i ",desdata[i]); } // make the vector data begin from 0 (i.e. 1st state) for (i = 0; i < len; i++) { desdata[i] -= minn; } // return the #state nstate = (maxx - minn + 1); return; }
//--------------------------------------------------------- bool CSG_Grid::_Load(const CSG_String &File_Name, TSG_Data_Type Type, TSG_Grid_Memory_Type Memory_Type) { bool bResult; //----------------------------------------------------- Destroy(); m_Type = Type; //----------------------------------------------------- SG_UI_Msg_Add(CSG_String::Format(SG_T("%s: %s..."), LNG("[MSG] Load grid"), File_Name.c_str()), true); if( SG_File_Cmp_Extension(File_Name, SG_T("grd")) ) { bResult = _Load_Surfer(File_Name, Memory_Type); } else { bResult = _Load_Native(File_Name, Memory_Type); } //----------------------------------------------------- if( bResult ) { Set_Update_Flag(); Set_File_Name(File_Name); Load_MetaData(File_Name); m_bCreated = true; SG_UI_Msg_Add(LNG("[MSG] okay"), false, SG_UI_MSG_STYLE_SUCCESS); } else { Destroy(); SG_UI_Msg_Add(LNG("[MSG] failed"), false, SG_UI_MSG_STYLE_FAILURE); SG_UI_Msg_Add_Error(LNG("[ERR] Grid file could not be opened.")); } //----------------------------------------------------- return( bResult ); }
//--------------------------------------------------------- bool CSG_CRSProjector::Set_Inverse(bool bOn) { if( m_bInverse == bOn ) { return( true ); } if( m_pTarget && ((PJ *)m_pTarget)->inv ) { m_bInverse = bOn; void *pTMP = m_pSource; m_pSource = m_pTarget; m_pTarget = pTMP; return( true ); } SG_UI_Msg_Add_Error(CSG_String::Format(SG_T("Proj4 [%s]: %s"), _TL("initialization"), _TL("inverse transformation not available"))); return( false ); }
//--------------------------------------------------------- bool CSG_mRMR::Get_Selection(int nFeatures, int Method) { m_pSelection->Del_Records(); if( !m_Samples[0] ) { SG_UI_Msg_Add_Error("The input data is NULL."); return( false ); } if( nFeatures < 0 ) { SG_UI_Msg_Add_Error("The input number of features is negative."); return( false ); } long poolUseFeaLen = 500; if( poolUseFeaLen > m_nVars - 1 ) // there is a target variable (the first one), that is why must remove one poolUseFeaLen = m_nVars - 1; if( nFeatures > poolUseFeaLen ) nFeatures = poolUseFeaLen; long *feaInd = new long[nFeatures]; if( !feaInd ) { SG_UI_Msg_Add_Error("Fail to allocate memory."); return( false ); } //----------------------------------------------------- // determine the pool TPool *Pool = (TPool *)SG_Malloc(m_nVars * sizeof(TPool)); if( !Pool ) { SG_UI_Msg_Add_Error("Fail to allocate memory."); return( false ); } //----------------------------------------------------- long i, j, k; for(i=0; i<m_nVars; i++) // the Pool[0].mival is the entropy of target classification variable { Pool[i].mival = -Get_MutualInfo(0, i); // set as negative for sorting purpose Pool[i].Index = i; Pool[i].Mask = 1; // initialized to be everything in pool would be considered } qsort(Pool + 1, m_nVars - 1, sizeof(TPool), Pool_Compare); Pool[0].mival = -Pool[0].mival; ADD_MESSAGE(CSG_String::Format( SG_T("\nTarget classification variable (#%d column in the input data) has name=%s \tentropy score=%5.3f"), 0 + 1, m_VarNames[0].c_str(), Pool[0].mival )); ADD_MESSAGE("\n*** MaxRel features ***"); ADD_MESSAGE("Order\tFea\tName\tScore"); for(i=1; i<m_nVars-1; i++) { Pool[i].mival = -Pool[i].mival; if( i <= nFeatures ) { ADD_MESSAGE(CSG_String::Format(SG_T("%d \t %d \t %s \t %5.3f"), i, (int)Pool[i].Index, m_VarNames[(int)Pool[i].Index].c_str(), Pool[i].mival )); } } //----------------------------------------------------- // mRMR selection long poolFeaIndMin = 1; long poolFeaIndMax = poolFeaIndMin + poolUseFeaLen - 1; feaInd[0] = Pool[1].Index; Pool[feaInd[0]].Mask = 0; // after selection, no longer consider this feature Pool[0 ].Mask = 0; // of course the first one, which corresponds to the classification variable, should not be considered. Just set the mask as 0 for safety. ADD_MESSAGE("\n*** mRMR features ***"); ADD_MESSAGE("Order\tFea\tName\tScore"); ADD_FEATURE(0, Pool[1].mival); for(k=1; k<nFeatures; k++) //the first one, feaInd[0] has been determined already { double relevanceVal, redundancyVal, tmpscore, selectscore; long selectind; int b_firstSelected = 0; for(i=poolFeaIndMin; i<=poolFeaIndMax; i++) { if( Pool[Pool[i].Index].Mask == 0 ) { continue; // skip this feature as it was selected already } relevanceVal = Get_MutualInfo(0, Pool[i].Index); // actually no necessary to re-compute it, this value can be retrieved from Pool[].mival vector redundancyVal = 0; for(j=0; j<k; j++) { redundancyVal += Get_MutualInfo(feaInd[j], Pool[i].Index); } redundancyVal /= k; switch( Method ) { default: // fprintf(stderr, "Undefined selection method=%d. Use MID instead.\n", mymethod); case SG_mRMR_Method_MID: tmpscore = relevanceVal - redundancyVal; break; case SG_mRMR_Method_MIQ: tmpscore = relevanceVal / (redundancyVal + 0.0001); break; } if( b_firstSelected == 0 ) { selectscore = tmpscore; selectind = Pool[i].Index; b_firstSelected = 1; } else if( tmpscore > selectscore ) { //update the best feature found and the score selectscore = tmpscore; selectind = Pool[i].Index; } } feaInd[k] = selectind; Pool[selectind].Mask = 0; ADD_FEATURE(k, selectscore); } //----------------------------------------------------- return( true ); }
bool Cconnectivity_analysis::On_Execute(void) { CSG_Grid *pinpgrid, *bingrid, *symb_grid, *hgrid; CSG_Shapes *pOutlines; bool filter, corners_centers, remove_marginal_regions; unsigned short numrows; unsigned short numcols; unsigned char center; double xmin; double ymin; short interm_grid_created; simple_REGIONC_list *reg_first; simple_REGIONC_list *reg_last; simple_REGIONC_list *reg_curr; pinpgrid = Parameters ("INPUT_GRID")->asGrid(); bingrid = Parameters ("FILTERED_MASK")->asGrid(); filter = Parameters ("FILTER")->asBool(); corners_centers = Parameters ("BORDER_PIXEL_CENTERS")->asBool(); remove_marginal_regions = Parameters ("REMOVE_MARGINAL_REGIONS")->asBool(); pOutlines = Parameters("OUTLINES")->asShapes(); symb_grid = Parameters ("SYMBOLIC_IMAGE")->asGrid(); CSG_String sName = pOutlines->Get_Name(); pOutlines->Destroy(); pOutlines->Set_Name(sName); pOutlines->Add_Field(SG_T("ID"), SG_DATATYPE_Int); numrows=pinpgrid->Get_NY()+2; numcols=pinpgrid->Get_NX()+2; // xmin=pinpgrid->Get_XMin()-2*pinpgrid->Get_Cellsize(); // ymin=pinpgrid->Get_YMin()-2*pinpgrid->Get_Cellsize(); xmin=pinpgrid->Get_XMin(); ymin=pinpgrid->Get_YMin(); unsigned char **bin_image; long **symb_image; if (corners_centers) center = 1; else center = 0; bin_image = (unsigned char **) matrix_all_alloc (numrows, numcols, 'U', 0); symb_image = (long **) matrix_all_alloc (numrows, numcols, 'L', 0); interm_grid_created = 0; //SG_Free(bin_image); //CSG_Grid *pTmp = new CSG_Grid(); //delete pTmp; if (filter) { if (bingrid == NULL) { SG_UI_Msg_Add(_TL("Filtered mask will be created automatically ..."), true); bingrid = SG_Create_Grid(SG_DATATYPE_Char, pinpgrid->Get_NX(), pinpgrid->Get_NY(), pinpgrid->Get_Cellsize(), pinpgrid->Get_XMin(), pinpgrid->Get_YMin()); if (bingrid == NULL) { SG_UI_Msg_Add_Error(_TL("Unable to create filtered mask grid!")); matrix_all_free ((void **) bin_image); matrix_all_free ((void **) symb_image); return (false); } Parameters("FILTERED_MASK")->Set_Value(bingrid); interm_grid_created = 1; } //----------------------------------------------------- RUN_MODULE("grid_filter" , 13, SET_PARAMETER("INPUT_GRID" , pinpgrid) && SET_PARAMETER("OUTPUT_GRID" , bingrid) && SET_PARAMETER("RADIUS" , Parameters ("SIZE")->asInt()) ) hgrid = bingrid; } else { hgrid = pinpgrid; } for (int y = 0; y < hgrid->Get_NY () && Set_Progress(y, hgrid->Get_NY()); y++) { for (int x = 0; x < hgrid->Get_NX(); x++) { if (hgrid->is_NoData(x,y)) bin_image[y+1][x+1] = 0; else bin_image[y+1][x+1] = hgrid->asChar(x,y); } } // Here the regions are removed which have contact with the image margins; // this is achieved by a region growing if (remove_marginal_regions) { for (int y = 1; y < numrows - 1; y++) { if (bin_image [y][1] != 0) background_region_growing (bin_image, numrows, numcols, y, 1); if (bin_image [y][numcols - 2] != 0) background_region_growing (bin_image, numrows, numcols, y, numcols-2); } for (int x = 1; x < numcols - 1; x++) { if (bin_image [1][x] != 0) background_region_growing (bin_image, numrows, numcols, 1, x); if (bin_image [numrows-2][x] != 0) background_region_growing (bin_image, numrows, numcols, numrows-2, x); } if (filter) { for (int y = 0; y < bingrid->Get_NY (); y++) { #pragma omp parallel for for (int x = 0; x < bingrid->Get_NX(); x++) { bingrid->Set_Value(x, y, bin_image[y+1][x+1]); } } } } if (interm_grid_created) bingrid->Destroy(); // The function which does the proper work: // computation of the symbolic image, construction of the border chains (shapes) comb_contour_region_marking (numrows, numcols, bin_image, symb_image, ®_first, ®_last, center); for (int y = 0; y < symb_grid->Get_NY () && Set_Progress(y, symb_grid->Get_NY()); y++) { #pragma omp parallel for for (int x = 0; x < symb_grid->Get_NX(); x++) { symb_grid->Set_Value(x, y, symb_image[y+1][x+1]); } } // Here the shapes are generated int iPolygon; for (iPolygon = 0, reg_curr = reg_first; reg_curr != NULL; reg_curr = reg_curr -> next, iPolygon++) { CSG_Shape *pShape = pOutlines->Add_Shape(); pShape->Set_Value(0, iPolygon); // set ID field (= first field in table) to polygon ID for (simple_PIXELC_list *pix_curr = reg_curr->first_pix; pix_curr != NULL; pix_curr = pix_curr->next) { TSG_Point point = symb_grid->Get_System().Get_Grid_to_World(pix_curr->col - 1, pix_curr->row - 1); pShape->Add_Point(point, 0); } int iHoles; simple_INNER_REGION_list *inner_curr; for (iHoles=0, inner_curr = reg_curr->inner_first; iHoles < reg_curr->num_holes; iHoles++, inner_curr = inner_curr->next) { for (simple_PIXELC_list *pix_curr = inner_curr->first_pix; pix_curr != NULL; pix_curr = pix_curr->next) { TSG_Point point = symb_grid->Get_System().Get_Grid_to_World(pix_curr->col - 1, pix_curr->row - 1); pShape->Add_Point(point, iHoles+1); } } if (!corners_centers) shift_shape (pShape, -Get_Cellsize()/2.0, -Get_Cellsize()/2.0); } matrix_all_free ((void **) bin_image); matrix_all_free ((void **) symb_image); free_regions (®_first, ®_last); 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 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 CShapes_Convert_Vertex_Type::On_Execute(void) { CSG_Shapes *pInput, *pOutput; int iFieldZ, iFieldM; pInput = Parameters("INPUT")->asShapes(); iFieldZ = Parameters("FIELD_Z")->asInt(); iFieldM = Parameters("FIELD_M")->asInt(); pOutput = Parameters("OUTPUT")->asShapes(); if( pInput->Get_Count() < 1 ) { SG_UI_Msg_Add_Error(_TL("Input shape is empty!")); return (false); } //----------------------------------------------------- if( pInput->Get_Vertex_Type() == SG_VERTEX_TYPE_XY ) { if( iFieldZ < 0 ) { SG_UI_Msg_Add_Error(_TL("Please provide an attribute field with z-information!")); return( false ); } if( iFieldM < 0 ) { pOutput->Create(pInput->Get_Type(), CSG_String::Format(SG_T("%s_Z"), pInput->Get_Name()), pInput, SG_VERTEX_TYPE_XYZ); } else { pOutput->Create(pInput->Get_Type(), CSG_String::Format(SG_T("%s_ZM"), pInput->Get_Name()), pInput, SG_VERTEX_TYPE_XYZM); } } else { pOutput->Create(pInput->Get_Type(), CSG_String::Format(SG_T("%s_XY"), pInput->Get_Name()), pInput, SG_VERTEX_TYPE_XY); pOutput->Add_Field(SG_T("Z"), SG_DATATYPE_Double); if( pInput->Get_Vertex_Type() == SG_VERTEX_TYPE_XYZM ) { pOutput->Add_Field(SG_T("M"), SG_DATATYPE_Double); } } //----------------------------------------------------- for(int iShape=0; iShape<pInput->Get_Count(); iShape++) { CSG_Shape *pShapeIn = pInput ->Get_Shape(iShape); CSG_Shape *pShapeOut = pOutput ->Add_Shape(pShapeIn, SHAPE_COPY_ATTR); for(int iPart=0; iPart<pShapeIn->Get_Part_Count(); iPart++) { for(int iPoint=0; iPoint<pShapeIn->Get_Point_Count(iPart); iPoint++) { pShapeOut->Add_Point(pShapeIn->Get_Point(iPoint, iPart), iPart); if( pInput->Get_Vertex_Type() == SG_VERTEX_TYPE_XY ) { pShapeOut->Set_Z(pShapeIn->asDouble(iFieldZ), iPoint, iPart); if( pOutput->Get_Vertex_Type() == SG_VERTEX_TYPE_XYZM ) { pShapeOut->Set_M(pShapeIn->asDouble(iFieldM), iPoint, iPart); } } else { if( pInput->Get_Vertex_Type() == SG_VERTEX_TYPE_XYZM ) { pShapeOut->Set_Value(pOutput->Get_Field_Count() - 1, pShapeIn->Get_M(iPoint, iPart)); pShapeOut->Set_Value(pOutput->Get_Field_Count() - 2, pShapeIn->Get_Z(iPoint, iPart)); } else { pShapeOut->Set_Value(pOutput->Get_Field_Count() - 1, pShapeIn->Get_Z(iPoint, iPart)); } } } } } //----------------------------------------------------- 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 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 SG_FTP_Download(const CSG_String &Target_Directory, const CSG_String &Source, const SG_Char *Username, const SG_Char *Password, unsigned short Port, bool bBinary, bool bVerbose) { CSG_String _Source(Source); _Source.Trim(); if( _Source.Find("ftp://") == 0 ) { _Source = _Source.Right(_Source.Length() - CSG_String("ftp://").Length()); } CSG_String ftpHost = _Source.BeforeFirst('/'); CSG_String ftpDir = _Source.AfterFirst ('/').BeforeLast('/'); // ftpDir.Prepend("/"); CSG_String ftpFile = _Source.AfterLast ('/'); //----------------------------------------------------- wxFTP ftp; if( Username && *Username ) { ftp.SetUser (Username); } if( Password && *Password ) { ftp.SetPassword(Password); } if( !ftp.Connect(ftpHost.c_str(), Port) ) { if( bVerbose ) { SG_UI_Msg_Add_Error(_TL("Couldn't connect")); } return( false ); } //----------------------------------------------------- if( !ftpDir.is_Empty() && !ftp.ChDir(ftpDir.c_str()) ) { if( bVerbose ) { SG_UI_Msg_Add_Error(CSG_String::Format("%s [%s]", _TL("Couldn't change to directory"), ftpDir.c_str())); } return( false ); } if( ftp.GetFileSize(ftpFile.c_str()) == -1 ) { if( bVerbose ) { SG_UI_Msg_Add_Error(CSG_String::Format("%s [%s]", _TL("Couldn't get the file size"), ftpFile.c_str())); } } //----------------------------------------------------- wxInputStream *pStream = ftp.GetInputStream(ftpFile.c_str()); if( !pStream ) { if( bVerbose ) { SG_UI_Msg_Add_Error(CSG_String::Format("%s [%s]", _TL("Couldn't get the file"), ftpFile.c_str())); } return( false ); } //----------------------------------------------------- wxFileOutputStream *pFile = new wxFileOutputStream(SG_File_Make_Path(Target_Directory, ftpFile).c_str()); if( !pFile ) { if( bVerbose ) { SG_UI_Msg_Add_Error(CSG_String::Format("%s [%s]", _TL("Couldn't create target file"), SG_File_Make_Path(Target_Directory, ftpFile).c_str())); } delete(pStream); return( false ); } //----------------------------------------------------- pFile->Write(*pStream); delete(pFile); delete(pStream); return( true ); }
//--------------------------------------------------------- template <class T> double * CSG_mRMR::Get_JointProb(T * img1, T * img2, long len, long maxstatenum, int &nstate1, int &nstate2) { long i, j; //----------------------------------------------------- // get and check size information if (!img1 || !img2 || len < 0) { SG_UI_Msg_Add_Error("At least one of the input vectors is invalid."); return( NULL ); } int b_findstatenum = 1; // int nstate1 = 0, nstate2 = 0; int b_returnprob = 1; //----------------------------------------------------- // copy data into new INT type array (hence quantization) and then reange them begin from 0 (i.e. state1) int *vec1 = new int[len]; int *vec2 = new int[len]; if( !vec1 || !vec2 ) { SG_UI_Msg_Add_Error("Fail to allocate memory.\n"); return( NULL ); } int nrealstate1 = 0, nrealstate2 = 0; Copy_Vector(img1, len, vec1, nrealstate1); Copy_Vector(img2, len, vec2, nrealstate2); //update the #state when necessary nstate1 = (nstate1 < nrealstate1) ? nrealstate1 : nstate1; //printf("First vector #state = %i\n",nrealstate1); nstate2 = (nstate2 < nrealstate2) ? nrealstate2 : nstate2; //printf("Second vector #state = %i\n",nrealstate2); // if (nstate1!=maxstatenum || nstate2!=maxstatenum) // printf("find nstate1=%d nstate2=%d\n", nstate1, nstate2); //----------------------------------------------------- // generate the joint-distribution table double *hab = new double[nstate1 * nstate2]; double **hab2d = new double *[nstate2]; if( !hab || !hab2d ) { SG_UI_Msg_Add_Error("Fail to allocate memory."); return( NULL ); } for(j=0; j<nstate2; j++) { hab2d[j] = hab + (long)j * nstate1; } for(i=0; i<nstate1; i++) { for(j=0; j<nstate2; j++) { hab2d[j][i] = 0; } } for(i=0; i<len; i++) { // old method -- slow // indx = (long)(vec2[i]) * nstate1 + vec1[i]; // hab[indx] += 1; // new method -- fast hab2d[vec2[i]][vec1[i]] += 1; //printf("vec2[%d]=%d vec1[%d]=%d\n", i, vec2[i], i, vec1[i]); } //----------------------------------------------------- // return the probabilities, otherwise return count numbers if( b_returnprob ) { for(i=0; i<nstate1; i++) { for(j=0; j<nstate2; j++) { hab2d[j][i] /= len; } } } //----------------------------------------------------- // finish DELETE_ARRAY(hab2d); DELETE_ARRAY(vec1); DELETE_ARRAY(vec2); return hab; }
bool CSG_Grid::Save(const CSG_String &File_Name, int Format, int xA, int yA, int xN, int yN) { bool bResult; CSG_String sFile_Name = SG_File_Make_Path(NULL, File_Name, SG_T("sgrd")); //----------------------------------------------------- if( xA < 0 || xA >= Get_NX() - 1 ) { xA = 0; } if( yA < 0 || yA >= Get_NY() - 1 ) { yA = 0; } if( xN > Get_NX() - xA ) { xN = Get_NX() - xA; } if( yN > Get_NY() - yA ) { yN = Get_NY() - yA; } //----------------------------------------------------- SG_UI_Msg_Add(CSG_String::Format(SG_T("%s: %s..."), LNG("[MSG] Save grid"), File_Name.c_str()), true); switch( Format ) { default: case GRID_FILE_FORMAT_Binary: // 1 - Binary bResult = _Save_Native(sFile_Name, xA, yA, xN, yN, true); break; case GRID_FILE_FORMAT_ASCII: // 2 - ASCII bResult = _Save_Native(sFile_Name, xA, yA, xN, yN, false); break; } //----------------------------------------------------- if( bResult ) { Set_Modified(false); Set_File_Name(sFile_Name); Save_MetaData(File_Name); SG_UI_Msg_Add(LNG("[MSG] okay"), false, SG_UI_MSG_STYLE_SUCCESS); } else { SG_UI_Msg_Add(LNG("[MSG] failed"), false, SG_UI_MSG_STYLE_FAILURE); SG_UI_Msg_Add_Error(LNG("[ERR] Grid file could not be saved.")); } return( bResult ); }
bool Cbin_erosion_reconst::On_Execute(void) { CSG_Grid *pinpgrid, *bingrid, *poutgrid; unsigned short numrows; unsigned short numcols; char **mask; char **marker; pinpgrid = Parameters ("INPUT_GRID")->asGrid (); poutgrid = Parameters ("OUTPUT_GRID")->asGrid (); numrows=pinpgrid->Get_NY(); numcols=pinpgrid->Get_NX(); // bingrid is not an output grid here, so it must be created ad hoc bingrid = SG_Create_Grid(SG_DATATYPE_Char, pinpgrid->Get_NX(), pinpgrid->Get_NY(), pinpgrid->Get_Cellsize(), pinpgrid->Get_XMin(), pinpgrid->Get_YMin()); if (bingrid == NULL) { SG_UI_Msg_Add_Error(_TL("Unable to create grid for the eroded image!")); return (false); } RUN_TOOL("grid_filter" , 8, SET_PARAMETER("INPUT" , pinpgrid) && SET_PARAMETER("RESULT" , bingrid) && SET_PARAMETER("MODE" , 1) && SET_PARAMETER("RADIUS" , Parameters ("RADIUS")->asInt()) && SET_PARAMETER("METHOD" , 1) ) mask = (char **) matrix_all_alloc (numrows, numcols, 'C', 0); marker = (char **) matrix_all_alloc (numrows, numcols, 'C', 0); for (int y = 0; y < numrows; y++) { #pragma omp parallel for for (int x = 0; x < numcols; x++) { if (pinpgrid->is_NoData(x,y)) // check if there are no_data in input datasets { mask [y][x] = 0; marker [y][x] = 0; } else { mask [y][x] = pinpgrid->asChar(x,y); marker [y][x] = bingrid->asChar(x,y); } } } bingrid->Destroy(); binary_geodesic_morphological_reconstruction (numrows, numcols, mask, marker); for (int y = 0; y < Get_NY () && Set_Progress(y, Get_NY()); y++) { #pragma omp parallel for for (int x = 0; x < Get_NX (); x++) { if (pinpgrid->is_NoData(x,y)) poutgrid->Set_NoData(x,y); else poutgrid->Set_Value(x,y, marker[y][x]); } } matrix_all_free ((void **) mask); matrix_all_free ((void **) marker); return( true ); }
//--------------------------------------------------------- bool CSG_PointCloud::_Load(const CSG_String &File_Name) { TSG_Data_Type Type; char ID[6]; int i, iBuffer, nPointBytes, nFields; char Name[1024]; CSG_File Stream; SG_UI_Msg_Add(CSG_String::Format(SG_T("%s: %s..."), _TL("Load point cloud"), File_Name.c_str()), true); //----------------------------------------------------- if( !Stream.Open(File_Name, SG_FILE_R, true) ) { SG_UI_Msg_Add(_TL("failed"), false, SG_UI_MSG_STYLE_FAILURE); SG_UI_Msg_Add_Error(_TL("file could not be opened.")); return( false ); } if( !Stream.Read(ID, 6) || strncmp(ID, PC_FILE_VERSION, 5) != 0 ) { SG_UI_Msg_Add(_TL("failed"), false, SG_UI_MSG_STYLE_FAILURE); SG_UI_Msg_Add_Error(_TL("incompatible file.")); return( false ); } if( !Stream.Read(&nPointBytes, sizeof(int)) || nPointBytes < (int)(3 * sizeof(float)) ) { SG_UI_Msg_Add(_TL("failed"), false, SG_UI_MSG_STYLE_FAILURE); SG_UI_Msg_Add_Error(_TL("incompatible file.")); return( false ); } if( !Stream.Read(&nFields, sizeof(int)) || nFields < 3 ) { SG_UI_Msg_Add(_TL("failed"), false, SG_UI_MSG_STYLE_FAILURE); SG_UI_Msg_Add_Error(_TL("incompatible file.")); return( false ); } //----------------------------------------------------- Destroy(); for(i=0; i<nFields; i++) { if( !Stream.Read(&Type , sizeof(TSG_Data_Type)) || !Stream.Read(&iBuffer , sizeof(int)) || !(iBuffer > 0 && iBuffer < 1024) || !Stream.Read(Name , iBuffer) ) { SG_UI_Msg_Add(_TL("failed"), false, SG_UI_MSG_STYLE_FAILURE); SG_UI_Msg_Add_Error(_TL("incompatible file.")); return( false ); } if( ID[5] == '0' ) // Data Type Definition changed!!! { switch( Type ) { default: Type = SG_DATATYPE_Undefined; break; case 1: Type = SG_DATATYPE_Char; break; case 2: Type = SG_DATATYPE_Short; break; case 3: Type = SG_DATATYPE_Int; break; case 4: Type = SG_DATATYPE_Long; break; case 5: Type = SG_DATATYPE_Float; break; case 6: Type = SG_DATATYPE_Double; break; } } Name[iBuffer] = '\0'; if( !_Add_Field(CSG_String((const char *)Name), Type) ) { SG_UI_Msg_Add(_TL("failed"), false, SG_UI_MSG_STYLE_FAILURE); SG_UI_Msg_Add_Error(_TL("incompatible file.")); return( false ); } } if( m_nPointBytes != nPointBytes + 1 ) { SG_UI_Msg_Add(_TL("failed"), false, SG_UI_MSG_STYLE_FAILURE); SG_UI_Msg_Add_Error(_TL("incompatible file.")); return( false ); } //----------------------------------------------------- sLong fLength = Stream.Length(); while( _Inc_Array() && Stream.Read(m_Cursor + 1, nPointBytes) && SG_UI_Process_Set_Progress((double)Stream.Tell(), (double)fLength) ) {} _Dec_Array(); Set_File_Name(File_Name, true); Load_MetaData(File_Name); if( 0 > Get_Count() ) { SG_UI_Msg_Add(_TL("failed"), false, SG_UI_MSG_STYLE_FAILURE); SG_UI_Msg_Add_Error(_TL("no records in file.")); return( false ); } //----------------------------------------------------- SG_UI_Process_Set_Ready(); Get_Projection().Load(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); return( true ); }
//--------------------------------------------------------- bool CSG_Table::_Save_DBase(const CSG_String &File_Name) { int iField, iRecord, nBytes; CSG_Table_DBase dbf; //----------------------------------------------------- CSG_Table_DBase::TFieldDesc *dbfFields = new CSG_Table_DBase::TFieldDesc[Get_Field_Count()]; for(iField=0; iField<Get_Field_Count(); iField++) { strncpy(dbfFields[iField].Name, SG_STR_SGTOMB(Get_Field_Name(iField)), 11); switch( Get_Field_Type(iField) ) { case SG_DATATYPE_String: default: dbfFields[iField].Type = DBF_FT_CHARACTER; dbfFields[iField].Width = (BYTE)((nBytes = Get_Field_Length(iField)) > 255 ? 255 : nBytes); break; case SG_DATATYPE_Date: dbfFields[iField].Type = DBF_FT_DATE; dbfFields[iField].Width = (BYTE)8; break; case SG_DATATYPE_Char: dbfFields[iField].Type = DBF_FT_CHARACTER; dbfFields[iField].Width = (BYTE)1; break; case SG_DATATYPE_Short: case SG_DATATYPE_Int: case SG_DATATYPE_Long: case SG_DATATYPE_Color: dbfFields[iField].Type = DBF_FT_NUMERIC; dbfFields[iField].Width = (BYTE)16; dbfFields[iField].Decimals = (BYTE)0; break; case SG_DATATYPE_Float: case SG_DATATYPE_Double: dbfFields[iField].Type = DBF_FT_NUMERIC; dbfFields[iField].Width = (BYTE)16; dbfFields[iField].Decimals = (BYTE)8; break; } } if( !dbf.Open(File_Name, Get_Field_Count(), dbfFields) ) { delete[](dbfFields); SG_UI_Msg_Add_Error(LNG("[ERR] dbase file could not be opened")); return( false ); } delete[](dbfFields); //----------------------------------------------------- for(iRecord=0; iRecord<Get_Record_Count() && SG_UI_Process_Set_Progress(iRecord, Get_Record_Count()); iRecord++) { CSG_Table_Record *pRecord = Get_Record(iRecord); dbf.Add_Record(); for(iField=0; iField<Get_Field_Count(); iField++) { switch( dbf.Get_FieldType(iField) ) { case DBF_FT_DATE: case DBF_FT_CHARACTER: dbf.Set_Value(iField, SG_STR_SGTOMB(pRecord->asString(iField))); break; case DBF_FT_NUMERIC: dbf.Set_Value(iField, pRecord->asDouble(iField)); break; } } dbf.Flush_Record(); } SG_UI_Process_Set_Ready(); return( true ); }
//--------------------------------------------------------- bool CGrid_Tiling::On_Execute(void) { bool bSaveTiles; int ix, iy, nx, ny, Overlap; double y, x, dx, dy, dCell; CSG_String FilePath, BaseName; TSG_Data_Type Type; TSG_Rect Extent; TSG_Grid_Resampling Interpolation; CSG_Grid *pGrid, *pTile; CSG_Parameter_Grid_List *pTiles; //----------------------------------------------------- pGrid = Parameters("GRID") ->asGrid(); pTiles = Parameters("TILES") ->asGridList(); Overlap = Parameters("OVERLAP") ->asInt(); bSaveTiles = Parameters("SAVE_TILES") ->asBool(); BaseName = Parameters("TILE_BASENAME") ->asString(); FilePath = Parameters("TILE_PATH") ->asString(); switch( Parameters("METHOD")->asInt() ) { case 0: default: Extent.xMin = pGrid->Get_XMin(); Extent.xMax = pGrid->Get_XMax(); Extent.yMin = pGrid->Get_YMin(); Extent.yMax = pGrid->Get_YMax(); dCell = pGrid->Get_Cellsize(); nx = Parameters("NX") ->asInt(); ny = Parameters("NY") ->asInt(); dx = dCell * nx; dy = dCell * ny; Type = pGrid->Get_Type(); Interpolation = GRID_RESAMPLING_NearestNeighbour; break; case 1: Extent.xMin = Parameters("XRANGE") ->asRange()->Get_LoVal(); Extent.xMax = Parameters("XRANGE") ->asRange()->Get_HiVal(); Extent.yMin = Parameters("YRANGE") ->asRange()->Get_LoVal(); Extent.yMax = Parameters("YRANGE") ->asRange()->Get_HiVal(); dCell = Parameters("DCELL") ->asDouble(); dx = Parameters("DX") ->asDouble(); dy = Parameters("DY") ->asDouble(); nx = (int)(dx / dCell); ny = (int)(dy / dCell); Type = pGrid->Get_Type(); Interpolation = GRID_RESAMPLING_Undefined; break; } switch( Parameters("OVERLAP_SYM")->asInt() ) { case 0: default: // symetric nx += Overlap * 2; ny += Overlap * 2; break; case 1: // bottom / left nx += Overlap; ny += Overlap; break; case 2: // top / right nx += Overlap; ny += Overlap; Overlap = 0; break; } pTiles->Del_Items(); //----------------------------------------------------- if( dx <= 0.0 || dy <= 0.0 || dCell <= 0.0 ) { Message_Add(_TL("no intersection with mask grid.")); return( false ); } if( bSaveTiles ) { if( !SG_STR_CMP(BaseName, SG_T("")) ) { SG_UI_Msg_Add_Error(_TL("Please provide a valid base name for the output files!")); return( false ); } if( !SG_STR_CMP(FilePath, SG_T("")) ) { SG_UI_Msg_Add_Error(_TL("Please provide a valid output directory for the output files!")); return( false ); } } //----------------------------------------------------- int iTiles = 0; for(y=Extent.yMin, iy=1; y<Extent.yMax && Process_Get_Okay(); y+=dy, iy++) { for(x=Extent.xMin, ix=1; x<Extent.xMax; x+=dx, ix++) { pTile = SG_Create_Grid(Type, nx, ny, dCell, x - dCell * Overlap, y - dCell * Overlap); pTile ->Assign(pGrid, Interpolation); pTile ->Set_Name(CSG_String::Format(SG_T("%s [%d, %d]"), pGrid->Get_Name(), iy, ix)); if( pTile->Get_NoData_Count() == pTile->Get_NCells() ) { delete(pTile); } else { if( bSaveTiles ) { CSG_String FileName = CSG_String::Format(SG_T("%s/%s_%d_%d"), FilePath.c_str(), BaseName.c_str(), iy, ix); pTile->Save(FileName); delete(pTile); } else { pTiles->Add_Item(pTile); } iTiles++; } } } SG_UI_Msg_Add(CSG_String::Format(_TL("%d tiles created."), iTiles), true); return( iTiles > 0 ); }
//--------------------------------------------------------- double CSG_mRMR::Get_MutualInfo(double *pab, long pabhei, long pabwid) { //----------------------------------------------------- // check if parameters are correct if( !pab ) { SG_UI_Msg_Add_Error("Got illeagal parameter in compute_mutualinfo()."); return( -1.0 ); } //----------------------------------------------------- long i, j; double **pab2d = new double *[pabwid]; for(j=0; j<pabwid; j++) { pab2d[j] = pab + (long)j * pabhei; } double *p1 = 0, *p2 = 0; long p1len = 0, p2len = 0; int b_findmarginalprob = 1; //----------------------------------------------------- //generate marginal probability arrays if( b_findmarginalprob != 0 ) { p1len = pabhei; p2len = pabwid; p1 = new double[p1len]; p2 = new double[p2len]; for (i = 0; i < p1len; i++) p1[i] = 0; for (j = 0; j < p2len; j++) p2[j] = 0; for (i = 0; i < p1len; i++) //p1len = pabhei { for (j = 0; j < p2len; j++) //p2len = panwid { // printf("%f ",pab2d[j][i]); p1[i] += pab2d[j][i]; p2[j] += pab2d[j][i]; } } } //----------------------------------------------------- // calculate the mutual information double muInf = 0; muInf = 0.0; for (j = 0; j < pabwid; j++) // should for p2 { for (i = 0; i < pabhei; i++) // should for p1 { if (pab2d[j][i] != 0 && p1[i] != 0 && p2[j] != 0) { muInf += pab2d[j][i] * log (pab2d[j][i] / p1[i] / p2[j]); // printf("%f %fab %fa %fb\n",muInf,pab2d[j][i]/p1[i]/p2[j],p1[i],p2[j]); } } } muInf /= log(2.0); //----------------------------------------------------- // free memory DELETE_ARRAY(pab2d); if( b_findmarginalprob != 0 ) { DELETE_ARRAY(p1); DELETE_ARRAY(p2); } return muInf; }
//--------------------------------------------------------- bool CGrid_Export::On_Execute(void) { //----------------------------------------------------- int y, iy, Method; double dTrans; CSG_Grid *pGrid, *pShade, Grid, Shade; //----------------------------------------------------- pGrid = Parameters("GRID" )->asGrid(); pShade = Parameters("SHADE" )->asGrid(); Method = Parameters("COLOURING" )->asInt (); dTrans = Parameters("SHADE_TRANS" )->asDouble() / 100.0; if( !pGrid ) { return( false ); } //----------------------------------------------------- if( Method == 5 ) // same as in graphical user interface { if( !SG_UI_DataObject_asImage(pGrid, &Grid) ) { Error_Set("could not retrieve colour coding from graphical user interface."); return( false ); } } else { double zMin, zScale; CSG_Colors Colors; CSG_Table LUT; if( SG_UI_Get_Window_Main() ) { Colors.Assign(Parameters("COL_PALETTE")->asColors()); } else { Colors.Set_Palette( Parameters("COL_PALETTE")->asInt (), Parameters("COL_REVERT" )->asBool(), Parameters("COL_COUNT" )->asInt () ); } switch( Method ) { case 0: // stretch to grid's standard deviation zMin = pGrid->Get_Mean() - Parameters("STDDEV")->asDouble() * pGrid->Get_StdDev(); zScale = Colors.Get_Count() / (2 * Parameters("STDDEV")->asDouble() * pGrid->Get_StdDev()); break; case 1: // stretch to grid's value range zMin = pGrid->Get_ZMin(); zScale = Colors.Get_Count() / pGrid->Get_ZRange(); break; case 2: // stretch to specified value range zMin = Parameters("STRETCH")->asRange()->Get_LoVal(); if( zMin >= (zScale = Parameters("STRETCH")->asRange()->Get_HiVal()) ) { Error_Set(_TL("invalid user specified value range.")); return( false ); } zScale = Colors.Get_Count() / (zScale - zMin); break; case 3: // lookup table if( !Parameters("LUT")->asTable() || Parameters("LUT")->asTable()->Get_Field_Count() < 5 ) { Error_Set(_TL("invalid lookup table.")); return( false ); } LUT.Create(*Parameters("LUT")->asTable()); break; case 4: // rgb coded values break; } //------------------------------------------------- Grid.Create(*Get_System(), SG_DATATYPE_Int); for(y=0, iy=Get_NY()-1; y<Get_NY() && Set_Progress(y); y++, iy--) { #pragma omp parallel for for(int x=0; x<Get_NX(); x++) { double z = pGrid->asDouble(x, y); if( Method == 3 ) // lookup table { int i, iColor = -1; for(i=0; iColor<0 && i<LUT.Get_Count(); i++) { if( z == LUT[i][3] ) { Grid.Set_Value(x, iy, LUT[iColor = i].asInt(0)); } } for(i=0; iColor<0 && i<LUT.Get_Count(); i++) { if( z >= LUT[i][3] && z <= LUT[i][4] ) { Grid.Set_Value(x, iy, LUT[iColor = i].asInt(0)); } } if( iColor < 0 ) { Grid.Set_NoData(x, iy); } } else if( pGrid->is_NoData(x, y) ) { Grid.Set_NoData(x, iy); } else if( Method == 4 ) // rgb coded values { Grid.Set_Value(x, iy, z); } else { int i = (int)(zScale * (z - zMin)); Grid.Set_Value(x, iy, Colors[i < 0 ? 0 : i >= Colors.Get_Count() ? Colors.Get_Count() - 1 : i]); } } } } //----------------------------------------------------- if( !pShade || pShade->Get_ZRange() <= 0.0 ) { pShade = NULL; } else { double dMinBright, dMaxBright; dMinBright = Parameters("SHADE_BRIGHT")->asRange()->Get_LoVal() / 100.0; dMaxBright = Parameters("SHADE_BRIGHT")->asRange()->Get_HiVal() / 100.0; if( dMinBright >= dMaxBright ) { SG_UI_Msg_Add_Error(_TL("Minimum shade brightness must be lower than maximum shade brightness!")); return( false ); } int nColors = 100; CSG_Colors Colors(nColors, SG_COLORS_BLACK_WHITE, true); //------------------------------------------------- Shade.Create(*Get_System(), SG_DATATYPE_Int); for(y=0, iy=Get_NY()-1; y<Get_NY() && Set_Progress(y); y++, iy--) { #pragma omp parallel for for(int x=0; x<Get_NX(); x++) { if( pShade->is_NoData(x, y) ) { Shade.Set_NoData(x, iy); } else { Shade.Set_Value (x, iy, Colors[(int)(nColors * (dMaxBright - dMinBright) * (pShade->asDouble(x, y) - pShade->Get_ZMin()) / pShade->Get_ZRange() + dMinBright)]); } } } } //----------------------------------------------------- wxImage Image(Get_NX(), Get_NY()); if( Grid.Get_NoData_Count() > 0 ) { Image.SetAlpha(); } for(y=0; y<Get_NY() && Set_Progress(y); y++) { #pragma omp parallel for for(int x=0; x<Get_NX(); x++) { if( Grid.is_NoData(x, y) || (pShade != NULL && Shade.is_NoData(x, y)) ) { if( Image.HasAlpha() ) { Image.SetAlpha(x, y, wxIMAGE_ALPHA_TRANSPARENT); } Image.SetRGB(x, y, 255, 255, 255); } else { if( Image.HasAlpha() ) { Image.SetAlpha(x, y, wxIMAGE_ALPHA_OPAQUE); } int r, g, b, c = Grid.asInt(x, y); r = SG_GET_R(c); g = SG_GET_G(c); b = SG_GET_B(c); if( pShade ) { c = Shade.asInt(x, y); r = dTrans * r + SG_GET_R(c) * (1.0 - dTrans); g = dTrans * g + SG_GET_G(c) * (1.0 - dTrans); b = dTrans * b + SG_GET_B(c) * (1.0 - dTrans); } Image.SetRGB(x, y, r, g, b); } } } //------------------------------------------------- CSG_String fName(Parameters("FILE")->asString()); if( !SG_File_Cmp_Extension(fName, SG_T("bmp")) && !SG_File_Cmp_Extension(fName, SG_T("jpg")) && !SG_File_Cmp_Extension(fName, SG_T("pcx")) && !SG_File_Cmp_Extension(fName, SG_T("png")) && !SG_File_Cmp_Extension(fName, SG_T("tif")) ) { fName = SG_File_Make_Path(NULL, fName, SG_T("png")); Parameters("FILE")->Set_Value(fName); } //----------------------------------------------------- wxImageHandler *pImgHandler = NULL; if( !SG_UI_Get_Window_Main() ) { if( SG_File_Cmp_Extension(fName, SG_T("jpg")) ) pImgHandler = new wxJPEGHandler; else if( SG_File_Cmp_Extension(fName, SG_T("pcx")) ) pImgHandler = new wxPCXHandler; else if( SG_File_Cmp_Extension(fName, SG_T("tif")) ) pImgHandler = new wxTIFFHandler; #ifdef _SAGA_MSW else if( SG_File_Cmp_Extension(fName, SG_T("bmp")) ) pImgHandler = new wxBMPHandler; #endif else // if( SG_File_Cmp_Extension(fName, SG_T("png")) ) pImgHandler = new wxPNGHandler; wxImage::AddHandler(pImgHandler); } if( !Image.SaveFile(fName.c_str()) ) { Error_Set(CSG_String::Format(SG_T("%s [%s]"), _TL("could not save image file"), fName.c_str())); return( false ); } pGrid->Get_Projection().Save(SG_File_Make_Path(NULL, fName, SG_T("prj")), SG_PROJ_FMT_WKT); //----------------------------------------------------- CSG_File Stream; if( SG_File_Cmp_Extension(fName, SG_T("bmp")) ) Stream.Open(SG_File_Make_Path(NULL, fName, SG_T("bpw")), SG_FILE_W, false); else if( SG_File_Cmp_Extension(fName, SG_T("jpg")) ) Stream.Open(SG_File_Make_Path(NULL, fName, SG_T("jgw")), SG_FILE_W, false); else if( SG_File_Cmp_Extension(fName, SG_T("pcx")) ) Stream.Open(SG_File_Make_Path(NULL, fName, SG_T("pxw")), SG_FILE_W, false); else if( SG_File_Cmp_Extension(fName, SG_T("png")) ) Stream.Open(SG_File_Make_Path(NULL, fName, SG_T("pgw")), SG_FILE_W, false); else if( SG_File_Cmp_Extension(fName, SG_T("tif")) ) Stream.Open(SG_File_Make_Path(NULL, fName, SG_T("tfw")), SG_FILE_W, false); if( Stream.is_Open() ) { Stream.Printf(SG_T("%.10f\n%f\n%f\n%.10f\n%.10f\n%.10f\n"), pGrid->Get_Cellsize(), 0.0, 0.0, -pGrid->Get_Cellsize(), pGrid->Get_XMin(), pGrid->Get_YMax() ); } //----------------------------------------------------- if( Parameters("FILE_KML")->asBool() ) { CSG_MetaData KML; KML.Set_Name("kml"); KML.Add_Property("xmlns", "http://www.opengis.net/kml/2.2"); // CSG_MetaData *pFolder = KML.Add_Child("Folder"); // pFolder->Add_Child("name" , "Raster exported from SAGA"); // pFolder->Add_Child("description", "System for Automated Geoscientific Analyses - www.saga-gis.org"); // CSG_MetaData *pOverlay = pFolder->Add_Child("GroundOverlay"); CSG_MetaData *pOverlay = KML.Add_Child("GroundOverlay"); pOverlay->Add_Child("name" , pGrid->Get_Name()); pOverlay->Add_Child("description", pGrid->Get_Description()); pOverlay->Add_Child("Icon" )->Add_Child("href", SG_File_Get_Name(fName, true)); pOverlay->Add_Child("LatLonBox" ); pOverlay->Get_Child("LatLonBox" )->Add_Child("north", pGrid->Get_YMax()); pOverlay->Get_Child("LatLonBox" )->Add_Child("south", pGrid->Get_YMin()); pOverlay->Get_Child("LatLonBox" )->Add_Child("east" , pGrid->Get_XMax()); pOverlay->Get_Child("LatLonBox" )->Add_Child("west" , pGrid->Get_XMin()); KML.Save(fName, SG_T("kml")); } //----------------------------------------------------- if( !SG_UI_Get_Window_Main() && pImgHandler != NULL) { wxImage::RemoveHandler(pImgHandler->GetName()); } //----------------------------------------------------- return( true ); }
//--------------------------------------------------------- bool CPointCloud_Create_Tileshape_From_SPCVF::On_Execute(void) { CSG_String sFileName; CSG_Shapes *pShapes; CSG_MetaData SPCVF; CSG_String sPathSPCVF, sFilePath; int iPoints; double dBBoxXMin, dBBoxYMin, dBBoxXMax, dBBoxYMax; //----------------------------------------------------- sFileName = Parameters("FILENAME")->asString(); pShapes = Parameters("TILE_SHP")->asShapes(); //----------------------------------------------------- if( !SPCVF.Create(sFileName) || SPCVF.Get_Name().CmpNoCase(SG_T("SPCVFDataset")) ) { SG_UI_Msg_Add_Error(_TL("Please provide a valid *.scpvf file!")); return( false ); } //----------------------------------------------------- CSG_String sMethodPaths; SPCVF.Get_Property(SG_T("Paths"), sMethodPaths); if( !sMethodPaths.CmpNoCase(SG_T("absolute")) ) { sPathSPCVF = SG_T(""); } else if( !sMethodPaths.CmpNoCase(SG_T("relative")) ) { sPathSPCVF = SG_File_Get_Path(sFileName); sPathSPCVF.Replace(SG_T("\\"), SG_T("/")); } else { SG_UI_Msg_Add_Error(_TL("Encountered invalid path description in *.spcvf file!")); return( false ); } //----------------------------------------------------- pShapes->Destroy(); pShapes->Add_Field(_TL("ID"), SG_DATATYPE_Int); pShapes->Add_Field(_TL("Filepath"), SG_DATATYPE_String); pShapes->Add_Field(_TL("File"), SG_DATATYPE_String); pShapes->Add_Field(_TL("Points"), SG_DATATYPE_Int); pShapes->Set_Name(CSG_String::Format(_TL("Tileshape_%s"), SG_File_Get_Name(sFileName, false).c_str())); //----------------------------------------------------- CSG_MetaData *pDatasets = SPCVF.Get_Child(SG_T("Datasets")); for(int i=0; i<pDatasets->Get_Children_Count(); i++) { CSG_MetaData *pDataset = pDatasets->Get_Child(i); CSG_MetaData *pBBox = pDataset->Get_Child(SG_T("BBox")); pDataset->Get_Property(SG_T("File"), sFilePath); pDataset->Get_Property(SG_T("Points"), iPoints); pBBox->Get_Property(SG_T("XMin"), dBBoxXMin); pBBox->Get_Property(SG_T("YMin"), dBBoxYMin); pBBox->Get_Property(SG_T("XMax"), dBBoxXMax); pBBox->Get_Property(SG_T("YMax"), dBBoxYMax); //----------------------------------------------------- CSG_Shape *pShape = pShapes->Add_Shape(); pShape->Add_Point(dBBoxXMin, dBBoxYMin); pShape->Add_Point(dBBoxXMin, dBBoxYMax); pShape->Add_Point(dBBoxXMax, dBBoxYMax); pShape->Add_Point(dBBoxXMax, dBBoxYMin); pShape->Set_Value(0, i + 1); if( sPathSPCVF.Length() == 0 ) // absolute paths { pShape->Set_Value(1, sFilePath.BeforeLast('/')); pShape->Set_Value(2, sFilePath.AfterLast('/')); } else // relative paths { pShape->Set_Value(1, sPathSPCVF); pShape->Set_Value(2, sFilePath); } pShape->Set_Value(3, iPoints); } //----------------------------------------------------- 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 ); }