/// <summary> /// Merge basins using using MapWinGIS.Utils /// </summary> /// <param name="shed"></param> /// <param name="drainage"></param> /// <returns></returns> private static IFeature mergeBasinsByDrainage(IFeatureSet shed, BinTree drainage) { if (drainage == null) return null; IFeature left = mergeBasinsByDrainage(shed, drainage.left); IFeature right = mergeBasinsByDrainage(shed, drainage.right); IFeature lr = mergeAbuttingPolygons(left, right); IFeature outlet = shed.get_Shape(drainage.val); // check for multipart shape if (outlet.NumGeometries > 1) { Trace.WriteLine("Subbasin " + drainage.val.ToString() + " has " + outlet.NumGeometries.ToString() + " parts"); } else { // check for anticlockwise polygon double area = SignedArea(outlet); if (area < 0) { Trace.WriteLine("Needed to reverse subbasin " + drainage.val.ToString()); outlet = ReverseShape(outlet); } } return mergeAbuttingPolygons(lr, outlet); }
// #endregion // #region "Create SWAT *.Fig" // /// <summary> // /// A function to generate a *.fig file from joined basins for use in SWAT. // /// </summary> // /// <param name="JoinBasinShapePath"></param> // /// <param name="ResultFigPath"></param> // /// <param name="callback"></param> // /// <returns></returns> // public static bool CreateSWATFig(string JoinBasinShapePath, string ResultFigPath, IProgressHandler callback) // { // int OutletIDFieldNum = -1, DSWSIDFieldNum = -1, USWSIDFieldNum1 = -1, USWSIDFieldNum2 = -1, ReservoirFieldNum = -1; // if (callback != null) callback.Progress("Status", 0, "Create SWAT *.fig"); // Shapefile sf = new Shapefile(); // sf.Open(JoinBasinShapePath, null); // for (int i = 0; i < sf.NumFields; i++) // { // switch (sf.DataTable.Columns[i].ColumnName) // { // case "OutletID": // OutletIDFieldNum = i; // break; // case "DSWSID": // DSWSIDFieldNum = i; // break; // case "USWSID1": // USWSIDFieldNum1 = i; // break; // case "USWSID2": // USWSIDFieldNum2 = i; // break; // case "Reservoir": // ReservoirFieldNum = i; // break; // } // } // if (OutletIDFieldNum == -1 || DSWSIDFieldNum == -1 || USWSIDFieldNum1 == -1 || USWSIDFieldNum2 == -1) // { // return false; // } // StreamWriter fig = new StreamWriter(ResultFigPath); // Stack<int> substack = new Stack<int>(); // List<int> subIDs = new List<int>(); // int Hyd_Stor_Num = 0; // int Res_Num = 0; // int InFlow_Num1 = 0; // int InFlow_Num2 = 0; // int InFlow_ID = 0; // int UpstreamCount, UpstreamFinishedCount; // //Write subbasins // for (int i = 0; i < sf.NumRows(); i++) // { // Hyd_Stor_Num++; // fig.Write("subbasin 1{0,6:G6}{0,6:G6} Subbasin: {0:G}\n {0,5:D5}0000.sub\n", Hyd_Stor_Num); // if (sf.get_CellValue(DSWSIDFieldNum, i).ToString() == "-1") // { // substack.Push(i); // } // subIDs.Add(-1); // } // //Write the rest // int curridx; // string currUS1, currUS2; // int currUS1idx, currUS2idx, currUS1ID, currUS2ID; // while (substack.Count > 0) // { // curridx = substack.Pop(); // currUS1 = sf.get_CellValue(USWSIDFieldNum1, curridx).ToString(); // currUS2 = sf.get_CellValue(USWSIDFieldNum2, curridx).ToString(); // if (currUS1 == "-1" && currUS2 == "-1") //then we're on an outer reach. // { // if (subIDs[curridx] == -1) //then it hasn't been added yet. add a route // { // Hyd_Stor_Num++; // InFlow_Num1 = curridx + 1; // fig.Write("route 2{0,6:G6}{1,6:G6}{2,6:G6}\n {1,5:D5}0000.rte{1,5:D5}0000.swq\n", Hyd_Stor_Num, curridx + 1, InFlow_Num1); // subIDs[curridx] = Hyd_Stor_Num; // if (sf.get_CellValue(ReservoirFieldNum, curridx).ToString() == "1") //it's a reservoir // { // Hyd_Stor_Num++; // Res_Num++; // InFlow_Num1 = Hyd_Stor_Num - 1; // InFlow_ID = curridx + 1; // fig.Write("routres 3{0,6:G6}{1,6:G6}{2,6:G6}{3,6:G6}\n {3,5:D5}0000.res{3,5:D5}0000.lwq\n", Hyd_Stor_Num, Res_Num, InFlow_Num1, InFlow_ID); // subIDs[curridx] = Hyd_Stor_Num; // } // } // } // else //we're on a middle or final reach // { // UpstreamCount = 0; // UpstreamFinishedCount = 0; // //Get the hydro IDs and indexes of the upstream links // currUS1ID = -2; // currUS2ID = -2; // currUS1idx = -1; // currUS2idx = -1; // if (currUS1 != "-1") // { // UpstreamCount++; // currUS1idx = GetBasinIndexByID(sf, Int32.Parse(currUS1)); // if (currUS1idx >= 0) // { // currUS1ID = subIDs[currUS1idx]; // if (currUS1ID != -1) // { // UpstreamFinishedCount++; // } // } // } // if (currUS2 != "-1") // { // UpstreamCount++; // currUS2idx = GetBasinIndexByID(sf, Int32.Parse(currUS2)); // if (currUS2idx >= 0) // { // currUS2ID = subIDs[currUS2idx]; // if (currUS2ID != -1) // { // UpstreamFinishedCount++; // } // } // } // if (UpstreamCount == UpstreamFinishedCount) //all upstreams finished // { // if (currUS1ID != -2 && currUS2ID != -2) //It has two upstream, have to do a double sum // { // Hyd_Stor_Num++; // InFlow_Num1 = currUS1ID; // InFlow_Num2 = curridx + 1; // fig.Write("add 5{0,6:G6}{1,6:G6}{2,6:G6}\n", Hyd_Stor_Num, InFlow_Num1, InFlow_Num2); // Hyd_Stor_Num++; // InFlow_Num1 = currUS2ID; // InFlow_Num2 = Hyd_Stor_Num - 1; // fig.Write("add 5{0,6:G6}{1,6:G6}{2,6:G6}\n", Hyd_Stor_Num, InFlow_Num1, InFlow_Num2); // } // else if (currUS1ID != -2) //It only has one upstream, check if it's 1 // { // Hyd_Stor_Num++; // InFlow_Num1 = currUS1ID; // InFlow_Num2 = curridx + 1; // fig.Write("add 5{0,6:G6}{1,6:G6}{2,6:G6}\n", Hyd_Stor_Num, InFlow_Num1, InFlow_Num2); // } // else if (currUS2ID != -2) //It only has one upstream, check if it's 2 // { // Hyd_Stor_Num++; // InFlow_Num1 = currUS2ID; // InFlow_Num2 = curridx + 1; // fig.Write("add 5{0,6:G6}{1,6:G6}{2,6:G6}\n", Hyd_Stor_Num, InFlow_Num1, InFlow_Num2); // } // //After summing, create the route and possibly reservoir // Hyd_Stor_Num++; // InFlow_Num1 = Hyd_Stor_Num - 1; // fig.Write("route 2{0,6:G6}{1,6:G6}{2,6:G6}\n {1,5:D5}0000.rte{1,5:D5}0000.swq\n", Hyd_Stor_Num, curridx + 1, InFlow_Num1); // subIDs[curridx] = Hyd_Stor_Num; // if (sf.get_CellValue(ReservoirFieldNum, curridx).ToString() == "1") // { // Hyd_Stor_Num++; // Res_Num++; // InFlow_Num1 = Hyd_Stor_Num - 1; // InFlow_ID = curridx + 1; // fig.Write("routres 3{0,6:G6}{1,6:G6}{2,6:G6}{3,6:G6}\n {3,5:D5}0000.res{3,5:D5}0000.lwq\n", Hyd_Stor_Num, Res_Num, InFlow_Num1, InFlow_ID); // subIDs[curridx] = Hyd_Stor_Num; // } // } // else //There are upstream items that need to still be processed before this one // { // substack.Push(curridx); // if (currUS1idx != -1 && currUS1ID == -1) // { // substack.Push(currUS1idx); // } // if (currUS2idx != -1 && currUS2ID == -1) // { // substack.Push(currUS2idx); // } // } // } // } // //Write out the saveconc and finish commands // int SaveFile_Num = 1; // int Print_Freq = 0; //0 for daily, 1 for hourly // fig.Write("saveconc 14{0,6:G6}{1,6:G6}{2,6:G6}\n watout.dat\n", Hyd_Stor_Num, SaveFile_Num, Print_Freq); // fig.WriteLine("finish 0"); // fig.Close(); // sf.Close(); // return true; // } // #endregion // #region "Hydrology Private Helper Functions" private static void GetStreamElevationPoints(int sindx, IFeatureSet streamShape, IRaster demGrid, out double elevLow, out double elevHigh) { var shapePoints = streamShape.get_Shape(sindx).NumPoints; elevLow = 10000000; elevHigh = -1000000; for (var i = 0; i < shapePoints; i += 2) { var pt = streamShape.get_Shape(sindx).Coordinates[i]; RcIndex position = demGrid.ProjToCell(pt.X, pt.Y); if (position.IsEmpty()) continue; double currVal = demGrid.Value[position.Row, position.Column]; if (currVal < elevLow) { elevLow = currVal; } if (currVal > elevHigh) { elevHigh = currVal; } } }