Skip to content

ProSnippets MapExploration

UmaHarano edited this page Nov 12, 2025 · 34 revisions
Language:              C#  
Subject:               MapExploration  
Contributor:           ArcGIS Pro SDK Team <[email protected]>  
Organization:          Esri, http://www.esri.com  
Date:                  11/7/2025  
ArcGIS Pro:            3.6  
Visual Studio:         2022  

Map View

Get the Active Map TOC content type

//Get the current active TOC content type for the map view 
  var mapTOCContentType = MapView.Active.CurrentMapTOCContent;

Set the Active Map TOC content type

//Get the current active TOC content type for the map view 
  var mapTOCContentType = (int)MapView.Active.CurrentMapTOCContent;
  //increment to the next tab whatever it is
  mapTOCContentType++;
  //Can we set this type on the TOC?
  if (MapView.Active.CanSetMapTOCContent((MapTOCContentType)mapTOCContentType))
    //Set it - must be on the UI! - No QueuedTask
    MapView.Active.SetMapTOCContentAsync((MapTOCContentType)mapTOCContentType);
  else
  {
    mapTOCContentType = (int)MapTOCContentType.DrawingOrder;
    //Set it - must be on the UI! - No QueuedTask
    MapView.Active.SetMapTOCContentAsync((MapTOCContentType)mapTOCContentType);
  }

Find a MapView by its Caption

string mapPaneCaption = "USNationalParks";
  IMapPane mapViewPane = FrameworkApplication.Panes.OfType<IMapPane>().FirstOrDefault((p) => p.Caption == mapPaneCaption);
  mapView = null;
  if (mapViewPane != null)
  {
    // activate the MapPane
    (mapViewPane as Pane).Activate();

    if (mapView != null)
    {
      // get the layers selected in the map's TOC
      var selectedLayers = mapView.GetSelectedLayers();
    }
  }

Test if the view is 3D

//Determine whether the viewing mode is SceneLocal or SceneGlobal
  var result = mapView.ViewingMode == MapViewingMode.SceneLocal ||
               mapView.ViewingMode == MapViewingMode.SceneGlobal;

  // Use the result variable as needed

Set ViewingMode

//Check if the view can be set to SceneLocal and if it can set it.
  var result = mapView.CanSetViewingMode(MapViewingMode.SceneLocal);
  if (result)
    mapView.SetViewingModeAsync(MapViewingMode.SceneLocal);

Enable View Linking

//Set the view linking mode to Center and Scale.
  MapView.LinkMode = LinkMode.Center | LinkMode.Scale;

Export the contents of a scene to an exchange format such as glTF and STL.

// Validate the current active view. Only a local scene can be exported.
  bool CanExportScene3DObjects = MapView.Active?.ViewingMode == MapViewingMode.SceneLocal;
  if (CanExportScene3DObjects)
  {
    // Create a scene content export format, export the scene context as a glTF file
    var exportFormat = new ExportSceneContentsFormat()
    {
      Extent = mapView.Extent, // sets Extent property
      FolderPath = @"C:\Temp", // sets FolderPath property
                               //sets FileName property.The export format is determined by the output file extension (e.g.,.stl, .gltf)
      FileName = "my-3d-objects.gltf",
      IsSingleFileOutput = true, // sets whether to export to one single file
      SaveTextures = true //sets whether to save textures
    };
    // Export the scene content as 3D objects
    mapView.ExportScene3DObjects(exportFormat);
  }

Update MapView Extent (Zoom, Pan etc)

Go To Previous Camera

//Zoom to the selected layers in the TOC
  if (mapView.HasPreviousCamera())
    mapView.PreviousCameraAsync();

Go To Next Camera

//Zoom to the selected layers in the TOC
  if (mapView.HasNextCamera())
    mapView.NextCameraAsync();

Zoom To Full Extent

// Note: Needs QueuedTask to run
  {
    //Zoom to the map's full extent
    mapView.ZoomToFullExtent();
  }

Zoom To Full Extent Async

//Zoom to the map's full extent
  mapView.ZoomToFullExtentAsync(TimeSpan.FromSeconds(2));

Fixed Zoom In

// Note: Needs QueuedTask to run
  {
    //Zoom in the map view by a fixed amount.
    mapView.ZoomInFixed();
  }

Fixed Zoom In Async

//Zoom in the map view by a fixed amount.
  mapView.ZoomInFixedAsync();

Fixed Zoom Out

// Note: Needs QueuedTask to run
  {
    //Zoom out in the map view by a fixed amount.
    mapView.ZoomOutFixed();
  }

Fixed Zoom Out Async

//Zoom in the map view by a fixed amount.
  mapView.ZoomOutFixedAsync();

Zoom To an Extent

envelope = EnvelopeBuilderEx.CreateEnvelope(xMin, yMin, xMax, yMax, spatialReference);

  //Zoom the view to a given extent.
  mapView.ZoomToAsync(envelope, TimeSpan.FromSeconds(2));

Zoom To a Point

// Note: Needs QueuedTask to run
  {
    //Create a point
    var pt = MapPointBuilderEx.CreateMapPoint(x, y, spatialReference);
    //Buffer it - for purpose of zoom
    var poly = GeometryEngine.Instance.Buffer(pt, buffer_size);

    //do we need to project the buffer polygon?
    if (!MapView.Active.Map.SpatialReference.IsEqual(poly.SpatialReference))
    {
      //project the polygon
      poly = GeometryEngine.Instance.Project(poly, MapView.Active.Map.SpatialReference);
    }

    //Zoom - add in a delay for animation effect
    mapView.ZoomTo(poly, new TimeSpan(0, 0, 0, 3));
  }

Zoom To Selected Features with a timespan

// Note: Needs QueuedTask to run
  {
    //Zoom to the map's selected features.
    mapView.ZoomToSelected(TimeSpan.FromSeconds(3));
  }

Zoom Async To Selected Features with a timespan

//Zoom to the map's selected features.
  mapView.ZoomToSelectedAsync(TimeSpan.FromSeconds(2));

Zoom To Bookmark by name

// Note: Needs QueuedTask to run
  {
    //Get the first bookmark with the given name.
    var bookmark = mapView.Map.GetBookmarks().FirstOrDefault(b => b.Name == bookmarkName);
    if (bookmark == null)
    {
      // Manage the error - bookmark not found
    }

    //Zoom the view to the bookmark.
    mapView.ZoomTo(bookmark);
  }

Zoom Async To Bookmark by name

// Note: Needs QueuedTask to run
  //Get the first bookmark with the given name.
  var bookmark = mapView.Map.GetBookmarks().FirstOrDefault(b => b.Name == bookmarkName);
  if (bookmark == null)
  {
    // Manage the error - bookmark not found
  }

  //Zoom the view to the bookmark.
  mapView.ZoomToAsync(bookmark, TimeSpan.FromSeconds(2));

Zoom To Visible Layers

// Note: Needs QueuedTask to run
  {
    //Zoom to all visible layers in the map.
    var visibleLayers = mapView.Map.Layers.Where(l => l.IsVisible);
    mapView.ZoomTo(visibleLayers);
  }

Zoom To Selected Layers

//Zoom to the selected layers in the TOC
  var selectedLayers = mapView.GetSelectedLayers();
  mapView.ZoomToAsync(selectedLayers);

Zoom to ObjectIDs

using var rowCursor = featureLayer.Search();
  var objectIds = new List<long>();
  while (rowCursor.MoveNext())
  {
    using var feature = rowCursor.Current as Feature;
    objectIds.Add(feature.GetObjectID());
  }
  if (objectIds.Count > 0)
  {
    MapView.Active.ZoomTo(featureLayer, objectIds, TimeSpan.FromSeconds(2));
  }

Pan To an Extent

// Note: Needs QueuedTask to run
  {
    //Pan the view to a given extent.
    envelope = EnvelopeBuilderEx.CreateEnvelope(xMin, yMin, xMax, yMax, spatialReference);
    mapView.PanTo(envelope);
  }

Pan Async To an Extent

//Create the envelope
  envelope = EnvelopeBuilderEx.CreateEnvelope(xMin, yMin, xMax, yMax, spatialReference);

  //Pan the view to a given extent.
  mapView.PanToAsync(envelope, TimeSpan.FromSeconds(2));

Pan To Selected Features

// Note: Needs QueuedTask to run
  {
    //Pan to the map's selected features.
    mapView.PanToSelected();
  }

Pan AsyncTo Selected Features

//Pan to the map's selected features.
  mapView.PanToSelectedAsync(TimeSpan.FromSeconds(2));

Pan To Bookmark

//Note: Needs QueuedTask to run
  {
    //Get the first bookmark with the given name.
    var bookmark = mapView.Map.GetBookmarks().FirstOrDefault(b => b.Name == bookmarkName);
    if (bookmark == null)
    {
      // Manage the error - bookmark not found
    }

    //Pan the view to the bookmark.
    mapView.PanTo(bookmark);
  }

Pan To Bookmark Async

//Get the first bookmark with the given name.
  var bookmark = mapView.Map.GetBookmarks().FirstOrDefault(b => b.Name == bookmarkName);
  if (bookmark == null)
  {
    // Manage the error - bookmark not found
  }

  //Pan the view to the bookmark.
  mapView.PanToAsync(bookmark, TimeSpan.FromSeconds(2));

Pan To Visible Layers

// Note: Needs QueuedTask to run
  {
    //Pan to all visible layers in the map.
    var visibleLayers = mapView.Map.Layers.Where(l => l.IsVisible);
    mapView.PanTo(visibleLayers);
  }

Pan To Selected Layers Asynchronous

//Pan to the selected layers in the TOC
  var selectedLayers = mapView.GetSelectedLayers();
  mapView.PanToAsync(selectedLayers);

Rotate the map view

//Get the camera for the view, adjust the heading and zoom to the new camera position.
  camera = mapView.Camera;
  camera.Heading = heading;
  await mapView.ZoomToAsync(camera, TimeSpan.Zero);
  //Or synchronously
  mapView.ZoomTo(camera, TimeSpan.Zero);

Expand Extent

//Note: Needs QueuedTask to run
  {
    //Expand the current extent by the given ratio.
    var extent = mapView.Extent;
    var newExtent = GeometryEngine.Instance.Expand(extent, dx, dy, true);
    mapView.ZoomTo(newExtent);
  }

Maps

Get the active map's name

//Return the name of the map currently displayed in the active map view.
  var result = mapView.Map.Name;
  // Use the result variable as needed

Clear all selection in an Active map

// Note: Needs QueuedTask to run
  {
    MapView.Active.Map?.SetSelection(null);
  }

Calculate Selection tolerance in map units

//Selection tolerance for the map in pixels
  var selectionTolerance = SelectionEnvironment.SelectionTolerance;
  // Note: Needs QueuedTask to run
  {
    //Get the map center
    var mapExtent = MapView.Active.Map.GetDefaultExtent();
    var mapPoint = mapExtent.Center;
    //Map center as screen point
    var screenPoint = MapView.Active.MapToScreen(mapPoint);
    //Add selection tolerance pixels to get a "radius".
    var radiusScreenPoint = new System.Windows.Point(screenPoint.X + selectionTolerance, screenPoint.Y);
    var radiusMapPoint = MapView.Active.ScreenToMap(radiusScreenPoint);
    //Calculate the selection tolerance distance in map units.
    var searchRadius = GeometryEngine.Instance.Distance(mapPoint, radiusMapPoint);
  }

MapView Overlay Control

//Create a Progress Bar user control
  System.Windows.Controls.ProgressBar progressBarControl = new()
  {
    //Configure the progress bar
    Minimum = 0,
    Maximum = 100,
    IsIndeterminate = true,
    Width = 300,
    Value = 10,
    Height = 25,
    Visibility = System.Windows.Visibility.Visible
  };
  //Create a MapViewOverlayControl. 
  var mapViewOverlayControl = new MapViewOverlayControl(progressBarControl, true, true, true, OverlayControlRelativePosition.BottomCenter, .5, .8);
  //Add to the active map
  MapView.Active.AddOverlayControl(mapViewOverlayControl);
  // Note: Needs QueuedTask to run
  {
    //Wait 3 seconds to remove the progress bar from the map.
    Thread.Sleep(3000);
  }
  //Remove from active map
  MapView.Active.RemoveOverlayControl(mapViewOverlayControl);

Layers

Select all feature layers in TOC

//Zoom to the selected layers in the TOC
  var featureLayers = mapView.Map.Layers.OfType<FeatureLayer>();
  mapView.SelectLayers(featureLayers.ToList());

Flash selected features

// Note: Needs QueuedTask to run
  {
    //Get the selected features from the map and filter out the standalone table selection.
    var selectedFeatures = mapView.Map.GetSelection();

    //Flash the collection of features.
    mapView.FlashFeature(selectedFeatures);
  }

Check if layer is visible in the current map view

if (layer == null)
  {
    // no layers in the map, leave
  }
  if (mapView == null)
  {
    // no active map view, leave
  }
  bool isLayerVisibleInView = layer.IsVisibleInView(mapView);
  if (isLayerVisibleInView)
  {
    //Do Something
  }

Select a layer and open its layer properties page

// select it in the TOC
  List<Layer> layersToSelect = [featureLayer];
  MapView.Active.SelectLayers(layersToSelect);

  // now execute the layer properties command
  var wrapper = FrameworkApplication.GetPlugInWrapper("esri_mapping_selectedLayerPropertiesButton");
  var command = wrapper as ICommand;
  if (command == null)
  {
    // the command is not found, leave
  }

  // execute the command
  if (command.CanExecute(null))
    command.Execute(null);

Clear selection for a specific layer

if (featureLayer != null)
  {
    // Note: Needs QueuedTask to run
    {
      featureLayer.ClearSelection();
    }
  }

Display Table pane for Map Member

mapMember = MapView.Active.Map.GetLayersAsFlattenedList().OfType<MapMember>().FirstOrDefault();
  //Gets or creates the CIMMapTableView for a MapMember.
  var mapTableView = FrameworkApplication.Panes.GetMapTableView(mapMember);
  //Configure the table view
  mapTableView.DisplaySubtypeDomainDescriptions = false;
  mapTableView.SelectionMode = false;
  mapTableView.ShowOnlyContingentValueFields = true;
  mapTableView.HighlightInvalidContingentValueFields = true;
  //Open the table pane using the configured tableView. If a table pane is already open it will be activated.
  //You must be on the UI thread to call this function.
  var tablePane = FrameworkApplication.Panes.OpenTablePane(mapTableView);

TableView

Set Table ViewingMode

// change to "selected record" mode
  tableView.SetViewMode(TableViewMode.eSelectedRecords);

Set ZoomLevel

// change zoom level
  if (tableView.ZoomLevel > zoomLevel)
    tableView.SetZoomLevel(zoomLevel);
  else
    tableView.SetZoomLevel(zoomLevel * 2);

Toggle Field Alias

// set the value
  tableView.ShowFieldAlias = true;

  // OR toggle it
  if (tableView.CanToggleFieldAlias)
    tableView.ToggleFieldAlias();

Toggle Subtype Descriptions

// set the value
  tableView.ShowSubtypeDomainDescriptions = true;

  // OR toggle it
  if (tableView.CanToggleSubtypeDomainDescriptions)
    tableView.ToggleSubtypeDomainDescriptionsAsync();

Get the active row

// get the active row index
  int rowIndex = tableView.ActiveRowIndex;

Change the active row

// get the active row index
  int rowIndex = tableView.ActiveRowIndex;

  // move to a different row
  var newIndex = 10 + rowIndex;
  tableView.BringIntoView(newIndex);

Get the active object ID

// get the active objectID
  long? OID = tableView.ActiveObjectId;

Translate between rowIndex and objectID

// get the active row index
  int rowIndex = tableView.ActiveRowIndex;
  // increase
  int newIndex = rowIndex + 10;
  // get the objectID
  long newOID = tableView.GetObjectIdAsync(newIndex).Result;

  // get the rowIndex for a specific objectID
  //   2nd parameter indicates if the search only occurs for the pages loaded
  //   if pass false, then in the worst case, a full table scan will occur to 
  //    find the objectID.
  long OID = 100;
  var idx = tableView.GetRowIndexAsync(OID, true);

Get selected rows or row indexes

// Note: Needs QueuedTask to run
  {
    // get the set of selected objectIDs 
    var selOids = tableView.GetSelectedObjectIds();
    // get the set of selected row indexes
    var selRows = tableView.GetSelectedRowIndexes();
  }

Change selected rows

// Note: Needs QueuedTask to run
  {
    // set of selected OIDS
    var newoids = new List<long>();
    newoids.AddRange([10, 15, 17]);
    tableView.Select(newoids, true);

    // add to set of selected row indexes
    var selRows = tableView.GetSelectedRowIndexes();
    var newRows = new List<long>(selRows);
    newRows.AddRange([21, 35]);
    tableView.Select(newRows, false);
  }

Select all rows

if (tableView.CanSelectAll)
    tableView.SelectAll();

Toggle, Switch, Clear Selection

// toggle the active rows selection
  if (tableView.CanToggleRowSelection)
    tableView.ToggleRowSelection();

  // switch the selection
  if (tableView.CanSwitchSelection)
    tableView.SwitchSelection();

  // clear the selection
  if (tableView.CanClearSelection)
    tableView.ClearSelection();

Zoom or Pan To Selected Rows

if (tableView.CanZoomToSelected)
    tableView.ZoomToSelected();

  if (tableView.CanPanToSelected)
    tableView.PanToSelected();

Delete Selected Rows

if (tableView.CanDeleteSelected)
    tableView.DeleteSelected();

Get highlighted row indexes

// Note: Needs QueuedTask to run
  {
    IReadOnlyList<long> highlightedOIDs = null;
    if (tableView.CanGetHighlightedObjectIds)
      // get the set of selected objectIDs 
      highlightedOIDs = tableView.GetHighlightedObjectIds();
  }

Change highlighted rows

// Note: Needs QueuedTask to run
  {
    // get list of current selected objectIDs
    IReadOnlyList<long> selectedObjectIds = tableView.GetSelectedObjectIds();
    List<long> idsToHighlight = [];

    // add the first two selected objectIds to highlight
    if (selectedObjectIds.Count >= 2)
    {
      idsToHighlight.Add(selectedObjectIds[0]);
      idsToHighlight.Add(selectedObjectIds[1]);
    }

    // highlight
    if (tableView.CanHighlight)
      tableView.Highlight(idsToHighlight, true);
  }

Toggle, Switch, Clear Highlights

// toggle the active rows selection
  if (tableView.CanToggleRowHighlight)
    tableView.ToggleRowHighlight();

  // switch highlighted rows
  if (tableView.CanSwitchHighlight)
    tableView.SwitchHighlight();

  // clear the highlights
  if (tableView.CanClearHighlighted)
    tableView.ClearHighlighted();

Zoom or Pan To Highlighted Rows

if (tableView.CanZoomToHighlighted)
    tableView.ZoomToHighlighted();

  if (tableView.CanPanToHighlighted)
    tableView.PanToHighlighted();

Delete Highlighted Rows

if (tableView.CanDeleteHighlighted)
    tableView.DeleteHighlighted();

Field Access

// field access
  var flds = tableView.GetFields();
  var fldIdx = tableView.GetFieldIndex("STATE_NAME");
  var fldDesc = tableView.GetField(fldIdx);

Get or set the Active Field

// get active field, active field name
  var activeFieldIdx = tableView.ActiveFieldIndex;
  var fldDesc = tableView.GetField(activeFieldIdx);
  var fldName = fldDesc.Name;

  // set active field by name
  tableView.SetActiveField("STATE_NAME");

  // or set active field by index
  tableView.SetActiveField(3);

Select Fields

// get selected fields
  var selectedfields = tableView.GetSelectedFields();

  // set selected fields
  tableView.SetSelectedFields(["CITY_FIPS", "STATE_FIPS"]);

Set Field Order

if (tableView.CanResetFieldOrder)
  {
    tableView.ResetFieldOrder();

    List<string> fldOrder =
    [
      "STATE_NAME",
      "STATE_FIPS"
    ];
    tableView.SetFieldOrderAsync(fldOrder);
  }

Show or Hide Fields

// get list of hidden fields
  var hiddenFields = tableView.GetHiddenFields();

  // show all fields
  if (tableView.CanShowAllFields)
    tableView.ShowAllFields();

  // hide only "CITY_FIPS", "STATE_FIPS"
  if (tableView.CanShowAllFields)
  {
    // show all fields
    tableView.ShowAllFields();
    tableView.SetHiddenFields(["CITY_FIPS", "STATE_FIPS"]);
  }

  // add "STATE_NAME to set of hidden fields
  tableView.SetHiddenFields(["STATE_NAME"]);

  // hide selected fields
  if (tableView.CanHideSelectedFields)
    tableView.HideSelectedFields();

Freeze Fields

// get list of frozen fields
  var frozenfields = tableView.GetFrozenFields();

  // unfreeze all fields
  tableView.ClearAllFrozenFieldsAsync();

  // freeze a set of fields
  tableView.SetFrozenFieldsAsync(["CITY_FIPS", "STATE_FIPS"]);

Sort

// sort the active field descending
  if (tableView.CanSortDescending)
    tableView.SortDescending();

  // sort the active field ascending
  if (tableView.CanSortAscending)
    tableView.SortAscending();

  // perform a custom sort programmatically
  if (tableView.CanCustomSort)
  {
    // sort fields
    Dictionary<string, FieldSortInfo> dict = new()
    {
      { "STATE_NAME", FieldSortInfo.Asc },
      { "CITY_NAME", FieldSortInfo.Desc }
    };
    tableView.SortAsync(dict);
  }

  // perform a custom sort via the UI
  if (tableView.CanCustomSort)
    tableView.CustomSort();

Find and Replace

// launch the find UI
  if (tableView.CanFind)
    tableView.Find();

  // or launch the find and replace UI
  if (tableView.CanFindAndReplace)
    tableView.FindAndReplace();

GoTo TableView

// launch the GoTo UI
  if (tableView.CanGoTo)
    tableView.GoTo();

Refresh

// refresh
  if (tableView.CanRefresh)
    tableView.Refresh();

Change table View caption

// find all the table panes (table panes hosting map data)
  var tablePanes = FrameworkApplication.Panes.OfType<ITablePane>();
  var tablePane = tablePanes.FirstOrDefault(p => p is ITablePaneEx { Caption: "oldCaption" });
  if (tablePane is ITablePaneEx tablePaneEx)
    tablePaneEx.Caption = "newCaption";

  // find all the external table panes (table panes hosting external data)
  var externalPanes = FrameworkApplication.Panes.OfType<IExternalTablePane>();
  var externalTablePane = externalPanes.FirstOrDefault(p => p.Caption == "oldCaption");
  if (externalTablePane != null)
    externalTablePane.Caption = "newCaption";

Get TableView from table pane

// find all the table panes (table panes hosting map data)
  var tablePanes = FrameworkApplication.Panes.OfType<ITablePane>();
  var tablePane = tablePanes.FirstOrDefault(p => p is ITablePaneEx { Caption: "caption" });
  if (tablePane is ITablePaneEx tablePaneEx)
    tableView = tablePaneEx.TableView;

  // if it's not found, maybe it's an external table pane
  if (tableView == null)
  {
    // find all the external table panes (table panes hosting external data)
    var externalPanes = FrameworkApplication.Panes.OfType<IExternalTablePane>();
    var externalTablePane = externalPanes.FirstOrDefault(p => p.Caption == "caption");
    if (externalTablePane != null)
      tableView = externalTablePane.TableView;
  }

Features

Mask feature

// Note: Needs QueuedTask to run
  {
    //Get the layer to be masked
    var lineLyrToBeMasked = MapView.Active.Map.Layers.FirstOrDefault(lyr => lyr.Name == "TestLine") as FeatureLayer;
    //Get the layer's definition
    var lyrDefn = lineLyrToBeMasked.GetDefinition();
    //Create an array of Masking layers (polygon only)
    //Set the LayerMasks property of the Masked layer
    lyrDefn.LayerMasks = ["CIMPATH=map3/testpoly.xml"];
    //Re-set the Masked layer's definition
    lineLyrToBeMasked.SetDefinition(lyrDefn);
  }

Bookmarks

Create a new bookmark using the active map view

// Note: Needs QueuedTask to run
  {
    //Adding a new bookmark using the active view.
    mapView.Map.AddBookmark(mapView, bookmarkName);
  }

Add New Bookmark from CIMBookmark

// Note: Needs QueuedTask to run
  {
    //Set properties for Camera
    CIMViewCamera cimCamera = new()
    {
      X = camera.X,
      Y = camera.Y,
      Z = camera.Z,
      Scale = camera.Scale,
      Pitch = camera.Pitch,
      Heading = camera.Heading,
      Roll = camera.Roll
    };

    //Create new CIM bookmark and populate its properties
    var cimBookmark = new CIMBookmark() { Camera = cimCamera, Name = cameraName, ThumbnailImagePath = "" };

    //Add a new bookmark for the active map.
    mapView.Map.AddBookmark(cimBookmark);
  }

Get the collection of bookmarks for the project

//Get the collection of bookmarks for the project.
  var result = Project.Current.GetBookmarks();
  // Use the bookmarks (if any)

Get Map Bookmarks

// Note: Needs QueuedTask to run
  {
    //Return the collection of bookmarks for the map.
    var result = mapView.Map.GetBookmarks();
    // Use the bookmarks (if any)
  }

Move Bookmark to the Top

// Note: Needs QueuedTask to run
  {
    var map = mapView.Map;
    //Find the first bookmark with the name
    var bookmark = map.GetBookmarks().FirstOrDefault(b => b.Name == bookmarkName);
    if (bookmark == null)
    {
      //Bookmark not found
    }

    //Move the bookmark to the top of the list
    map.MoveBookmark(bookmark, 0);
  }

Rename Bookmark

oldBookmark = mapView.Map.GetBookmarks().FirstOrDefault(b => b.Name == bookmarkName);
  oldBookmark.Rename(newBookmarkName);

Remove bookmark with a given name

// Note: Needs QueuedTask to run
  {
    //Find the first bookmark with the name
    var bookmark = mapView.Map.GetBookmarks().FirstOrDefault(b => b.Name == bookmarkName);
    if (bookmark == null)
    {
      //Bookmark not found
    }

    //Remove the bookmark
    mapView.Map.RemoveBookmark(bookmark);
  }

Change the thumbnail for a bookmark

//Set the thumbnail to an image on disk, i.e. C:\Pictures\MyPicture.png.
  BitmapImage image = new(new Uri(imagePath, UriKind.RelativeOrAbsolute));
  oldBookmark.SetThumbnail(image);

Update Bookmark

// Note: Needs QueuedTask to run
  {
    //Update the bookmark using the active map view.
    oldBookmark.Update(mapView);
  }

Update Extent for a Bookmark

// Note : Needs QueuedTask to run
  {
    //Get the bookmark's definition
    var bookmarkDef = oldBookmark.GetDefinition();

    //Modify the bookmark's location
    bookmarkDef.Location = envelope;

    //Clear the camera as it is no longer valid.
    bookmarkDef.Camera = null;

    //Set the bookmark definition
    oldBookmark.SetDefinition(bookmarkDef);
  }

Time

Step forward in time by 1 month

//Step current map time forward by 1 month
  TimeDelta timeDelta = new(1, TimeUnit.Months);
  mapView.Time = mapView.Time.Offset(timeDelta);

Disable time in the map.

MapView.Active.Time.Start = null;
  MapView.Active.Time.End = null;

Animations

Set Animation Length

var animation = mapView.Map.Animation;
  var duration = animation.Duration;
  if (duration == TimeSpan.Zero)
    return;

  var factor = length.TotalSeconds / duration.TotalSeconds;
  animation.ScaleDuration(factor);

Scale Animation

var animation = mapView.Map.Animation;
  var duration = animation.Duration;
  if (duration == TimeSpan.Zero || duration <= afterTime)
  {
    // Nothing to scale, leave
  }

  var factor = length.TotalSeconds / (duration.TotalSeconds - afterTime.TotalSeconds);
  animation.ScaleDuration(afterTime, duration, factor);

Camera Keyframes

var animation = mapView.Map.Animation;
  var cameraTrack = animation.Tracks.OfType<CameraTrack>().First(); //There will always be only 1 CameraTrack in the animation.
  var result = cameraTrack.Keyframes.OfType<CameraKeyframe>().ToList();
  //Use the camera keyframes (if any)

Interpolate Camera

//Return the collection representing the camera for each frame in animation.
  // Note: Needs QueuedTask to run
  {
    var animation = mapView.Map.Animation;

    var cameras = new List<Camera>();
    //We will use ticks here rather than milliseconds to get the highest precision possible.
    var ticksPerFrame = Convert.ToInt64(animation.Duration.Ticks / (animation.NumberOfFrames - 1));
    for (int i = 0; i < animation.NumberOfFrames; i++)
    {
      var time = TimeSpan.FromTicks(i * ticksPerFrame);
      //Because of rounding for ticks the last calculated time may be greater than the duration.
      if (time > animation.Duration)
        time = animation.Duration;
      cameras.Add(mapView.Animation.GetCameraAtTime(time));
    }
    // Use cameras
  }

Interpolate Time

//Return the collection representing the map time for each frame in animation.
  // Note: Needs QueuedTask to run
  {
    var animation = mapView.Map.Animation;

    var timeRanges = new List<TimeRange>();
    //We will use ticks here rather than milliseconds to get the highest precision possible.
    var ticksPerFrame = Convert.ToInt64(animation.Duration.Ticks / (animation.NumberOfFrames - 1));
    for (int i = 0; i < animation.NumberOfFrames; i++)
    {
      var time = TimeSpan.FromTicks(i * ticksPerFrame);
      //Because of rounding for ticks the last calculated time may be greater than the duration.
      if (time > animation.Duration)
        time = animation.Duration;
      timeRanges.Add(mapView.Animation.GetCurrentTimeAtTime(time));
    }
    // Use timeRanges;
  }

Interpolate Range

//Return the collection representing the map time for each frame in animation.
  // Note: Needs QueuedTask to run
  {
    var animation = mapView.Map.Animation;

    var ranges = new List<ArcGIS.Desktop.Mapping.Range>();
    //We will use ticks here rather than milliseconds to get the highest precision possible.
    var ticksPerFrame = Convert.ToInt64(animation.Duration.Ticks / (animation.NumberOfFrames - 1));
    for (int i = 0; i < animation.NumberOfFrames; i++)
    {
      var time = TimeSpan.FromTicks(i * ticksPerFrame);
      //Because of rounding for ticks the last calculated time may be greeting than the duration.
      if (time > animation.Duration)
        time = animation.Duration;
      ranges.Add(mapView.Animation.GetCurrentRangeAtTime(time));
    }
    // Use ranges
  }

Create Camera Keyframe

var animation = mapView.Map.Animation;
  var cameraTrack = animation.Tracks.OfType<CameraTrack>().First(); //There will always be only 1 CameraTrack in the animation.
  cameraTrack.CreateKeyframe(mapView.Camera, atTime, AnimationTransition.FixedArc);

Create Time Keyframe

var animation = mapView.Map.Animation;
  var timeTrack = animation.Tracks.OfType<TimeTrack>().First(); //There will always be only 1 TimeTrack in the animation.
  timeTrack.CreateKeyframe(mapView.Time, atTime, AnimationTransition.Linear);

Create Range Keyframe

var animation = mapView.Map.Animation;
  var rangeTrack = animation.Tracks.OfType<RangeTrack>().First(); //There will always be only 1 RangeTrack in the animation.
  rangeTrack.CreateKeyframe(range, atTime, AnimationTransition.Linear);

Create Layer Keyframe

var animation = mapView.Map.Animation;
  var layerTrack = animation.Tracks.OfType<LayerTrack>().First(); //There will always be only 1 LayerTrack in the animation.
  layerTrack.CreateKeyframe(layer, atTime, true, transparency, AnimationTransition.Linear);

Graphic overlay

Graphic Overlay

// get the current MapView and point
  var myextent = mapView.Extent;
  var point = myextent.Center;
  IDisposable _graphic = null;

  // add point graphic to the overlay at the center of the mapView
  // Note: Needs QueuedTask to run
  _graphic = mapView.AddOverlay(point,
      SymbolFactory.Instance.ConstructPointSymbol(
              ColorFactory.Instance.RedRGB, 30.0, SimpleMarkerStyle.Star).MakeSymbolReference());

  // update the overlay with new point graphic symbol
  MessageBox.Show("Now to update the overlay...");
  // Note: Needs QueuedTask to run
  {
    mapView.UpdateOverlay(_graphic, point, SymbolFactory.Instance.ConstructPointSymbol(
                                  ColorFactory.Instance.BlueRGB, 20.0, SimpleMarkerStyle.Circle).MakeSymbolReference());
  }

  // clear the overlay display by disposing of the graphic
  MessageBox.Show("Now to clear the overlay...");
  _graphic.Dispose();

Graphic Overlay with CIMPictureGraphic

// Use SourceURL for the URL to the image content. For
  // a local file, use a file path. For a web/internet file
  // location, use its URL
  //
  // Supported image types are:
  // png, jpg, tiff, bmp, gif, svg

  var pictureGraphic = new CIMPictureGraphic
  {
    SourceURL = @"C:\Images\MyImage.png",
    Shape = envelope
  };

  IDisposable _graphic = mapView.AddOverlay(pictureGraphic);
}
// cref: ArcGIS.Desktop.Mapping.MapTool.AddOverlayAsync(ArcGIS.Core.Geometry.Geometry, ArcGIS.Core.CIM.CIMSymbolReference, System.Double, System.Double)
// cref: ArcGIS.Desktop.Mapping.MappingExtensions.AddOverlay(ArcGIS.Desktop.Mapping.MapView, ArcGIS.Core.CIM.CIMGraphic, System.Double)

#region Add overlay graphic with text
{
  IDisposable _graphic = null;

  //define the text symbol
  var textSymbol = new CIMTextSymbol();
  //define the text graphic
  var textGraphic = new CIMTextGraphic();

  // Note: Needs QueuedTask to run
  {
    //Create a simple text symbol
    textSymbol = SymbolFactory.Instance.ConstructTextSymbol(ColorFactory.Instance.BlackRGB, 8.5, "Corbel", "Regular");
    //Sets the geometry of the text graphic
    textGraphic.Shape = geometry;
    //Sets the text string to use in the text graphic
    textGraphic.Text = "This is my line";
    //Sets symbol to use to draw the text graphic
    textGraphic.Symbol = textSymbol.MakeSymbolReference();
    //Draw the overlay text graphic
    _graphic = MapView.Active.AddOverlay(textGraphic);
  }

Mapping Options

Get/Set Selection Options

var options = ApplicationOptions.SelectionOptions;

  // Note: Needs QueuedTask to run
  {
    var defaultColor = options.DefaultSelectionColor;

    var color = options.SelectionColor as CIMRGBColor;
    options.SetSelectionColor(ColorFactory.Instance.CreateRGBColor(255, 0, 0));

    var defaultFill = options.DefaultSelectionFillColor;
    var fill = options.SelectionFillColor;
    var isHatched = options.IsSelectionFillHatched;
    options.SetSelectionFillColor(ColorFactory.Instance.CreateRGBColor(100, 100, 0));
    if (!isHatched)
      options.SetSelectionFillIsHatched(true);

    var showSelectionChip = options.ShowSelectionChip;
    options.SetShowSelectionChip(!showSelectionChip);

    var showSelectionGraphic = options.ShowSelectionGraphic;
    options.SetShowSelectionGraphic(!showSelectionGraphic);

    var saveSelection = options.SaveSelection;
    options.SetSaveSelection(!saveSelection);

    var defaultTol = options.DefaultSelectionTolerance;
    var tol = options.SelectionTolerance;
    options.SetSelectionTolerance(2 * defaultTol);

    // extension methods available 
    var selMethod = options.SelectionMethod;
    options.SetSelectionMethod(SelectionMethod.Contains);

    var combMethod = options.CombinationMethod;
    options.SetCombinationMethod(SelectionCombinationMethod.Add);

    // note that the following SelectionCombinationMethod is not supported
    //options.SetCombinationMethod(SelectionCombinationMethod.XOR);
  }

Get/Set Table Options

var options = ApplicationOptions.TableOptions;

  var hideAddNewRow = options.HideAddNewRow;
  options.HideAddNewRow = !hideAddNewRow;

  var overrides = options.HonorSelectionColorOverrides;
  options.HonorSelectionColorOverrides = !overrides;

  var activateMapView = options.ActivateMapViewAfterOperations;
  options.ActivateMapViewAfterOperations = !activateMapView;

  var defaultFontTName = options.DefaultFontName;
  var fontName = options.FontName;
  if (options.IsValidFontName("Arial"))
    options.FontName = "Arial";

  var defaultFontSize = options.DefaultFontSize;
  var fontSize = options.FontSize;
  if (options.IsValidFontSize(10))
    options.FontSize = 10;

  var heightType = options.ColumnHeaderHeightType;
  options.ColumnHeaderHeightType = TableRowHeightType.Double;

  var rowHeightType = options.RowHeightType;
  options.RowHeightType = TableRowHeightType.Single;

  var defaultColor = options.DefaultHighlightColor;
  var color = options.HighlightColor;
  // Note: Needs QueuedTask to run
  options.SetHighlightColor(ColorFactory.Instance.CreateRGBColor(0, 0, 255));

Popups

Show a pop-up for a feature

mapView.ShowPopup(mapMember, objectID);

Show a custom pop-up

//Create custom popup content
  List<PopupContent> popups =
      [
          new("<b>This text is bold.</b>", "Custom tooltip from HTML string"),
          new(new Uri("https://www.esri.com/"), "Custom tooltip from Uri")
      ];
  mapView.ShowCustomPopup(popups);

Show a pop-up for a feature using pop-up window properties

if (mapView == null) return;
  // Sample code: https://github.com/Esri/arcgis-pro-sdk-community-samples/blob/master/Map-Exploration/CustomIdentify/CustomIdentify.cs
  var topLeftCornerPoint = new System.Windows.Point(200, 200);
  var popupDef = new PopupDefinition()
  {
    Append = true,      // if true new record is appended to existing (if any)
    Dockable = true,    // if true popup is dockable - if false Append is not applicable
    Position = topLeftCornerPoint,  // Position of top left corner of the popup (in pixels)
    Size = new System.Windows.Size(200, 400)    // size of the popup (in pixels)
  };
  mapView.ShowPopup(mapMember, objectID, popupDef);

Show a custom pop-up using pop-up window properties

if (mapView == null) return;

  //Create custom popup content
  List<PopupContent> popups =
  [
      new("<b>This text is bold.</b>", "Custom tooltip from HTML string"),
          new(new Uri("https://www.esri.com/"), "Custom tooltip from Uri")
  ];
  // Sample code: https://github.com/Esri/arcgis-pro-sdk-community-samples/blob/master/Framework/DynamicMenu/DynamicFeatureSelectionMenu.cs
  var topLeftCornerPoint = new System.Windows.Point(200, 200);
  var popupDef = new PopupDefinition()
  {
    Append = true,      // if true new record is appended to existing (if any)
    Dockable = true,    // if true popup is dockable - if false Append is not applicable
    Position = topLeftCornerPoint,  // Position of top left corner of the popup (in pixels)
    Size = new System.Windows.Size(200, 400)    // size of the popup (in pixels)
  };
  mapView.ShowCustomPopup(popups, null, true, popupDef);

Show A pop-up With Custom Commands

//Create custom popup content from existing map member and object id
  List<PopupContent> popups = [new PopupContent(mapMember, objectID)];

  //Create a new custom command to add to the popup window
  List<PopupCommand> commands =
  [
    new PopupCommand(
          p => MessageBox.Show(string.Format("Map Member: {0}, ID: {1}", p.MapMember, p.IDString)),
          p => { return p != null; },
          "My custom command",
          System.Windows.Application.Current.Resources["GenericCheckMark16"] as ImageSource),
      ];

  mapView.ShowCustomPopup(popups, commands, true);

Show A Dynamic Pop-up

public static void ShowDynamicPopup(MapMember mapMember, List<long> objectIDs)
{
  MapView mapView = MapView.Active;
  if (mapView == null) return;
  //Create popup whose content is created the first time the item is requested.
  var popups = new List<PopupContent>();
  foreach (var id in objectIDs)
  {
    popups.Add(new DynamicPopupContent(mapMember, id));
  }
  mapView.ShowCustomPopup(popups);
}
internal class DynamicPopupContent : PopupContent
{
  public DynamicPopupContent(MapMember mapMember, long objectID)
  {
    MapMember = mapMember;
    IDString = objectID.ToString();
    IsDynamicContent = true;
  }

  //Called when the pop-up is loaded in the window.
  protected override Task<string> OnCreateHtmlContent()
  {
    return QueuedTask.Run(() => string.Format("<b>Map Member: {0}, ID: {1}</b>", MapMember, IDString));
  }
}

Tools

Change symbol for a sketch tool

internal class SketchTool_WithSymbol : MapTool
{
  public SketchTool_WithSymbol()
  {
    IsSketchTool = true;
    SketchOutputMode = SketchOutputMode.Map; //Changing the Sketch Symbol is only supported with map sketches.
    SketchType = SketchGeometryType.Rectangle;
  }

  protected override Task OnToolActivateAsync(bool hasMapViewChanged)
  {
    return QueuedTask.Run(() =>
    {
      //Set the Sketch Symbol if it hasn't already been set.
      if (SketchSymbol != null)
        return;
      var polygonSymbol = SymbolFactory.Instance.ConstructPolygonSymbol(ColorFactory.Instance.CreateRGBColor(24, 69, 59),
                          SimpleFillStyle.Solid,
                        SymbolFactory.Instance.ConstructStroke(ColorFactory.Instance.BlackRGB, 1.0, SimpleLineStyle.Dash));
      SketchSymbol = polygonSymbol.MakeSymbolReference();
    });
  }
}

Create a tool to the return coordinates of the point clicked in the map

internal class GetMapCoordinates : MapTool
{
  protected override void OnToolMouseDown(MapViewMouseButtonEventArgs e)
  {
    if (e.ChangedButton == System.Windows.Input.MouseButton.Left)
      e.Handled = true; //Handle the event args to get the call to the corresponding async method
  }

  protected override Task HandleMouseDownAsync(MapViewMouseButtonEventArgs e)
  {
    return QueuedTask.Run(() =>
    {
      //Convert the clicked point in client coordinates to the corresponding map coordinates.
      var mapPoint = MapView.Active.ClientToMap(e.ClientPoint);
      ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(string.Format("X: {0} Y: {1} Z: {2}",
                  mapPoint.X, mapPoint.Y, mapPoint.Z), "Map Coordinates");
    });
  }
}

Create a tool to identify the features that intersect the sketch geometry

internal class CustomIdentify : MapTool
{
  public CustomIdentify()
  {
    IsSketchTool = true;
    SketchType = SketchGeometryType.Rectangle;

    //To perform a interactive selection or identify in 3D or 2D, sketch must be created in screen coordinates.
    SketchOutputMode = SketchOutputMode.Screen;
  }

  protected override Task<bool> OnSketchCompleteAsync(ArcGIS.Core.Geometry.Geometry geometry)
  {
    return QueuedTask.Run(() =>
    {
      var mapView = MapView.Active;
      if (mapView == null)
        return true;

      //Get all the features that intersect the sketch geometry and flash them in the view. 
      var results = mapView.GetFeatures(geometry);
      mapView.FlashFeature(results);

      var debug = System.String.Join("\n", results.ToDictionary()
                    .Select(kvp => System.String.Format("{0}: {1}", kvp.Key.Name, kvp.Value.Count())));
      System.Diagnostics.Debug.WriteLine(debug);
      return true;
    });
  }
}

Change the cursor of a Tool

internal class CustomMapTool : MapTool
{
  public CustomMapTool()
  {
    IsSketchTool = true;
    SketchType = SketchGeometryType.Rectangle;
    SketchOutputMode = SketchOutputMode.Map;
    //A custom cursor file as an embedded resource
    var cursorEmbeddedResource = new Cursor(new MemoryStream(Resource1.red_cursor));
    //A built in system cursor
    var systemCursor = System.Windows.Input.Cursors.ArrowCD;
    //Set the "CustomMapTool's" Cursor property to either one of the cursors defined above
    Cursor = cursorEmbeddedResource;
    //or
    Cursor = systemCursor;
  }
}

Tool with an Embeddable Control

// Using the Visual Studio SDK templates, add a MapTool and an EmbeddableControl
// The EmbeddableControl is registered in the "esri_embeddableControls" category in the config.daml file
// 
//  <categories>
//    <updateCategory refID = "esri_embeddableControls" >
//      <insertComponent id="mapTool_EmbeddableControl" className="EmbeddableControl1ViewModel">
//        <content className = "EmbeddableControl1View" />
//      </insertComponent>
//    <updateCategory>
//  </categories>
internal class MapTool_WithControl : MapTool
{
  public MapTool_WithControl()
  {
    // substitute this string with the daml ID of the embeddable control you added
    ControlID = "mapTool_EmbeddableControl";
  }

  protected override void OnToolMouseDown(MapViewMouseButtonEventArgs e)
  {
    e.Handled = true;
  }

  protected override Task HandleMouseDownAsync(MapViewMouseButtonEventArgs e)
  {
    //Get the instance of the ViewModel
    var vm = EmbeddableControl;
    if (vm == null)
      return Task.FromResult(0);

    // cast vm to your viewModel in order to access your properties

    //Get the map coordinates from the click point and set the property on the ViewMode.
    return QueuedTask.Run(() =>
    {
      var mapPoint = MapView.Active.ClientToMap(e.ClientPoint);
      string clickText = string.Format("X: {0}, Y: {1}, Z: {2}", mapPoint.X, mapPoint.Y, mapPoint.Z);
    });
  }
}

Tool with an Overlay Embeddable Control

// Using the Visual Studio SDK templates, add a MapTool and an EmbeddableControl
// The EmbeddableControl is registered in the "esri_embeddableControls" category in the config.daml file
// 
//  <categories>
//    <updateCategory refID = "esri_embeddableControls" >
//      <insertComponent id="mapTool_EmbeddableControl" className="EmbeddableControl1ViewModel">
//        <content className = "EmbeddableControl1View" />
//      </insertComponent>
//    <updateCategory>
//  </categories>

internal class MapTool_WithOverlayControl : MapTool
{
  public MapTool_WithOverlayControl()
  {
    // substitute this string with the daml ID of the embeddable control you added
    OverlayControlID = "mapTool_EmbeddableControl";
  }

  protected override void OnToolMouseDown(MapViewMouseButtonEventArgs e)
  {
    e.Handled = true;
  }

  protected override Task HandleMouseDownAsync(MapViewMouseButtonEventArgs e)
  {
    //Get the instance of the ViewModel
    var vm = OverlayEmbeddableControl;
    if (vm == null)
      return Task.FromResult(0);

    // cast vm to your viewModel in order to access your properties

    //Get the map coordinates from the click point and set the property on the ViewMode.
    return QueuedTask.Run(() =>
    {
      var mapPoint = MapView.Active.ClientToMap(e.ClientPoint);
      string clickText = string.Format("X: {0}, Y: {1}, Z: {2}", mapPoint.X, mapPoint.Y, mapPoint.Z);
    });
  }
}

Home

ProSnippets: MapExploration

Clone this wiki locally