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); })); }
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); }
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); } } }
/// <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); }
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); }
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); } } } }
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); } } } }
/// <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); }
/// <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 }