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");
            }
        }
Exemple #2
0
        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");
        }
Exemple #3
0
        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)");
            }
        }