private void Rev_Caculate(IRaster direction, IRaster label)
        {
            bool is_break = false;

            for (int i = ExecuteRaster.NumRows - 1; i >= 0; i--)
            {
                for (int j = ExecuteRaster.NumColumns - 1; j >= 0; j--)
                {
                    if (label.Value[i, j] == 0.0)
                    {
                        if (ExecuteRaster.Value[i, j] != ExecuteRaster.NoDataValue)
                        {
                            RasterPixel rp        = new RasterPixel(i, j, ExecuteRaster.Value[i, j]);
                            int         Direction = Direct(rp);
                            direction.Value[i, j] = Direction;
                            label.Value[i, j]     = ExecuteRaster.NoDataValue;
                        }
                        else
                        {
                            direction.Value[i, j] = ExecuteRaster.NoDataValue;
                            label.Value[i, j]     = ExecuteRaster.NoDataValue;
                        }
                    }
                    else
                    {
                        is_break = true;
                        break;
                    }
                }
                if (is_break)
                {
                    break;
                }
            }
        }
        //Execute the drop of two cells
        private double Drop(RasterPixel rp1, RasterPixel rp2) //rp1 is the middle pixel.
        {
            Coordinate coor1    = ExecuteRaster.CellToProj(rp1.Row, rp1.Column);
            Coordinate coor2    = ExecuteRaster.CellToProj(rp2.Row, rp2.Column);
            double     distance = coor1.Distance(coor2);
            double     change_z = rp1.Value - rp2.Value;
            double     drop     = change_z / distance;

            return(drop);
        }
        //Get the max value pixel's direction
        private int Pixel_MaxValue(List <RasterPixel> RsList, double MaxValue, RasterPixel rp)
        {
            int row = 0, column = 0;

            for (int i = 0; i < RsList.Count; i++)
            {
                if (RsList[i].Value == MaxValue)
                {
                    row    = RsList[i].Row;
                    column = RsList[i].Column;
                }
            }
            if ((rp.Row - row == 0) && (rp.Column - column == 1)) //Left
            {
                return(16);
            }
            else if ((rp.Row - row == 0) && (rp.Column - column == -1)) //Right
            {
                return(1);
            }
            else if ((rp.Column - column == 0) && (rp.Row - row == 1)) //Top
            {
                return(64);
            }
            else if ((rp.Column - column == 0) && (rp.Row - row == -1)) //Bottom
            {
                return(4);
            }
            else if ((rp.Row - row == 1) && (rp.Column - column == 1)) //TopLeft
            {
                return(32);
            }
            else if ((rp.Row - row == 1) && (rp.Column - column == -1)) //TopRight
            {
                return(128);
            }
            else if ((rp.Row - row == -1) && (rp.Column - column == 1)) //BottomLeft
            {
                return(8);
            }
            else if ((rp.Row - row == -1) && (rp.Column - column == -1))  //BottomRight
            {
                return(2);
            }
            else
            {
                return(-1);
            }
        }
 public void Rev_Accumulate()
 {
     for (int i = ExecuteRaster.NumRows - 1; i >= 0; i--)
     {
         for (int j = ExecuteRaster.NumColumns - 1; j >= 0; j--)
         {
             if (LabelRaster.Value[i, j] == 0.0)
             {
                 if (ExecuteRaster.Value[i, j] != ExecuteRaster.NoDataValue)
                 {
                     Stack <RasterPixel> Stack1     = new Stack <RasterPixel>();
                     long        Accumulation_Count = 0;
                     RasterPixel NewRp = new RasterPixel(i, j, ExecuteRaster.Value[i, j]);
                     Stack1.Push(NewRp);
                     LabelRaster.Value[NewRp.Row, NewRp.Column] = LabelRaster.NoDataValue;
                     do
                     {
                         RasterPixel        tempRP = Stack1.Pop();
                         List <RasterPixel> RpArr  = NeiborList(tempRP);
                         for (int a = 0; a < RpArr.Count; a++)
                         {
                             RasterPixel tempRP2 = Get_Direction_Pixel(tempRP, RpArr[a]);
                             if (tempRP2 != null)
                             {
                                 if (LabelRaster.Value[tempRP2.Row, tempRP2.Column] == 0.0)
                                 {
                                     Stack1.Push(tempRP2);
                                     Accumulation_Count++;
                                     LabelRaster.Value[tempRP2.Row, tempRP2.Column] = LabelRaster.NoDataValue;
                                 }
                             }
                         }
                     } while (Stack1.Count != 0);
                     AccumulationRaster.Value[i, j] = Accumulation_Count;
                 }
                 else
                 {
                     AccumulationRaster.Value[i, j] = AccumulationRaster.NoDataValue;
                 }
             }
         }
     }
 }
        //Judge the direction
        private int Direct(RasterPixel rp)
        {
            //Init neibor
            List <RasterPixel> DropList = new List <RasterPixel>();

            if (0 <= rp.Column - 1)
            {
                //if(ExecuteRaster.Value[rp.Row,rp.Column-1]!=ExecuteRaster.NoDataValue)
                //{
                RasterPixel rp_Left   = new RasterPixel(rp.Row, rp.Column - 1, ExecuteRaster.Value[rp.Row, rp.Column - 1]);
                double      DropValue = Drop(rp, rp_Left);
                rp_Left.Value = DropValue;
                DropList.Add(rp_Left);
                //}
            }
            if ((0 <= rp.Column - 1) && (0 <= rp.Row - 1))
            {
                //if(ExecuteRaster.Value[rp.Row-1,rp.Column-1]!=ExecuteRaster.NoDataValue)
                //{
                RasterPixel rp_TopLeft = new RasterPixel(rp.Row - 1, rp.Column - 1, ExecuteRaster.Value[rp.Row - 1, rp.Column - 1]);
                double      DropValue  = Drop(rp, rp_TopLeft);
                rp_TopLeft.Value = DropValue;
                DropList.Add(rp_TopLeft);
                //}
            }
            if ((0 <= rp.Row - 1))
            {
                //if(ExecuteRaster.Value[rp.Row-1,rp.Column]!=ExecuteRaster.NoDataValue)
                //{
                RasterPixel rp_Top    = new RasterPixel(rp.Row - 1, rp.Column, ExecuteRaster.Value[rp.Row - 1, rp.Column]);
                double      DropValue = Drop(rp, rp_Top);
                rp_Top.Value = DropValue;
                DropList.Add(rp_Top);
                //}
            }
            if ((rp.Row - 1 >= 0) && (rp.Column + 1 < ExecuteRaster.NumColumns))
            {
                //if((ExecuteRaster.Value[rp.Row-1,rp.Column+1]!=ExecuteRaster.NoDataValue))
                //{
                RasterPixel rp_TopRight = new RasterPixel(rp.Row - 1, rp.Column + 1, ExecuteRaster.Value[rp.Row - 1, rp.Column + 1]);
                double      DropValue   = Drop(rp, rp_TopRight);
                rp_TopRight.Value = DropValue;
                DropList.Add(rp_TopRight);
                //}
            }
            if ((rp.Column + 1 < ExecuteRaster.NumColumns))
            {
                //if(ExecuteRaster.Value[rp.Row,rp.Column+1]!=ExecuteRaster.NoDataValue)
                //{
                RasterPixel rp_Right  = new RasterPixel(rp.Row, rp.Column + 1, ExecuteRaster.Value[rp.Row, rp.Column + 1]);
                double      DropValue = Drop(rp, rp_Right);
                rp_Right.Value = DropValue;
                DropList.Add(rp_Right);
                //}
            }
            if ((rp.Column + 1 < ExecuteRaster.NumColumns) && (rp.Row + 1 < ExecuteRaster.NumRows))
            {
                //if(ExecuteRaster.Value[rp.Row+1,rp.Column+1]!=ExecuteRaster.NoDataValue)
                //{
                RasterPixel rp_BottomRight = new RasterPixel(rp.Row + 1, rp.Column + 1, ExecuteRaster.Value[rp.Row + 1, rp.Column + 1]);
                double      DropValue      = Drop(rp, rp_BottomRight);
                rp_BottomRight.Value = DropValue;
                DropList.Add(rp_BottomRight);
                //}
            }
            if (rp.Row + 1 < ExecuteRaster.NumRows)
            {
                //if(ExecuteRaster.Value[rp.Row+1,rp.Column]!=ExecuteRaster.NoDataValue)
                //{
                RasterPixel rp_Bottom = new RasterPixel(rp.Row + 1, rp.Column, ExecuteRaster.Value[rp.Row + 1, rp.Column]);
                double      DropValue = Drop(rp, rp_Bottom);
                rp_Bottom.Value = DropValue;
                DropList.Add(rp_Bottom);
                //}
            }
            if ((rp.Row + 1 < ExecuteRaster.NumRows) && (rp.Column - 1 >= 0))
            {
                //if(ExecuteRaster.Value[rp.Row+1,rp.Column-1]!=ExecuteRaster.NoDataValue)
                //{
                RasterPixel rp_BottomLeft = new RasterPixel(rp.Row + 1, rp.Column - 1, ExecuteRaster.Value[rp.Row + 1, rp.Column - 1]);
                double      DropValue     = Drop(rp, rp_BottomLeft);
                rp_BottomLeft.Value = DropValue;
                DropList.Add(rp_BottomLeft);
                //}
            }

            double MaxValue = GetMaxValue(DropList);

            if (MaxValue < 0) //This pixel is depression
            {
                return(-1);
            }
            else if ((MaxValue >= 0) && (Num_MaxValue(DropList, MaxValue) == 1))
            {
                return(Pixel_MaxValue(DropList, MaxValue, rp));
            }
            else if ((MaxValue == 0) && (Num_MaxValue(DropList, MaxValue) > 1)) //This pixel is depression
            {
                return(Pixel_MaxValue(DropList, MaxValue, rp));
            }
            else if ((MaxValue > 0) && (Num_MaxValue(DropList, MaxValue) > 1))
            {
                return(Pixel_MaxValue(DropList, MaxValue, rp));
            }
            else
            {
                return(-1);
            }
        }
 //Get direction pixel
 private RasterPixel Get_Direction_Pixel(RasterPixel mid_rp, RasterPixel neibor_pixel)
 {
     if ((mid_rp.Row - neibor_pixel.Row == 0) && (mid_rp.Column - neibor_pixel.Column == 1)) //Left
     {
         if (ExecuteRaster.Value[neibor_pixel.Row, neibor_pixel.Column] == 1)
         {
             RasterPixel TempRaster = new RasterPixel(neibor_pixel.Row, neibor_pixel.Column, neibor_pixel.Value);
             return(TempRaster);
         }
     }
     else if ((mid_rp.Row - neibor_pixel.Row == 0) && (mid_rp.Column - neibor_pixel.Column == -1)) //Right
     {
         if (ExecuteRaster.Value[neibor_pixel.Row, neibor_pixel.Column] == 16)
         {
             RasterPixel TempRaster = new RasterPixel(neibor_pixel.Row, neibor_pixel.Column, neibor_pixel.Value);
             return(TempRaster);
         }
     }
     else if ((mid_rp.Column - neibor_pixel.Column == 0) && (mid_rp.Row - neibor_pixel.Row == 1)) //Top
     {
         if (ExecuteRaster.Value[neibor_pixel.Row, neibor_pixel.Column] == 4)
         {
             RasterPixel TempRaster = new RasterPixel(neibor_pixel.Row, neibor_pixel.Column, neibor_pixel.Value);
             return(TempRaster);
         }
     }
     else if ((mid_rp.Column - neibor_pixel.Column == 0) && (mid_rp.Row - neibor_pixel.Row == -1)) //Bottom
     {
         if (ExecuteRaster.Value[neibor_pixel.Row, neibor_pixel.Column] == 64)
         {
             RasterPixel TempRaster = new RasterPixel(neibor_pixel.Row, neibor_pixel.Column, neibor_pixel.Value);
             return(TempRaster);
         }
     }
     else if ((mid_rp.Row - neibor_pixel.Row == 1) && (mid_rp.Column - neibor_pixel.Column == 1)) //TopLeft
     {
         if (ExecuteRaster.Value[neibor_pixel.Row, neibor_pixel.Column] == 2)
         {
             RasterPixel TempRaster = new RasterPixel(neibor_pixel.Row, neibor_pixel.Column, neibor_pixel.Value);
             return(TempRaster);
         }
     }
     else if ((mid_rp.Row - neibor_pixel.Row == 1) && (mid_rp.Column - neibor_pixel.Column == -1)) //TopRight
     {
         if (ExecuteRaster.Value[neibor_pixel.Row, neibor_pixel.Column] == 8)
         {
             RasterPixel TempRaster = new RasterPixel(neibor_pixel.Row, neibor_pixel.Column, neibor_pixel.Value);
             return(TempRaster);
         }
     }
     else if ((mid_rp.Row - neibor_pixel.Row == -1) && (mid_rp.Column - neibor_pixel.Column == 1)) //BottomLeft
     {
         if (ExecuteRaster.Value[neibor_pixel.Row, neibor_pixel.Column] == 128)
         {
             RasterPixel TempRaster = new RasterPixel(neibor_pixel.Row, neibor_pixel.Column, neibor_pixel.Value);
             return(TempRaster);
         }
     }
     else if ((mid_rp.Row - neibor_pixel.Row == -1) && (mid_rp.Column - neibor_pixel.Column == -1))  //BottomRight
     {
         if (ExecuteRaster.Value[neibor_pixel.Row, neibor_pixel.Column] == 32)
         {
             RasterPixel TempRaster = new RasterPixel(neibor_pixel.Row, neibor_pixel.Column, neibor_pixel.Value);
             return(TempRaster);
         }
     }
     return(null);
 }
        //Get the Neibor pixel list
        private List <RasterPixel> NeiborList(RasterPixel rp)
        {
            List <RasterPixel> Neibor_L = new List <RasterPixel>();

            if (0 <= rp.Column - 1)
            {
                if (ExecuteRaster.Value[rp.Row, rp.Column - 1] != ExecuteRaster.NoDataValue)
                {
                    RasterPixel rp_Left = new RasterPixel(rp.Row, rp.Column - 1, ExecuteRaster.Value[rp.Row, rp.Column - 1]);
                    Neibor_L.Add(rp_Left);
                }
            }
            if ((0 <= rp.Column - 1) && (0 <= rp.Row - 1))
            {
                if (ExecuteRaster.Value[rp.Row - 1, rp.Column - 1] != ExecuteRaster.NoDataValue)
                {
                    RasterPixel rp_TopLeft = new RasterPixel(rp.Row - 1, rp.Column - 1, ExecuteRaster.Value[rp.Row - 1, rp.Column - 1]);
                    Neibor_L.Add(rp_TopLeft);
                }
            }
            if ((0 <= rp.Row - 1))
            {
                if (ExecuteRaster.Value[rp.Row - 1, rp.Column] != ExecuteRaster.NoDataValue)
                {
                    RasterPixel rp_Top = new RasterPixel(rp.Row - 1, rp.Column, ExecuteRaster.Value[rp.Row - 1, rp.Column]);
                    Neibor_L.Add(rp_Top);
                }
            }
            if ((rp.Row - 1 >= 0) && (rp.Column + 1 < ExecuteRaster.NumColumns))
            {
                if ((ExecuteRaster.Value[rp.Row - 1, rp.Column + 1] != ExecuteRaster.NoDataValue))
                {
                    RasterPixel rp_TopRight = new RasterPixel(rp.Row - 1, rp.Column + 1, ExecuteRaster.Value[rp.Row - 1, rp.Column + 1]);
                    Neibor_L.Add(rp_TopRight);
                }
            }
            if ((rp.Column + 1 < ExecuteRaster.NumColumns))
            {
                if (ExecuteRaster.Value[rp.Row, rp.Column + 1] != ExecuteRaster.NoDataValue)
                {
                    RasterPixel rp_Right = new RasterPixel(rp.Row, rp.Column + 1, ExecuteRaster.Value[rp.Row, rp.Column + 1]);
                    Neibor_L.Add(rp_Right);
                }
            }
            if ((rp.Column + 1 < ExecuteRaster.NumColumns) && (rp.Row + 1 < ExecuteRaster.NumRows))
            {
                if (ExecuteRaster.Value[rp.Row + 1, rp.Column + 1] != ExecuteRaster.NoDataValue)
                {
                    RasterPixel rp_BottomRight = new RasterPixel(rp.Row + 1, rp.Column + 1, ExecuteRaster.Value[rp.Row + 1, rp.Column + 1]);
                    Neibor_L.Add(rp_BottomRight);
                }
            }
            if (rp.Row + 1 < ExecuteRaster.NumRows)
            {
                if (ExecuteRaster.Value[rp.Row + 1, rp.Column] != ExecuteRaster.NoDataValue)
                {
                    RasterPixel rp_Bottom = new RasterPixel(rp.Row + 1, rp.Column, ExecuteRaster.Value[rp.Row + 1, rp.Column]);
                    Neibor_L.Add(rp_Bottom);
                }
            }
            if ((rp.Row + 1 < ExecuteRaster.NumRows) && (rp.Column - 1 >= 0))
            {
                if (ExecuteRaster.Value[rp.Row + 1, rp.Column - 1] != ExecuteRaster.NoDataValue)
                {
                    RasterPixel rp_BottomLeft = new RasterPixel(rp.Row + 1, rp.Column - 1, ExecuteRaster.Value[rp.Row + 1, rp.Column - 1]);
                    Neibor_L.Add(rp_BottomLeft);
                }
            }
            return(Neibor_L);
        }