/// <summary> /// Execute the trace with a custom component that can extend it /// </summary> /// <param name="extender"></param> /// <returns></returns> public Task Trace(IComponentCategoryInterface extender) { _sb = null; _sb = new StringBuilder(); return(QueuingTaskFactory.StartNew(async() => { //get the stops foreach (var stop in extender.GetStops()) { _sb.AppendFormat("Stop: {0}\r\n", stop.Name); } //barriers foreach (var barrier in extender.GetBarriers()) { _sb.AppendFormat("Barrier: {0}\r\n", barrier.Name); } //do whatever await System.Threading.Tasks.Task.Delay(1000); //extenders turn await extender.ModifyTrace(this); //results string sep = ""; _sb.AppendLine("\r\nResults"); _sb.Append("OIDS: "); foreach (var oid in _tr.tracedSegmentOids) { _sb.Append(sep + oid.ToString()); sep = ","; } })); }
/// <summary> /// Retrieves a specific row/feature for given ObjectID. /// </summary> /// <param name="table">Table of Feature class containing the row/feature.</param> /// <param name="oid">The ObjectID of the row/feature to be returned.</param> /// <returns>The row/feature specified by the ObjectID. If entity with the ObjectID exists, a null reference is returned.</returns> public static async Task <Row> GetRowByIDAsync(this Table table, long oid) { Row foundRow = null; if (table == null) { return(foundRow); } await QueuingTaskFactory.StartNew(() => { if (table.Definition is TableDefinition) { var tableDefinition = table.Definition as TableDefinition; var queryFilter = new QueryFilter { WhereClause = tableDefinition.ObjectIDField + " = " + oid.ToString() }; RowCursor rc = table.Search(queryFilter, false); if (rc.MoveNext()) { foundRow = rc.Current; } } }); return(foundRow); }
/// <summary> /// Retrieves a specific row/feature for given ObjectID. /// </summary> /// <param name="table">Table of Feature class containing the row/feature.</param> /// <param name="oid">The ObjectID of the row/feature to be returned.</param> /// <returns>The row/feature specified by the ObjectID. If entity with the ObjectID exists, a null reference is returned.</returns> public static async Task <Row> GetRowByIDAsync(this Table table, long oid) { Row foundRow = null; if (table == null) { return(foundRow); } await QueuingTaskFactory.StartNew(() => { if (table.Definition is TableDefinition) { var tableDefinition = table.Definition as TableDefinition; // TODO // specify query filter to return only the row with the specified identifier QueryFilter queryFilter = new QueryFilter(); RowCursor rc = table.Search(queryFilter, false); if (rc.MoveNext()) { foundRow = rc.Current; } } }); return(foundRow); }
/// <summary> /// Backup function to load bookmarks from a cached mapx file in case the /// loaded project does not have any /// </summary> private static Task <IList <Bookmark> > LoadBookmarksFromMapxAsync() { return(QueuingTaskFactory.StartNew <IList <Bookmark> >(async() => { var assemblyPath = Assembly.GetExecutingAssembly().Location; var mapXPath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(assemblyPath), "SamplesData", "World.mapx"); var project = ProjectModule.CurrentProject; var types = new string[1] { @"Map" }; var paths = new string[1] { mapXPath }; Tuple <string[], string[]> importResult = await project.ImportProjectItemAsync(types, paths, CancelableProgressor.None); var mapPath = importResult.Item2[0]; var map = await MappingModule.GetMapAsync(mapPath); var bookmarks = await map.QueryBookmarks(); List <Bookmark> bookMarks = new List <Bookmark>(); foreach (Bookmark bmk in bookmarks) { bookMarks.Add(bmk); } return bookMarks; })); }
/// <summary> /// Asynchronous task that splits the current sketch geometry into 100 segments of equal length. /// </summary> /// <returns>Task{bool}</returns> private async Task <bool> ExecuteDensify() { // get the current sketch geometry from the editing module var sketchGeometry = await EditingModule.GetSketchGeometryAsync(); // check if geometry is valid bool isGeometryValid = await QueuingTaskFactory.StartNew <bool>(() => { bool validGeometry = true; if (sketchGeometry == null || sketchGeometry.IsEmpty) { validGeometry = false; } return(validGeometry); }); if (!isGeometryValid) { return(false); } // get the currently selected features from the map // the selected feature uses the above selected geometry var currentlySelectedFeature = await MappingModule.ActiveMapView.Map.GetSelectionSetAsync(); // set up an edit operation EditOperation editOperation = new EditOperation(); editOperation.Name = "Densify selected geometry"; Geometry densifiedGeometry = null; // modify the geometry in the sketch geometry // the geometry operation needs to run as it own task await QueuingTaskFactory.StartNew(() => { // compute a length fur the current geometry when divided into 100 segments var segmentLength = GeometryEngine.Length(sketchGeometry) / 100; // compute a new densified geometry densifiedGeometry = GeometryEngine.Densify(sketchGeometry, segmentLength); }); // for the currently selected feature go through the layers to which the feature belongs foreach (var mapMember in currentlySelectedFeature.MapMembers) { // for each of the selections in the layer (map member) foreach (var selectedOID in currentlySelectedFeature[mapMember]) { // provide the densified geometry for the selected feature as part of the modify operation editOperation.Modify((Layer)mapMember, selectedOID, densifiedGeometry); } } // execute the edit operation and return return(await editOperation.ExecuteAsync()); }
/// <summary> /// Zoom to the specified location /// </summary> /// <param name="extent">The extent of the geocoded candidate</param> /// <returns></returns> public static Task ZoomToLocation(CandidateExtent extent) { return(QueuingTaskFactory.StartNew(() => { ArcGIS.Core.Geometry.Envelope envelope = new ArcGIS.Core.Geometry.Envelope( extent.XMin, extent.YMin, extent.XMax, extent.YMax, new ArcGIS.Core.Geometry.SpatialReference(extent.WKID) ); //apply extent ProSDKSampleModule.ActiveMapView.ZoomToAsync(GeometryEngine.Expand(envelope, 3, 3, true)); })); }
private async Task QueryRows(object query) { string where = ""; if (query != null) { where = query.ToString(); } IsLoading = true; lock (_theLock) { ListOfRows.Clear(); } if (_layerSource == null) { _layerSource = await _selectedLayer.getFeatureClass(); } if (_layerSource != null) { var data = new List <DynamicDataRow>(); await QueuingTaskFactory.StartNew(() => { var queryFilter = new ArcGIS.Core.Data.QueryFilter { WhereClause = where }; int maxcols = 6; RowCursor cursor = _layerSource.Search(queryFilter); if (cursor.MoveNext()) { ExtendListView.Columns = new List <ArcGIS.Core.Data.Field>(); maxcols = cursor.Current.Fields.Count() > 6 ? 6 : cursor.Current.Fields.Count(); for (int c = 0; c < maxcols; c++) { ExtendListView.Columns.Add(cursor.Current.Fields[c]); } do { var row = new DynamicDataRow(); for (int v = 0; v < maxcols; v++) { row[GetName(cursor.Fields[v])] = cursor.Current[v].ToString(); } data.Add(row); } while (cursor.MoveNext()); } }); lock (_theLock) { ListOfRows = null; ListOfRows = data; } } RaisePropertyChanged("ListOfRows"); Status = string.Format("{0} rows loaded", ListOfRows.Count()); IsLoading = false; }
/// <summary> /// Find the first field of the provided field type. /// </summary> /// <param name="table">Table or FeatureClass containing the field.</param> /// <param name="fieldType"> /// The type of field to be retrieved. /// <remarks>Some types can only exist once per table.</remarks> /// </param> /// <returns> /// The first occurrence of the field type is returned. If no field of the given type is found, a null reference /// is returned. /// </returns> public static async Task <Field> GetFieldByTypeAsync(this Table table, FieldType fieldType) { Field foundField = null; await QueuingTaskFactory.StartNew(() => { IReadOnlyList <Field> fields = ((TableDefinition)table.Definition).Fields; foundField = fields.FirstOrDefault(a => a.FieldType == fieldType); }); return(foundField); }
/// <summary> /// Create sample polyline feature using the geometries from the point feature layer. /// </summary> /// <param name="polylineLayer">Polyline geometry feature layer used to add the new features.</param> /// <param name="pointLayer">The geometries from the point layer are used as vertices for the new line features.</param> /// <returns></returns> private Task <bool> constructSamplePolylines(FeatureLayer polylineLayer, FeatureLayer pointLayer) { // execute the fine grained API calls on the CIM main thread return(QueuingTaskFactory.StartNew(() => { // get the underlying feature class for each layer var polylineFeatureClass = polylineLayer.GetTableAsync().Result as FeatureClass; var pointFeatureClass = pointLayer.GetTableAsync().Result as FeatureClass; // construct a cursor for all point features, since we want all feature there is no // QueryFilter required var pointCursor = pointFeatureClass.Search(null, false); // retrieve the feature class schema information for the feature classes var polylineDefinition = polylineFeatureClass.Definition as FeatureClassDefinition; var pointDefinition = pointFeatureClass.Definition as FeatureClassDefinition; // initialize a counter variable int pointCounter = 0; // initialize a list to hold 5 coordinates that are used as vertices for the polyline var lineCoordinates = new List <Coordinate>(5); // set up the edit operation for the feature creation var createOperation = EditingModule.CreateEditOperation(); createOperation.Name = "Create polylines"; // loop through the point features while (pointCursor.MoveNext()) { pointCounter++; var pointFeature = pointCursor.Current as Feature; // add the feature point geometry as a coordinate into the vertex list of the line // - ensure that the projection of the point geometry is converted to match the spatial reference of the line lineCoordinates.Add(((MapPoint)GeometryEngine.Project(pointFeature.Shape, polylineDefinition.SpatialReference)).Coordinate); // for every 5 geometries, construct a new polyline and queue a feature create if (pointCounter % 5 == 0) { var newPolyline = new Polyline(lineCoordinates, polylineDefinition.SpatialReference); createOperation.Create(polylineLayer, newPolyline); lineCoordinates = new List <Coordinate>(5); } } // execute the edit (create) operation var t = createOperation.ExecuteAsync().Result; // save the edits return EditingModule.SaveEditsAsync(); })); }
/// <summary> /// Create random sample points in the extent of the spatial reference /// </summary> /// <param name="pointLayer">Point geometry feature layer used to the generate the points.</param> /// <returns>Task of bool</returns> private Task <bool> constructSamplePoints(FeatureLayer pointLayer) { // create a random number generator var randomGenerator = new Random(); // the database and geometry interactions are considered fine-grained and must be executed on // the main CIM thread return(QueuingTaskFactory.StartNew(() => { // get the feature class associated with the layer var featureClass = pointLayer.GetTableAsync().Result as FeatureClass; // retrieve the class definition of the point feature class var classDefinition = featureClass.Definition as FeatureClassDefinition; // store the spatial reference as its own variable SpatialReference spatialReference = featureClass.SpatialReference; // define an area of interest. Random points are generated in the allowed // confines of the allow extent range var areaOfInterest = MappingModule.ActiveMapView.GetExtentAsync().Result; // start an edit operation to create new (random) point features var createOperation = EditingModule.CreateEditOperation(); createOperation.Name = "Generate points"; // create 20 new point geometries and queue them for creation for (int i = 0; i < 20; i++) { MapPoint newMapPoint = null; // generate either 2D or 3D geometries if (classDefinition.HasZ) { newMapPoint = new MapPoint(randomGenerator.NextCoordinate(areaOfInterest, true), spatialReference); } else { newMapPoint = new MapPoint(randomGenerator.NextCoordinate(areaOfInterest, false), spatialReference); } // queue feature creation createOperation.Create(pointLayer, newMapPoint); } // execute the edit (feature creation) operation var t = createOperation.ExecuteAsync().Result; return EditingModule.SaveEditsAsync().Result; })); }
/// <summary> /// This is a basic FinishSketch method which illustrates the process of using the sketch geometry for a cut. /// 1. look at all layers in the active map /// for each layer: /// 2. Use the sketch geometry to perform a spatial query (Crosses) /// 3. Use the found features and use them to set up a cut operation /// 4. Create edit operation /// 5. Execute the edit operation /// ! edits are not saved ! /// /// </summary> /// <returns>Task of bool</returns> protected override async Task <bool> OnFinishSketch(Geometry geometry, Dictionary <string, object> attributes) { // use all layers of the active map to perform the cut foreach (var layer in ActiveMap.Layers) { // intialize a list of ObjectIDs that need to be cut List <long> cutOiDs = new List <long>(); Table fc = await layer.getFeatureClass(); // on a separate thread await QueuingTaskFactory.StartNew(() => { // find the features crossed by the sketch geometry RowCursor rc = fc.Search(geometry, SpatialRelationship.Crosses); // add the feature IDs into our prepared list while (rc.MoveNext()) { cutOiDs.Add(rc.Current.ObjectID); } }); // no features 'crossed' by the sketched line if (!cutOiDs.Any()) { continue; } // create an edit operation for the cut EditOperation op = EditingModule.CreateEditOperation(); op.Name = string.Format("Cut {0}", layer.Name); op.ProgressMessage = "Working..."; op.CancelMessage = "Operation canceled"; op.ErrorMessage = "Error cutting features"; op.SelectModifiedFeatures = false; op.SelectNewFeatures = false; // for each of the found features set up a cut method inside our edit operation // for multiple ObjectIDs the cuts with will be stacked into one operation foreach (var oid in cutOiDs) { op.Cut(layer, oid, geometry); } await op.ExecuteAsync(); } //execute the operation return(true); }
/// <summary> /// Returns the field index of the shape/geometry field. /// </summary> /// <param name="table">FeatureClass containing the shape field.</param> /// <returns>The index of the shape field.</returns> public static async Task <int> GetShapeFieldIndexAsync(this Table table) { int fieldIndex = -1; await QueuingTaskFactory.StartNew(() => { var fcDefinition = table.Definition as FeatureClassDefinition; if (fcDefinition != null) { fieldIndex = fcDefinition.FindField(fcDefinition.ShapeField); } }); return(fieldIndex); }
/// <summary> /// Returns the name of the shape/geometry field. /// </summary> /// <param name="table">FeatureClass containing the shape field.</param> /// <returns>The name of the shape field.</returns> public static async Task <string> GetShapeFieldNameAsync(this Table table) { string shapeFieldName = String.Empty; await QueuingTaskFactory.StartNew(() => { var fcDefinition = table.Definition as FeatureClassDefinition; if (fcDefinition != null) { shapeFieldName = fcDefinition.ShapeField; } }); return(shapeFieldName); }
/// <summary> /// This is a basic FinishSketch method which illustrates the process of using the sketch geometry for a cut. /// 1. Create edit operation /// 2. Use the sketch geometry to perform a spatial query /// 3. Use the found features and use them to set up a cut operation /// 3. Execute the edit operation /// /// </summary> /// <returns>Task of bool</returns> protected override async Task <bool> FinishSketch(ArcGIS.Core.Geometry.Geometry geometry, Dictionary <string, object> attributes) { if (CurrentTemplate == null) { return(false); } // intialize a list of ObjectIDs that need to be cut List <int> cutOIDs = new List <int>(); Table fc = await this.CurrentTemplate.Layer.getFeatureClass(); // on a separate thread await QueuingTaskFactory.StartNew(() => { // find the features crossed by the sketch geometry RowCursor rc = fc.Search(geometry, SpatialRelationship.Crosses); // add the feature IDs into our prepared list while (rc.MoveNext()) { cutOIDs.Add(rc.Current.ObjectID); } }); if (!cutOIDs.Any()) { return(true);//nothing to cut } // create an edit operation for the cut var op = await EditingModule.CreateEditOperationAsync(); op.Name = string.Format("Cut {0}", this.CurrentTemplate.Layer.Name); op.ProgressMessage = "Working..."; op.CancelMessage = "Operation canceled"; op.ErrorMessage = "Error cutting features"; op.SelectModifiedFeatures = false; op.SelectNewFeatures = false; // for each of the found features set up a cut method inside our edit operation // for multiple ObjectIDs the cuts with will be stacked into one operation foreach (var oid in cutOIDs) { op.Cut(this.CurrentTemplate.Layer, oid, geometry); } //execute the operation return(await op.ExecuteAsync()); }
/// <summary> /// Performs a spatial query against the table/feature class. /// </summary> /// <remarks>It is assumed that the feature class and the search geometry are using the same spatial reference.</remarks> /// <param name="searchTable">The table/feature class 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></returns> public static async Task <RowCursor> SearchAsync(this Table searchTable, Geometry searchGeometry, SpatialRelationship spatialRelationship) { RowCursor rowCursor = null; await QueuingTaskFactory.StartNew(() => { // TODO // define a spatial query filter using the provided spatial relationship and search geometry SpatialQueryFilter spatialQueryFilter = new SpatialQueryFilter(); // apply the spatial filter to the feature class in question rowCursor = searchTable.Search(spatialQueryFilter); }); return(rowCursor); }
/// <summary> /// Create a single multi-point feature that is comprised of 20 points. /// </summary> /// <param name="multiPointLayer">Multi-point geometry feature layer used to add the multi-point feature.</param> /// <returns></returns> private async Task constructSampleMultiPoints(FeatureLayer multiPointLayer) { // get the feature class associated with the layer var featureClass = await multiPointLayer.GetTableAsync() as FeatureClass; // create a random number generator var randomGenerator = new Random(); // the database and geometry interactions are considered fine-grained and need to be executed on // a separate thread await QueuingTaskFactory.StartNew(async() => { // store the spatial reference as its own variable var spatialReference = featureClass.SpatialReference; // define an area of interest. Random points are generated in the allowed // confines of the allow extent range var areaOfInterest = await MappingModule.ActiveMapView.GetExtentAsync(); // start an edit operation to create new (random) multi-point feature var createOperation = EditingModule.CreateEditOperation(); createOperation.Name = "Generate multi-point"; // retrieve the class definition of the point feature class var classDefinition = featureClass.Definition as FeatureClassDefinition; // create a list to hold the 20 coordinates of the multi-point feature IList <Coordinate> coordinateList = new List <Coordinate>(20); for (int i = 0; i < 20; i++) { // generate either 2D or 3D geometries if (classDefinition.HasZ) { coordinateList.Add(randomGenerator.NextCoordinate(areaOfInterest, true)); } else { coordinateList.Add(randomGenerator.NextCoordinate(areaOfInterest, false)); } } // create and execute the feature creation operation createOperation.Create(multiPointLayer, new MultiPoint(coordinateList, classDefinition.SpatialReference)); await createOperation.ExecuteAsync(); }); }
/// <summary> /// Create sample polygon feature using the point geometries from the multi-point feature using the /// ConvexHull method provided by the GeometryEngine. /// </summary> /// <param name="polygonLayer">Polygon geometry feature layer used to add the new feature.</param> /// <param name="lineLayer">The polyline feature layer containing the features used to construct the polygon.</param> /// <returns></returns> private Task <bool> constructSamplePolygon(FeatureLayer polygonLayer, FeatureLayer lineLayer) { // execute the fine grained API calls on the CIM main thread return(QueuingTaskFactory.StartNew(() => { // get the underlying feature class for each layer var polygonFeatureClass = polygonLayer.GetTableAsync().Result as FeatureClass; var lineFeatureClass = lineLayer.GetTableAsync().Result as FeatureClass; // construct a cursor to retrieve the line features var lineCursor = lineFeatureClass.Search(null, false); // retrieve the feature class schema information for the feature class var polygonDefinition = polygonFeatureClass.Definition as FeatureClassDefinition; var polylineDefinition = lineFeatureClass.Definition as FeatureClassDefinition; // set up the edit operation for the feature creation var createOperation = EditingModule.CreateEditOperation(); createOperation.Name = "Create polygons"; List <CoordinateCollection> combinedCoordinates = new List <CoordinateCollection>(); while (lineCursor.MoveNext()) { // retrieve the first feature var lineFeature = lineCursor.Current as Feature; // add the coordinate collection of the current geometry into our overall list of collections var polylineGeometry = lineFeature.Shape as Polyline; combinedCoordinates.AddRange(polylineGeometry.Paths); } // use the ConvexHull method from the GeometryEngine to construct the polygon geometry var newPolygon = Polygon.Clone(GeometryEngine.ConvexHull(new Polyline(combinedCoordinates, lineFeatureClass.SpatialReference))) as Polygon; // queue the polygon creation createOperation.Create(polygonLayer, newPolygon); // execute the edit (polygon create) operation var t = createOperation.ExecuteAsync().Result; // save the edits return EditingModule.SaveEditsAsync(); })); }
protected override Task OnActivateAsync(bool active) { if (active == true) { var targetLayers = MappingModule.ActiveTOC.SelectedLayers; FeatureLayer targetLayer = targetLayers.First() as FeatureLayer; _linearDisplayUnit = DisplayUnitEnvironment.GetEnvironment.DefaultMapLinearUnit; List <Layer> layersToKeep = new List <Layer>(targetLayers.Count); foreach (var item in targetLayers) { layersToKeep.Add(item); } if (GeometryExercisesSolutionModule.Current.HasBeenAdded == false) { string layerTemplatesLocation = String.Empty; DirectoryInfo arcgisProDirectoryInfo = new DirectoryInfo(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)); layerTemplatesLocation = Path.Combine(arcgisProDirectoryInfo.Parent.FullName, "Resources", "LayerTemplates", "en-US"); IEnumerable <FileInfo> fileInfos = new DirectoryInfo(layerTemplatesLocation).EnumerateFiles(); QueuingTaskFactory.StartNew(async() => { foreach (var templateFileInfo in fileInfos) { ItemInfoValue?packageItemInfo = await ItemInfoHelper.GetItemInfoValueAsync(templateFileInfo.FullName); PackageItem layerPackage = new PackageItem(packageItemInfo.Value); await layerPackage.AddToCurrentMapAsync(null); GeometryExercisesSolutionModule.Current.HasBeenAdded = true; break; } MappingModule.ActiveTOC.ClearSelection(); MappingModule.ActiveTOC.SelectLayers(layersToKeep); }); } } else { System.Diagnostics.Debug.WriteLine(""); } return(base.OnActivateAsync(active)); }
/// <summary> /// Find the field with the provided field name. /// </summary> /// <param name="table">Table or FeatureClass containing the field.</param> /// <param name="fieldName"> /// The name of the field to be retrieved. /// </param> /// <returns> /// The field with the provided name. If no field of the given name is found, a null reference /// is returned. /// </returns> public static async Task <Field> GetFieldByNameAsync(this Table table, string fieldName) { Field foundField = null; if (String.IsNullOrEmpty(fieldName)) { return(foundField); } await QueuingTaskFactory.StartNew(() => { IReadOnlyList <Field> fields = ((TableDefinition)table.Definition).Fields; foundField = fields.FirstOrDefault(a => a.Name.Equals(fieldName)); }); return(foundField); }
/// <summary> /// Performs a spatial query against the table/feature class. /// </summary> /// <remarks>It is assumed that the feature class and the search geometry are using the same spatial reference.</remarks> /// <param name="searchTable">The table/feature class 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></returns> public static async Task <RowCursor> SearchAsync(this Table searchTable, Geometry searchGeometry, SpatialRelationship spatialRelationship) { RowCursor rowCursor = null; await QueuingTaskFactory.StartNew(() => { // 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 class in question rowCursor = searchTable.Search(spatialQueryFilter); }); return(rowCursor); }
/// <summary> /// Loads all the bookmarks found in the project /// </summary> /// <param name="currentProject">Current project</param> /// <returns></returns> public static Task <IList <Bookmark> > LoadBookmarksAsync(this Project currentProject) { return(QueuingTaskFactory.StartNew <IList <Bookmark> >(async() => { var mc = currentProject.ProjectItemContainers.OfType <MapContainer>().FirstOrDefault(); List <Bookmark> bookMarks = new List <Bookmark>(); foreach (var mapItem in mc) { var map = await MappingModule.GetMapAsync(mapItem.Path); if (map != null) { var bmks = await map.QueryBookmarksAsync(); if (null != bmks && bmks.Count() > 0) { foreach (var bmk in bmks) { bookMarks.Add(bmk); } } } } return bookMarks; })); }
protected override async void OnMouseUp(System.Windows.Input.MouseButtonEventArgs e) { if (e.ButtonState == MouseButtonState.Released) { if (e.ChangedButton == System.Windows.Input.MouseButton.Left) { e.Handled = true; POINT clickPOINT; GetCursorPos(out clickPOINT); MapPoint clickMapPoint = await MappingModule.ActiveMapView.ScreenToLocationAsync(new System.Windows.Point(clickPOINT.X, clickPOINT.Y)); Envelope ext = await MappingModule.ActiveMapView.GetExtentAsync(); double searchDistance = 0.0; await QueuingTaskFactory.StartNew(() => { searchDistance = ext.Width / 2.0; }); var targetLayer = MappingModule.ActiveTOC.SelectedLayers.OfType <FeatureLayer>().First(); ArcGIS.Core.Geometry.GeometryEngine.ProximityResult clickResult = await ComputeDistanceToGeometryAsync(clickMapPoint, targetLayer, 1, searchDistance); var templateGroupLayer = MappingModule.ActiveMapView.Map.GetFlattenedLayers().OfType <GroupLayer>().Where(lyr => lyr.Name.Equals("Bright Map Notes")).First(); var flashLayer = templateGroupLayer.GetFlattenedLayers().OfType <FeatureLayer>().Where(lyr => lyr.Name.Equals("Bright - Point Notes")).First(); if (clickResult != null) { await flashLayer.AddAndFlashGeometryAsync(clickResult.Point); } } base.OnMouseUp(e); } }
private async Task <ArcGIS.Core.Geometry.GeometryEngine.ProximityResult> ComputeDistanceToGeometryAsync(MapPoint clickPoint, FeatureLayer targetLayer, int hitNumber, double searchDistance) { FeatureClass featureClass = await targetLayer.GetTableAsync() as FeatureClass; Geometry searchBuffer = null; List <Geometry> geometryList = new List <Geometry>(); double closestDistance = double.MaxValue; ArcGIS.Core.Geometry.GeometryEngine.ProximityResult clickResult = null; MapPoint closestPoint = null; bool foundFeatureAndComputedDistance = false; await QueuingTaskFactory.StartNew(() => { var classDefinition = featureClass.Definition as FeatureClassDefinition; searchBuffer = GeometryEngine.Project(GeometryEngine.Buffer(clickPoint, searchDistance), classDefinition.SpatialReference); SpatialQueryFilter spatialFilter = new SpatialQueryFilter() { FilterGeometry = searchBuffer, SpatialRelationship = SpatialRelationship.EnvelopeIntersects }; RowCursor featureCursor = featureClass.Search(spatialFilter, false); while (featureCursor.MoveNext()) { var feature = featureCursor.Current as Feature; geometryList.Add(feature.Shape); } clickPoint = GeometryEngine.Project(clickPoint, classDefinition.SpatialReference) as MapPoint; foreach (var geometry in geometryList) { var geoResult = GeometryEngine.NearestBoundaryPoint(geometry, clickPoint, searchDistance); if (geoResult.Distance < closestDistance) { closestDistance = geoResult.Distance; clickResult = geoResult; foundFeatureAndComputedDistance = true; } } }); if (foundFeatureAndComputedDistance) { DockPane dockPane = FrameworkApplication.FindDockPane("GeometrySamples_ClosestGeometryPane"); if (dockPane == null) { return(new ArcGIS.Core.Geometry.GeometryEngine.ProximityResult()); } DistancePaneViewModel cgVM = dockPane as DistancePaneViewModel; cgVM.DistanceDisplayUnit = _linearDisplayUnit; cgVM.ClickResult = clickResult; } return(clickResult); }
/// <summary> /// This is a basic FinishSketch method which illustrates the process of using the sketch geometry for feature creation. /// 1. Create edit operation /// 2. Use the sketch geometry to perform a spatial query /// 3. Use the found features and use them to set up a cut operation /// 3. Execute the edit operation /// /// Any construction tool will execute successfully with this routine commented out (the default implementation is /// supplied by the Editor framework). Uncomment this method if you wish to add your own additional implementation details. /// </summary> /// <returns>Task{bool}</returns> protected override Task <bool> OnFinishSketch(Geometry geometry, Dictionary <string, object> attributes) { return(QueuingTaskFactory.StartNew(() => ExecuteCut(CurrentTemplate, geometry, attributes))); }
protected async Task <bool> ExecuteCut(EditingTemplate template, Geometry geometry, Dictionary <string, object> attributes) { if (template == null) { return(false); } if (geometry == null) { return(false); } // create an edit operation EditOperation op = EditingModule.CreateEditOperation(); op.Name = "Cut Elements"; op.ProgressMessage = "Working..."; op.CancelMessage = "Operation canceled."; op.ErrorMessage = "Error cutting polygons"; op.SelectModifiedFeatures = false; op.SelectNewFeatures = false; // get the feature class associated with the layer Table fc = await template.Layer.GetTableAsync(); // initialize a list of ObjectIDs that need to be cut var cutOIDs = new List <long>(); // on a separate thread await QueuingTaskFactory.StartNew(async() => { // TODO // find the features crossed by the sketch geometry RowCursor rc = await fc.SearchAsync(geometry, SpatialRelationship.Crosses); // add the feature IDs into our prepared list while (rc.MoveNext()) { var feature = rc.Current as Feature; if (feature == null) { break; } if (feature.Shape != null) { // we are interested in the intersection points // in case there is only one intersection then the sketch geometry doesn't enter and leave the // base geometry and the cut operation won't work. Geometry intersectionGeometry = GeometryEngine.Intersection(feature.Shape, geometry, GeometryDimension.esriGeometry0Dimension); if (intersectionGeometry is MultiPoint) { //var intersectionPoints = intersectionGeometry as MultiPoint; //// we are only interested in feature IDs where the count of intersection points is larger than 1 //// i.e., at least one entry and one exit //if (intersectionPoints.Coordinates.Count > 1) //{ // // add the current feature to the overall list of features to cut // cutOIDs.Add(rc.Current.ObjectID); //} } } } }); // add the elements to cut into the edit operation op.Cut(template.Layer, cutOIDs, geometry); //execute the operation bool operationResult = await op.ExecuteAsync(); return(operationResult); }