FeatureLayer selection attribute value (C#)

3674
8
Jump to solution
05-31-2018 06:10 AM
MikeRatcliffe
Occasional Contributor

I have a single feature selected and need to get the attribute value (string) from "PS_CODE" field to a variable.

1 Solution

Accepted Solutions
MikeRatcliffe
Occasional Contributor

//--The answer was row.GetOriginalValue--

private async void SsPltbtn_Click(object sender, EventArgs e)
{
GVar.PltVal = null; //global variable to carry attribute field value.

if ((MapView.Active.Map.SelectionCount == 1) && (Pltsrch_txtbx.Text != null) && (Pltsrch_txtbx.Text != ""))
{
await ActMap(); //active map checker

Map map = MapView.Active.Map;

var QS_lyr = map.FindLayers("Quarter Section").FirstOrDefault() as FeatureLayer;

if (QS_lyr == null) { return; }

await QueuedTask.Run(() =>
{
var QS_TD = QS_lyr.GetTable().GetDefinition(); //table definition of featurelayer

var Find_Fld = QS_TD.FindField("PS_CODE"); //find the search field index

var QS_lyr_sel = QS_lyr.GetSelection(); //This is NOT a table, but a Selection -- it works.

using (RowCursor rowCursor = QS_lyr_sel.Search()) //http://pro.arcgis.com/en/pro-app/sdk/api-reference/index.html#topic7003.html
{
while (rowCursor.MoveNext())
{
using (Row row = rowCursor.Current)
{
string OrigVal = row.GetOriginalValue(Find_Fld) as string;
GVar.PltVal = OrigVal;
}
}
}
});
try
{
var filepath = @"C:\GISdata\Plat_Sheets\PDF\Sewer\" + GVar.PltVal + ".pdf";
System.Diagnostics.Process.Start(filepath);
}
catch (Exception)
{
MessageBox.Show(" The filepath is incorrect or file is missing.", "File Not Found",
MessageBoxButtons.OK,
MessageBoxIcon.Warning,
MessageBoxDefaultButton.Button1,
MessageBoxOptions.DefaultDesktopOnly);
return;
}
}
else { return; }
}

View solution in original post

8 Replies
MikeRatcliffe
Occasional Contributor

//--The answer was row.GetOriginalValue--

private async void SsPltbtn_Click(object sender, EventArgs e)
{
GVar.PltVal = null; //global variable to carry attribute field value.

if ((MapView.Active.Map.SelectionCount == 1) && (Pltsrch_txtbx.Text != null) && (Pltsrch_txtbx.Text != ""))
{
await ActMap(); //active map checker

Map map = MapView.Active.Map;

var QS_lyr = map.FindLayers("Quarter Section").FirstOrDefault() as FeatureLayer;

if (QS_lyr == null) { return; }

await QueuedTask.Run(() =>
{
var QS_TD = QS_lyr.GetTable().GetDefinition(); //table definition of featurelayer

var Find_Fld = QS_TD.FindField("PS_CODE"); //find the search field index

var QS_lyr_sel = QS_lyr.GetSelection(); //This is NOT a table, but a Selection -- it works.

using (RowCursor rowCursor = QS_lyr_sel.Search()) //http://pro.arcgis.com/en/pro-app/sdk/api-reference/index.html#topic7003.html
{
while (rowCursor.MoveNext())
{
using (Row row = rowCursor.Current)
{
string OrigVal = row.GetOriginalValue(Find_Fld) as string;
GVar.PltVal = OrigVal;
}
}
}
});
try
{
var filepath = @"C:\GISdata\Plat_Sheets\PDF\Sewer\" + GVar.PltVal + ".pdf";
System.Diagnostics.Process.Start(filepath);
}
catch (Exception)
{
MessageBox.Show(" The filepath is incorrect or file is missing.", "File Not Found",
MessageBoxButtons.OK,
MessageBoxIcon.Warning,
MessageBoxDefaultButton.Button1,
MessageBoxOptions.DefaultDesktopOnly);
return;
}
}
else { return; }
}

by Anonymous User
Not applicable

Alternatively you can use an inspector.

      QueuedTask.Run(() =>
      {
        // get the currently selected features in the map
        var selectedFeatures = ArcGIS.Desktop.Mapping.MapView.Active.Map.GetSelection();

        // get the first layer and its corresponding selected feature OIDs
        var firstSelectionSet = selectedFeatures.First();

        // create an instance of the inspector class
        var inspector = new ArcGIS.Desktop.Editing.Attributes.Inspector();

        // load the selected features into the inspector using a list of object IDs
        inspector.Load(firstSelectionSet.Key, firstSelectionSet.Value);

        //get the value of
        var pscode = inspector["ps_code"];
      });
MikeRatcliffe
Occasional Contributor

Thanks, Sean.  I'll try this method when I have some time.

(Ln 7): ".First()" is not available to Featurelayer.GetSelection();.  I need to work from selections on a specific feature layer, not  MapView.Active.Map.GetSelection();.

0 Kudos
BradJones3
Occasional Contributor

I had the same question.  I saw the RowCursor class, but thought there would be a simpler way the get an attributte for a selected feature of a specified layer. I tried both approaches but went with the Inspector. It I don't like to use RowCursors unless i'm manipulating tables. 

Thanks for the snippets!

0 Kudos
MikeRatcliffe
Occasional Contributor

Thanks, Brad.

Care to share your Inspector-based solution that gets the attribute value of a selection from a specific featurelayer instead of Active.Map.GetSelection()?

0 Kudos
BradJones3
Occasional Contributor
    protected override Task<bool> OnSketchCompleteAsync(Geometry geometry)
        {
            return QueuedTask.Run(() =>
            {
                try
                {
                    ActiveMapView.SelectFeatures(geometry, SelectionCombinationMethod.New);

                    //string mhNum = null;
                    var map = MapView.Active.Map;
                    //var mhLayer = map.FindLayers("Manholes").FirstOrDefault(m => m.Name == "Manholes") as FeatureLayer;


                    // get the currently selected features in the map
                    var selectedFeatures = map.GetSelection();

                    if (selectedFeatures.Count == 0)
                    {
                        MessageBox.Show("No manhole was selected.\n\nTry selecting a manhole again.", "Warning");
                    }
                    else if (selectedFeatures.Count > 1)
                    {
                        MessageBox.Show("More than one manhole selected.\n\nTry selecting manholes again.", "Warning");
                    }
                    else
                    {
                        // get the first layer and its corresponding selected feature OIDs
                        var firstSelectionSet = selectedFeatures.First();

                        // create an instance of the inspector class
                        var inspector = new Inspector();

                        // load the selected features into the inspector using a list of object IDs
                        inspector.Load(firstSelectionSet.Key, firstSelectionSet.Value);

                        //get the value of
                        string mhNum = inspector["MH_NO"].ToString();
                        MessageBox.Show(mhNum, "Selected Manhole");

                    }

                }

                catch (Exception)
                {
                    string caption = "Failed to select manhole!";
                    string message = "Process failed. \n\nSave and restart ArcGIS Pro and try process again.\n\n" +
                        "If problem persist, contact your local GIS nerd.";

                    //Using the ArcGIS Pro SDK MessageBox class
                    MessageBox.Show(message, caption);
                }
                return true;
            });
        }

I'm building a trace tool where the user selects a manhole as the start of the the trace.  I clear all selections and make the manholes layer the only selectable layer at the start.  So any features selected in the map with this tool will be in the desired layer.

That's how I can use var selectedFeatures = map.GetSelection();

BTW, I really don't know what the hell I'm doing.

MikeRatcliffe
Occasional Contributor

Aren't we all...

Looks great to me!  Any 'working' info. is invaluable.

For my application, I need the attribute value for a selected plat sheet poly so I can assign it to an interface button that opens the matching utility .pdf. (yep, still using .pdf's)

Thanks for the code.

by Anonymous User
Not applicable

Hi Mike, Sorry I missed the question but it sounds like Brad has you up and running.

Featurelayer.GetSelection() returns a selection class which is more or less a collection of oids for that layer.

From there you can get the list of oids and feed those into the inspector if you wanted to modify them all at once or iterate through the list with a for each loop and load them individually.

        //get selected features from featlayer and update them all at once
        Selection selSet = featLayer.GetSelection();
        IReadOnlyList<long> selSetOids = selSet.GetObjectIDs();

        var op = new EditOperation();
        op.Name = "Update parcel";
        var insp = new Inspector();
        insp.Load(featLayer, selSetOids);
        insp["Pin"] = 42;
        op.Modify(insp);
        op.Execute();‍‍‍‍‍‍‍‍‍‍‍

You could have also come in through the maps selection and filter the selection by layer. The map's selection is a simple dictionary so you can extract the oids by a layer key and feed those oids into the inspector as above.

        //get the oids for featlayer from the map selection
        Dictionary<MapMember,List<long>> mapSel = MapView.Active.Map.GetSelection();
        List<long> featLayerOids = mapSel[featLayer];‍‍‍

Seeing more code examples cant hurt.

0 Kudos