Exemple #1
0
        private Task <Tuple <IDisposable, long> > AddFeatureToOverlay(MapViewMouseEventArgs e)
        {
            return(QueuedTask.Run(() => {
                double llx = e.ClientPoint.X - 3;
                double lly = e.ClientPoint.Y - 3;
                double urx = e.ClientPoint.X + 3;
                double ury = e.ClientPoint.Y + 3;

                EnvelopeBuilder envBuilder = new EnvelopeBuilder(ActiveMapView.ClientToMap(new Point(llx, lly)),
                                                                 ActiveMapView.ClientToMap(new Point(urx, ury)));

                MapPoint mp = ActiveMapView.ClientToMap(e.ClientPoint);
                var cursor = _trees.Search(new SpatialQueryFilter()
                {
                    FilterGeometry = envBuilder.ToGeometry(), SpatialRelationship = SpatialRelationship.Intersects
                });
                if (cursor.MoveNext())
                {
                    return new Tuple <IDisposable, long>(
                        ActiveMapView.AddOverlay(ActiveMapView.ClientToMap(e.ClientPoint),
                                                 _overlaySymbol.MakeSymbolReference()),
                        cursor.Current.GetObjectID());
                }

                //var select = _trees.Select(new SpatialQueryFilter() {
                //    FilterGeometry = envBuilder.ToGeometry(),
                //    SpatialRelationship = SpatialRelationship.Intersects
                //});
                //if (select.GetCount() > 0) {
                //    return ActiveMapView.AddOverlay(ActiveMapView.ClientToMap(e.ClientPoint), _overlaySymbol.MakeSymbolReference());
                //}

                return new Tuple <IDisposable, long>(null, -1);
            }));
        }
Exemple #2
0
 public static void LoadDamCandidatesFromLayer(List <CandidateDam> candidates, BasicFeatureLayer damCandidatesLayer)
 {
     using (var cursor = damCandidatesLayer.Search())
     {
         while (cursor.MoveNext())
         {
             using (Row row = cursor.Current)
             {
                 CandidateDam candidate = new CandidateDam();
                 candidate.ObjectID             = (int)row["ObjectID"];
                 candidate.ContourID            = (int)row["ContourID"];
                 candidate.StartPointID         = (int)row["StartPointID"];
                 candidate.EndPointID           = (int)row["EndPointID"];
                 candidate.ContourHeight        = Convert.ToInt32(row["ContourHeight"]);
                 candidate.DistanceOnLine       = (int)row["DistanceOnLine"];
                 candidate.Length               = Convert.ToInt32(row["Length"]);
                 candidate.StartPointDistance   = Convert.ToInt32(row["StartPointDistance"]);
                 candidate.EndPointDistance     = Convert.ToInt32(row["EndPointDistance"]);
                 candidate.DamSpansContourStart = Convert.ToInt32(row["DamSpansContourStart"]) == 1;
                 candidate.DamHeight            = Convert.ToInt32(row["DamHeight"]);
                 candidate.Line            = (row as Feature).GetShape() as Polyline;
                 candidate.StartPoint      = candidate.Line.Points.First();
                 candidate.EndPoint        = candidate.Line.Points.Last();
                 candidate.ReservoirVolume = Convert.ToInt64(row["ReservoirVolume"]);
                 candidates.Add(candidate);
             }
         }
     }
 }
        /// <summary>
        /// Get the list of selected features GUID from the layer
        /// </summary>
        /// <param name="fl">Layer</param>
        /// <param name="selectedFeatures">Selected features</param>
        /// <returns>List of GUID</returns>
        private static List <Guid> GetGuidFromLayer(BasicFeatureLayer fl, Selection selectedFeatures)
        {
            List <Guid> listIds = new List <Guid>();

            // some data have restriction of element number in a clause IN, so we cut the in smaller list
            List <string> lEid = FormatOidToString(selectedFeatures.GetObjectIDs().ToList());

            TableDefinition tbl       = fl.GetTable().GetDefinition();
            string          FieldName = tbl.GetObjectIDField();

            QueryFilter qf = new QueryFilter
            {
                SubFields = "*"
            };

            foreach (string se in lEid)
            {
                qf.WhereClause = String.Format("{0} IN ({1})", FieldName, se);

                try
                {
                    RowCursor rc = fl.Search(qf);

                    while (rc.MoveNext())
                    {
                        listIds.Add(rc.Current.GetGlobalID());
                    }
                }
                catch { }
            }

            return(listIds);
        }
        /// <summary>
        /// Get GUID from Layer
        /// </summary>
        /// <param name="Fl">BasicFeatureLayer</param>
        /// <param name="SelectedFeatures">Selection</param>
        /// <returns></returns>
        private static List <Guid> GetGuidFromLayer(BasicFeatureLayer Fl, Selection SelectedFeatures)
        {
            List <Guid> listIds = new List <Guid>();

            // Some SGDB having limitations on the list size when using WHERE IN clauses, the list is cut in smaller lists
            List <string> lEid = FormatOidToString(SelectedFeatures.GetObjectIDs().ToList());

            TableDefinition tbl       = Fl.GetTable().GetDefinition();
            string          FieldName = tbl.GetObjectIDField();

            QueryFilter qf = new QueryFilter
            {
                SubFields = "*"
            };

            //List<long> lselected = new List<long>();

            foreach (string se in lEid)
            {
                qf.WhereClause = String.Format("{0} IN ({1})", FieldName, se);

                try
                {
                    RowCursor rc = Fl.Search(qf);

                    while (rc.MoveNext())
                    {
                        listIds.Add(rc.Current.GetGlobalID());
                    }
                }
                catch { }
            }

            return(listIds);
        }
Exemple #5
0
        public static IEnumerable <T> GetRows <T>([NotNull] BasicFeatureLayer layer,
                                                  [CanBeNull] QueryFilter filter = null)
            where T : Row
        {
            Assert.ArgumentNotNull(layer, nameof(layer));

            using (RowCursor cursor = layer.Search(filter))
            {
                while (cursor.MoveNext())
                {
                    yield return((T)cursor.Current);
                }
            }
        }
Exemple #6
0
        /// <summary>
        /// Performs a spatial query against a feature layer.
        /// </summary>
        /// <remarks>It is assumed that the feature layer and the search geometry are using the same spatial reference.</remarks>
        /// <param name="searchLayer">The feature layer to be searched.</param>
        /// <param name="searchGeometry">The geometry used to perform the spatial query.</param>
        /// <param name="spatialRelationship">The spatial relationship used by the spatial filter.</param>
        /// <returns>Cursor containing the features that satisfy the spatial search criteria.</returns>
        public static RowCursor Search(this BasicFeatureLayer searchLayer, Geometry searchGeometry, SpatialRelationship spatialRelationship)
        {
            RowCursor rowCursor = null;
            // define a spatial query filter
            var spatialQueryFilter = new SpatialQueryFilter
            {
                // passing the search geometry to the spatial filter
                FilterGeometry = searchGeometry,
                // define the spatial relationship between search geometry and feature class
                SpatialRelationship = spatialRelationship
            };

            // apply the spatial filter to the feature layer in question
            rowCursor = searchLayer.Search(spatialQueryFilter);
            return(rowCursor);
        }
Exemple #7
0
        public static List <long> GetAllIdsFromLayer(BasicFeatureLayer layer)
        {
            List <long> result = new List <long>();

            using (var cursor = layer.Search())
            {
                while (cursor.MoveNext())
                {
                    using (Row row = cursor.Current)
                    {
                        result.Add((int)row["ObjectID"]);
                    }
                }
            }
            return(result);
        }
Exemple #8
0
 public static void LoadReservoirSurfacesFromLayer(List <ReservoirSurface> surfaces, BasicFeatureLayer surfacesLayer)
 {
     using (var cursor = surfacesLayer.Search())
     {
         while (cursor.MoveNext())
         {
             using (Row row = cursor.Current)
             {
                 ReservoirSurface reservoirSurface = new ReservoirSurface();
                 reservoirSurface.ObjectID = (int)row["ObjectID"];
                 reservoirSurface.DamID    = (int)row["DamID"];
                 reservoirSurface.Polygon  = (row as Feature).GetShape() as Polygon;
                 surfaces.Add(reservoirSurface);
             }
         }
     }
 }
Exemple #9
0
 public static void LoadContoursFromLayer(List <Contour> contours, BasicFeatureLayer contoursLayer)
 {
     using (var cursor = contoursLayer.Search())
     {
         while (cursor.MoveNext())
         {
             using (Row row = cursor.Current)
             {
                 Contour contour = new Contour();
                 contour.ObjectID = (int)row["ObjectID"];
                 contour.Polyline = (row as Feature).GetShape() as Polyline;
                 contour.Height   = System.Convert.ToInt32(row["Contour"]);
                 contours.Add(contour);
             }
         }
     }
 }
Exemple #10
0
        /// <summary>
        /// Returns oids of features filtered by spatial relationship. Honors definition queries on the layer.
        /// </summary>
        public static IEnumerable <long> FilterLayerOidsByGeometry(
            BasicFeatureLayer layer, ArcGIS.Core.Geometry.Geometry filterGeometry,
            SpatialRelationship spatialRelationship = SpatialRelationship.Intersects)
        {
            var qf = new SpatialQueryFilter()
            {
                FilterGeometry      = filterGeometry,
                SpatialRelationship = spatialRelationship
            };
            var oids = new List <long>();

            using (RowCursor rowCursor = layer.Search(qf))
            {
                while (rowCursor.MoveNext())
                {
                    oids.Add(rowCursor.Current.GetObjectID());
                }
            }

            return(oids);
        }
Exemple #11
0
        /// <summary>
        /// Returns features filtered by spatial relationship. Honors definition queries on the layer.
        /// </summary>
        public static IEnumerable <Feature> FilterLayerFeaturesByGeometry(
            BasicFeatureLayer layer, ArcGIS.Core.Geometry.Geometry filterGeometry,
            SpatialRelationship spatialRelationship = SpatialRelationship.Intersects)
        {
            var qf = new SpatialQueryFilter()
            {
                FilterGeometry      = filterGeometry,
                SpatialRelationship = spatialRelationship
            };
            var features = new List <Feature>();

            using (RowCursor rowCursor = layer.Search(qf))
            {
                while (rowCursor.MoveNext())
                {
                    features.Add((Feature)rowCursor.Current);
                }
            }

            return(features);
        }
        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");
            }
        }
        //Using Inspector...
        internal async void UpdateTextString()
        {
            BasicFeatureLayer annoLayer = MapView.Active.Map.GetLayersAsFlattenedList().First() as BasicFeatureLayer;
            var oid = 1;

            #region Update Annotation Text via attribute. Caveat: The TEXTSTRING Anno attribute must exist

            //See "Change Annotation Text Graphic" for an alternative if TEXTSTRING is missing from the schema
            await QueuedTask.Run(() =>
            {
                //annoLayer is ~your~ Annotation layer...

                // use the inspector methodology
                var insp = new Inspector();
                insp.Load(annoLayer, oid);

                // make sure TextString attribute exists.
                //It is not guaranteed to be in the schema
                ArcGIS.Desktop.Editing.Attributes.Attribute att = insp.FirstOrDefault(a => a.FieldName == "TEXTSTRING");
                if (att != null)
                {
                    insp["TEXTSTRING"] = "Hello World";

                    //create and execute the edit operation
                    EditOperation op = new EditOperation();
                    op.Name          = "Update annotation";
                    op.Modify(insp);

                    //OR using a Dictionary - again TEXTSTRING has to exist in the schema
                    //Dictionary<string, object> newAtts = new Dictionary<string, object>();
                    //newAtts.Add("TEXTSTRING", "hello world");
                    //op.Modify(annoLayer, oid, newAtts);

                    op.Execute();
                }
            });

            #endregion

            #region Rotate or Move the Annotation

            await QueuedTask.Run(() =>
            {
                //Don't use 'Shape'....Shape is the bounding box of the annotation text. This is NOT what you want...
                //
                //var insp = new Inspector();
                //insp.Load(annoLayer, oid);
                //var shape = insp["SHAPE"] as Polygon;
                //...wrong shape...

                //Instead, we must get the TextGraphic from the anno feature.
                //The TextGraphic shape will be the anno baseline...
                //At 2.1 the only way to retrieve this textLine is to obtain the TextGraphic from the AnnotationFeature
                QueryFilter qf = new QueryFilter()
                {
                    WhereClause = "OBJECTID = 1"
                };

                //annoLayer is ~your~ Annotation layer

                using (var rowCursor = annoLayer.Search(qf))
                {
                    if (rowCursor.MoveNext())
                    {
                        using (var annoFeature = rowCursor.Current as ArcGIS.Core.Data.Mapping.AnnotationFeature)
                        {
                            var graphic     = annoFeature.GetGraphic();
                            var textGraphic = graphic as CIMTextGraphic;
                            var textLine    = textGraphic.Shape as Polyline;
                            // rotate the shape 90 degrees
                            var origin = GeometryEngine.Instance.Centroid(textLine);
                            Geometry rotatedPolyline = GeometryEngine.Instance.Rotate(textLine, origin, System.Math.PI / 2);
                            //Move the line 5 "units" in the x and y direction
                            //GeometryEngine.Instance.Move(textLine, 5, 5);

                            EditOperation op = new EditOperation();
                            op.Name          = "Change annotation angle";
                            op.Modify(annoLayer, oid, rotatedPolyline);
                            op.Execute();
                        }
                    }
                }
            });

            #endregion

            #region Change Annotation Text Graphic

            await QueuedTask.Run(() =>
            {
                EditOperation op = new EditOperation();
                op.Name          = "Change annotation graphic";

                //At 2.1 we must use an edit operation Callback...
                op.Callback(context =>
                {
                    QueryFilter qf = new QueryFilter()
                    {
                        WhereClause = "OBJECTID = 1"
                    };
                    //Cursor must be non-recycling. Use the table ~not~ the layer..i.e. "GetTable().Search()"
                    //annoLayer is ~your~ Annotation layer
                    using (var rowCursor = annoLayer.GetTable().Search(qf, false))
                    {
                        if (rowCursor.MoveNext())
                        {
                            using (var annoFeature = rowCursor.Current as ArcGIS.Core.Data.Mapping.AnnotationFeature)
                            {
                                //Get the graphic from the anno feature
                                var graphic     = annoFeature.GetGraphic();
                                var textGraphic = graphic as CIMTextGraphic;

                                // change the text and the color
                                textGraphic.Text = "hello world";
                                var symbol       = textGraphic.Symbol.Symbol;
                                symbol.SetColor(ColorFactory.Instance.RedRGB);
                                textGraphic.Symbol = symbol.MakeSymbolReference();
                                // update the graphic
                                annoFeature.SetGraphic(textGraphic);
                                // store is required
                                annoFeature.Store();
                                //refresh layer cache
                                context.Invalidate(annoFeature);
                            }
                        }
                    }
                }, annoLayer.GetTable());

                op.Execute();
            });

            #endregion
        }