ProConcepts Map Exploration - EsriJapan/arcgis-pro-sdk GitHub Wiki
The mapping functionality in ArcGIS Pro is delivered through the ArcGIS.Desktop.Mapping assembly. Map Exploration provides classes and members that support navigating and interacting with views of a map. This includes modifying the view's extent by zooming to layers, features, and bookmarks, and interactively selecting or returning features that intersect a given sketch geometry.
- ArcGIS.Desktop.Mapping.dll
- ArcGIS.Desktop.Extensions.dll
Language: C#
Subject: Map Exploration
Contributor: ArcGIS Pro SDK Team <[email protected]>
Organization: Esri, http://www.esri.com
Date: 04/25/2025
ArcGIS Pro: 3.5
Visual Studio: 2022
- MapView
- Camera
- TableView
- MapTool
- Animation
- MapControl
- TableControl
- MapView Graphic Overlay
- MapView Overlay Control
- Table Options
A project can contain multiple maps, either 2D or 3D, and each defines the collection of layers that make up that map. A map view is simply a view of a map. Map views are the primary interface used to display, navigate, select, identify, and edit data in a 2D or 3D map. The MapView class provides properties and methods to navigate and interact with layers in the map. The map being visualized in the view can be accessed via the Map property.
There can be multiple map views open at a given time, but there can only be one active map view. The active map view will set the context for the ribbon and many of the dock panes in the application. For example, the map Contents pane will reflect the layers of the active map view's map. The instance of the active map view can be accessed via the static Active property on MapView. The active property will return null if there is no active map view. This is useful when writing commands designed to interact with the active map.
Drawing mode of 3D map views can be set via the SetSceneDrawingMode method. The scene drawing mode can be either perspective or isometric. Default drawing mode is perspective and new 3D map views always open in perspective mode. Scene's field of view angle can be changed using the SetFieldOfView method.
The map view also provides the context for the selected items in the Contents pane (a.k.a. "TOC"). For example, the GetSelectedLayers method returns the collection of layers that are currently selected in the Contents pane. This context is used to determine which contextual tabs to show, for example, when one or more feature layers are selected, the Feature Layer tab group will display, and the commands will act on the selected feature layers. This is useful when writing commands to work with the selected items in the Contents pane.
The map view's camera defines the area being displayed in the map. The camera can be accessed via the Camera property on the map view. You can set the map view's camera by using the ZoomTo(Camera) method. In addition to directly setting the camera, there are several overload methods for ZoomTo and PanTo that can be used to zoom to the extent of a layer, the definition of a bookmark, a specific geometry, and so on.
In some cases, you may want to provide a tool that allows the user to interactively click and sketch in the map and select or get a collection of features that intersect the sketch. The MapTool abstract class provides an easy way to author a tool that can create a sketch in the map view and return the geometry from the sketch. This geometry can then be passed into the SelectFeatures or GetFeatures method to select or return the collection of features that intersect the geometry.
Starting at ArcGIS Pro 3.3, a new type of map, the "link chart" or "link chart map" is added to the public API. Link charts are displayed on link chart views. Link chart views use the MapView class; same as 2d and 3d map and scene views. Link chart maps are accessed off the MapView.Active.Map application context same as any other map type if a link chart is the current active view. To determine if a given MapView is for a link chart or not, use the MapView.IsLinkChartView property.
//Check the active view...
if (MapView.Active.IsLinkChartView) {
//the current active view is a link chart...
}
//Find a particular link chart view amongst the open map panes
var mapPanes = FrameworkApplication.Panes.OfType<IMapPane>().ToList();
var mapPane = mapPanes.FirstOrDefault(
mp => mp.MapView.IsLinkChartView && mp.MapView.Map.Name == "Acme Link Chart");
var linkChartMap = mapPane.MapView.Map;
//etc.Refer to the ProConcepts Knowledge Graph for more information about Knowledge Graphs and Link Charts.
The camera serves as a tool to display the world or map, and it can be moved through space to change your view. The camera describes your active point of view, in both 2D and 3D, on the map. You can get the current camera from the view using the Camera property. You can set the camera by calling the ZoomTo(Camera) method and passing in the desired camera.
The virtual camera is your window to the map. Much like a physical camera you can manipulate in the real world, the ArcGIS Pro virtual camera is moved around to view the map (in both 2D and 3D). The movement of the camera is done in coordinates of the map or the 3D axis system (X, Y, and Z).
Both 2D and 3D properties are available on the camera object. If the map view's ViewingMode is Map, you can set 2D properties. If the ViewingMode is SceneGlobal or SceneLocal, you can set 3D properties.
In 2D, the camera defines its viewing location using X and Y. The values are in the same units as those defined by the camera’s spatial reference. This will be the center point of the 2D view’s extent. The viewing direction, or rotation, of the map is defined using the camera’s Heading property. The camera’s Scale property then defines how far the view is zoomed in or out. The value is expressed as a double representing the value on the right side of the ratio. For example, a value of 1000 is equal to a scale of 1:1000.
In 3D, the camera defines its viewing location using X, Y, and Z. As with 2D, the values are stored in the same units as those defined by the camera’s spatial reference, with the additional possibility that XY units and Z units may be different. The viewing direction is defined by a combination of the Heading, Pitch, and Roll properties, which rotate, tilt, and roll how the camera looks at the content in the map.
You can use a camera to define either the coordinate you're looking from (the observer) or the position that you are looking at (the target) using the Viewpoint property. If you set the Viewpoint to LookFrom, the camera viewing location will be the coordinate of the observer. If you set the Viewpoint to LookAt, the camera viewing location will be the coordinate of the target. The camera returned from the map view's Camera property will always have a Viewpoint of LookAt.
A table view is a view of a table or feature class. Table views are the primary interface for displaying, selecting and editing data in a tabular fashion. The TableView class provides properties and methods to navigate and interact with the table.
There can be multiple table views open at a given time, but there can only be one active table view. The active table view will set the context for the ribbon and the Table of Contents. The instance of the active table view can be accessed via the static Active property on TableView. The active property will return null if there is no active table view.
Typically a table view is linked to a layer or standalone table that is in a map. When visualized in this way use the MapMember property to obtain the underlying object. However, a table view can also be linked to a table or featureclass directly from an external geodatabase (ie, the table or featureclass are not in the map). In this case, the underlying object can be accessed with the Item property. Use ArcGIS.Desktop.Core.ItemFactory.CanGetDataset and ArcGIS.Desktop.Core.ItemFactory.GetDataset to retrieve the data.
Here's an example of a table view displaying data from an external source. See how the context of the Table of Contents and ribbon are different from the above picture showing table views containing map data.
The following snippet shows how to access the active table view.
// get the active table view
var activeTV = TableView.Active;
// get the active map member
var mm = activeTV.MapMember;
// it could be a feature layer
var fl = mm as FeatureLayer;
// or it could be a standalone table
var st = mm as StandaloneTable;
// if mapMember is null, then the data has come from an external source
// use TableView.Item
var item = activeTV.Item;You can set the view mode (All records or Selected records) and zoom level of the table view with the SetViewMode and SetZoomLevel methods. There are also properties to get the current ViewMode and ZoomLevel values.
// get the active table view
var tableView = TableView.Active;
// set the zoom level
tableView.SetZoomLevel(200);
// toggle view mode
var vmode = tableView.ViewMode;
tableView.SetViewMode(
vmode == TableViewMode.eAllRecords ? TableViewMode.eSelectedRecords : TableViewMode.eAllRecords);If you wish to show tabular data hosted on a dockpane or form, use the TableControl. All the functionalities discussed in the sections below, apply to both the TableView and TableControl.
Access to rows in the table view is typically achieved using the row index. You can find the active row index using the ActiveRowIndex property. Navigate between rows by modifying the ActiveRowIndex property or by using the BringIntoView function which also scrolls the table view to that row. You can retrieve the object ID of a particular row by using the GetObjectIdAsync method
In many cases however, you may only know the ObjectID of the row that you wish to make current. In this case, use the GetRowIndex or GetRowIndexAsync methods to determine the row index for a given ObjectID in the dataset and then use the ActiveRowIndex or BringIntoView function to set the row.
var tableView = TableView.Active;
if (tableView != null)
{
// get the active rowindex
int rowIndex = tableView.ActiveRowIndex;
// get the active OID
long? OID = tableView.ActiveObjectId;
long newOID = -1;
// move to a different row
var newIndex = 10 + rowIndex;
await tableView.BringIntoView(newIndex);
newOID = await tableView.GetObjectIdAsync(newIndex);
// or move to a different row via objectID
newOID = OID.Value + 20;
var idx = await tableView.GetRowIndexAsync(newOID, true);
if (idx != -1)
await tableView.BringIntoView(idx);
}Selected rows are displayed in the table view with a cyan highlight. When the table view is in Selected records view mode, you can work with a subset of the selected records by highlighting records. Highlighted records appear yellow in both the table and the map or scene view. The benefit of being able to highlight records within a selection set is that you are identifying specific features from an already defined subgroup. Note that selection is persisted but highlighting is not. That is, if you close and reopen the map, or change the selection, the highlighting is cleared, but the selection remains.
There are numerous methods to manipulate the row selection using the TableView class. You can select records by either object ID or row index using the Select method, or you can toggle the current row selection with the ToggleRowSelection method. Other options include SwitchSelection, SelectAll or ClearSelection. Each of these methods should be preceded in use by its corresponding CanXXX property (for example CanSelect, CanToggleRowSelection, CanSwitchSelection, CanClearSelection.
You can retrieve the set of selected records using either of the GetSelectedObjectIds or GetSelectedRowIndexes methods.
See the following code snippet as an example.
var tv = TableView.Active;
if (tv == null)
return;
QueuedTask.Run(async () =>
{
// get the set of selected objectIDs
var selOids = tv.GetSelectedObjectIds();
// get the set of selected row indexes
var selRows = tv.GetSelectedRowIndexes();
// add to the set of selected records
var newoids = new List<long>(selOids);
newoids.AddRange(new List<long>() { 10, 15, 17 });
tv.Select(newoids, true);
// or switch the current selection
if (tv.CanSwitchSelection)
tv.SwitchSelection();
// toggle the active rows selection
if (tv.CanToggleRowSelection)
tv.ToggleRowSelection();
// clear the selection
if (tv.CanClearSelection)
tv.ClearSelection();
});Similar methods exist to manipulate and retrieve the highlighted records when the table view is in Selected records view mode. Retrieve the highlighted records using GetHighightedObjectIds. Use CanHighlight, Highlight, CanToggleRowHighlight, ToggleRowHighlight, CanSwitchHighlight, SwitchHighlight or CanClearHighlighted and ClearHighlighted to modify the highlighted set.
var tv = TableView.Active;
if (tv == null)
return;
QueuedTask.Run(() =>
{
// highlighted records are only accessible when viewMode = selected records
if (tv.ViewMode == TableViewMode.eSelectedRecords)
{
// get list of current highlighted objectIDs
var highlightedObjectIDs = tv.GetHighlightedObjectIds();
// get list of current selected objectIDs
var selectedObjectIds = tv.GetSelectedObjectIds();
var idsToHighlight = new List<long>();
// add the first two selected objectIds to highlight
if (selectedObjectIds.Count >= 2)
{
idsToHighlight.Add(selectedObjectIds[0]);
idsToHighlight.Add(selectedObjectIds[1]);
}
// highlight
if (tv.CanHighlight)
tv.Highlight(idsToHighlight, true);
// or clear the highlight
//if (tv.CanClearHighlighted)
// tv.ClearHighlighted();
// or switch the highlight of the active row
//if (tv.CanSwitchHighlight)
// tv.SwitchHighlight();
}
});Once you have a set of selected or highlighted records you can zoom or pan to those records using the ZoomToSelected, PanToSelected, ZoomToHiglighted or PanToHighlighted methods. Precede each of these methods with the appropriate CanXXX property to ensure that the action is valid.
var tv = TableView.Active;
if (tv == null)
return;
if (tv.CanZoomToSelected)
tv.ZoomToSelected();Specific fields in the table view can be accessed by GetField or a combination of GetFieldIndex to obtain a field index followed by a GetField call (with that index). The collection of fields in the table view can be retrieved with the GetFields method.
Set the active field with the SetActiveField method using either the field index or the field name. Retrieve the active field index using ActiveFieldIndex.
The TableView class also has a number of methods and properties to allow you to alter the display by manipulating the table fields. Options include selecting fields, customize showing the field alias or field name, setting the field order, hiding fields, freezing fields (freezing fields means that the field column is aligned to the left of the table and kept visible as you scroll horizontally) or sorting the table.
See the following snippets for examples of the above actions.
var tv = TableView.Active;
if (tv == null)
return;
// field access
var flds = tv.GetFields();
var fldIdx = tv.GetFieldIndex("STATE_NAME");
var fldDesc = tv.GetField(fldIdx);
var activeIdx = tv.ActiveFieldIndex;
tv.SetActiveField("STATE_NAME");
// select a set of fields
var selectedfields = tv.GetSelectedFields();
tv.SetSelectedFields(new List<string> { "CITY_FIPS", "STATE_FIPS" });
selectedfields = tv.GetSelectedFields();
// hide fields
tv.ShowAllFields();
tv.SetHiddenFields(new List<string> { "CITY_FIPS", "STATE_FIPS" });
// adds to hidden
tv.SetHiddenFields(new List<string> { "STATE_NAME" });
// sort fields
var dict = new Dictionary<string, FieldSortInfo>();
dict.Add("STATE_NAME", FieldSortInfo.Asc);
dict.Add("CITY_NAME", FieldSortInfo.Desc);
await tv.SortAsync(dict);
var fields = tv.GetFields();
tv.ResetFieldOrder();
var fldOrder = new List<string>();
fldOrder.Add("STATE_NAME");
fldOrder.Add("STATE_FIPS");
await tv.SetFieldOrderAsync(fldOrder);As mentioned before, the table view can contain data that is either within the map or from an external source. Each view has a pane associated with it - for more information on panes see this link.
The table pane is represented by the following API interfaces; ITablePane, ITablePaneEx and IExternalTablePane depending upon the data hosted in the view.
ITablePaneEx and IExternalTablePane were introduced at 3.1, ITablePane was an existing interface which provided a few customization methods. Developers should use the ITablePaneEx and IExternalTablePane interfaces to obtain the TableView for access to the full set of table view capabilities.
// find all the table panes (table panes hosting map data)
var tablePanes = FrameworkApplication.Panes.OfType<ITablePane>();
// find all the external table panes (table panes hosting external data)
var externalPanes = FrameworkApplication.Panes.OfType<IExternalTablePane>();
TableView tv = null;
var firstTablePane = tablePanes.FirstOrDefault();
var firstExternalTablePane = externalPanes.FirstOrDefault();
if (firstTablePane != null)
{
var firstTablePaneEx = firstTablePane as ITablePaneEx;
// change the caption
firstTablePaneEx.Caption = "My table pane";
tv = firstTablePaneEx.TableView;
}
else if (firstExternalTablePane != null)
{
firstExternalTablePane.Caption = "My table pane";
tv = firstExternalTablePane.TableView;
}
if (tv == null)
return;
// set the zoom level
tv.SetZoomLevel(200);
// set some frozen fields
var frozenFields = tv .GetFrozenFields();
if (!frozenFields.Contains("CITY_FIPS"))
{
await tv.ClearAllFrozenFieldsAsync();
await tv.SetFrozenFieldsAsync(new List<string> { "CITY_FIPS", "STATE_FIPS" });
// adds to frozen
await tv.SetFrozenFieldsAsync(new List<string> { "STATE_NAME" });
}ArcGIS.Desktop.Mapping.MapTool is an abstract base class that provides a basic implementation of ArcGIS.Desktop.Framework.Contracts.Tool and represents a tool command used to perform interactive operations on a MapView. It provides virtual methods that can be overridden to perform actions when keyboard and mouse events occur in the map view. It also provides properties that can be set to configure the behavior of the tool, as well as methods that wrap common functions when interacting with the view. This base class will be used to create tools to interactively identify and select features in the view as well as when creating custom construction and editing tools.
Map tools are added to the <controls> section of the add-in Config.daml. Same as buttons, map tools should be referenced within the groups that will contain them and the groups are, themselves, referenced within the individual tabs on which they should be shown. They have a corresponding code file which contains the map tool "class" implementation and it should also be referenced in the tool daml. For example:
<modules>
<insertModule id="..." ... caption="Module1">
<tabs>
<tab id="ProAppModule1_Tab1" caption="New Tab">
<group refID="ProAppModule1_Group1"/><!-- reference the group here -->
</tab>
</tabs>
<groups>
<group id="ProAppModule1_Group1" caption="Group 1">
<tool refID="ProAppModule1_MapTool1" size="large" /><!-- reference the tool in the group(s) -->
</group>
</groups>
<controls>
<!-- define the tool element -->
<tool id="ProAppModule1_MapTool1" caption="MapTool 1" className="MapTool1" ... />
</controls>
</insertModule>
</modules>This is the map tool code:
///<summary>MapTool1 derives from the class. Note: MapTool1 is referenced in the className attribute of
///its <tool> element in the Config.daml</summary>
internal class MapTool1 : MapTool
{
public MapTool1()
{
...
}
...
}The Pro SDK includes the ArcGIS Pro Map Tool template which automates much of the daml and code class file definition required to create a basic map tool. Simply run the Pro SDK map tool template to auto-generate the tool daml and class file definition.
Enabled/Disabled status of a map tool can be controlled by adding a condition attribute on the tool daml element. The condition can be:
- An existing Pro condition (find a complete list for each extension ArcGIS Pro DAML ID Reference)
- A custom condition (learn about making custom conditions in ProGuide Code Your Own States and Conditions)
- The daml id of a pane.
If the condition of a tool is set to be the daml id of a pane then only when instances of that type of pane are activated will your tool be enabled. The default condition for a map tool is set by the SDK Map Tool template as condition="esri_mapping_mapPane" where esri_mapping_mapPane is the daml id for the Pro MapView pane element.
<controls>
<!-- Enable our tool whenever a 2D or 3D map view is active. Disable it otherwise -->
<tool id="ProAppModule1_MapTool1" ... condition="esri_mapping_mapPane">
<tooltip .../>
</tool>MapTool provides several virtual methods such as OnToolMouseDown and OnToolKeyDown that are called when the corresponding event occurs in the map view. By overriding these methods in the derived class, you can perform actions when these events occur. The mouse events provide event arguments that contain information such as which mouse button was used, as well as the ClientPoint, relative to the top left corner of the map view, where the event occurred. The client point can be passed into the ClientToMap method to return the corresponding location in the map. The keyboard events provide event argument that provides information such as which key was used.
These virtual methods are intended to perform synchronous operations. If you need to execute any asynchronous code, you should set the handled property on the event arguments to true. By doing this, the corresponding Handle...Async virtual method will be called with the same event arguments. For example, to perform an asynchronous operation when the left mouse button is pressed, you would do the following:
protected override void OnToolMouseDown(MapViewMouseButtonEventArgs e)
{
if (e.ChangedButton == System.Windows.Input.MouseButton.Left)
e.Handled = true; //Handle the event to get the call to the async method
}
protected




