//--------------------------------------------------------- bool CFlow_AreaUpslope::Get_Area(void) { int i, x, y; if( m_pDTM && m_pFlow ) { for(i=0; i<m_pDTM->Get_NCells() && SG_UI_Process_Set_Progress(i, m_pDTM->Get_NCells()); i++) { m_pDTM->Get_Sorted(i, x, y, false, false); if( m_pFlow->asDouble(x, y) > 0.0 ) { break; } } for(i++; i<m_pDTM->Get_NCells() && SG_UI_Process_Set_Progress(i, m_pDTM->Get_NCells()); i++) { m_pDTM->Get_Sorted(i, x, y, false, false); Set_Value(x, y); } return( true ); } return( false ); }
//--------------------------------------------------------- bool CSG_Shapes::Assign(CSG_Data_Object *pObject) { int iShape; CSG_Shape *pShape; CSG_Shapes *pShapes; //----------------------------------------------------- if( pObject && pObject->is_Valid() && (pObject->Get_ObjectType() == DATAOBJECT_TYPE_Shapes || pObject->Get_ObjectType() == DATAOBJECT_TYPE_PointCloud) ) { pShapes = (CSG_Shapes *)pObject; Create(pShapes->Get_Type(), pShapes->Get_Name(), pShapes, pShapes->Get_Vertex_Type()); for(iShape=0; iShape<pShapes->Get_Count() && SG_UI_Process_Set_Progress(iShape, pShapes->Get_Count()); iShape++) { pShape = Add_Shape(); pShape->Assign(pShapes->Get_Shape(iShape)); } SG_UI_Process_Set_Ready(); Update(); Get_History() = pObject->Get_History(); return( true ); } return( false ); }
//--------------------------------------------------------- void CSG_Grid::Invert(void) { int x, y; double zMin, zMax; if( is_Valid() && Get_ZRange() > 0.0 ) { zMin = Get_ZMin(); zMax = Get_ZMax(); for(y=0; y<Get_NY() && SG_UI_Process_Set_Progress(y, Get_NY()); y++) { for(x=0; x<Get_NX(); x++) { if( !is_NoData(x, y) ) { Set_Value(x, y, zMax - (asDouble(x, y) - zMin)); } } } SG_UI_Process_Set_Ready(); Get_History().Add_Child(SG_T("GRID_OPERATION"), LNG("Inversion")); } }
//--------------------------------------------------------- bool CSG_PRQuadTree::Create(CSG_Shapes *pShapes, int Attribute, bool bStatistics) { Destroy(); if( pShapes && pShapes->is_Valid() && Create(pShapes->Get_Extent(), bStatistics) ) { for(int iShape=0; iShape<pShapes->Get_Count() && SG_UI_Process_Set_Progress(iShape, pShapes->Get_Count()); iShape++) { CSG_Shape *pShape = pShapes->Get_Shape(iShape); if( Attribute < 0 || !pShape->is_NoData(Attribute) ) { double z = Attribute < 0 ? iShape : pShape->asDouble(Attribute); for(int iPart=0; iPart<pShape->Get_Part_Count(); iPart++) { for(int iPoint=0; iPoint<pShape->Get_Point_Count(iPart); iPoint++) { Add_Point(pShape->Get_Point(iPoint, iPart), z); } } } } return( Get_Point_Count() > 0 ); } return( false ); }
//--------------------------------------------------------- bool CSG_Grid::_Assign_Interpolated(CSG_Grid *pGrid, TSG_Grid_Interpolation Interpolation) { int x, y; double xPosition, yPosition, z; Set_NoData_Value_Range(pGrid->Get_NoData_Value(), pGrid->Get_NoData_hiValue()); for(y=0, yPosition=Get_YMin(); y<Get_NY() && SG_UI_Process_Set_Progress(y, Get_NY()); y++, yPosition+=Get_Cellsize()) { for(x=0, xPosition=Get_XMin(); x<Get_NX(); x++, xPosition+=Get_Cellsize()) { if( pGrid->Get_Value(xPosition, yPosition, z, Interpolation) ) { Set_Value (x, y, z); } else { Set_NoData(x, y); } } } Get_History() = pGrid->Get_History(); Get_History().Add_Child(SG_T("GRID_OPERATION"), CSG_String::Format(SG_T("%f -> %f"), pGrid->Get_Cellsize(), Get_Cellsize()))->Add_Property(SG_T("NAME"), LNG("Resampling")); SG_UI_Process_Set_Ready(); return( true ); }
//--------------------------------------------------------- bool CSG_Table::_Save_Text(const CSG_String &File_Name, bool bHeadline, const SG_Char *Separator) { int iField, iRecord; CSG_File Stream; if( Get_Field_Count() > 0 ) { if( Stream.Open(File_Name, SG_FILE_W, false) ) { for(iField=0; iField<Get_Field_Count(); iField++) { Stream.Printf(SG_T("%s%s"), Get_Field_Name(iField), iField < Get_Field_Count() - 1 ? Separator : SG_T("\n")); } for(iRecord=0; iRecord<Get_Record_Count() && SG_UI_Process_Set_Progress(iRecord, Get_Record_Count()); iRecord++) { for(iField=0; iField<Get_Field_Count(); iField++) { Stream.Printf(SG_T("%s"), Get_Record(iRecord)->asString(iField)); Stream.Printf(SG_T("%s"), iField < Get_Field_Count() - 1 ? Separator : SG_T("\n")); } } SG_UI_Process_Set_Ready(); return( true ); } } return( false ); }
//--------------------------------------------------------- int CGrid_Filler::Fill(const TSG_Point &Point) { int x = m_pGrid->Get_System().Get_xWorld_to_Grid(Point.x); int y = m_pGrid->Get_System().Get_yWorld_to_Grid(Point.y); if( !m_pGrid->is_InGrid(x, y, m_bNoData) ) { return( 0 ); } //----------------------------------------------------- double zMin, zMax; switch( m_Replace ) { default: // value at mouse position zMin = m_pGrid->asDouble(x, y) - m_zTolerance; zMax = m_pGrid->asDouble(x, y) + m_zTolerance; break; case 1: // fixed value zMin = m_zReplace - m_zTolerance; zMax = m_zReplace + m_zTolerance; break; } //----------------------------------------------------- int nReplaced = 1; m_pGrid->Set_Value(x, y, m_zFill); m_Stack.Push(x, y); while( m_Stack.Get_Size() > 0 && SG_UI_Process_Set_Progress(nReplaced, m_pGrid->Get_NCells()) ) { m_Stack.Pop(x, y); for(int i=0; i<8; i+=2) { int ix = m_pGrid->Get_System().Get_xTo(i, x); int iy = m_pGrid->Get_System().Get_yTo(i, y); if( m_pGrid->is_InGrid(ix, iy, m_bNoData) ) { double z = m_pGrid->asDouble(ix, iy); if( z != m_zFill && z >= zMin && z <= zMax ) { nReplaced++; m_pGrid->Set_Value(ix, iy, m_zFill); m_Stack.Push(ix, iy); } } } } m_Stack.Clear(); //----------------------------------------------------- return( nReplaced ); }
//--------------------------------------------------------- void CSG_Grid::Normalise(void) { if( is_Valid() ) { Update(); if( m_zStats.Get_StdDev() > 0.0 ) { int x, y; if( (Get_NoData_hiValue() > -NORMALISED_NODATA && Get_NoData_hiValue() < NORMALISED_NODATA) || (Get_NoData_Value () > -NORMALISED_NODATA && Get_NoData_Value () < NORMALISED_NODATA) ) { for(y=0; y<Get_NY() && SG_UI_Process_Set_Progress(y, Get_NY()); y++) { for(x=0; x<Get_NX(); x++) { if( is_NoData(x, y) ) { Set_Value(x, y, -NORMALISED_NODATA); } } } Set_NoData_Value(-NORMALISED_NODATA); } for(y=0; y<Get_NY() && SG_UI_Process_Set_Progress(y, Get_NY()); y++) { for(x=0; x<Get_NX(); x++) { if( !is_NoData(x, y) ) { Set_Value(x, y, (asDouble(x, y) - m_zStats.Get_Mean()) / m_zStats.Get_StdDev() ); } } } SG_UI_Process_Set_Ready(); Get_History().Add_Child(SG_T("GRID_OPERATION"), LNG("Normalisation")); } } }
//--------------------------------------------------------- CSG_Grid & CSG_Grid::_Operation_Arithmetic(double Value, TSG_Grid_Operation Operation) { //----------------------------------------------------- switch( Operation ) { case GRID_OPERATION_Addition: Get_History().Add_Child(SG_T("GRID_OPERATION"), Value)->Add_Property(SG_T("NAME"), LNG("Addition")); break; case GRID_OPERATION_Subtraction: Get_History().Add_Child(SG_T("GRID_OPERATION"), Value)->Add_Property(SG_T("NAME"), LNG("Subtraction")); Value = -Value; break; case GRID_OPERATION_Multiplication: Get_History().Add_Child(SG_T("GRID_OPERATION"), Value)->Add_Property(SG_T("NAME"), LNG("Multiplication")); break; case GRID_OPERATION_Division: if( Value == 0.0 ) return( *this ); Get_History().Add_Child(SG_T("GRID_OPERATION"), Value)->Add_Property(SG_T("NAME"), LNG("Division")); Value = 1.0 / Value; break; } //----------------------------------------------------- for(int y=0; y<Get_NY() && SG_UI_Process_Set_Progress(y, Get_NY()); y++) { for(int x=0; x<Get_NX(); x++) { if( !is_NoData(x, y) ) { switch( Operation ) { case GRID_OPERATION_Addition: case GRID_OPERATION_Subtraction: Add_Value(x, y, Value); break; case GRID_OPERATION_Multiplication: case GRID_OPERATION_Division: Mul_Value(x, y, Value); break; } } } } SG_UI_Process_Set_Ready(); return( *this ); }
//--------------------------------------------------------- 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 Cut_Shapes(CSG_Rect Extent, int Method, CSG_Shapes *pShapes, CSG_Shapes *pCut) { if( pCut && pShapes && pShapes->is_Valid() && Extent.Intersects(pShapes->Get_Extent()) ) { pCut->Create( pShapes->Get_Type(), CSG_String::Format(SG_T("%s [%s]"), pShapes->Get_Name(), _TL("Cut")), pShapes ); for(int iShape=0; iShape<pShapes->Get_Count() && SG_UI_Process_Set_Progress(iShape, pShapes->Get_Count()); iShape++) { bool bAdd; CSG_Shape *pShape = pShapes->Get_Shape(iShape); if( Method == 2 ) // center { bAdd = pShapes->Get_Type() == SHAPE_TYPE_Polygon ? Extent.Contains(((CSG_Shape_Polygon *)pShape)->Get_Centroid()) : Extent.Contains(pShape->Get_Extent().Get_Center()); } else // completely contained, intersects { switch( pShape->Intersects(Extent) ) { case INTERSECTION_Identical: case INTERSECTION_Contained: bAdd = true; break; case INTERSECTION_Overlaps: case INTERSECTION_Contains: bAdd = Method == 1; break; default: bAdd = false; break; } } if( bAdd ) { pCut->Add_Shape(pShape); } } return( pCut->Get_Count() > 0 ); } return( false ); }
//--------------------------------------------------------- bool SG_Matrix_LU_Solve(int n, const int *Permutation, const double **Matrix, double *Vector, bool bSilent) { int i, j, k; double Sum; for(i=0, k=-1; i<n && (bSilent || SG_UI_Process_Set_Progress(i, n)); i++) { Sum = Vector[Permutation[i]]; Vector[Permutation[i]] = Vector[i]; if( k >= 0 ) { for(j=k; j<=i-1; j++) { Sum -= Matrix[i][j] * Vector[j]; } } else if( Sum ) { k = i; } Vector[i] = Sum; } for(i=n-1; i>=0 && (bSilent || SG_UI_Process_Set_Progress(n-i, n)); i--) { Sum = Vector[i]; for(j=i+1; j<n; j++) { Sum -= Matrix[i][j] * Vector[j]; } Vector[i] = Sum / Matrix[i][i]; } return( true ); }
//--------------------------------------------------------- bool CSG_Grid::_Assign_ExtremeValue(CSG_Grid *pGrid, bool bMaximum) { if( Get_Cellsize() < pGrid->Get_Cellsize() || is_Intersecting(pGrid->Get_Extent()) == INTERSECTION_None ) { return( false ); } //----------------------------------------------------- int x, y, ix, iy; double px, py, ax, ay, d, z; CSG_Matrix S(Get_NY(), Get_NX()), N(Get_NY(), Get_NX()); d = pGrid->Get_Cellsize() / Get_Cellsize(); Set_NoData_Value(pGrid->Get_NoData_Value()); Assign_NoData(); //----------------------------------------------------- ax = 0.5 + (pGrid->Get_XMin() - Get_XMin()) / Get_Cellsize(); ay = 0.5 + (pGrid->Get_YMin() - Get_YMin()) / Get_Cellsize(); for(y=0, py=ay; y<pGrid->Get_NY() && SG_UI_Process_Set_Progress(y, pGrid->Get_NY()); y++, py+=d) { if( (iy = (int)floor(py)) >= 0 && iy < Get_NY() ) { for(x=0, px=ax; x<pGrid->Get_NX(); x++, px+=d) { if( !pGrid->is_NoData(x, y) && (ix = (int)floor(px)) >= 0 && ix < Get_NX() ) { z = pGrid->asDouble(x, y); if( is_NoData(ix, iy) || (bMaximum == true && z > asDouble(ix, iy)) || (bMaximum == false && z < asDouble(ix, iy)) ) { Set_Value(ix, iy, z); } } } } } //----------------------------------------------------- Get_History() = pGrid->Get_History(); Get_History().Add_Child(SG_T("GRID_OPERATION"), CSG_String::Format(SG_T("%f -> %f"), pGrid->Get_Cellsize(), Get_Cellsize()))->Add_Property(SG_T("NAME"), LNG("Resampling")); SG_UI_Process_Set_Ready(); return( true ); }
//--------------------------------------------------------- bool CSG_Shapes::Make_Clean(void) { if( m_Type != SHAPE_TYPE_Polygon ) { return( true ); } for(int iShape=0; iShape<Get_Count() && SG_UI_Process_Set_Progress(iShape, Get_Count()); iShape++) { CSG_Shape_Polygon *pPolygon = (CSG_Shape_Polygon *)Get_Shape(iShape); for(int iPart=0; iPart<pPolygon->Get_Part_Count(); iPart++) { if( m_Vertex_Type == SG_VERTEX_TYPE_XY ) // currently we have to disable this check for 3D shapefiles since the // _Update_Area() method can not handle polygons with no horizontal extent { //-------------------------------------------- // ring direction: outer rings > clockwise, inner rings (lakes) > counterclockwise ! if( (pPolygon->is_Lake(iPart) == pPolygon->is_Clockwise(iPart)) ) { pPolygon->Revert_Points(iPart); } } //-------------------------------------------- // last point == first point ! if( !CSG_Point(pPolygon->Get_Point(0, iPart)).is_Equal(pPolygon->Get_Point(pPolygon->Get_Point_Count(iPart) - 1, iPart)) ) { ((CSG_Shape *)pPolygon)->Add_Point(pPolygon->Get_Point(0, iPart), iPart); if( m_Vertex_Type != SG_VERTEX_TYPE_XY ) { pPolygon->Set_Z(pPolygon->Get_Z(0, iPart), pPolygon->Get_Point_Count(iPart) - 1, iPart); if( m_Vertex_Type == SG_VERTEX_TYPE_XYZM ) { pPolygon->Set_M(pPolygon->Get_M(0, iPart), pPolygon->Get_Point_Count(iPart) - 1, iPart); } } } //-------------------------------------------- // no self intersection ! } } return( true ); }
//--------------------------------------------------------- bool CSG_Matrix::Set_Inverse(bool bSilent, int nSubSquare) { bool bResult = false; int n = 0; //----------------------------------------------------- if( nSubSquare > 0 ) { if( nSubSquare <= m_nx && nSubSquare <= m_ny ) { n = nSubSquare; } } else if( is_Square() ) { n = m_nx; } //----------------------------------------------------- if( n > 0 ) { CSG_Matrix m(*this); int *Permutation = (int *)SG_Malloc(n * sizeof(int)); if( SG_Matrix_LU_Decomposition(n, Permutation, m.Get_Data(), bSilent) ) { CSG_Vector v(n); for(int j=0; j<n && (bSilent || SG_UI_Process_Set_Progress(j, n)); j++) { v.Set_Zero(); v[j] = 1.0; SG_Matrix_LU_Solve(n, Permutation, m, v.Get_Data(), true); for(int i=0; i<n; i++) { m_z[i][j] = v[i]; } } bResult = true; } SG_Free(Permutation); } return( bResult ); }
//--------------------------------------------------------- bool CSG_Table::_Save_Text(const CSG_String &File_Name, bool bHeadline, const SG_Char *Separator) { int iField, iRecord; CSG_File Stream; if( Get_Field_Count() > 0 ) { if( Stream.Open(File_Name, SG_FILE_W, false) ) { for(iField=0; iField<Get_Field_Count(); iField++) { Stream.Printf(SG_T("%s%s"), Get_Field_Name(iField), iField < Get_Field_Count() - 1 ? Separator : SG_T("\n")); } for(iRecord=0; iRecord<Get_Record_Count() && SG_UI_Process_Set_Progress(iRecord, Get_Record_Count()); iRecord++) { for(iField=0; iField<Get_Field_Count(); iField++) { if( !Get_Record(iRecord)->is_NoData(iField) ) { switch( Get_Field_Type(iField) ) { case SG_DATATYPE_String: case SG_DATATYPE_Date: Stream.Printf(SG_T("\"%s\""), Get_Record(iRecord)->asString(iField)); break; default: Stream.Printf(SG_T("%s") , Get_Record(iRecord)->asString(iField)); break; } } Stream.Printf(SG_T("%s"), iField < Get_Field_Count() - 1 ? Separator : SG_T("\n")); } } SG_UI_Process_Set_Ready(); return( true ); } } return( false ); }
//--------------------------------------------------------- bool CGrid_Normalise::On_Execute(void) { CSG_Grid *pGrid = Parameters("INPUT")->asGrid(); if( pGrid->Get_StdDev() <= 0.0 ) { return( false ); } if( pGrid != Parameters("OUTPUT")->asGrid() ) { pGrid = Parameters("OUTPUT")->asGrid(); pGrid ->Assign(Parameters("INPUT")->asGrid()); } pGrid->Fmt_Name("%s (%s)", pGrid->Get_Name(), _TL("Normalized")); //----------------------------------------------------- double Minimum, Maximum, Offset, Scale; Minimum = Parameters("RANGE")->asRange()->Get_Min(); Maximum = Parameters("RANGE")->asRange()->Get_Max(); Offset = pGrid->Get_Min(); Scale = (Maximum - Minimum) / pGrid->Get_Range(); for(int y=0; y<Get_NY() && SG_UI_Process_Set_Progress(y, Get_NY()); y++) { for(int x=0; x<Get_NX(); x++) { if( !pGrid->is_NoData(x, y) ) { pGrid->Set_Value(x, y, Minimum + Scale * (pGrid->asDouble(x, y) - Offset)); } } } //----------------------------------------------------- if( pGrid == Parameters("INPUT")->asGrid() ) { DataObject_Update(pGrid); } return( true ); }
//--------------------------------------------------------- bool CGrid_Standardise::On_Execute(void) { CSG_Grid *pGrid = Parameters("INPUT")->asGrid(); if( pGrid->Get_StdDev() <= 0.0 ) { return( false ); } if( pGrid != Parameters("OUTPUT")->asGrid() ) { pGrid = Parameters("OUTPUT")->asGrid(); pGrid ->Assign(Parameters("INPUT")->asGrid()); } pGrid->Fmt_Name("%s (%s)", pGrid->Get_Name(), _TL("Standard Score")); //----------------------------------------------------- double Mean = pGrid->Get_Mean(); double Stretch = Parameters("STRETCH")->asDouble() / pGrid->Get_StdDev(); for(int y=0; y<Get_NY() && SG_UI_Process_Set_Progress(y, Get_NY()); y++) { #pragma omp parallel for for(int x=0; x<Get_NX(); x++) { if( !pGrid->is_NoData(x, y) ) { pGrid->Set_Value(x, y, Stretch * (pGrid->asDouble(x, y) - Mean)); } } } //----------------------------------------------------- if( pGrid == Parameters("INPUT")->asGrid() ) { DataObject_Update(pGrid); } return( true ); }
//--------------------------------------------------------- void CSG_Grid::Mirror(void) { int xA, xB, y; double d; if( is_Valid() ) { for(y=0; y<Get_NY() && SG_UI_Process_Set_Progress(y, Get_NY()); y++) { for(xA=0, xB=Get_NX()-1; xA<xB; xA++, xB--) { d = asDouble(xA, y); Set_Value(xA, y, asDouble(xB, y)); Set_Value(xB, y, d); } } SG_UI_Process_Set_Ready(); Get_History().Add_Child(SG_T("GRID_OPERATION"), LNG("Horizontally mirrored")); } }
//--------------------------------------------------------- bool CGrid_Invert::On_Execute(void) { CSG_Grid *pGrid = Parameters("INVERSE")->asGrid(); if( pGrid == NULL ) { pGrid = Parameters("GRID")->asGrid(); } else if( pGrid != Parameters("GRID")->asGrid() ) { pGrid->Create(*Parameters("GRID")->asGrid()); pGrid->Fmt_Name("%s [%s]", pGrid->Get_Name(), _TL("Inverse")); } //----------------------------------------------------- double zMin = pGrid->Get_Min(); double zMax = pGrid->Get_Max(); for(int y=0; y<Get_NY() && SG_UI_Process_Set_Progress(y, Get_NY()); y++) { #pragma omp parallel for for(int x=0; x<Get_NX(); x++) { if( !pGrid->is_NoData(x, y) ) { pGrid->Set_Value(x, y, zMax - (pGrid->asDouble(x, y) - zMin)); } } } //----------------------------------------------------- if( pGrid == Parameters("GRID")->asGrid() ) { DataObject_Update(pGrid); } return( true ); }
//--------------------------------------------------------- bool CSG_Grid::_Load_ASCII(CSG_File &Stream, TSG_Grid_Memory_Type Memory_Type, bool bFlip) { int x, y, iy, dy; double Value; if( Stream.is_Open() && m_System.is_Valid() && m_Type != SG_DATATYPE_Undefined && _Memory_Create(Memory_Type) ) { Set_File_Type(GRID_FILE_FORMAT_ASCII); if( bFlip ) { y = Get_NY() - 1; dy = -1; } else { y = 0; dy = 1; } //------------------------------------------------- for(iy=0; iy<Get_NY() && SG_UI_Process_Set_Progress(iy, Get_NY()); iy++, y+=dy) { for(x=0; x<Get_NX(); x++) { SG_FILE_SCANF(Stream.Get_Stream(), SG_T("%lf"), &Value); Set_Value(x, y, Value); } } SG_UI_Process_Set_Ready(); return( true ); } return( false ); }
//--------------------------------------------------------- bool CSG_Grid::_Save_ASCII(CSG_File &Stream, int xA, int yA, int xN, int yN, bool bFlip) { int x, y, ix, iy, dy; if( Stream.is_Open() && is_Valid() ) { Set_File_Type(GRID_FILE_FORMAT_ASCII); if( bFlip ) { y = yA + yN - 1; dy = -1; } else { y = yA; dy = 1; } //------------------------------------------------- for(iy=0; iy<yN && SG_UI_Process_Set_Progress(iy, yN); iy++, y+=dy) { for(ix=0, x=xA; ix<xN; ix++, x++) { Stream.Printf(SG_T("%lf "), asDouble(x, y)); } Stream.Printf(SG_T("\n")); } SG_UI_Process_Set_Ready(); return( true ); } return( false ); }
//--------------------------------------------------------- void CSG_Grid::Flip(void) { int x, yA, yB; double *Line, d; if( is_Valid() ) { Line = (double *)SG_Malloc(Get_NX() * sizeof(double)); for(yA=0, yB=Get_NY()-1; yA<yB && SG_UI_Process_Set_Progress(2 * yA, Get_NY()); yA++, yB--) { for(x=0; x<Get_NX(); x++) { Line[x] = asDouble(x, yA); } for(x=0; x<Get_NX(); x++) { d = Line[x]; Line[x] = asDouble(x, yB); Set_Value(x, yB, d); } for(x=0; x<Get_NX(); x++) { Set_Value(x, yA, Line[x]); } } SG_UI_Process_Set_Ready(); SG_Free(Line); Get_History().Add_Child(SG_T("GRID_OPERATION"), LNG("Vertically mirrored")); } }
//--------------------------------------------------------- void CSG_Grid::DeNormalise(double ArithMean, double Variance) { int x, y; if( is_Valid() ) { Variance = sqrt(Variance); for(y=0; y<Get_NY() && SG_UI_Process_Set_Progress(y, Get_NY()); y++) { for(x=0; x<Get_NX(); x++) { if( !is_NoData(x, y) ) { Set_Value(x, y, Variance * asDouble(x, y) + ArithMean); } } } SG_UI_Process_Set_Ready(); Get_History().Add_Child(SG_T("GRID_OPERATION"), LNG("Denormalisation")); } }
//--------------------------------------------------------- void CVisibility_BASE::Set_Visibility(CSG_Grid *pDTM, CSG_Grid *pVisibility, int x_Pos, int y_Pos, double z_Pos, double dHeight, int iMethod) { double Exaggeration = 1.0; double aziDTM, decDTM, aziSrc, decSrc, d, dx, dy, dz; for(int y=0; y<pDTM->Get_NY() && SG_UI_Process_Set_Progress(y, pDTM->Get_NY()); y++) { for(int x=0; x<pDTM->Get_NX(); x++) { if( pDTM->is_NoData(x, y) ) { pVisibility->Set_NoData(x, y); } else { dx = x_Pos - x; dy = y_Pos - y; dz = z_Pos - pDTM->asDouble(x, y); //----------------------------------------- if( Trace_Point(pDTM, x, y, dx, dy, dz) ) { switch( iMethod ) { case 0: // Visibility pVisibility->Set_Value(x, y, 1); break; case 1: // Shade pDTM->Get_Gradient(x, y, decDTM, aziDTM); decDTM = M_PI_090 - atan(Exaggeration * tan(decDTM)); decSrc = atan2(dz, sqrt(dx*dx + dy*dy)); aziSrc = atan2(dx, dy); d = acos(sin(decDTM) * sin(decSrc) + cos(decDTM) * cos(decSrc) * cos(aziDTM - aziSrc)); if( d > M_PI_090 ) d = M_PI_090; if( pVisibility->asDouble(x, y) > d ) pVisibility->Set_Value(x, y, d); break; case 2: // Distance d = pDTM->Get_Cellsize() * sqrt(dx*dx + dy*dy); if( pVisibility->is_NoData(x, y) || pVisibility->asDouble(x, y) > d ) pVisibility->Set_Value(x, y, d); break; case 3: // Size if( (d = pDTM->Get_Cellsize() * sqrt(dx*dx + dy*dy)) > 0.0 ) { d = atan2(dHeight, d); if( pVisibility->is_NoData(x, y) || pVisibility->asDouble(x, y) < d ) pVisibility->Set_Value(x, y, d); } break; } } } } } return; }
bool g_Set_Progress (int i, int n) { return( g_bProgress ? SG_UI_Process_Set_Progress(i, n) : SG_UI_Process_Get_Okay() ); }
//--------------------------------------------------------- bool Cut_Shapes(CSG_Shapes *pPolygons, int Method, CSG_Shapes *pShapes, CSG_Shapes *pCut) { if( pCut && pShapes && pShapes->is_Valid() && pPolygons && pPolygons->is_Valid() && pPolygons->Get_Extent().Intersects(pShapes->Get_Extent()) ) { pCut->Create( pShapes->Get_Type(), CSG_String::Format(SG_T("%s [%s]"), pShapes->Get_Name(), _TL("Cut")), pShapes ); for(int iShape=0; iShape<pShapes->Get_Count() && SG_UI_Process_Set_Progress(iShape, pShapes->Get_Count()); iShape++) { bool bAdd; CSG_Shape *pShape = pShapes->Get_Shape(iShape); if( Method == 2 ) // center { bAdd = false; TSG_Point Center; if( pShapes->Get_Type() == SHAPE_TYPE_Polygon ) Center = ((CSG_Shape_Polygon *)pShape)->Get_Centroid(); else Center = pShape->Get_Extent().Get_Center(); if( pPolygons->Select(Center) ) { bAdd = true; } } else if( Method == 1 ) // intersects { bAdd = false; for(int iPart=0; iPart<pShape->Get_Part_Count() && !bAdd; iPart++) { for(int iPoint=0; iPoint<pShape->Get_Point_Count(iPart) && !bAdd; iPoint++) { if( pPolygons->Select(pShape->Get_Point(iPoint, iPart)) ) { bAdd = true; } } } } else // completely contained { bAdd = true; for(int iPart=0; iPart<pShape->Get_Part_Count() && bAdd; iPart++) { for(int iPoint=0; iPoint<pShape->Get_Point_Count(iPart) && bAdd; iPoint++) { if( pPolygons->Select(pShape->Get_Point(iPoint, iPart)) == false ) { bAdd = false; } } } } if( bAdd ) { pCut->Add_Shape(pShape); } } return( pCut->Get_Count() > 0 ); } return( false ); }
//--------------------------------------------------------- bool CGrid_Mirror::On_Execute(void) { CSG_Grid *pGrid = Parameters("MIRROR")->asGrid(); if( pGrid == NULL ) { pGrid = Parameters("GRID")->asGrid(); } else if( pGrid != Parameters("GRID")->asGrid() ) { pGrid->Create(*Parameters("GRID")->asGrid()); pGrid->Fmt_Name("%s [%s %s]", pGrid->Get_Name(), _TL("mirrored"), Parameters("METHOD")->asString()); } //----------------------------------------------------- switch( Parameters("METHOD")->asInt() ) { //----------------------------------------------------- case 0: // vertically { for(int xa=0, xb=Get_NX()-1; xa<xb && SG_UI_Process_Set_Progress(xa, Get_NX()/2); xa++, xb--) { #pragma omp parallel for for(int y=0; y<Get_NY(); y++) { double d = pGrid->asDouble(xa, y); pGrid->Set_Value(xa, y, pGrid->asDouble(xb, y)); pGrid->Set_Value(xb, y, d); } } } break; //----------------------------------------------------- case 1: // horizontally { for(int ya=0, yb=Get_NY()-1; ya<yb && SG_UI_Process_Set_Progress(ya, Get_NY()/2); ya++, yb--) { #pragma omp parallel for for(int x=0; x<Get_NX(); x++) { double d = pGrid->asDouble(x, ya); pGrid->Set_Value(x, ya, pGrid->asDouble(x, yb)); pGrid->Set_Value(x, yb, d); } } } break; //----------------------------------------------------- default: // both { for(int ya=0, yb=Get_NY()-1; ya<=yb && SG_UI_Process_Set_Progress(ya, Get_NY()/2); ya++, yb--) { for(int xa=0, xb=Get_NX()-1; xa<=xb; xa++, xb--) { if( ya < yb && xa < xb ) { double d = pGrid->asDouble(xa, ya); pGrid->Set_Value(xa, ya, pGrid->asDouble(xb, yb)); pGrid->Set_Value(xb, yb, d); d = pGrid->asDouble(xa, yb); pGrid->Set_Value(xa, yb, pGrid->asDouble(xb, ya)); pGrid->Set_Value(xb, ya, d); } else if( xa < xb ) { double d = pGrid->asDouble(xa, ya); pGrid->Set_Value(xa, ya, pGrid->asDouble(xb, ya)); pGrid->Set_Value(xb, ya, d); } else if( ya < yb ) { double d = pGrid->asDouble(xa, ya); pGrid->Set_Value(xa, ya, pGrid->asDouble(xa, yb)); pGrid->Set_Value(xa, yb, d); } } } } break; } //----------------------------------------------------- if( pGrid == Parameters("GRID")->asGrid() ) { DataObject_Update(pGrid); } return( true ); }
//--------------------------------------------------------- bool CSG_TIN::_Triangulate(CSG_TIN_Node **Points, int nPoints, TTIN_Triangle *Triangles, int &nTriangles) { int i, j, k, inside, trimax, nedge = 0, emax = 200, status = 0, *complete = NULL; double dmax, xp, yp, x1, y1, x2, y2, x3, y3, xc, yc, r; TTIN_Edge *edges = NULL; //----------------------------------------------------- // Update extent... if( nPoints >= 3 ) { TSG_Rect r; m_Extent.Assign( Points[0]->Get_X(), Points[0]->Get_Y(), Points[0]->Get_X(), Points[0]->Get_Y() ); for(i=1; i<nPoints; i++) { r.xMin = r.xMax = Points[i]->Get_X(); r.yMin = r.yMax = Points[i]->Get_Y(); m_Extent.Union(r); } } else { return( false ); } //----------------------------------------------------- // Allocate memory for the completeness list, flag for each triangle trimax = 4 * nPoints; if( (complete = (int *)SG_Malloc(trimax * sizeof(int))) == NULL ) { status = 1; goto skip; } //----------------------------------------------------- // Allocate memory for the edge list if( (edges = (TTIN_Edge *)SG_Malloc(emax * sizeof(TTIN_Edge))) == NULL ) { status = 2; goto skip; } //----------------------------------------------------- // Find the maximum and minimum vertex bounds. // This is to allow calculation of the bounding triangle // Set up the supertriangle // This is a triangle which encompasses all the sample points. // The supertriangle coordinates are added to the end of the // vertex list. The supertriangle is the first triangle in // the triangle list. dmax = m_Extent.Get_XRange() > m_Extent.Get_YRange() ? m_Extent.Get_XRange() : m_Extent.Get_YRange(); Points[nPoints + 0]->m_Point.x = m_Extent.Get_XCenter() - 20 * dmax; Points[nPoints + 1]->m_Point.x = m_Extent.Get_XCenter(); Points[nPoints + 2]->m_Point.x = m_Extent.Get_XCenter() + 20 * dmax; Points[nPoints + 0]->m_Point.y = m_Extent.Get_YCenter() - dmax; Points[nPoints + 1]->m_Point.y = m_Extent.Get_YCenter() + 20 * dmax; Points[nPoints + 2]->m_Point.y = m_Extent.Get_YCenter() - dmax; Triangles[0].p1 = nPoints; Triangles[0].p2 = nPoints + 1; Triangles[0].p3 = nPoints + 2; complete [0] = false; nTriangles = 1; //----------------------------------------------------- // Include each point one at a time into the existing mesh for(i=0; i<nPoints && SG_UI_Process_Set_Progress(i, nPoints); i++) { xp = Points[i]->Get_X(); yp = Points[i]->Get_Y(); nedge = 0; //------------------------------------------------- // Set up the edge buffer. // If the point (xp,yp) lies inside the circumcircle then the // three edges of that triangle are added to the edge buffer // and that triangle is removed. for(j=0; j<nTriangles; j++) { if( complete[j] ) { continue; } x1 = Points[Triangles[j].p1]->Get_X(); y1 = Points[Triangles[j].p1]->Get_Y(); x2 = Points[Triangles[j].p2]->Get_X(); y2 = Points[Triangles[j].p2]->Get_Y(); x3 = Points[Triangles[j].p3]->Get_X(); y3 = Points[Triangles[j].p3]->Get_Y(); inside = _CircumCircle(xp, yp, x1, y1, x2, y2, x3, y3, &xc, &yc, &r); if( xc + r < xp ) { complete[j] = true; } if( inside ) { // Check that we haven't exceeded the edge list size if( nedge + 3 >= emax ) { emax += 100; if( (edges = (TTIN_Edge *)SG_Realloc(edges, emax * sizeof(TTIN_Edge))) == NULL ) { status = 3; goto skip; } } edges[nedge + 0].p1 = Triangles[j].p1; edges[nedge + 0].p2 = Triangles[j].p2; edges[nedge + 1].p1 = Triangles[j].p2; edges[nedge + 1].p2 = Triangles[j].p3; edges[nedge + 2].p1 = Triangles[j].p3; edges[nedge + 2].p2 = Triangles[j].p1; nedge += 3; Triangles[j] = Triangles[nTriangles - 1]; complete [j] = complete [nTriangles - 1]; nTriangles--; j--; } } //------------------------------------------------- // Tag multiple edges // Note: if all triangles are specified anticlockwise then all // interior edges are opposite pointing in direction. for(j=0; j<nedge-1; j++) { for(k=j+1; k<nedge; k++) { if( (edges[j].p1 == edges[k].p2) && (edges[j].p2 == edges[k].p1) ) { edges[j].p1 = -1; edges[j].p2 = -1; edges[k].p1 = -1; edges[k].p2 = -1; } // Shouldn't need the following, see note above if( (edges[j].p1 == edges[k].p1) && (edges[j].p2 == edges[k].p2) ) { edges[j].p1 = -1; edges[j].p2 = -1; edges[k].p1 = -1; edges[k].p2 = -1; } } } //------------------------------------------------- // Form new triangles for the current point // Skipping over any tagged edges. // All edges are arranged in clockwise order. for(j=0; j<nedge; j++) { if( edges[j].p1 < 0 || edges[j].p2 < 0 ) { continue; } if( nTriangles >= trimax ) { status = 4; goto skip; } Triangles[nTriangles].p1 = edges[j].p1; Triangles[nTriangles].p2 = edges[j].p2; Triangles[nTriangles].p3 = i; complete [nTriangles] = false; nTriangles++; } } //----------------------------------------------------- // Remove triangles with supertriangle vertices // These are triangles which have a vertex number greater than nPoints for(i=0; i<nTriangles; i++) { if( Triangles[i].p1 >= nPoints || Triangles[i].p2 >= nPoints || Triangles[i].p3 >= nPoints ) { Triangles[i] = Triangles[nTriangles - 1]; nTriangles--; i--; } } //----------------------------------------------------- skip: if( edges ) { SG_Free(edges); } if( complete ) { SG_Free(complete); } return( status == 0 ); }
//--------------------------------------------------------- bool CSG_TIN::_Triangulate(void) { bool bResult; int i, j, n, nTriangles; CSG_TIN_Node **Nodes; TTIN_Triangle *Triangles; //----------------------------------------------------- _Destroy_Edges(); _Destroy_Triangles(); //----------------------------------------------------- Nodes = (CSG_TIN_Node **)SG_Malloc((Get_Node_Count() + 3) * sizeof(CSG_TIN_Node *)); for(i=0; i<Get_Node_Count(); i++) { Nodes[i] = Get_Node(i); Nodes[i] ->_Del_Relations(); } //----------------------------------------------------- qsort(Nodes, Get_Node_Count(), sizeof(CSG_TIN_Node *), SG_TIN_Compare); for(i=0, j=0, n=Get_Node_Count(); j<n; i++) // remove duplicates { Nodes[i] = Nodes[j++]; while( j < n && Nodes[i]->Get_X() == Nodes[j]->Get_X() && Nodes[i]->Get_Y() == Nodes[j]->Get_Y() ) { Del_Node(Nodes[j++]->Get_Index(), false); } } //----------------------------------------------------- for(i=Get_Node_Count(); i<Get_Node_Count()+3; i++) { Nodes[i] = new CSG_TIN_Node(this, 0); } //----------------------------------------------------- Triangles = (TTIN_Triangle *)SG_Malloc(3 * Get_Node_Count() * sizeof(TTIN_Triangle)); if( (bResult = _Triangulate(Nodes, Get_Node_Count(), Triangles, nTriangles)) == true ) { for(i=0; i<nTriangles && SG_UI_Process_Set_Progress(i, nTriangles); i++) { _Add_Triangle(Nodes[Triangles[i].p1], Nodes[Triangles[i].p2], Nodes[Triangles[i].p3]); } } SG_Free(Triangles); //----------------------------------------------------- for(i=Get_Node_Count(); i<Get_Node_Count()+3; i++) { delete(Nodes[i]); } SG_Free(Nodes); SG_UI_Process_Set_Ready(); return( bResult ); }