Select to view content in your preferred language

How to convert selected feature from feature class to geometry

2764
13
Jump to solution
11-14-2018 02:02 PM
JoshuaO_Neil
Emerging Contributor

Hello,

I cannot figure out how to convert selected features from a feature dataset to geometry, so that I can zoom the map to the selected features (I want to zoom the map to only the selected state from the code below).

I have two layers in my map (project area and states). I was able to select the state from the states layer that intersects my project area polygon using the code below. However, I cannot figure out how to zoom the map to the selected state (the state that intersects with my project area boundary). I thought the last 2 lines of my code would do it, but that zooms the map to the entire states layer (not just the selected state). Does anyone know what I am doing wrong?

 

{
var layout = Project.Current.GetItems<LayoutProjectItem>()?.First().GetLayout();
if (layout == null) return;
MapFrame mf = layout.FindElement("Main Map") as MapFrame;
Map m = mf.Map;


FeatureLayer fl1 = m.FindLayers("ProjectArea1").First() as FeatureLayer;
QueryFilter queryFilter = new QueryFilter();


using (ArcGIS.Core.Data.RowCursor rowCursor = fl1.Search(queryFilter = null))
{
//Grab the first record (and hopefully only record)
while (rowCursor.MoveNext())
{
//Grab the features geometry
Feature feature1 = rowCursor.Current as Feature;
Geometry geo = feature1.GetShape();

//Set up a spatial query
var spatialQuery = new SpatialQueryFilter()
{ FilterGeometry = geo, SpatialRelationship = SpatialRelationship.Intersects };

//Reference county layer and apply spatial query
FeatureLayer fl2 = m.FindLayers("States").First() as FeatureLayer;
fl2.Select(spatialQuery);

Geometry geo1 = fl2.QueryExtent();

Envelope env = geo1.Extent;
mf.ZoomTo(env);
}
}

0 Kudos
1 Solution

Accepted Solutions
Wolf
by Esri Regular Contributor
Esri Regular Contributor

I adapted your code snippet to an Add-in button and fixed your code.  One feature in States is selected by using one feature from ProjectArea and the envelope of the selected States record is used to zoom the map to the selection.  This is what I see after I click my test button:

This is the code behind for the button:

    protected override async void OnClick()
    {
      {
        Map m = MapView.Active.Map;
        if (m != null)
        {
          var env = await SelectStateAsync(m);
          if (env != null) await MapView.Active.ZoomToAsync(env);
        }
      }
    }

    private Task<Envelope> SelectStateAsync(Map m)
    {
      return QueuedTask.Run<Envelope>(() =>
      {
        Envelope selectionEnvelope = null;
        FeatureLayer fl1 = m.FindLayers("ProjectArea").FirstOrDefault() as FeatureLayer;
        if (fl1 == null) return selectionEnvelope;
        QueryFilter queryFilter = new QueryFilter();

        using (ArcGIS.Core.Data.RowCursor rowCursor = fl1.Search(queryFilter = null))
        {
          //Grab the first record (and hopefully only record)
          while (rowCursor.MoveNext())
          {
            //Grab the features geometry
            Feature feature1 = rowCursor.Current as Feature;
            Geometry geo = feature1.GetShape().Clone();
            //Set up a spatial query
            var spatialQuery = new SpatialQueryFilter()
            {
              FilterGeometry = geo,
              SpatialRelationship = SpatialRelationship.Intersects
            };
            //Reference county layer and apply spatial query
            FeatureLayer fl2 = m.FindLayers("States").FirstOrDefault() as FeatureLayer;
            if (fl2 != null)
            {
              // this selects the feature(s) in fl2
              var selection = fl2.Select(spatialQuery);
              // this get the envelope
              using (RowCursor rowCursor2 = selection.Search())
              {
                if (rowCursor2.MoveNext())
                {
                  // stop with the first extent
                  Geometry geo1 = (rowCursor2.Current as Feature).GetShape().Clone();
                  selectionEnvelope = geo1.Extent.Expand(1.1, 1.1, true);
                }
              }
            }
          }
        }
        return selectionEnvelope;
      });
    }

Hope this helps.  

View solution in original post

13 Replies
GKmieliauskas
Esri Regular Contributor
0 Kudos
JoshuaO_Neil
Emerging Contributor

Thanks, I can't seem to get this to work with my example. I can't figure out the code after fl2.Select(spatialQuery); 

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

I adapted your code snippet to an Add-in button and fixed your code.  One feature in States is selected by using one feature from ProjectArea and the envelope of the selected States record is used to zoom the map to the selection.  This is what I see after I click my test button:

This is the code behind for the button:

    protected override async void OnClick()
    {
      {
        Map m = MapView.Active.Map;
        if (m != null)
        {
          var env = await SelectStateAsync(m);
          if (env != null) await MapView.Active.ZoomToAsync(env);
        }
      }
    }

    private Task<Envelope> SelectStateAsync(Map m)
    {
      return QueuedTask.Run<Envelope>(() =>
      {
        Envelope selectionEnvelope = null;
        FeatureLayer fl1 = m.FindLayers("ProjectArea").FirstOrDefault() as FeatureLayer;
        if (fl1 == null) return selectionEnvelope;
        QueryFilter queryFilter = new QueryFilter();

        using (ArcGIS.Core.Data.RowCursor rowCursor = fl1.Search(queryFilter = null))
        {
          //Grab the first record (and hopefully only record)
          while (rowCursor.MoveNext())
          {
            //Grab the features geometry
            Feature feature1 = rowCursor.Current as Feature;
            Geometry geo = feature1.GetShape().Clone();
            //Set up a spatial query
            var spatialQuery = new SpatialQueryFilter()
            {
              FilterGeometry = geo,
              SpatialRelationship = SpatialRelationship.Intersects
            };
            //Reference county layer and apply spatial query
            FeatureLayer fl2 = m.FindLayers("States").FirstOrDefault() as FeatureLayer;
            if (fl2 != null)
            {
              // this selects the feature(s) in fl2
              var selection = fl2.Select(spatialQuery);
              // this get the envelope
              using (RowCursor rowCursor2 = selection.Search())
              {
                if (rowCursor2.MoveNext())
                {
                  // stop with the first extent
                  Geometry geo1 = (rowCursor2.Current as Feature).GetShape().Clone();
                  selectionEnvelope = geo1.Extent.Expand(1.1, 1.1, true);
                }
              }
            }
          }
        }
        return selectionEnvelope;
      });
    }

Hope this helps.  

JoshuaO_Neil
Emerging Contributor

I greatly appreciate your assistance on this! I tried the above, and am still not getting the map zoomed to the selected state. Here is what I am getting. NY is selected, which is correct, but the map is zoomed to the entire states layer, not just NY.

0 Kudos
JoshuaO_Neil
Emerging Contributor

I apologize. I made a mistake. This worked!!!

I greatly appreciate your help.

One other question though is how I can get this to work if the project boundary crosses two states (I would need to zoom to two states instead of one).

0 Kudos
JoshuaO_Neil
Emerging Contributor

Also, now that this code has worked, how can I zoom out a bit more, such as a factor of 2?

Thanks!

0 Kudos
GKmieliauskas
Esri Regular Contributor

Change line:

selectionEnvelope = geo1.Extent.Expand(1.1, 1.1, true);

to:

selectionEnvelope = geo1.Extent.Expand(2, 2, true);

JoshuaO_Neil
Emerging Contributor

I am new to coding, and have used the above code in an ArcGIS Pro button. However, I cannot seem to get any code to work after zooming to the states layer in the private Task<Envelope> SelectStateAsync(Map m) method. For example, if I want to create a new map frame and add it to the layout after that, why won't the code below work? Anything starting at the "public void BuildEnvelopeGeometry()" won't work.

protected override async void OnClick()
{
{
Map m = MapView.Active.Map;
if (m != null)
{
var env = await SelectStateAsync(m);
if (env != null) await MapView.Active.ZoomToAsync(env);
}
}
}

private Task<Envelope> SelectStateAsync(Map m)
{
return QueuedTask.Run<Envelope>(() =>
{
Envelope selectionEnvelope = null;
FeatureLayer fl1 = m.FindLayers("ProjectArea1").FirstOrDefault() as FeatureLayer;
if (fl1 == null) return selectionEnvelope;
QueryFilter queryFilter = new QueryFilter();

using (ArcGIS.Core.Data.RowCursor rowCursor = fl1.Search(queryFilter = null))
{
//Grab the first record (and hopefully only record)
while (rowCursor.MoveNext())
{
//Grab the features geometry
Feature feature1 = rowCursor.Current as Feature;
Geometry geo = feature1.GetShape().Clone();
//Set up a spatial query
var spatialQuery = new SpatialQueryFilter()
{
FilterGeometry = geo,
SpatialRelationship = SpatialRelationship.Intersects
};
//Reference county layer and apply spatial query
FeatureLayer fl2 = m.FindLayers("States").FirstOrDefault() as FeatureLayer;
if (fl2 != null)
{
// this selects the feature(s) in fl2
var selection = fl2.Select(spatialQuery);
// this get the envelope
using (RowCursor rowCursor2 = selection.Search())
{
if (rowCursor2.MoveNext())
{
// stop with the first extent
Geometry geo1 = (rowCursor2.Current as Feature).GetShape().Clone();
selectionEnvelope = geo1.Extent.Expand(1.1, 1.1, true);
}
}
}
}
return selectionEnvelope;
}
});
}
public void BuildEnvelopeGeometry()
{
//Build Envelope Geometry for Main Map Frame
Envelope mf_env_Main = EnvelopeBuilder.CreateEnvelope(new Coordinate2D(0.5, 2.5), new Coordinate2D(8.0, 10.5));

//Reference map, create MF and add to layout
MapProjectItem mapPrjItem_Main = Project.Current.GetItems<MapProjectItem>().FirstOrDefault(item => item.Name.Equals("Map"));
Map mfMap_Main = mapPrjItem_Main.GetMap();

MapFrame mfELM_Main = LayoutElementFactory.Instance.CreateMapFrame(LayoutView.Active.Layout, mf_env_Main, mfMap_Main);

mfELM_Main.SetName("Main Map");
}
}
}

0 Kudos
GKmieliauskas
Esri Regular Contributor

Hi Joshua,

There is no calling of BuildEnvelopeGeometry in your code.

0 Kudos