protected override async void OnClick() { SharedFunctions.Log("Starting To Pair Reservoirs"); DateTime startTime = DateTime.Now; await Project.Current.SaveEditsAsync(); try { await QueuedTask.Run(async() => { if (!SharedFunctions.LayerExists("DamCandidates") || !SharedFunctions.LayerExists("ReservoirSurfaces")) { return; } var damCandidatesLayer = MapView.Active.Map.FindLayers("DamCandidates").FirstOrDefault(); var reservoirSurfacesLayer = MapView.Active.Map.FindLayers("ReservoirSurfaces").FirstOrDefault(); SpatialReference = damCandidatesLayer.GetSpatialReference(); var reservoirPairsLayer = await CreateFeatureClass("ReservoirPairs"); await FindPairs(reservoirPairsLayer, reservoirSurfacesLayer as BasicFeatureLayer, damCandidatesLayer as BasicFeatureLayer); }); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } finally { DateTime endTime = DateTime.Now; SharedFunctions.Log("Analysed in " + (endTime - startTime).TotalSeconds.ToString() + " seconds"); } }
protected override async void OnClick() { if (!SharedFunctions.LayerExists("TIN") || !SharedFunctions.LayerExists("DamCandidates") || !SharedFunctions.LayerExists("ReservoirSurfaces")) { return; } await Project.Current.SaveEditsAsync(); string TINLayer = "TIN"; string damCandidatesLayer = "DamCandidates"; string reservoirSurfacesLayer = "ReservoirSurfaces"; var args = Geoprocessing.MakeValueArray(reservoirSurfacesLayer, damCandidatesLayer, TINLayer, damCandidatesLayer); await SharedFunctions.RunModel(args, "Reservoir Volume"); }
protected override async void OnClick() { SharedFunctions.Log("Starting To Create 3D Visualization"); DateTime startTime = DateTime.Now; CIMLineSymbol symbol = SymbolFactory.Instance.ConstructLineSymbol(ColorFactory.Instance.GreyRGB, 5.0, SimpleLineStyle.Solid); CIMSymbolReference symbolReference = symbol.MakeSymbolReference(); try { await QueuedTask.Run(async() => { if (!SharedFunctions.LayerExists("DamCandidates") || !SharedFunctions.LayerExists("ReservoirSurfaces")) { return; } var damCandidatesLayer = MapView.Active.Map.FindLayers("DamCandidates").FirstOrDefault(); var reservoirSurfacesLayer = MapView.Active.Map.FindLayers("ReservoirSurfaces").FirstOrDefault(); SpatialReference = damCandidatesLayer.GetSpatialReference(); var damVisLayer = await CreateMultiPatchFeatureClass("DamVisualization"); var reservoirVisLayer = await CreatePolygonFeatureClass("ReservoirVisualization"); Visualize(damVisLayer, reservoirVisLayer, reservoirSurfacesLayer as BasicFeatureLayer, damCandidatesLayer as BasicFeatureLayer); }); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } finally { DateTime endTime = DateTime.Now; SharedFunctions.Log("Visualized in " + (endTime - startTime).TotalSeconds.ToString() + " seconds"); } }
protected override async void OnClick() { SharedFunctions.Log("Search for candidate dams started"); pointsIntervalOnContour = Convert.ToInt32(Parameter.PointIntervalBox.Text); DateTime startTime = DateTime.Now; chosenCandidates = new List <CandidateDam>(); PotentialCandidates = 0; var pd = new ProgressDialog("Search for candidate dams", "Canceled", 100, false); cps = new CancelableProgressorSource(pd); cps.Progressor.Max = 100; PointsAnalyzed = 0; TotalPointsCount = 0; try { await Project.Current.SaveEditsAsync(); BasicFeatureLayer layer = null; await QueuedTask.Run(async() => { if (!SharedFunctions.LayerExists("ContourPoints")) { return; } CancellationToken ctoken = new CancellationToken(); //create line feature layer if it does not exist BasicFeatureLayer damCandidatesLayer = await CreateDamFeatureClass("DamCandidates"); var contourPointsLayer = MapView.Active.Map.FindLayers("ContourPoints").FirstOrDefault(); layer = contourPointsLayer as BasicFeatureLayer; // store the spatial reference of the current layer SpatialReference = layer.GetSpatialReference(); //Cursor for selected points RowCursor cursor = layer.GetSelection().Search(); //If no selection was set, use full points layer if (layer.GetSelection().GetCount() == 0) { cursor = layer.Search(); } Dictionary <int, SortedDictionary <int, SortedDictionary <long, MapPoint> > > contourHeights = new Dictionary <int, SortedDictionary <int, SortedDictionary <long, MapPoint> > >(); cps.Progressor.Status = "Loading ContourPoints into memory"; SharedFunctions.Log("Loading all ContourPoints into memory"); while (cursor.MoveNext()) { if (ctoken.IsCancellationRequested) { SharedFunctions.Log("Canceled"); return; } using (Row row = cursor.Current) { var point = row[1] as MapPoint; var pointID = (int)row[0]; var contourHeight = (int)(double)row[4]; var contourID = (int)row[2]; if (!ContourLengths.ContainsKey(contourID)) { ContourLengths.Add(contourID, (double)row["Shape_Length"]); } if (!contourHeights.ContainsKey((int)contourHeight)) { contourHeights.Add((int)contourHeight, new SortedDictionary <int, SortedDictionary <long, MapPoint> >()); } if (!contourHeights[contourHeight].ContainsKey((int)contourID)) { contourHeights[contourHeight].Add((int)contourID, new SortedDictionary <long, MapPoint>()); } contourHeights[contourHeight][(int)contourID].Add(pointID, point); TotalPointsCount++; } } cps.Progressor.Status = "Analyze Contours"; SharedFunctions.Log("Analyze Contours"); bool multiThreading = (Parameter.MultiThreadingBox == null || !Parameter.MultiThreadingBox.IsChecked.HasValue || Parameter.MultiThreadingBox.IsChecked.Value); if (multiThreading) { HeightsToProcess = contourHeights.Keys.ToList(); int ThreadCount = Math.Min(HeightsToProcess.Count, Environment.ProcessorCount); SharedFunctions.Log("Divided work into " + ThreadCount + " threads..."); await Task.WhenAll(Enumerable.Range(1, ThreadCount).Select(c => Task.Run( () => { while (HeightsToProcess.Count > 0) // && !ctoken.IsCancellationRequested) { int height = -1; lock (HeightsToProcess) { height = HeightsToProcess.FirstOrDefault(); if (height != 0) { HeightsToProcess.Remove(height); } } if (height != -1) { var calc = new Dictionary <int, SortedDictionary <int, SortedDictionary <long, MapPoint> > >(); calc.Add(height, contourHeights[height]); AnalyseContourHeights(calc, ctoken); } } } , ctoken)) ); } else { //Single Thread: AnalyseContourHeights(contourHeights, ctoken); } cps.Progressor.Status = "Saving all " + chosenCandidates.Count + " candidates"; SharedFunctions.Log("Saving all " + chosenCandidates.Count + " candidates"); foreach (var candidate in chosenCandidates) { if (ctoken.IsCancellationRequested) { SharedFunctions.Log("Canceled"); return; } //Create coordinates for Polyline Feature with height ContourHeight + 5 Meters! List <Coordinate3D> coordinates = new List <Coordinate3D>() { new Coordinate3D(candidate.StartPoint.X, candidate.StartPoint.Y, candidate.ContourHeight + 5), new Coordinate3D(candidate.EndPoint.X, candidate.EndPoint.Y, candidate.ContourHeight + 5) }; //save all selected candidates into the db var attributes = new Dictionary <string, object> { { "Shape", PolylineBuilder.CreatePolyline(coordinates) }, { "ContourID", (long)candidate.ContourID }, { "StartPointID", (long)candidate.StartPointID }, { "EndPointID", (long)candidate.EndPointID }, { "ContourHeight", (short)candidate.ContourHeight }, { "LengthRating", (float)candidate.Rating }, { "DistanceOnLine", (long)candidate.DistanceOnLine }, { "Length", (short)candidate.Length }, { "StartPointDistance", (long)candidate.StartPointDistance }, { "EndPointDistance", (long)candidate.EndPointDistance }, { "DamSpansContourStart", (short)(candidate.DamSpansContourStart ? 1 : 0) } }; var editOp = new EditOperation() { Name = "Create dam candidate", SelectNewFeatures = false }; editOp.Create(damCandidatesLayer, attributes); ////Execute the operations editOp.Execute(); } }, cps.Progressor); //save all edits await Project.Current.SaveEditsAsync(); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } finally { DateTime endTime = DateTime.Now; SharedFunctions.Log("Analysed " + PotentialCandidates.ToString("N0") + " candidates ( " + chosenCandidates.Count.ToString("N0") + " selected) in " + (endTime - startTime).TotalSeconds.ToString("N") + " seconds"); } }
protected override async void OnClick() { SharedFunctions.Log("DamVolume Calculation started"); DateTime startTime = DateTime.Now; await Project.Current.SaveEditsAsync(); IncomingCandidates = 0; OutgoingCandidates = 0; List <CandidateDam> candidates = new List <CandidateDam>(); List <CandidateDam> candidates2Delete = new List <CandidateDam>(); try { await QueuedTask.Run(async() => { if (!SharedFunctions.LayerExists("DamCandidates") || !SharedFunctions.LayerExists("Contours")) { return; } var _damCandidatesLayer = MapView.Active.Map.FindLayers("DamCandidates").FirstOrDefault(); BasicFeatureLayer damCandidatesLayer = _damCandidatesLayer as BasicFeatureLayer; SharedFunctions.LoadDamCandidatesFromLayer(candidates, damCandidatesLayer); IncomingCandidates = candidates.Count(); OutgoingCandidates = IncomingCandidates; //create stacked profile string inputDEM = Parameter.DEMCombo.SelectedItem.ToString(); var valueArray = Geoprocessing.MakeValueArray(damCandidatesLayer.Name, inputDEM, "DamProfile", null); var environments = Geoprocessing.MakeEnvironmentArray(overwriteoutput: true); var cts = new CancellationTokenSource(); await Project.Current.SaveEditsAsync(); var res = await Geoprocessing.ExecuteToolAsync("StackProfile", valueArray, environments, cts.Token, null, GPExecuteToolFlags.Default); //analyse profile and add data to line feature or delete line feature //profile can be used to calculate frontal dam area and dam volume?! var damProfileTable = MapView.Active.Map.FindStandaloneTables("DamProfile").FirstOrDefault(); if (damProfileTable == null) { SharedFunctions.Log("No DamProfile Table found!"); } CandidateDam cand = null; double prev_dist = 0; int prev_lineID = -1; using (var profileCursor = damProfileTable.Search()) { while (profileCursor.MoveNext()) { using (Row profileRow = profileCursor.Current) { var first_dist = (double)profileRow[1]; var first_z = (double)profileRow[2]; var line_ID = (int)profileRow[5]; if (prev_lineID != line_ID) { prev_dist = 0; cand = candidates.SingleOrDefault(c => c.ObjectID == line_ID); // set Volume and ZMin to the default values cand.DamVolume = 0; cand.ZMin = cand.ContourHeight; } else if (candidates2Delete.Contains(cand)) { continue; } //set lowest point of dam to calculate max dam height later if (cand.ZMin > (int)first_z) { cand.ZMin = (int)first_z; } if ((int)first_z > (cand.ContourHeight + 5)) { candidates2Delete.Add(cand); continue; } //add volume of current block of dam... the assumption is a triangle dam shape (cross section) with alpha = 45° //thus the area of the cross section is calculated by <height²> and the volume by <height² * length> cand.DamVolume += (long)(Math.Pow((cand.ContourHeight - first_z), 2) * (first_dist - prev_dist)); prev_lineID = line_ID; prev_dist = first_dist; } } } await DeleteCandidates(candidates, damCandidatesLayer, candidates2Delete); //remove candidates with dam heights outside of the limits await DeleteCandidates(candidates, damCandidatesLayer, candidates.Where(c => (c.ContourHeight - c.ZMin) < 10 || (c.ContourHeight - c.ZMin) > 300).ToList()); //update the new attributes to the feature foreach (var candidate in candidates) { var editOp2 = new EditOperation(); Dictionary <string, object> attributes = new Dictionary <string, object>(); attributes.Add("DamHeight", (short)(candidate.ContourHeight - candidate.ZMin)); attributes.Add("DamVolume", (long)(candidate.DamVolume)); editOp2.Modify(damCandidatesLayer, candidate.ObjectID, attributes); var resu = await editOp2.ExecuteAsync(); } await Project.Current.SaveEditsAsync(); }); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } finally { DateTime endTime = DateTime.Now; SharedFunctions.Log("Analysed in " + (endTime - startTime).TotalSeconds.ToString("N") + " seconds completed (" + OutgoingCandidates.ToString("N0") + " of " + IncomingCandidates.ToString("N0") + " candidates left)"); } }