Moving selected features

404
12
Jump to solution
08-22-2017 12:49 PM
Highlighted
Regular Contributor

Hi,

i'm having some trouble trying to figure out how to move a bunch of selected features from a specific point layer in the map.  This is what I have so far:

//****Get all of the selected ObjectIDs from the VLS layer.
var abLayer = MapView.Active.Map.FindLayers("GISWRKS1.WORKS.AsBuilts").First() as BasicFeatureLayer;
var selection = abLayer.GetSelection();
IReadOnlyList<long> selectedOIDs = selection.GetObjectIDs(); //save the selected OBJECTIDs to a list.

var insp = new ArcGIS.Desktop.Editing.Attributes.Inspector(); //create the Inspector

var moveFeature = new EditOperation();

moveFeature.Name = "Move AsBuilts";

//Loop through each selected OBJECTID
foreach (var oid in selectedOIDs)
{
insp.Load(abLayer, oid);

moveFeature.Move(..............);      //****  This is where I get stuck....I don't know what to do

}

I think my approach is all wrong, but I'm not sure what to do.  I'm not exactly sure how to interpret this:  ArcGIS Pro 2.0 API Reference Guide 

Thanks

1 Solution

Accepted Solutions
Highlighted
Esri Regular Contributor

Hi Brian,

This snippet below worked for me.  The Move method has a couple of overrides you can use. Move method from Pro API Reference guide

 QueuedTask.Run(() =>
            {
                //Get all of the selected ObjectIDs from the layer.
                var abLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault();
                var selection = abLayer.GetSelection();

                // set up a dictionary to store the layer and the object IDs of the selected features
                var selectionDictionary = new Dictionary<MapMember, List<long>>();
                selectionDictionary.Add(abLayer as MapMember, selection.GetObjectIDs().ToList());
                var moveFeature = new EditOperation();
                moveFeature.Name = "Move features";
                moveFeature.Move(selectionDictionary, 10, 10);  //specify your units along axis to move the geometry

                moveFeature.Execute();
            });

View solution in original post

0 Kudos
12 Replies
Highlighted
Esri Regular Contributor

Hi Brian,

This snippet below worked for me.  The Move method has a couple of overrides you can use. Move method from Pro API Reference guide

 QueuedTask.Run(() =>
            {
                //Get all of the selected ObjectIDs from the layer.
                var abLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault();
                var selection = abLayer.GetSelection();

                // set up a dictionary to store the layer and the object IDs of the selected features
                var selectionDictionary = new Dictionary<MapMember, List<long>>();
                selectionDictionary.Add(abLayer as MapMember, selection.GetObjectIDs().ToList());
                var moveFeature = new EditOperation();
                moveFeature.Name = "Move features";
                moveFeature.Move(selectionDictionary, 10, 10);  //specify your units along axis to move the geometry

                moveFeature.Execute();
            });

View solution in original post

0 Kudos
Highlighted
Regular Contributor

Thanks Uma.  That is working now.

Do you know if there is a similar method that will move the feature to a specific coordinate??  Or is there a built-in method for calculating the offset between two coordinates??

0 Kudos
Highlighted
Esri Regular Contributor

Hi Brian

If you use EditOperation's Modify method you can move the point to a specific coordinate -

 QueuedTask.Run(() =>
            {
                //Get all of the selected ObjectIDs from the layer.
                var abLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault();
                var selection = abLayer.GetSelection();
                var oid = selection.GetObjectIDs().FirstOrDefault();

                var moveToPoint = new MapPointBuilder(1.0, 2.0, 3.0, 4.0, MapView.Active.Map.SpatialReference); //can pass in coordinates.

                var modifyFeature = new EditOperation();
                modifyFeature.Name = "Move features";
                modifyFeature.Modify(abLayer, oid, moveToPoint.ToGeometry());  //Modify the feature to the new geometry
                modifyFeature.Execute();
            });‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Also, the GeometryEngine has a "Distance" method that could be used to calculate the offset distance between 2 points (to plug into the "Move" method - For the original Move method snippet).

Thanks

Uma

Highlighted
Regular Contributor

Thanks again Uma.  You have been a great help!

I tweaked yours to work with a selection of features.  Here is my final solution for anyone else who may be following this thread:

// Get the layers and also any selected OIDs for the AsBuilt and the SitePlan layers

                var asBuiltLayer = MapView.Active.Map.FindLayers("GISWRKS1.WORKS.Drawings_AsBuilts").FirstOrDefault() as BasicFeatureLayer;

               

                // variable for the coordinate of the mouse click in the whatever the SpatialReference of the map is

                var coord = GeometryEngine.Instance.Project(geometry, MapView.Active.Map.SpatialReference) as MapPoint;

                var moveToPoint = new MapPointBuilder(coord.X, coord.Y, MapView.Active.Map.SpatialReference);

 

                // create counter for showing final results

                int abCount = 0;

  

                // start the EditOperation

                var modifyAsBuilts = new EditOperation();

                modifyAsBuilts.Name = "Move As-Builts and Site Plans";

  

                // Get any selected OIDs for the layer, and move each point to the mouse click point.

                if (asBuiltLayer != null)

                {

                    var selectedAB = asBuiltLayer.GetSelection();

                    IReadOnlyList<long> selectedAsbuiltOIDs = selectedAB.GetObjectIDs();

 

                    foreach (var oid in selectedAsbuiltOIDs)

                    {

                        modifyAsBuilts.Modify(asBuiltLayer, oid, moveToPoint.ToGeometry());

                        abCount++;

                    }

                }

modifyAsBuilts.Execute();

Highlighted
Esri Contributor

Brian, thanks for taking the time on this.

FYI: on:

 // variable for the coordinate of the mouse click in the whatever the SpatialReference of the map is

                var coord = GeometryEngine.Instance.Project(geometry, MapView.Active.Map.SpatialReference) as MapPoint;

                var moveToPoint = new MapPointBuilder(coord.X, coord.Y, MapView.Active.Map.SpatialReference);<-- not needed

coord is a MapPoint already (reading your code). 

So this:

modifyAsBuilts.Modify(asBuiltLayer, oid, moveToPoint.ToGeometry());

can become this:

modifyAsBuilts.Modify(asBuiltLayer, oid, coord);

I think you may have some copy/paste inheritance from Uma's code where she used a MapPointBuilder because she built the point from scratch.

One other point (no pun intended ;-). I noticed this:

var coord = GeometryEngine.Instance.Project(geometry, MapView.Active.Map.SpatialReference) as MapPoint;

I don't now what the overall context of the "surrounding" code is but I suspect that your digitized geometry may already be in the map spatial reference. Can you just try:

modifyAsBuilts.Modify(asBuiltLayer, oid, geometry);

using the geometry directly and see if that works?

Highlighted
Regular Contributor

Hi Charles,

Yes, I was doing some copy/paste without really realizing what the MapPointBuilder was doing.

Anyways.....just using the geometry parameter is working:

modifyAsBuilts.Modify(asBuiltLayer, oid, geometry);

One thing I am noticing is that the points in the map don't actually move until I click on 'OK' for the message box that pops up after I run modifyAsBuilts.Execute().....see below:

modifyAsBuilts.Execute();

ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(abCount.ToString() + " As-Builts moved.", "Points moved");

I am guessing that I need some sort of a delay in there for the moving of the points to catch up to the processing of the code.....right??

Now on to the next phase;  figuring out how to enable/disable this tool based on certain layers being in the map or not....and also changing the mouse cursor to the 'Explore' tool after the points have been moved.  Any advice?? 

0 Kudos
Highlighted
Esri Contributor

If you have this:

QueuedTask.Run(() => {

       op.Execute();

       MessageBox.Show("...");

}

you probably won't see the move (until after).

Instead, do this:

await QueuedTask.Run(() => {

       op.Execute();

       

};

MessageBox.Show("...");

and you will. Note, if you add "await", you must also add "async" to the method declaration (eg SketchComplete or whichever it is).

0 Kudos
Highlighted
Regular Contributor

Excellent....thanks Charles!

0 Kudos
Highlighted
Esri Regular Contributor

To enable/disable your tool based on layers, you can use states and conditions.  There is ConstructMarkerFromFont sample that demonstrates this.  

0 Kudos