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);
}
}
Solved! Go to Solution.
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.
Hi Joshua,
Look at ArcGIS pro community sample:
Thanks, I can't seem to get this to work with my example. I can't figure out the code after fl2.Select(spatialQuery);
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.
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.
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).
Also, now that this code has worked, how can I zoom out a bit more, such as a factor of 2?
Thanks!
Change line:
selectionEnvelope = geo1.Extent.Expand(1.1, 1.1, true);
to:
selectionEnvelope = geo1.Extent.Expand(2, 2, true);
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");
}
}
}
Hi Joshua,
There is no calling of BuildEnvelopeGeometry in your code.