Skip to content

ProSnippets MapAuthoring

UmaHarano edited this page Nov 6, 2023 · 19 revisions
Language:              C#  
Subject:               MapAuthoring  
Contributor:           ArcGIS Pro SDK Team <arcgisprosdk@esri.com>  
Organization:          esri, http://www.esri.com  
Date:                  10/16/2023  
ArcGIS Pro:            3.2  
Visual Studio:         2022  
.NET Target Framework: .Net 6  

Maps

Get the active map

Map map = MapView.Active.Map;

Create a new map with a default basemap layer

await QueuedTask.Run(() =>
{
  var map = MapFactory.Instance.CreateMap(mapName, basemap: Basemap.ProjectDefault);
  //TODO: use the map...
});

Find a map within a project and open it

public static async Task<Map> FindOpenExistingMapAsync(string mapName)
{
  return await QueuedTask.Run(async () =>
  {
    Map map = null;
    Project proj = Project.Current;

    //Finding the first project item with name matches with mapName
    MapProjectItem mpi = proj.GetItems<MapProjectItem>()
      .FirstOrDefault(m => m.Name.Equals(mapName, StringComparison.CurrentCultureIgnoreCase));
    if (mpi != null)
    {
      map = mpi.GetMap();
      //Opening the map in a mapview
      await ProApp.Panes.CreateMapPaneAsync(map);
    }
    return map;
  });

}

Open a webmap

Map map = null;

//Assume we get the selected webmap from the Project pane's Portal tab
if (Project.Current.SelectedItems.Count > 0)
{
  if (MapFactory.Instance.CanCreateMapFrom(Project.Current.SelectedItems[0]))
  {
    map = MapFactory.Instance.CreateMapFromItem(Project.Current.SelectedItems[0]);
    await ProApp.Panes.CreateMapPaneAsync(map);
  }
}

Get Map Panes

public static IEnumerable<IMapPane> GetMapPanes()
{
  //Sorted by Map Uri
  return ProApp.Panes.OfType<IMapPane>().OrderBy((mp) => mp.MapView.Map.URI ?? mp.MapView.Map.Name);
}

Get the Unique List of Maps From the Map Panes

public static IReadOnlyList<Map> GetMapsFromMapPanes()
{
  //Gets the unique list of Maps from all the MapPanes.
  //Note: The list of maps retrieved from the MapPanes
  //maybe less than the total number of Maps in the project.
  //It depends on what maps the user has actually opened.
  var mapPanes = ProApp.Panes.OfType<IMapPane>()
              .GroupBy((mp) => mp.MapView.Map.URI).Select(grp => grp.FirstOrDefault());
  List<Map> uniqueMaps = new List<Map>();
  foreach (var pane in mapPanes)
    uniqueMaps.Add(pane.MapView.Map);
  return uniqueMaps;
}

Change the Map name

MapView.Active.Map.SetName("Test");

Renames the caption of the pane

ProApp.Panes.ActivePane.Caption = "Caption";

Convert Map to Local Scene

//Note: Run within the context of QueuedTask.Run
bool canConvertMap = MapFactory.Instance.CanConvertMap(map, MapConversionType.SceneLocal);
if (canConvertMap)
  MapFactory.Instance.ConvertMap(map, MapConversionType.SceneLocal, true);

Get Basemaps

//Basemaps stored locally in the project. This is usually an empty collection
string localBasemapTypeID = "cim_map_basemap";
var localBasemaps = await QueuedTask.Run(() =>
{
  var mapContainer = Project.Current.GetProjectItemContainer("Map");
  return mapContainer.GetItems().Where(i => i.TypeID == localBasemapTypeID).ToList();
});

//portal basemaps. If there is no current active portal, the usual default
//is arcgis online
var portal = ArcGISPortalManager.Current.GetActivePortal();
var portalBaseMaps = await portal.GetBasemapsAsync();

//use one of them...local or portal...
//var map = MapView.Active.Map;
//QueuedTask.Run(() => map?.SetBasemapLayers(portalBaseMaps[0]));

Save Map as MapX

map.SaveAsFile(@"C:\Data\MyMap.mapx", true);

Save 2D Map as WebMap on Disk

//2D maps only
//Must be on the QueuedTask.Run(...)
if (map.DefaultViewingMode == MapViewingMode.Map)
  //Only webmap compatible layers will be saved out to the file
  map.SaveAsWebMapFile(@"C:\Data\MyMap.json");

Clip Map to the provided clip polygon

//Run within QueuedTask
var map = MapView.Active.Map;
//A layer to use for the clip extent
var lyrOfInterest = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().Where(l => l.Name == "TestPoly").FirstOrDefault();
//Get the polygon to use to clip the map
var extent = lyrOfInterest.QueryExtent();
var polygonForClipping = PolygonBuilderEx.CreatePolygon(extent);
//Clip the map using the layer's extent
map.SetClipGeometry(polygonForClipping,
      SymbolFactory.Instance.ConstructLineSymbol(
      SymbolFactory.Instance.ConstructStroke(
        ColorFactory.Instance.BlueRGB, 2.0, SimpleLineStyle.Dash)));

Clear the current map clip geometry

//Run within QueuedTask
var map = MapView.Active.Map;
//Clear the Map clip.
//If no clipping is set then this is a no-op.
map.ClearClipGeometry();

Get the map clipping geometry

var map = MapView.Active.Map;
//If clipping is set to ArcGIS.Core.CIM.ClippingMode.None or ArcGIS.Core.CIM.ClippingMode.MapSeries null is returned
//If clipping is set to ArcGIS.Core.CIM.ClippingMode.MapExtent the ArcGIS.Core.CIM.CIMMap.CustomFullExtent is returned.
//Otherwise, if clipping is set to ArcGIS.Core.CIM.ClippingMode.CustomShape the custom clip polygon is returned.
var poly = map.GetClipGeometry();
//You can use the polygon returned
//For example: We make a polygon graphic element and add it to a Graphics Layer.
var gl = map.GetLayersAsFlattenedList().OfType<GraphicsLayer>().FirstOrDefault();
if (gl == null) return;
var polygonSymbol = SymbolFactory.Instance.ConstructPolygonSymbol(CIMColor.CreateRGBColor(255, 255, 0));
var cimGraphicElement = new CIMPolygonGraphic
{
  Polygon = poly,
  Symbol = polygonSymbol.MakeSymbolReference()
};
gl.AddElement(cimGraphicElement);

Get the Current Map Location Unit

//var map = MapView.Active.Map;
//Must be on the QueuedTask.Run()

//Get the current location unit
var loc_unit = map.GetLocationUnitFormat();
var line = $"{loc_unit.DisplayName}, {loc_unit.UnitCode}";
System.Diagnostics.Debug.WriteLine(line);

Get the Available List of Map Location Units

//var map = MapView.Active.Map;
//Must be on the QueuedTask.Run()

//Linear location unit formats are not included if the map sr
//is geographic.
var loc_units = map.GetAvailableLocationUnitFormats();

Format a Location Using the Current Map Location Unit

var mv = MapView.Active;
var map = mv.Map;

QueuedTask.Run(() =>
{
  //Get the current view camera location
  var center_pt = new Coordinate2D(mv.Camera.X, mv.Camera.Y);
  //Get the current location unit
  var loc_unit = map.GetLocationUnitFormat();

  //Format the camera location
  var str = loc_unit.FormatLocation(center_pt, map.SpatialReference);
  System.Diagnostics.Debug.WriteLine($"Formatted location: {str}");
});

Set the Location Unit for the Current Map

var mv = MapView.Active;
var map = mv.Map;

QueuedTask.Run(() =>
{
  //Get the list of available location unit formats
  //for the current map
  var loc_units = map.GetAvailableLocationUnitFormats();

  //arbitrarily use the last unit in the list
  map.SetLocationUnitFormat(loc_units.Last());
});

Get the Current Map Elevation Unit

//var map = MapView.Active.Map;
//Must be on the QueuedTask.Run()

//If the map is not a scene, the default Project distance
//unit will be returned
var elev_unit = map.GetElevationUnitFormat();
var line = $"{elev_unit.DisplayName}, {elev_unit.UnitCode}";
System.Diagnostics.Debug.WriteLine(line);

Get the Available List of Map Elevation Units

//var map = MapView.Active.Map;
//Must be on the QueuedTask.Run()

//If the map is not a scene, the list of current
//Project distance units will be returned
var elev_units = map.GetAvailableElevationUnitFormats();

Format an Elevation Using the Current Map Elevation Unit

var mv = MapView.Active;
var map = mv.Map;

QueuedTask.Run(() =>
{
  //Get the current elevation unit. If the map is not
  //a scene the default Project distance unit is returned
  var elev_unit = map.GetElevationUnitFormat();

  //Format the view camera elevation
  var str = elev_unit.FormatValue(mv.Camera.Z);

  System.Diagnostics.Debug.WriteLine($"Formatted elevation: {str}");
});

Set the Elevation Unit for the Current Map

var map = MapView.Active.Map;

QueuedTask.Run(() =>
{
  //Trying to set the elevation unit on a map other than
  //a scene will throw an InvalidOperationException
  if (map.IsScene)
  {
    //Get the list of available elevation unit formats
    //for the current map
    var loc_units = map.GetAvailableElevationUnitFormats();
    //arbitrarily use the last unit in the list
    map.SetElevationUnitFormat(loc_units.Last());
  }

});

Offline Map

Check Map Has Sync-Enabled Content

//namespace ArcGIS.Desktop.Mapping.Offline
var map = MapView.Active.Map;

//await if needed...
QueuedTask.Run(() =>
{
  var hasSyncEnabledContent = GenerateOfflineMap.Instance.GetCanGenerateReplicas(map);
  if (hasSyncEnabledContent)
  {
    //TODO - use status...
  }
});

Generate Replicas for Sync-Enabled Content

//namespace ArcGIS.Desktop.Mapping.Offline
var extent = MapView.Active.Extent;
var map = MapView.Active.Map;

//await if needed...
QueuedTask.Run(() =>
{
  //Check map has sync-enabled content that can be taken offline
  var hasSyncEnabledContent = GenerateOfflineMap.Instance.GetCanGenerateReplicas(map);
  if (hasSyncEnabledContent)
  {
    //Generate Replicas and take the content offline
    //sync-enabled content gets copied local into a SQLite DB
    var gen_params = new GenerateReplicaParams()
    {
      Extent = extent, //SR of extent must match map SR

      //DestinationFolder can be left blank, if specified,
      //it must exist. Defaults to project offline maps location
      DestinationFolder = @"C:\Data\Offline"
    };
    //Sync-enabled layer content will be resourced to point to the
    //local replica content.
    GenerateOfflineMap.Instance.GenerateReplicas(map, gen_params);

  }
});

Check Map Has Local Syncable Content

//namespace ArcGIS.Desktop.Mapping.Offline
var map = MapView.Active.Map;

//await if needed...
QueuedTask.Run(() =>
{
  //Check map has local syncable content
  var canSyncContent = GenerateOfflineMap.Instance.GetCanSynchronizeReplicas(map);
  if (canSyncContent)
  {
    //TODO - use status
  }
});

Synchronize Replicas for Syncable Content

//namespace ArcGIS.Desktop.Mapping.Offline
var map = MapView.Active.Map;

//await if needed...
QueuedTask.Run(() =>
{
  //Check map has local syncable content
  var canSyncContent = GenerateOfflineMap.Instance.GetCanSynchronizeReplicas(map);
  if (canSyncContent)
  {
    //Sync Replicas - changes since last sync are pushed to the
    //parent replica. Parent changes are pulled to the client.
    //Unsaved edits are _not_ sync'd. 
    GenerateOfflineMap.Instance.SynchronizeReplicas(map);
  }
});

Remove Replicas for Syncable Content

//namespace ArcGIS.Desktop.Mapping.Offline
var extent = MapView.Active.Extent;
var map = MapView.Active.Map;

//await if needed...
QueuedTask.Run(() =>
{
  //Check map has local syncable content
  //Either..
  //var canSyncContent = GenerateOfflineMap.Instance.GetCanSynchronizeReplicas(map);
  //Or...both accomplish the same thing...
  var canRemove = GenerateOfflineMap.Instance.GetCanRemoveReplicas(map);
  if (canRemove)
  {
    //Remove Replicas - any unsync'd changes are lost
    //Call sync _first_ to push any outstanding changes if
    //needed. Local syncable content is re-sourced
    //to point to the service
    GenerateOfflineMap.Instance.RemoveReplicas(map);
  }
});

Export Map Raster Tile Cache Content

//namespace ArcGIS.Desktop.Mapping.Offline
var extent = MapView.Active.Extent;
var map = MapView.Active.Map;

//await if needed...
QueuedTask.Run(() =>
{
  //Does the map have any exportable raster content?
  var canExport = GenerateOfflineMap.Instance.GetCanExportRasterTileCache(map);
  if (canExport)
  {
    //Check the available LOD scale ranges
    var scales = GenerateOfflineMap.Instance.GetExportRasterTileCacheScales(map, extent);
    //Pick the desired LOD scale
    var max_scale = scales[scales.Count() / 2];

    //Configure the export parameters
    var export_params = new ExportTileCacheParams()
    {
      Extent = extent,//Use same extent as was used to retrieve scales
      MaximumUserDefinedScale = max_scale
      //DestinationFolder = .... (optional)
    };
    //If DestinationFolder is not set, output defaults to project
    //offline maps location set in the project properties. If that is 
    //not set, output defaults to the current project folder location.

    //Do the export. Depending on the MaximumUserDefinedScale and the
    //area of the extent requested, this can take minutes for tile packages
    //over 1 GB or less if your network speed is slow...
    GenerateOfflineMap.Instance.ExportRasterTileCache(map, export_params);
  }
});

Export Map Vector Tile Cache Content

//namespace ArcGIS.Desktop.Mapping.Offline
var extent = MapView.Active.Extent;
var map = MapView.Active.Map;

//await if needed...
QueuedTask.Run(() =>
{
  //Does the map have any exportable vector tile content?
  var canExport = GenerateOfflineMap.Instance.GetCanExportVectorTileCache(map);
  if (canExport)
  {
    //Check the available LOD scale ranges
    var scales = GenerateOfflineMap.Instance.GetExportVectorTileCacheScales(map, extent);
    //Pick the desired LOD scale
    var max_scale = scales[scales.Count() / 2];

    //Configure the export parameters
    var export_params = new ExportTileCacheParams()
    {
      Extent = extent,//Use same extent as was used to retrieve scales
      MaximumUserDefinedScale = max_scale,
      DestinationFolder = @"C:\Data\Offline"
    };
    //If DestinationFolder is not set, output defaults to project
    //offline maps location set in the project properties. If that is 
    //not set, output defaults to the current project folder location.

    //Do the export. Depending on the MaximumUserDefinedScale and the
    //area of the extent requested, this can take minutes for tile packages
    //over 1 GB or less if your network speed is slow...
    GenerateOfflineMap.Instance.ExportVectorTileCache(map, export_params);
  }
});

Create Layer

Create and add a layer to the active map

/*
* string url = @"c:\data\project.gdb\DEM";  //Raster dataset from a FileGeodatabase
* string url = @"c:\connections\mySDEConnection.sde\roads";  //FeatureClass of a SDE
* string url = @"c:\connections\mySDEConnection.sde\States\roads";  //FeatureClass within a FeatureDataset from a SDE
* string url = @"c:\data\roads.shp";  //Shapefile
* string url = @"c:\data\imagery.tif";  //Image from a folder
* string url = @"c:\data\mySDEConnection.sde\roads";  //.lyrx or .lpkx file
* string url = @"c:\data\CAD\Charlottesville\N1W1.dwg\Polyline";  //FeatureClass in a CAD dwg file
* string url = @"C:\data\CAD\UrbanHouse.rvt\Architectural\Windows"; //Features in a Revit file
* string url = @"http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer";  //map service
* string url = @"http://sampleserver6.arcgisonline.com/arcgis/rest/services/NapervilleShelters/FeatureServer/0";  //FeatureLayer off a map service or feature service
*/
string url = @"c:\data\project.gdb\roads";  //FeatureClass of a FileGeodatabase

Uri uri = new Uri(url);
await QueuedTask.Run(() => LayerFactory.Instance.CreateLayer(uri, MapView.Active.Map));

Create layer with create-params

var flyrCreatnParam = new FeatureLayerCreationParams(new Uri(@"c:\data\world.gdb\cities"))
{
  Name = "World Cities",
  IsVisible = false,
  MinimumScale = 1000000,
  MaximumScale = 5000,
  // At 2.x - DefinitionFilter = new CIMDefinitionFilter()
  //{
  //  DefinitionExpression = "Population > 100000",
  //  Name = "More than 100k"
  //},
  DefinitionQuery = new DefinitionQuery(whereClause: "Population > 100000", name: "More than 100k"),
  RendererDefinition = new SimpleRendererDefinition()
  {
    SymbolTemplate = SymbolFactory.Instance.ConstructPointSymbol(
      CIMColor.CreateRGBColor(255, 0, 0), 8, SimpleMarkerStyle.Hexagon).MakeSymbolReference()
  }
};

var featureLayer = LayerFactory.Instance.CreateLayer<FeatureLayer>(
  flyrCreatnParam, map);

Create FeatureLayer and add to Map using LayerCreationParams

//Note: Call within QueuedTask.Run()
var layerDoc = new LayerDocument(@"E:\Data\SDK\Default2DPointSymbols.lyrx");
var createParams = new LayerCreationParams(layerDoc.GetCIMLayerDocument());
LayerFactory.Instance.CreateLayer<FeatureLayer>(createParams, MapView.Active.Map);

Create FeatureLayer and set to not display in Map.

//The catalog path of the feature layer to add to the map
var featureClassUriVisibility = new Uri(@"C:\Data\Admin\AdminData.gdb\USA\cities");
//Define the Feature Layer's parameters.
var layerParamsVisibility = new FeatureLayerCreationParams(featureClassUriVisibility)
{
  //Set visibility
  IsVisible = false,
};
//Create the layer with the feature layer parameters and add it to the active map
var createdFC = LayerFactory.Instance.CreateLayer<FeatureLayer>(layerParamsVisibility, MapView.Active.Map);

Create FeatureLayer with a Renderer

//Note: Call within QueuedTask.Run()
//Define a simple renderer to draw the Point US Cities feature class.
var simpleRender = new SimpleRendererDefinition
{
  SymbolTemplate = SymbolFactory.Instance.ConstructPointSymbol(ColorFactory.Instance.RedRGB, 4.0, SimpleMarkerStyle.Circle).MakeSymbolReference()

};
//The catalog path of the feature layer to add to the map
var featureClassUri = new Uri(@"C:\Data\Admin\AdminData.gdb\USA\cities");
//Define the Feature Layer's parameters.
var layerParams = new FeatureLayerCreationParams(featureClassUri)
{
  //Set visibility
  IsVisible = true,
  //Set Renderer
  RendererDefinition = simpleRender,
};
//Create the layer with the feature layer parameters and add it to the active map
var createdFCWithRenderer = LayerFactory.Instance.CreateLayer<FeatureLayer>(layerParams, MapView.Active.Map);

Create FeatureLayer with a Query Definition

//The catalog path of the feature layer to add to the map
var featureClassUriDefinition = new Uri(@"C:\Data\Admin\AdminData.gdb\USA\cities");
//Define the Feature Layer's parameters.
//At 2.x - var layerParamsQueryDefn = new FeatureLayerCreationParams(featureClassUriDefinition)
//{
//  IsVisible = true,
//  DefinitionFilter = new CIMDefinitionFilter()
//  {
//    Name = "CACities",
//    DefinitionExpression = "STATE_NAME = 'California'"
//  }
//};
var layerParamsQueryDefn = new FeatureLayerCreationParams(featureClassUriDefinition)
{
  IsVisible = true,
  DefinitionQuery = new DefinitionQuery(whereClause: "STATE_NAME = 'California'", name: "CACities")
};

//Create the layer with the feature layer parameters and add it to the active map
var createdFCWithQueryDefn = LayerFactory.Instance.CreateLayer<FeatureLayer>(layerParamsQueryDefn, MapView.Active.Map);

Create TopologyLayer with an Uri pointing to a Topology dataset

var path = @"D:\Data\CommunitySamplesData\Topology\GrandTeton.gdb\BackCountry\Backcountry_Topology";
var lcp = new TopologyLayerCreationParams(new Uri(path));
lcp.Name = "GrandTeton_Backcountry";
lcp.AddAssociatedLayers = true;
var topoLayer = LayerFactory.Instance.CreateLayer<ArcGIS.Desktop.Mapping.TopologyLayer>(lcp, MapView.Active.Map);

Create Topology Layer using Topology dataset

//Note: Call within QueuedTask.Run()
//Get the Topology of another Topology layer
var existingTopology = MapView.Active.Map.GetLayersAsFlattenedList().OfType<TopologyLayer>().FirstOrDefault();
if (existingTopology != null)
{
  var topology = existingTopology.GetTopology();
  //Configure the settings for a new Catalog layer using the CatalogDataset of an existing layer
  var topologyLyrParams = new TopologyLayerCreationParams(topology);
  topologyLyrParams.Name = "NewTopologyLayerFromAnotherTopologyLayer";
  topologyLyrParams.AddAssociatedLayers = true;
  LayerFactory.Instance.CreateLayer<TopologyLayer>(topologyLyrParams, MapView.Active.Map);
}

Create Catalog Layer using Uri to a Catalag Feature Class

//Note: Call within QueuedTask.Run()
var createParams = new CatalogLayerCreationParams(new Uri(@"C:\CatalogLayer\CatalogDS.gdb\HurricaneCatalogDS"));
//Set the definition query
createParams.DefinitionQuery = new DefinitionQuery("Query1", "cd_itemname = 'PuertoRico'");
//Set name of the new Catalog Layer
createParams.Name = "PuertoRico";
//Create Layer
var catalogLayer = LayerFactory.Instance.CreateLayer<CatalogLayer>(createParams, MapView.Active.Map);

Create Catalog Layer using CatalogDataset

//Note: Call within QueuedTask.Run()
//Get the CatalogDataset of another Catalog layer
var existingCatalogLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<CatalogLayer>().FirstOrDefault();
if (existingCatalogLayer != null)
{
  var catalogDataset = existingCatalogLayer.GetCatalogDataset();
  //Configure the settings for a new Catalog layer using the CatalogDataset of an existing layer
  var catalogLyrParams = new CatalogLayerCreationParams(catalogDataset);
  catalogLyrParams.Name = "NewCatalogLayerFromAnotherCatalogLayer";
  catalogLyrParams.DefinitionQuery = new DefinitionQuery("Query1", "cd_itemname = 'Asia'");
  LayerFactory.Instance.CreateLayer<CatalogLayer>(catalogLyrParams, MapView.Active.Map);
}

Add MapNotes to the active map

//Gets the collection of layer template packages installed with Pro for use with maps
var items = MapView.Active.Map.LayerTemplatePackages;
//Iterate through the collection of items to add each Map Note to the active map
foreach (var item in items)
{
  //Create a parameter item for the map note
  var layer_params = new LayerCreationParams(item);
  layer_params.IsVisible = false;
  await QueuedTask.Run(() =>
  {
    //Create a feature layer for the map note
    var layer = LayerFactory.Instance.CreateLayer<Layer>(layer_params, MapView.Active.Map);
  });
}

Apply Symbology from a Layer in the TOC

//Note: Call within QueuedTask.Run()
if (MapView.Active.Map == null) return;

//Get an existing Layer. This layer has a symbol you want to use in a new layer.
var lyr = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>()
      .Where(l => l.ShapeType == esriGeometryType.esriGeometryPoint).FirstOrDefault();
//This is the renderer to use in the new Layer
var renderer = lyr.GetRenderer() as CIMSimpleRenderer;
//Set the Dataconnection for the new layer
Geodatabase geodatabase = new Geodatabase(
  new FileGeodatabaseConnectionPath(new Uri(@"E:\Data\Admin\AdminData.gdb")));
FeatureClass featureClass = geodatabase.OpenDataset<FeatureClass>("Cities");
var dataConnection = featureClass.GetDataConnection();
//Create the definition for the new feature layer
var featureLayerParams = new FeatureLayerCreationParams(dataConnection)
{
  RendererDefinition = new SimpleRendererDefinition(renderer.Symbol),
  IsVisible = true,
};
//create the new layer
LayerFactory.Instance.CreateLayer<FeatureLayer>(
  featureLayerParams, MapView.Active.Map);

Create a new SubTypeGroupLayer

var subtypeGroupLayerCreateParam = new SubtypeGroupLayerCreationParams
(
    new Uri(@"c:\data\SubtypeAndDomain.gdb\Fittings")
);

// Define Subtype layers
//At 2.x - var rendererDefn1 = new UniqueValueRendererDefinition(new string[] { "type" });
var rendererDefn1 = new UniqueValueRendererDefinition(new List<string> { "type" });
var renderDefn2 = new SimpleRendererDefinition()
{
  SymbolTemplate = SymbolFactory.Instance.ConstructPointSymbol(
          CIMColor.CreateRGBColor(255, 0, 0), 8, SimpleMarkerStyle.Hexagon).MakeSymbolReference()
};
subtypeGroupLayerCreateParam.SubtypeLayers = new List<SubtypeFeatureLayerCreationParams>()
{
  //define first subtype layer with unique value renderer
  //At 2.x - new SubtypeFeatureLayerCreationParams(new UniqueValueRendererDefinition(new string[] { "type" }), 1),
  new SubtypeFeatureLayerCreationParams(new UniqueValueRendererDefinition(new List<string> { "type" }), 1),

  //define second subtype layer with simple symbol renderer
  new SubtypeFeatureLayerCreationParams(renderDefn2, 2)
};

// Define additional parameters
//At - 2.x subtypeGroupLayerCreateParam.DefinitionFilter = new CIMDefinitionFilter()
//{
//  Name = "IsActive",
//  DefinitionExpression = "Enabled = 1"
//};
subtypeGroupLayerCreateParam.DefinitionQuery = new DefinitionQuery(whereClause: "Enabled = 1", name: "IsActive");
subtypeGroupLayerCreateParam.IsVisible = true;
subtypeGroupLayerCreateParam.MinimumScale = 50000;

SubtypeGroupLayer subtypeGroupLayer2 = LayerFactory.Instance.CreateLayer<SubtypeGroupLayer>(
              subtypeGroupLayerCreateParam, MapView.Active.Map);

Create layer from a lyrx file

var lyrDocFromLyrxFile = new LayerDocument(@"d:\data\cities.lyrx");
var cimLyrDoc = lyrDocFromLyrxFile.GetCIMLayerDocument();

//modifying its renderer symbol to red
var r = ((CIMFeatureLayer)cimLyrDoc.LayerDefinitions[0]).Renderer as CIMSimpleRenderer;
r.Symbol.Symbol.SetColor(new CIMRGBColor() { R = 255 });

//optionally save the updates out as a file
lyrDocFromLyrxFile.Save(@"c:\data\cities_red.lyrx");

//get a json representation of the layer document and you want store away...
var aJSONString = lyrDocFromLyrxFile.AsJson();

//... and load it back when needed
lyrDocFromLyrxFile.Load(aJSONString);
cimLyrDoc = lyrDocFromLyrxFile.GetCIMLayerDocument();

//create a layer and add it to a map
var lcp = new LayerCreationParams(cimLyrDoc);
var lyr = LayerFactory.Instance.CreateLayer<FeatureLayer>(lcp, map);

Apply Symbology to a layer from a Layer file

//Note: Run within QueuedTask.Run
//Get the Layer Document from the lyrx file
var lyrDocFromLyrxFile = new LayerDocument(layerFile);
var cimLyrDoc = lyrDocFromLyrxFile.GetCIMLayerDocument();

//Get the renderer from the layer file
var rendererFromLayerFile = ((CIMFeatureLayer)cimLyrDoc.LayerDefinitions[0]).Renderer as CIMUniqueValueRenderer;

//Apply the renderer to the feature layer
//Note: If working with a raster layer, use the SetColorizer method.
featureLayer?.SetRenderer(rendererFromLayerFile);

Add a WMS service

// Create a connection to the WMS server
var serverConnection = new CIMInternetServerConnection { URL = "URL of the WMS service" };
var connection = new CIMWMSServiceConnection { ServerConnection = serverConnection };

// Add a new layer to the map
var layerParams = new LayerCreationParams(connection);
await QueuedTask.Run(() =>
{
  var layer = LayerFactory.Instance.CreateLayer<FeatureLayer>(layerParams, MapView.Active.Map);
});

Add a WFS Service

CIMStandardDataConnection cIMStandardDataConnection = new CIMStandardDataConnection()
{
  WorkspaceConnectionString = @"SWAPXY=TRUE;SWAPXYFILTER=FALSE;URL=http://sampleserver6.arcgisonline.com/arcgis/services/SampleWorldCities/MapServer/WFSServer;VERSION=2.0.0",
  WorkspaceFactory = WorkspaceFactory.WFS,
  Dataset = "Continent",
  DatasetType = esriDatasetType.esriDTFeatureClass
};

// Add a new layer to the map
var layerPamsDC = new LayerCreationParams(cIMStandardDataConnection);
await QueuedTask.Run(() =>
{
  Layer layer = LayerFactory.Instance.CreateLayer<FeatureLayer>(layerPamsDC, MapView.Active.Map);
});

Adding and changing styles for WMS Service Layer

var serverConnection = new CIMInternetServerConnection { URL = "https://spritle.esri.com/arcgis/services/sanfrancisco_sld/MapServer/WMSServer" };
var connection = new CIMWMSServiceConnection { ServerConnection = serverConnection };
LayerCreationParams parameters = new LayerCreationParams(connection);
parameters.MapMemberPosition = MapMemberPosition.AddToBottom;
await QueuedTask.Run(() =>
{
  var compositeLyr = LayerFactory.Instance.CreateLayer<WMSLayer>(parameters, MapView.Active.Map);
  //wms layer in ArcGIS Pro always has a composite layer inside it
  var wmsLayers = compositeLyr.Layers[0] as ServiceCompositeSubLayer;
  //each wms sublayer belongs in that composite layer
  var highwayLayerWMSSub = wmsLayers.Layers[1] as WMSSubLayer;
  //toggling a sublayer's visibility
  if ((highwayLayerWMSSub != null))
  {
    bool visibility = highwayLayerWMSSub.IsVisible;
    highwayLayerWMSSub.SetVisibility(!visibility);
  }
  //applying an existing style to a wms sub layer
  var pizzaLayerWMSSub = wmsLayers.Layers[0] as WMSSubLayer;
  var currentStyles = pizzaLayerWMSSub.GetStyleNames();
  pizzaLayerWMSSub.SetStyleName(currentStyles[1]);
});

Create a query layer

await QueuedTask.Run(() =>
{
  Map map = MapView.Active.Map;
  Geodatabase geodatabase = new Geodatabase(new DatabaseConnectionFile(new Uri(@"C:\Connections\mySDE.sde")));
  CIMSqlQueryDataConnection sqldc = new CIMSqlQueryDataConnection()
  {
    WorkspaceConnectionString = geodatabase.GetConnectionString(),
    GeometryType = esriGeometryType.esriGeometryPolygon,
    OIDFields = "OBJECTID",
    Srid = "102008",
    SqlQuery = "select * from MySDE.dbo.STATES",
    Dataset = "States"
  };
  var lcp = new LayerCreationParams(sqldc)
  {
    Name = "States"
  };
  FeatureLayer flyr = LayerFactory.Instance.CreateLayer<FeatureLayer>(lcp, map);
});

Create a feature layer with class breaks renderer with defaults

await QueuedTask.Run(() =>
{
  var featureLayerCreationParams = new FeatureLayerCreationParams(new Uri(@"c:\data\countydata.gdb\counties"))
  {
    Name = "Population Density (sq mi) Year 2010",
    RendererDefinition = new GraduatedColorsRendererDefinition("POP10_SQMI")
  };
  LayerFactory.Instance.CreateLayer<FeatureLayer>(
    featureLayerCreationParams,
    MapView.Active.Map
  );
});

Create a feature layer with class breaks renderer

string colorBrewerSchemesName = "ColorBrewer Schemes (RGB)";
StyleProjectItem style = Project.Current.GetItems<StyleProjectItem>().First(s => s.Name == colorBrewerSchemesName);
string colorRampName = "Greens (Continuous)";
IList<ColorRampStyleItem> colorRampList = await QueuedTask.Run(() =>
{
  return style.SearchColorRamps(colorRampName);
});
ColorRampStyleItem colorRamp = colorRampList[0];

await QueuedTask.Run(() =>
{
  GraduatedColorsRendererDefinition gcDef = new GraduatedColorsRendererDefinition()
  {
    ClassificationField = "CROP_ACR07",
    ClassificationMethod = ArcGIS.Core.CIM.ClassificationMethod.NaturalBreaks,
    BreakCount = 6,
    ColorRamp = colorRamp.ColorRamp,
    SymbolTemplate = SymbolFactory.Instance.ConstructPolygonSymbol(
                            ColorFactory.Instance.GreenRGB, SimpleFillStyle.Solid, null).MakeSymbolReference(),
    ExclusionClause = "CROP_ACR07 = -99",
    ExclusionSymbol = SymbolFactory.Instance.ConstructPolygonSymbol(
                            ColorFactory.Instance.RedRGB, SimpleFillStyle.Solid, null).MakeSymbolReference(),
    ExclusionLabel = "No yield",
  };
  var featureLayerCreationParams = new FeatureLayerCreationParams((new Uri(@"c:\Data\CountyData.gdb\Counties")))
  {
    Name = "Crop",
    RendererDefinition = gcDef
  };
  LayerFactory.Instance.CreateLayer<FeatureLayer>(featureLayerCreationParams, MapView.Active.Map);
});

Basemap Layers

Update a map's basemap layer

aMap.SetBasemapLayers(Basemap.Gray);

Remove basemap layer from a map

aMap.SetBasemapLayers(Basemap.None);

Working with Layers

Get a list of layers filtered by layer type from a map

List<FeatureLayer> featureLayerList = aMap.GetLayersAsFlattenedList().OfType<FeatureLayer>().ToList();

Get a layer of a certain geometry type

//Get an existing Layer. This layer has a symbol you want to use in a new layer.
var lyr = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>()
      .Where(l => l.ShapeType == esriGeometryType.esriGeometryPoint).FirstOrDefault();

Find a layer

//Finds layers by name and returns a read only list of Layers
IReadOnlyList<Layer> layers = aMap.FindLayers("cities", true);

//Finds a layer using a URI.
//The Layer URI you pass in helps you search for a specific layer in a map
var lyrFindLayer = MapView.Active.Map.FindLayer("CIMPATH=map/u_s__states__generalized_.xml");

//This returns a collection of layers of the "name" specified. You can use any Linq expression to query the collection.  
var lyrExists = MapView.Active.Map.GetLayersAsFlattenedList()
                   .OfType<FeatureLayer>().Any(f => f.Name == "U.S. States (Generalized)");

Find a standalone table

// these routines find a standalone table whether it is a child of the Map or a GroupLayer
var tblFind = aMap.FindStandaloneTable("CIMPATH=map/address_audit.xml");

IReadOnlyList<StandaloneTable> tables = aMap.FindStandaloneTables("addresses");

// this method finds a standalone table as a child of the map only
var table = aMap.StandaloneTables.FirstOrDefault(t => t.Name == "Addresses");

Find a layer using partial name search

Map map = MapView.Active.Map;
IEnumerable<Layer> matches = map.GetLayersAsFlattenedList().Where(l => l.Name.IndexOf(partialName, StringComparison.CurrentCultureIgnoreCase) >= 0);

Change layer visibility, editability, snappability

if (!layer.IsVisible)
  layer.SetVisibility(true);

if (layer is FeatureLayer featureLayer)
{
  if (!featureLayer.IsEditable)
    featureLayer.SetEditable(true);

  if (!featureLayer.IsSnappable)
    featureLayer.SetSnappable(true);
}

Create a Lyrx file

LayerDocument layerDocument = new LayerDocument(layer);
layerDocument.Save(@"c:\Data\MyLayerDocument.lyrx");

Count the features selected on a layer

var lyr = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault();
var noFeaturesSelected = lyr.SelectionCount;

Access the display field for a layer

var featureLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault();
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // get the CIM definition from the layer
  var cimFeatureDefinition = featureLayer.GetDefinition() as ArcGIS.Core.CIM.CIMBasicFeatureLayer;
  // get the view of the source table underlying the layer
  var cimDisplayTable = cimFeatureDefinition.FeatureTable;
  // this field is used as the 'label' to represent the row
  var displayField = cimDisplayTable.DisplayField;
});

Enable labeling on a layer

var featureLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault();
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // toggle the label visibility
  featureLayer.SetLabelVisibility(!featureLayer.IsLabelVisible);
});

Move a layer in the 2D group to the 3D Group in a Local Scene

//The layer in the 2D group to move to the 3D Group in a Local Scene
var layer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault();
QueuedTask.Run(() =>
{
  //Get the layer's definition
  var lyrDefn = layer.GetDefinition() as CIMBasicFeatureLayer;
  //setting this property moves the layer to 3D group in a scene
  lyrDefn.IsFlattened = false;
  //Set the definition back to the layer
  layer.SetDefinition(lyrDefn);
});

Reset the URL of a feature service layer

CIMStandardDataConnection dataConnection = dataConnectionLayer.GetDataConnection() as CIMStandardDataConnection;
dataConnection.WorkspaceConnectionString = newConnectionString;
dataConnectionLayer.SetDataConnection(dataConnection);

Change the underlying data source of a feature layer - same workspace type

//This is the existing layer for which we want to switch the underlying datasource
var lyr = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault();
QueuedTask.Run(() =>
{
  var connectionStringToReplace = lyr.GetFeatureClass().GetDatastore().GetConnectionString();
  string databaseConnectionPath = @"Path to the .sde connection file to replace with";
  //If the new SDE connection did not have a dataset with the same name as in the feature layer,
  //pass false for the validate parameter of the FindAndReplaceWorkspacePath method to achieve this. 
  //If validate is true and the SDE did not have a dataset with the same name, 
  //FindAndReplaceWorkspacePath will return failure
  lyr.FindAndReplaceWorkspacePath(connectionStringToReplace, databaseConnectionPath, true);
});

Change Geodatabase Version of layers off a specified version in a map

await QueuedTask.Run(() =>
{
  //Getting the current version name from the first feature layer of the map
  FeatureLayer flyr = MapView.Active.Map.GetLayersAsFlattenedList()
    .OfType<FeatureLayer>().FirstOrDefault();  //first feature layer
  Datastore dataStore = flyr.GetFeatureClass().GetDatastore();  //getting datasource
  Geodatabase geodatabase = dataStore as Geodatabase; //casting to Geodatabase
  if (geodatabase == null)
    return;

  VersionManager versionManager = geodatabase.GetVersionManager();
  ArcGIS.Core.Data.Version currentVersion = versionManager.GetCurrentVersion();

  //Getting all available versions except the current one
  IEnumerable<ArcGIS.Core.Data.Version> versions = versionManager.GetVersions()
    .Where(v => !v.GetName().Equals(currentVersion.GetName(), StringComparison.CurrentCultureIgnoreCase));

  //Assuming there is at least one other version we pick the first one from the list
  ArcGIS.Core.Data.Version toVersion = versions.FirstOrDefault();
  if (toVersion != null)
  {
    //Changing version
    MapView.Active.Map.ChangeVersion(currentVersion, toVersion);
  }
});

Querying a feature layer

var count = await QueuedTask.Run(() =>
{
  QueryFilter qf = new QueryFilter()
  {
    WhereClause = "Class = 'city'"
  };

  //Getting the first selected feature layer of the map view
  var flyr = (FeatureLayer)MapView.Active.GetSelectedLayers()
              .OfType<FeatureLayer>().FirstOrDefault();
  using (RowCursor rows = flyr.Search(qf)) //execute
  {
    //Looping through to count
    int i = 0;
    while (rows.MoveNext()) i++;

    return i;
  }
});
MessageBox.Show(String.Format(
   "Total features that matched the search criteria: {0}", count));

Get the attribute rotation field of a layer

var featureLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault();
QueuedTask.Run(() =>
{
  var cimRenderer = featureLayer.GetRenderer() as CIMUniqueValueRenderer;
  var cimRotationVariable = cimRenderer.VisualVariables.OfType<CIMRotationVisualVariable>().FirstOrDefault();
  var rotationInfoZ = cimRotationVariable.VisualVariableInfoZ;
  var rotationExpression = rotationInfoZ.ValueExpressionInfo.Expression; // this expression stores the field name  
});

Find connected attribute field for rotation

var featureLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault();
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // get the CIM renderer from the layer
  var cimRenderer = featureLayer.GetRenderer() as ArcGIS.Core.CIM.CIMSimpleRenderer;
  // get the collection of connected attributes for rotation
  var cimRotationVariable = cimRenderer.VisualVariables.OfType<ArcGIS.Core.CIM.CIMRotationVisualVariable>().FirstOrDefault();
  // the z direction is describing the heading rotation
  var rotationInfoZ = cimRotationVariable.VisualVariableInfoZ;
  var rotationExpression = rotationInfoZ.Expression; // this expression stores the field name  
});

Toggle "Scale layer symbols when reference scale is set"

var featureLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault();
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // get the CIM layer definition
  var cimFeatureLayer = featureLayer.GetDefinition() as ArcGIS.Core.CIM.CIMFeatureLayer;
  // turn on the option to scale the symbols in this layer based in the map's reference scale
  cimFeatureLayer.ScaleSymbols = true;
});

Set the layer cache

var featureLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault();
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // change the layer cache type to maximum age
  //At 2.x - featureLayer.SetDisplayCacheType(ArcGIS.Core.CIM.DisplayCacheType.MaxAge);
  featureLayer.SetCacheOptions(LayerCacheType.MaxAge);
  // change from the default 5 min to 2 min
  featureLayer.SetDisplayCacheMaxAge(TimeSpan.FromMinutes(2));
});

Change the layer selection color

var featureLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault();
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
  // get the CIM definition of the layer
  var layerDef = featureLayer.GetDefinition() as ArcGIS.Core.CIM.CIMBasicFeatureLayer;
  // disable the default symbol
  layerDef.UseSelectionSymbol = false;
  // assign a new color
  layerDef.SelectionColor = ColorFactory.Instance.RedRGB;
  // apply the definition to the layer
  featureLayer.SetDefinition(layerDef);

  if (!featureLayer.IsVisible)
    featureLayer.SetVisibility(true);
  //Do a selection

  MapView.Active.SelectFeatures(MapView.Active.Extent);
});

Removes all layers that are unchecked

var map = MapView.Active.Map;
if (map == null)
  return;
//Get the group layers first
IReadOnlyList<GroupLayer> groupLayers = map.Layers.OfType<GroupLayer>().ToList();
//Iterate and remove the layers within the group layers that are unchecked.
foreach (var groupLayer in groupLayers)
{
  //Get layers that not visible within the group
  var layers = groupLayer.Layers.Where(l => l.IsVisible == false).ToList();
  //Remove all the layers that are not visible within the group
  await QueuedTask.Run(() => map.RemoveLayers(layers));
}

//Group Layers that are empty and are unchecked
foreach (var group in groupLayers)
{
  if (group.Layers.Count == 0 && group.IsVisible == false) //No layers in the group
  {
    //remove the group
    await QueuedTask.Run(() => map.RemoveLayer(group));
  }
}

//Get Layers that are NOT Group layers and are unchecked
var notAGroupAndUnCheckedLayers = map.Layers.Where(l => !(l is GroupLayer) && l.IsVisible == false).ToList();
//Remove all the non group layers that are not visible
await QueuedTask.Run(() => map.RemoveLayers(notAGroupAndUnCheckedLayers));

Remove empty groups

var map = MapView.Active.Map;
if (map == null)
  return;
//Get the group layers
IReadOnlyList<GroupLayer> groupLayers = map.Layers.OfType<GroupLayer>().ToList();
foreach (var group in groupLayers)
{
  if (group.Layers.Count == 0) //No layers in the group
  {
    //remove the group
    await QueuedTask.Run(() => map.RemoveLayer(group));
  }
}

Create and apply Abbreviation Dictionary in the Map Definition to a layer

public static void CreateDictionary()
{
  //Get the map's defintion
  var mapDefn = MapView.Active.Map.GetDefinition();
  //Get the Map's Maplex labelling engine properties
  var mapDefnPlacementProps = mapDefn.GeneralPlacementProperties as CIMMaplexGeneralPlacementProperties;

  //Define the abbreaviations we need in an array            
  List<CIMMaplexDictionaryEntry> abbreviationDictionary = new List<CIMMaplexDictionaryEntry>
        {
            new CIMMaplexDictionaryEntry {
            Abbreviation = "Hts",
            Text = "Heights",
            MaplexAbbreviationType = MaplexAbbreviationType.Ending

         },
            new CIMMaplexDictionaryEntry
            {
                Abbreviation = "Ct",
                Text = "Text",
                MaplexAbbreviationType = MaplexAbbreviationType.Ending

            }
            //etc
        };
  //The Maplex Dictionary - can hold multiple Abbreviation collections
  var maplexDictionary = new List<CIMMaplexDictionary>
        {
            new CIMMaplexDictionary {
                Name = "NameEndingsAbbreviations",
                MaplexDictionary = abbreviationDictionary.ToArray()
            }

        };
  //Set the Maplex Label Engine Dictionary property to the Maplex Dictionary collection created above.
  mapDefnPlacementProps.Dictionaries = maplexDictionary.ToArray();
  //Set the Map defintion 
  MapView.Active.Map.SetDefinition(mapDefn);
}

private static void ApplyDictionary()
{
  var featureLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().First();

  QueuedTask.Run(() =>
  {
    //Creates Abbreviation dictionary and adds to Map Defintion                                
    CreateDictionary();
    //Get the layer's definition
    var lyrDefn = featureLayer.GetDefinition() as CIMFeatureLayer;
    //Get the label classes - we need the first one
    var listLabelClasses = lyrDefn.LabelClasses.ToList();
    var theLabelClass = listLabelClasses.FirstOrDefault();
    //Modify label Placement props to use abbreviation dictionary 
    CIMGeneralPlacementProperties labelEngine = MapView.Active.Map.GetDefinition().GeneralPlacementProperties;
    theLabelClass.MaplexLabelPlacementProperties.DictionaryName = "NameEndingsAbbreviations";
    theLabelClass.MaplexLabelPlacementProperties.CanAbbreviateLabel = true;
    theLabelClass.MaplexLabelPlacementProperties.CanStackLabel = false;
    //Set the labelClasses back
    lyrDefn.LabelClasses = listLabelClasses.ToArray();
    //set the layer's definition
    featureLayer.SetDefinition(lyrDefn);
  });
}

Attribute Table - ITablePane

Set zoom level for Attribute Table

if (FrameworkApplication.Panes.ActivePane is ITablePane tablePane)
{
  var currentZoomLevel = tablePane.ZoomLevel;

  var newZoomLevel = currentZoomLevel + 50;
  tablePane.SetZoomLevel(newZoomLevel);
}

Retrieve the values of selected cell in the attribute table

if (FrameworkApplication.Panes.ActivePane is ITablePane tablePane)
{
  var mapMember = tablePane.MapMember;
  var oid = tablePane.ActiveObjectID;
  if (oid.HasValue && oid.Value != -1 && mapMember != null)
  {
    var activeField = tablePane.ActiveColumn;
    return QueuedTask.Run<object>(() =>
    {
      // TODO: Use core objects to retrieve record and get value

      return null;
    });
  }
}

Move to a particular row

if (FrameworkApplication.Panes.ActivePane is ITablePane tablePane)
{
  // move to first row
  tablePane.BringIntoView(0);

  // move to sixth row
  tablePane.BringIntoView(5);
}
      }

Metadata

Get and Set Map Metadata

var map = MapView.Active.Map;
if (map == null) return;
//Get map's metadata
var mapMetadata = map.GetMetadata();
//TODO:Make edits to metadata using the retrieved mapMetadata string.

//Set the modified metadata back to the map.
if (map.GetCanEditMetadata())
  map.SetMetadata(mapMetadata);

Layer Metadata

MapMember mapMember = map.GetLayersAsFlattenedList().FirstOrDefault(); //Search for only layers/tables here if needed.
if (mapMember == null) return;

//Gets whether or not the MapMember stores its own metadata or uses metadata retrieved
//from its source. This method must be called on the MCT. Use QueuedTask.Run
bool doesUseSourceMetadata = mapMember.GetUseSourceMetadata();

//Sets whether or not the MapMember will use its own metadata or the metadata from
//its underyling source (if it has one). This method must be called on the MCT.
//Use QueuedTask.Run
mapMember.SetUseSourceMetadata(true);

//Does the MapMember supports metadata
var supportsMetadata = mapMember.SupportsMetadata;

//Get MapMember metadata
var metadatstring = mapMember.GetMetadata();
//TODO:Make edits to metadata using the retrieved mapMetadata string.

//Set the modified metadata back to the mapmember (layer, table..)
if (mapMember.GetCanEditMetadata())
  mapMember.SetMetadata(metadatstring);

Renderers

Set unique value renderer to the selected feature layer of the active map

await QueuedTask.Run(() =>
{
  var fields = new List<string> { "Type" }; //field to be used to retrieve unique values
  CIMPointSymbol pointSym = SymbolFactory.Instance.ConstructPointSymbol(
      ColorFactory.Instance.GreenRGB, 16.0, SimpleMarkerStyle.Pushpin);  //constructing a point symbol as a template symbol
  CIMSymbolReference symbolPointTemplate = pointSym.MakeSymbolReference();

  //constructing renderer definition for unique value renderer
  UniqueValueRendererDefinition uniqueValueRendererDef =
new UniqueValueRendererDefinition(fields, symbolPointTemplate);

  //creating a unique value renderer
  var flyr = MapView.Active.GetSelectedLayers()[0] as FeatureLayer;
  CIMUniqueValueRenderer uniqueValueRenderer = flyr.CreateRenderer(uniqueValueRendererDef) as CIMUniqueValueRenderer;

  //setting the renderer to the feature layer
  flyr.SetRenderer(uniqueValueRenderer);
});

Create a UniqueValueRenderer to specify symbols to values

return QueuedTask.Run(() =>
{
  //The goal is to construct the CIMUniqueValueRenderer which will be applied to the feature layer.
  // To do this, the following are the objects we need to set the renderer up with the fields and symbols.
  // As a reference, this is the USCities dataset. Snippet will create a unique value renderer that applies 
  // specific symbols to all the cities in California and Alabama.  The rest of the cities will use a default symbol.

  // First create a "CIMUniqueValueClass" for the cities in Alabama.
  List<CIMUniqueValue> listUniqueValuesAlabama = new List<CIMUniqueValue> { new CIMUniqueValue { FieldValues = new string[] { "Alabama" } } };
  CIMUniqueValueClass alabamaUniqueValueClass = new CIMUniqueValueClass
  {
    Editable = true,
    Label = "Alabama",
    Patch = PatchShape.Default,
    Symbol = SymbolFactory.Instance.ConstructPointSymbol(ColorFactory.Instance.RedRGB).MakeSymbolReference(),
    Visible = true,
    Values = listUniqueValuesAlabama.ToArray()

  };
  // Create a "CIMUniqueValueClass" for the cities in California.
  List<CIMUniqueValue> listUniqueValuescalifornia = new List<CIMUniqueValue> { new CIMUniqueValue { FieldValues = new string[] { "California" } } };
  CIMUniqueValueClass californiaUniqueValueClass = new CIMUniqueValueClass
  {
    Editable = true,
    Label = "California",
    Patch = PatchShape.Default,
    Symbol = SymbolFactory.Instance.ConstructPointSymbol(ColorFactory.Instance.BlueRGB).MakeSymbolReference(),
    Visible = true,
    Values = listUniqueValuescalifornia.ToArray()
  };
  //Create a list of the above two CIMUniqueValueClasses
  List<CIMUniqueValueClass> listUniqueValueClasses = new List<CIMUniqueValueClass>
    {
                  alabamaUniqueValueClass, californiaUniqueValueClass
    };
  //Create a list of CIMUniqueValueGroup
  CIMUniqueValueGroup uvg = new CIMUniqueValueGroup
  {
    Classes = listUniqueValueClasses.ToArray(),
  };
  List<CIMUniqueValueGroup> listUniqueValueGroups = new List<CIMUniqueValueGroup> { uvg };
  //Create the CIMUniqueValueRenderer
  CIMUniqueValueRenderer uvr = new CIMUniqueValueRenderer
  {
    UseDefaultSymbol = true,
    DefaultLabel = "all other values",
    DefaultSymbol = SymbolFactory.Instance.ConstructPointSymbol(ColorFactory.Instance.GreyRGB).MakeSymbolReference(),
    Groups = listUniqueValueGroups.ToArray(),
    Fields = new string[] { "STATE_NAME" }
  };
  //Set the feature layer's renderer.
  featureLayer.SetRenderer(uvr);
});

Create a Heatmap Renderer

string colorBrewerSchemesName = "ArcGIS Colors";
StyleProjectItem style = Project.Current.GetItems<StyleProjectItem>().First(s => s.Name == colorBrewerSchemesName);
string colorRampName = "Heat Map 4 - Semitransparent";
IList<ColorRampStyleItem> colorRampList = await QueuedTask.Run(() =>
{
  return style.SearchColorRamps(colorRampName);
});
ColorRampStyleItem colorRamp = colorRampList[0];

await QueuedTask.Run(() =>
{
  //defining a heatmap renderer that uses values from Population field as the weights
  HeatMapRendererDefinition heatMapDef = new HeatMapRendererDefinition()
  {
    Radius = 20,
    WeightField = "Population",
    ColorRamp = colorRamp.ColorRamp,
    RendereringQuality = 8,
    UpperLabel = "High Density",
    LowerLabel = "Low Density"
  };

  FeatureLayer flyr = MapView.Active.Map.Layers[0] as FeatureLayer;
  CIMHeatMapRenderer heatMapRndr = flyr.CreateRenderer(heatMapDef) as CIMHeatMapRenderer;
  flyr.SetRenderer(heatMapRndr);
});

Create an Unclassed Renderer

string colorBrewerSchemesName = "ArcGIS Colors";
StyleProjectItem style = Project.Current.GetItems<StyleProjectItem>().First(s => s.Name == colorBrewerSchemesName);
string colorRampName = "Heat Map 4 - Semitransparent";
IList<ColorRampStyleItem> colorRampList = await QueuedTask.Run(() =>
{
  return style.SearchColorRamps(colorRampName);
});
ColorRampStyleItem colorRamp = colorRampList[0];

await QueuedTask.Run(() =>
{
  CIMPointSymbol pointSym = SymbolFactory.Instance.ConstructPointSymbol(ColorFactory.Instance.GreenRGB, 16.0, SimpleMarkerStyle.Diamond);
  CIMSymbolReference symbolPointTemplate = pointSym.MakeSymbolReference();

  //defining an unclassed renderer with custom upper and lower stops
  //all features with value >= 5,000,000 will be drawn with the upper color from the color ramp
  //all features with value <= 50,000 will be drawn with the lower color from the color ramp
  UnclassedColorsRendererDefinition unclassRndrDef = new UnclassedColorsRendererDefinition
                        ("Population", symbolPointTemplate, colorRamp.ColorRamp, "Highest", "Lowest", 5000000, 50000)
  {

    //drawing features with null values with a different symbol
    ShowNullValues = true,
    NullValueLabel = "Unknown"
  };
  CIMPointSymbol nullSym = SymbolFactory.Instance.ConstructPointSymbol(ColorFactory.Instance.RedRGB, 16.0, SimpleMarkerStyle.Circle);
  unclassRndrDef.NullValueSymbol = nullSym.MakeSymbolReference();
  FeatureLayer flyr = MapView.Active.Map.Layers[0] as FeatureLayer;
  CIMClassBreaksRenderer cbRndr = flyr.CreateRenderer(unclassRndrDef) as CIMClassBreaksRenderer;
  flyr.SetRenderer(cbRndr);
});

Create a Proportion Renderer with max and min symbol size capped

string colorBrewerSchemesName = "ArcGIS Colors";
StyleProjectItem style = Project.Current.GetItems<StyleProjectItem>().First(s => s.Name == colorBrewerSchemesName);
string colorRampName = "Heat Map 4 - Semitransparent";
IList<ColorRampStyleItem> colorRampList = await QueuedTask.Run(() =>
{
  return style.SearchColorRamps(colorRampName);
});
ColorRampStyleItem colorRamp = colorRampList[0];

await QueuedTask.Run(() =>
{
  CIMPointSymbol pointSym = SymbolFactory.Instance.ConstructPointSymbol(ColorFactory.Instance.GreenRGB, 1.0, SimpleMarkerStyle.Circle);
  CIMSymbolReference symbolPointTemplate = pointSym.MakeSymbolReference();

  //minimum symbol size is capped to 4 point while the maximum symbol size is set to 50 point
  ProportionalRendererDefinition prDef = new ProportionalRendererDefinition("POPULATION", symbolPointTemplate, 4, 50, true)
  {

    //setting upper and lower size stops to stop symbols growing or shrinking beyond those thresholds
    UpperSizeStop = 5000000,  //features with values >= 5,000,000 will be drawn with maximum symbol size
    LowerSizeStop = 50000    //features with values <= 50,000 will be drawn with minimum symbol size
  };
  FeatureLayer flyr = MapView.Active.Map.Layers[0] as FeatureLayer;
  CIMProportionalRenderer propRndr = flyr.CreateRenderer(prDef) as CIMProportionalRenderer;
  flyr.SetRenderer(propRndr);

});

Create a True Proportion Renderer

string colorBrewerSchemesName = "ArcGIS Colors";
StyleProjectItem style = Project.Current.GetItems<StyleProjectItem>().First(s => s.Name == colorBrewerSchemesName);
string colorRampName = "Heat Map 4 - Semitransparent";
IList<ColorRampStyleItem> colorRampList = await QueuedTask.Run(() =>
{
  return style.SearchColorRamps(colorRampName);
});
ColorRampStyleItem colorRamp = colorRampList[0];

await QueuedTask.Run(() =>
{
  CIMPointSymbol pointSym = SymbolFactory.Instance.ConstructPointSymbol(ColorFactory.Instance.GreenRGB, 1.0, SimpleMarkerStyle.Circle);
  CIMSymbolReference symbolPointTemplate = pointSym.MakeSymbolReference();

  //Defining proportional renderer where size of symbol will be same as its value in field used in the renderer.
  ProportionalRendererDefinition prDef = new ProportionalRendererDefinition("POPULATION", esriUnits.esriMeters, symbolPointTemplate, SymbolShapes.Square, ValueRepresentations.Radius);

  FeatureLayer flyr = MapView.Active.Map.Layers[0] as FeatureLayer;
  CIMProportionalRenderer propRndr = flyr.CreateRenderer(prDef) as CIMProportionalRenderer;
  flyr.SetRenderer(propRndr);

});

Elevation Surface Layers

Create a scene with a ground surface layer

// wrap in QueuedTask.Run
var scene = MapFactory.Instance.CreateScene("My scene", groundSourceUri, MapViewingMode.SceneGlobal);

Create a New Elevation Surface

//Note: call within QueuedTask.Run()
//Define a ServiceConnection to use for the new Elevation surface
var serverConnection = new CIMInternetServerConnection
{
  Anonymous = true,
  HideUserProperty = true,
  URL = "https://elevation.arcgis.com/arcgis/services"
};
CIMAGSServiceConnection serviceConnection = new CIMAGSServiceConnection
{
  ObjectName = "WorldElevation/Terrain",
  ObjectType = "ImageServer",
  URL = "https://elevation.arcgis.com/arcgis/services/WorldElevation/Terrain/ImageServer",
  ServerConnection = serverConnection
};
//Defines a new elevation source set to the CIMAGSServiceConnection defined above
//At 2.x - var newElevationSource = new ArcGIS.Core.CIM.CIMElevationSource
//{
//  VerticalUnit = ArcGIS.Core.Geometry.LinearUnit.Meters,
//  DataConnection = serviceConnection,
//  Name = "WorldElevation/Terrain",
//  Visibility = true
//};
//The elevation surface
//At 2.x - var newElevationSurface = new ArcGIS.Core.CIM.CIMMapElevationSurface
//{
//  Name = "New Elevation Surface",
//  BaseSources = new ArcGIS.Core.CIM.CIMElevationSource[1] { newElevationSource },
//  Visibility = true,
//  ElevationMode = ElevationMode.CustomSurface,
//  VerticalExaggeration = 1,
//  EnableSurfaceShading = false,
//  SurfaceTINShadingMode = SurfaceTINShadingMode.Smooth,
//  Expanded = false,
//  MapElevationID = "{3DEC3CC5-7C69-4132-A700-DCD5BDED14D6}"
//};
//Get the active map
var map = MapView.Active.Map;
//Get the elevation surfaces defined in the map
//At 2.x - var listOfElevationSurfaces = definition.ElevationSurfaces.ToList();
var listOfElevationSurfaces = map.GetElevationSurfaceLayers();
//Add the new elevation surface 
//At 2.x - listOfElevationSurfaces.Add(newElevationSurface);
var elevationLyrCreationParams = new ElevationLayerCreationParams(serviceConnection);
var elevationSurface = LayerFactory.Instance.CreateLayer<ElevationSurfaceLayer>(
       elevationLyrCreationParams, map);

Set a custom elevation surface to a Z-Aware layer

//Define the custom elevation surface to use
//At 2.x - var layerElevationSurface = new CIMLayerElevationSurface
//{
//  MapElevationID = "{3DEC3CC5-7C69-4132-A700-DCD5BDED14D6}"
//};
var layerElevationSurface = new CIMLayerElevationSurface
{
  ElevationSurfaceLayerURI = "https://elevation3d.arcgis.com/arcgis/services/WorldElevation3D/Terrain3D/ImageServer"
};
//Get the layer's definition
var lyrDefn = featureLayer.GetDefinition() as CIMBasicFeatureLayer;
//Set the layer's elevation surface
lyrDefn.LayerElevation = layerElevationSurface;
//Set the layer's definition
featureLayer.SetDefinition(lyrDefn);

Add an elevation source to an existing elevation surface layer

// wrap in QueuendTask.Run

// surfaceLayer could also be the ground layer

string uri = "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer";
var createParams = new ElevationLayerCreationParams(new Uri(uri));
createParams.Name = "Terrain 3D";
var eleSourceLayer = LayerFactory.Instance.CreateLayer<Layer>(createParams, surfaceLayer);

Get the elevation surface layers and elevation source layers from a map

// retrieve the elevation surface layers in the map including the Ground
var surfaceLayers = map.GetElevationSurfaceLayers();

// retrieve the single ground elevation surface layer in the map
var groundSurfaceLayer = map.GetGroundElevationSurfaceLayer();

// determine the number of elevation sources in the ground elevation surface layer
int numberGroundSources = groundSurfaceLayer.Layers.Count;
// get the first elevation source layer from the ground elevation surface layer
var groundSourceLayer = groundSurfaceLayer.Layers.FirstOrDefault();

Find an elevation surface layer

var surfaceLayers = map.GetElevationSurfaceLayers();
var surfaceLayer = surfaceLayers.FirstOrDefault(l => l.Name == "Surface2");

surfaceLayer = map.FindElevationSurfaceLayer(layerUri);

Remove elevation surface layers

// wrap in a QueuedTask.Run

map.ClearElevationSurfaceLayers();   //Ground will not be removed

map.RemoveLayer(surfaceLayer);//Cannot remove ground
map.RemoveLayers(map.GetElevationSurfaceLayers()); //Ground will not be removed

Get Z values from a surface

var geometry = await QueuedTask.Run<Geometry>(() =>
{
  Geometry mapCentergeometry = MapView.Active.Map.CalculateFullExtent().Center;
  return mapCentergeometry;
});
//Pass any Geometry type to GetZsFromSurfaceAsync
var surfaceZResult = await MapView.Active.Map.GetZsFromSurfaceAsync(geometry);
return surfaceZResult;

Raster Layers

Create a raster layer

string url = @"C:\Images\Italy.tif";
await QueuedTask.Run(() =>
{
  // Create a raster layer using a path to an image.
  // Note: You can create a raster layer from a url, project item, or data connection.
  rasterLayer = LayerFactory.Instance.CreateLayer(new Uri(url), aMap) as RasterLayer;
});

Update the raster colorizer on a raster layer

await QueuedTask.Run(() =>
{
  // Get the colorizer from the raster layer.
  CIMRasterColorizer rasterColorizer = rasterLayer.GetColorizer();
  // Update raster colorizer properties.
  rasterColorizer.Brightness = 10;
  rasterColorizer.Contrast = -5;
  rasterColorizer.ResamplingType = RasterResamplingType.NearestNeighbor;
  // Update the raster layer with the changed colorizer.
  rasterLayer.SetColorizer(rasterColorizer);
});

Update the RGB colorizer on a raster layer

await QueuedTask.Run(() =>
{
  // Get the colorizer from the raster layer.
  CIMRasterColorizer rColorizer = rasterLayer.GetColorizer();
  // Check if the colorizer is an RGB colorizer.
  if (rColorizer is CIMRasterRGBColorizer rasterRGBColorizer)
  {
    // Update RGB colorizer properties.
    rasterRGBColorizer.StretchType = RasterStretchType.ESRI;
    // Update the raster layer with the changed colorizer.
    rasterLayer.SetColorizer(rasterRGBColorizer);
  }
});

Check if a certain colorizer can be applied to a raster layer

await QueuedTask.Run(() =>
{
  // Get the list of colorizers that can be applied to the raster layer.
  IEnumerable<RasterColorizerType> applicableColorizerList = rasterLayer.GetApplicableColorizers();
  // Check if the RGB colorizer is part of the list.
  bool isTrue_ContainTheColorizerType =
    applicableColorizerList.Contains(RasterColorizerType.RGBColorizer);
});

Create a new colorizer based on a default colorizer definition and apply it to the raster layer

await QueuedTask.Run(async () =>
{
  // Check if the Stretch colorizer can be applied to the raster layer.
  if (rasterLayer.GetApplicableColorizers().Contains(RasterColorizerType.StretchColorizer))
  {
    // Create a new Stretch Colorizer Definition using the default constructor.
    StretchColorizerDefinition stretchColorizerDef_default = new StretchColorizerDefinition();
    // Create a new Stretch colorizer using the colorizer definition created above.
    CIMRasterStretchColorizer newStretchColorizer_default =
await rasterLayer.CreateColorizerAsync(stretchColorizerDef_default) as CIMRasterStretchColorizer;
    // Set the new colorizer on the raster layer.
    rasterLayer.SetColorizer(newStretchColorizer_default);
  }
});

Create a new colorizer based on a custom colorizer definition and apply it to the raster layer

await QueuedTask.Run(async () =>
{
  // Check if the Stretch colorizer can be applied to the raster layer.
  if (rasterLayer.GetApplicableColorizers().Contains(RasterColorizerType.StretchColorizer))
  {
    // Create a new Stretch Colorizer Definition specifying parameters 
    // for band index, stretch type, gamma and color ramp.
    StretchColorizerDefinition stretchColorizerDef_custom =
new StretchColorizerDefinition(1, RasterStretchType.ESRI, 2, colorRamp);
    // Create a new stretch colorizer using the colorizer definition created above.
    CIMRasterStretchColorizer newStretchColorizer_custom =
await rasterLayer.CreateColorizerAsync(stretchColorizerDef_custom) as CIMRasterStretchColorizer;
    // Set the new colorizer on the raster layer.
    rasterLayer.SetColorizer(newStretchColorizer_custom);
  }
});

Create a raster layer with a new colorizer definition

// Create a new stretch colorizer definition using default constructor.
StretchColorizerDefinition stretchColorizerDef = new StretchColorizerDefinition();
var rasterLayerCreationParams = new RasterLayerCreationParams(new Uri(url))
{
  ColorizerDefinition = stretchColorizerDef,
  Name = layerName,
  MapMemberIndex = 0
};
await QueuedTask.Run(() =>
{
  // Create a raster layer using the colorizer definition created above.
  // Note: You can create a raster layer from a url, project item, or data connection.
  RasterLayer rasterLayerfromURL =
    LayerFactory.Instance.CreateLayer<RasterLayer>(rasterLayerCreationParams, aMap);
});

Mosaic Layers

Create a mosaic layer

MosaicLayer mosaicLayer = null;
string url = @"C:\Images\countries.gdb\Italy";
await QueuedTask.Run(() =>
{
  // Create a mosaic layer using a path to a mosaic dataset.
  // Note: You can create a mosaic layer from a url, project item, or data connection.
  mosaicLayer = LayerFactory.Instance.CreateLayer(new Uri(url), aMap) as MosaicLayer;
});

Update the raster colorizer on a mosaic layer

await QueuedTask.Run(() =>
{
  // Get the image sub-layer from the mosaic layer.
  ImageMosaicSubLayer mosaicImageSubLayer = mosaicLayer.GetImageLayer();
  // Get the colorizer from the image sub-layer.
  CIMRasterColorizer rasterColorizer = mosaicImageSubLayer.GetColorizer();
  // Update raster colorizer properties.
  rasterColorizer.Brightness = 10;
  rasterColorizer.Contrast = -5;
  rasterColorizer.ResamplingType = RasterResamplingType.NearestNeighbor;
  // Update the image sub-layer with the changed colorizer.
  mosaicImageSubLayer.SetColorizer(rasterColorizer);
});

Update the RGB colorizer on a mosaic layer

await QueuedTask.Run(() =>
{
  // Get the image sub-layer from the mosaic layer.
  ImageMosaicSubLayer mosaicImageSubLayer = mosaicLayer.GetImageLayer();
  // Get the colorizer from the image sub-layer.
  CIMRasterColorizer rColorizer = mosaicImageSubLayer.GetColorizer();
  // Check if the colorizer is an RGB colorizer.
  if (rColorizer is CIMRasterRGBColorizer rasterRGBColorizer)
  {
    // Update RGB colorizer properties.
    rasterRGBColorizer.StretchType = RasterStretchType.ESRI;
    // Update the image sub-layer with the changed colorizer.
    mosaicImageSubLayer.SetColorizer(rasterRGBColorizer);
  }
});

Check if a certain colorizer can be applied to a mosaic layer

await QueuedTask.Run(() =>
{
  // Get the image sub-layer from the mosaic layer.
  ImageMosaicSubLayer mosaicImageSubLayer = mosaicLayer.GetImageLayer();
  // Get the list of colorizers that can be applied to the image sub-layer.
  IEnumerable<RasterColorizerType> applicableColorizerList =
    mosaicImageSubLayer.GetApplicableColorizers();
  // Check if the RGB colorizer is part of the list.
  bool isTrue_ContainTheColorizerType =
    applicableColorizerList.Contains(RasterColorizerType.RGBColorizer);
});

Create a new colorizer based on a default colorizer definition and apply it to the mosaic layer

await QueuedTask.Run(async () =>
{
  // Get the image sub-layer from the mosaic layer.
  ImageMosaicSubLayer mosaicImageSubLayer = mosaicLayer.GetImageLayer();
  // Check if the Stretch colorizer can be applied to the image sub-layer.
  if (mosaicImageSubLayer.GetApplicableColorizers().Contains(RasterColorizerType.StretchColorizer))
  {
    // Create a new Stretch Colorizer Definition using the default constructor.
    StretchColorizerDefinition stretchColorizerDef_default = new StretchColorizerDefinition();
    // Create a new Stretch colorizer using the colorizer definition created above.
    CIMRasterStretchColorizer newStretchColorizer_default =
await mosaicImageSubLayer.CreateColorizerAsync(stretchColorizerDef_default) as CIMRasterStretchColorizer;
    // Set the new colorizer on the image sub-layer.
    mosaicImageSubLayer.SetColorizer(newStretchColorizer_default);
  }
});

Create a new colorizer based on a custom colorizer definition and apply it to the mosaic layer

await QueuedTask.Run(async () =>
{
  // Get the image sub-layer from the mosaic layer.
  ImageMosaicSubLayer mosaicImageSubLayer = mosaicLayer.GetImageLayer();
  // Check if the Stretch colorizer can be applied to the image sub-layer.
  if (mosaicImageSubLayer.GetApplicableColorizers().Contains(RasterColorizerType.StretchColorizer))
  {
    // Create a new Stretch colorizer definition specifying parameters
    // for band index, stretch type, gamma and color ramp.
    StretchColorizerDefinition stretchColorizerDef_custom =
new StretchColorizerDefinition(1, RasterStretchType.ESRI, 2, colorRamp);
    // Create a new stretch colorizer using the colorizer definition created above.
    CIMRasterStretchColorizer newStretchColorizer_custom =
await mosaicImageSubLayer.CreateColorizerAsync(stretchColorizerDef_custom) as CIMRasterStretchColorizer;
    // Set the new colorizer on the image sub-layer.
    mosaicImageSubLayer.SetColorizer(newStretchColorizer_custom);
  }
});

Create a mosaic layer with a new colorizer definition

// Create a new colorizer definition using default constructor.
StretchColorizerDefinition stretchColorizerDef = new StretchColorizerDefinition();
var rasterLayerCreationParams = new RasterLayerCreationParams(new Uri(url))
{
  Name = layerName,
  ColorizerDefinition = stretchColorizerDef,
  MapMemberIndex = 0

};
await QueuedTask.Run(() =>
{
  // Create a mosaic layer using the colorizer definition created above.
  // Note: You can create a mosaic layer from a url, project item, or data connection.
  MosaicLayer newMosaicLayer =
    LayerFactory.Instance.CreateLayer<MosaicLayer>(rasterLayerCreationParams, aMap);
});

Update the sort order - mosaic method on a mosaic layer

await QueuedTask.Run(() =>
{
  // Get the image sub-layer from the mosaic layer.
  ImageServiceLayer mosaicImageSubLayer = mosaicLayer.GetImageLayer() as ImageServiceLayer;
  // Get the mosaic rule.
  CIMMosaicRule mosaicingRule = mosaicImageSubLayer.GetMosaicRule();
  // Set the Mosaic Method to Center.
  mosaicingRule.MosaicMethod = RasterMosaicMethod.Center;
  // Update the mosaic with the changed mosaic rule.
  mosaicImageSubLayer.SetMosaicRule(mosaicingRule);
});

Update the resolve overlap - mosaic operator on a mosaic layer

await QueuedTask.Run(() =>
{
  // Get the image sub-layer from the mosaic layer.
  ImageServiceLayer mosaicImageSublayer = mosaicLayer.GetImageLayer() as ImageServiceLayer;
  // Get the mosaic rule.
  CIMMosaicRule mosaicRule = mosaicImageSublayer.GetMosaicRule();
  // Set the Mosaic Operator to Mean.
  mosaicRule.MosaicOperatorType = RasterMosaicOperatorType.Mean;
  // Update the mosaic with the changed mosaic rule.
  mosaicImageSublayer.SetMosaicRule(mosaicRule);
});

Image Service Layers

Create an image service layer

ImageServiceLayer isLayer = null;
string url =
@"http://imagery.arcgisonline.com/arcgis/services/LandsatGLS/GLS2010_Enhanced/ImageServer";
await QueuedTask.Run(() =>
{
  // Create an image service layer using the url for an image service.
  isLayer = LayerFactory.Instance.CreateLayer(new Uri(url), aMap) as ImageServiceLayer;
});

Update the raster colorizer on an image service layer

await QueuedTask.Run(() =>
{
  // Get the colorizer from the image service layer.
  CIMRasterColorizer rasterColorizer = isLayer.GetColorizer();
  // Update the colorizer properties.
  rasterColorizer.Brightness = 10;
  rasterColorizer.Contrast = -5;
  rasterColorizer.ResamplingType = RasterResamplingType.NearestNeighbor;
  // Update the image service layer with the changed colorizer.
  isLayer.SetColorizer(rasterColorizer);
});

Update the RGB colorizer on an image service layer

await QueuedTask.Run(() =>
{
  // Get the colorizer from the image service layer.
  CIMRasterColorizer rColorizer = isLayer.GetColorizer();
  // Check if the colorizer is an RGB colorizer.
  if (rColorizer is CIMRasterRGBColorizer rasterRGBColorizer)
  {
    // Update RGB colorizer properties.
    rasterRGBColorizer.StretchType = RasterStretchType.ESRI;
    // Update the image service layer with the changed colorizer.
    isLayer.SetColorizer((CIMRasterColorizer)rasterRGBColorizer);
  }
});

Check if a certain colorizer can be applied to an image service layer

await QueuedTask.Run(() =>
{
  // Get the list of colorizers that can be applied to the imager service layer.
  IEnumerable<RasterColorizerType> applicableColorizerList = isLayer.GetApplicableColorizers();
  // Check if the RGB colorizer is part of the list.
  bool isTrue_ContainTheColorizerType =
    applicableColorizerList.Contains(RasterColorizerType.RGBColorizer);
});

Create a new colorizer based on a default colorizer definition and apply it to the image service layer

await QueuedTask.Run(async () =>
{
  // Check if the Stretch colorizer can be applied to the image service layer.
  if (isLayer.GetApplicableColorizers().Contains(RasterColorizerType.StretchColorizer))
  {
    // Create a new Stretch Colorizer Definition using the default constructor.
    StretchColorizerDefinition stretchColorizerDef_default = new StretchColorizerDefinition();
    // Create a new Stretch colorizer using the colorizer definition created above.
    CIMRasterStretchColorizer newStretchColorizer_default =
await isLayer.CreateColorizerAsync(stretchColorizerDef_default) as CIMRasterStretchColorizer;
    // Set the new colorizer on the image service layer.
    isLayer.SetColorizer(newStretchColorizer_default);
  }
});

Create a new colorizer based on a custom colorizer definition and apply it to the image service layer

await QueuedTask.Run(async () =>
{
  // Check if the Stretch colorizer can be applied to the image service layer.
  if (isLayer.GetApplicableColorizers().Contains(RasterColorizerType.StretchColorizer))
  {
    // Create a new Stretch Colorizer Definition specifying parameters
    // for band index, stretch type, gamma and color ramp. 
    StretchColorizerDefinition stretchColorizerDef_custom =
new StretchColorizerDefinition(1, RasterStretchType.ESRI, 2, colorRamp);
    // Create a new stretch colorizer using the colorizer definition created above.
    CIMRasterStretchColorizer newStretchColorizer_custom =
await isLayer.CreateColorizerAsync(stretchColorizerDef_custom) as CIMRasterStretchColorizer;
    // Set the new colorizer on the image service layer.
    isLayer.SetColorizer(newStretchColorizer_custom);
  }
});

Create an image service layer with a new colorizer definition

// Create a new colorizer definition using default constructor.
StretchColorizerDefinition stretchColorizerDef = new StretchColorizerDefinition();
var rasterLayerCreationParams = new RasterLayerCreationParams(new Uri(url))
{
  Name = layerName,
  ColorizerDefinition = stretchColorizerDef,
  MapMemberIndex = 0
};
await QueuedTask.Run(() =>
{
  // Create an image service layer using the colorizer definition created above.
  ImageServiceLayer imageServiceLayer =
    LayerFactory.Instance.CreateLayer<ImageServiceLayer>(rasterLayerCreationParams, aMap);
});

Update the sort order - mosaic method on an image service layer

await QueuedTask.Run(() =>
{
  // Get the mosaic rule of the image service.
  CIMMosaicRule mosaicRule = isLayer.GetMosaicRule();
  // Set the Mosaic Method to Center.
  mosaicRule.MosaicMethod = RasterMosaicMethod.Center;
  // Update the image service with the changed mosaic rule.
  isLayer.SetMosaicRule(mosaicRule);
});

Update the resolve overlap - mosaic operator on an image service layer

await QueuedTask.Run(() =>
{
  // Get the mosaic rule of the image service.
  CIMMosaicRule mosaicingRule = isLayer.GetMosaicRule();
  // Set the Mosaic Operator to Mean.
  mosaicingRule.MosaicOperatorType = RasterMosaicOperatorType.Mean;
  // Update the image service with the changed mosaic rule.
  isLayer.SetMosaicRule(mosaicingRule);
});

Working with Standalone Tables

Create a StandaloneTable

//container can be a map or group layer
var container = MapView.Active.Map;
//var container =  MapView.Active.Map.GetLayersAsFlattenedList()
//                                  .OfType<GroupLayer>().First();
QueuedTask.Run(() =>
{
  //use a local path
  var table = StandaloneTableFactory.Instance.CreateStandaloneTable(
new Uri(@"C:\Temp\Data\SDK.gdb\EarthquakeDamage", UriKind.Absolute),
container);
  //use a URI to a feature service table endpoint
  var table2 = StandaloneTableFactory.Instance.CreateStandaloneTable(
    new Uri(@"https://bexdog.esri.com/server/rest/services/FeatureServer" + "/2", UriKind.Absolute),
    container);
  //Use an item
  var item = ItemFactory.Instance.Create(@"C:\Temp\Data\SDK.gdb\ParcelOwners");
  var tableCreationParams = new StandaloneTableCreationParams(item);
  var table3 = StandaloneTableFactory.Instance.CreateStandaloneTable(tableCreationParams, container);

  //use table creation params
  var table_params = new StandaloneTableCreationParams(item)
  {
    // At 2.x - DefinitionFilter = new CIMDefinitionFilter()
    //{
    //  //optional - use a filter
    //  DefinitionExpression = "LAND_USE = 3"
    //}
    DefinitionQuery = new DefinitionQuery(whereClause: "LAND_USE = 3", name: "Landuse")
  };
  var table4 = StandaloneTableFactory.Instance.CreateStandaloneTable(table_params,
                           container);

});

Retrieve a table from its container

var container = MapView.Active.Map;

//the map standalone table collection
var table = container.GetStandaloneTablesAsFlattenedList()
                        .FirstOrDefault(tbl => tbl.Name == "EarthquakeDamage");

//or from a group layer
var grp_layer = MapView.Active.Map.FindLayers("GroupLayer1").First() as GroupLayer;
var table2 = grp_layer.FindStandaloneTables("EarthquakeDamage").First();
//or         grp_layer.GetStandaloneTablesAsFlattenedList().First()
//or         grp_layer.StandaloneTables.Where(...).First(), etc.

//show the table in a table view 
//use FrameworkApplication.Current.Dispatcher.BeginInvoke if not on the UI thread
FrameworkApplication.Panes.OpenTablePane(table2);

Move a Standalone table

//get the first group layer that has at least one table
var grp_layer = MapView.Active.Map.GetLayersAsFlattenedList()
  .OfType<GroupLayer>().First(g => g.StandaloneTables.Count > 0);
var map = MapView.Active.Map;//assumes non-null
QueuedTask.Run(() =>
{
  //move the first table to the bottom of the container
  grp_layer.MoveStandaloneTable(grp_layer.StandaloneTables.First(), -1);

  //move the last table in the map standalone tables to a group
  //layer and place it at position 3. If 3 is invalid, the table
  //will be placed at the bottom of the target container
  //assumes the map has at least one standalone table...
  var table = map.StandaloneTables.Last();
  map.MoveStandaloneTable(table, grp_layer, 3);

  //move a table from a group layer to the map standalone tables
  //collection - assumes a table called 'Earthquakes' exists
  var table2 = grp_layer.FindStandaloneTables("Earthquakes").First();
  //move to the map container
  map.MoveStandaloneTable(table2, 0);//will be placed at the top
});

Remove a Standalone table

//get the first group layer that has at least one table
var grp_layer = MapView.Active.Map.GetLayersAsFlattenedList()
  .OfType<GroupLayer>().First(g => g.StandaloneTables.Count > 0);
var map = MapView.Active.Map;//assumes non-null

QueuedTask.Run(() =>
{
  //get the tables from the map container
  var tables = map.GetStandaloneTablesAsFlattenedList();
  //delete the first...
  if (tables.Count() > 0)
  {
    map.RemoveStandaloneTable(tables.First());
    //or delete all of them
    map.RemoveStandaloneTables(tables);
  }

  //delete a table from a group layer
  //assumes it has at least one table...
  grp_layer.RemoveStandaloneTable(grp_layer.StandaloneTables.First());
});

SelectionSet

Translate From Dictionary to SelectionSet

//Create a selection set from a list of object ids
//using FromDictionary
var addToSelection = new Dictionary<MapMember, List<long>>();
addToSelection.Add(us_zips_layer, new List<long> { 1506, 2696, 2246, 1647, 948 });
var selSet =  ArcGIS.Desktop.Mapping.SelectionSet.FromDictionary(addToSelection);

Tranlate from SelectionSet to Dictionary

var selSetDict = selSet.ToDictionary();

// convert to the dictionary and only include those that are of type FeatureLayer
var selSetDictFeatureLayer = selSet.ToDictionary<FeatureLayer>();

Get OIDS from a SelectionSet for a given MapMember

if (selSet.Contains(us_zips_layer))
{
  var oids = selSet[us_zips_layer];
}

Get OIDS from a SelectionSet for a given MapMember by Name

var kvp = selSet.ToDictionary().Where(kvp => kvp.Key.Name == "LayerName").FirstOrDefault();
var oidList = kvp.Value;

Symbol Layer Drawing (SLD)

Add SLD

QueuedTask.Run(() =>
{
  //check if it can be added to the layer
  if (featLayer.CanAddSymbolLayerDrawing())
    featLayer.AddSymbolLayerDrawing();

  //ditto for a group layer...must have at least
  //one child feature layer that can participate
  if (groupLayer.CanAddSymbolLayerDrawing())
    groupLayer.AddSymbolLayerDrawing();
});

Determine if a layer has SLD added

//SLD can be added to feature layers and group layers
//For a group layer, SLD controls all child feature layers
//that are participating in the SLD

//var featLayer = ...;//retrieve the feature layer
//var groupLayer = ...;//retrieve the group layer
QueuedTask.Run(() =>
{
  //Check if the layer has SLD added -returns a tuple
  var tuple = featLayer.HasSymbolLayerDrawingAdded();
  if (tuple.addedOnLayer)
  {
    //SLD is added on the layer
  }
  else if (tuple.addedOnParent)
  {
    //SLD is added on the parent (group layer) - 
    //check parent...this can be recursive
    var parentLayer = GetParentLayerWithSLD(featLayer.Parent as GroupLayer);
    /*
     * 
   //Recursively get the parent with SLD
   public GroupLayer GetParentLayerWithSLD(GroupLayer groupLayer) 
   {
     if (groupLayer == null)
       return null;
     //Must be on QueuedTask
     var sld_added = groupLayer.HasSymbolLayerDrawingAdded();
     if (sld_added.addedOnLayer)
       return groupLayer;
     else if (sld_added.addedOnParent)
       return GetParentLayerWithSLD(groupLayer.Parent as GroupLayer);
     return null;
   }
  */
  }
});

Enable/Disable SLD

QueuedTask.Run(() =>
{
  //A layer may have SLD added but is not using it
  //HasSymbolLayerDrawingAdded returns a tuple - to check
  //the layer has SLD (not its parent) check addedOnLayer
  if (featLayer.HasSymbolLayerDrawingAdded().addedOnLayer)
  {
    //the layer has SLD but is the layer currently using it?
    //GetUseSymbolLayerDrawing returns a tuple - useOnLayer for 
    //the layer (and useOnParent for the parent layer)
    if (!featLayer.GetUseSymbolLayerDrawing().useOnLayer)
    {
      //enable it
      featLayer.SetUseSymbolLayerDrawing(true);
    }
  }

  //Enable/Disable SLD on a layer parent
  if (featLayer.HasSymbolLayerDrawingAdded().addedOnParent)
  {
    //check parent...this can be recursive
    var parent = GetParentLayerWithSLD(featLayer.Parent as GroupLayer);
    if (parent.GetUseSymbolLayerDrawing().useOnLayer)
      parent.SetUseSymbolLayerDrawing(true);
  }
  /*
   * 
   //Recursively get the parent with SLD
   public GroupLayer GetParentLayerWithSLD(GroupLayer groupLayer) 
   {
     if (groupLayer == null)
       return null;
     //Must be on QueuedTask
     var sld_added = groupLayer.HasSymbolLayerDrawingAdded();
     if (sld_added.addedOnLayer)
       return groupLayer;
     else if (sld_added.addedOnParent)
       return GetParentLayerWithSLD(groupLayer.Parent as GroupLayer);
     return null;
   }
  */
});

Device Location API, GPS/GNSS Devices

Connect to a Device Location Source

var newSrc = new SerialPortDeviceLocationSource();

//Specify the COM port the device is connected to
newSrc.ComPort = "Com3";
newSrc.BaudRate = 4800;
newSrc.AntennaHeight = 3;  // meters
                           //fill in other properties as needed

var props = new DeviceLocationProperties();
props.AccuracyThreshold = 10;   // meters

// jump to the background thread
await QueuedTask.Run(() =>
{
  //open the device
  DeviceLocationService.Instance.Open(newSrc, props);
});

Get the Current Device Location Source

var source = DeviceLocationService.Instance.GetSource();
if (source == null)
{
  //There is no current source
}

Close the Current Device Location Source

//Is there a current device source?
var src = DeviceLocationService.Instance.GetSource();
if (src == null)
  return;//no current source

await QueuedTask.Run(() =>
{
  DeviceLocationService.Instance.Close();
});

Get Current Device Location Source and Properties

bool isConnected = DeviceLocationService.Instance.IsDeviceConnected();

var src = DeviceLocationService.Instance.GetSource();

if (src is SerialPortDeviceLocationSource serialPortSrc)
{
  var port = serialPortSrc.ComPort;
  var antennaHeight = serialPortSrc.AntennaHeight;
  var dataBits = serialPortSrc.DataBits;
  var baudRate = serialPortSrc.BaudRate;
  var parity = serialPortSrc.Parity;
  var stopBits = serialPortSrc.StopBits;

  // retrieving spatial reference needs the MCT
  var sr = await QueuedTask.Run(() =>
  {
    return serialPortSrc.GetSpatialReference();
  });

}
var dlProps = DeviceLocationService.Instance.GetProperties();
var accuracy = dlProps.AccuracyThreshold;

Update Properties on the Current Device Location Source

await QueuedTask.Run(() =>
{
  var dlProps = DeviceLocationService.Instance.GetProperties();
  //Change the accuracy threshold
  dlProps.AccuracyThreshold = 22.5; // meters

  DeviceLocationService.Instance.UpdateProperties(dlProps);
});

Subscribe to DeviceLocationPropertiesUpdated event

private void SubscribeToPropertiesEvents()
{
  DeviceLocationPropertiesUpdatedEvent.Subscribe(OnDeviceLocationPropertiesUpdated);
}
private void OnDeviceLocationPropertiesUpdated(DeviceLocationPropertiesUpdatedEventArgs args)
{
  if (args == null)
    return;

  var properties = args.DeviceLocationProperties;

  //  TODO - something with the updated properties
}

Subscribe to DeviceLocationSourceChanged event

private void SubscribeToSourceEvents()
{
  DeviceLocationSourceChangedEvent.Subscribe(OnDeviceLocationSourceChanged);
}
private void OnDeviceLocationSourceChanged(DeviceLocationSourceChangedEventArgs args)
{
  if (args == null)
    return;

  var source = args.DeviceLocationSource;

  //  TODO - something with the updated source properties
}

Map Device Location Options

Enable/Disable Current Device Location Source For the Map

bool enabled = MapDeviceLocationService.Instance.IsDeviceLocationEnabled;

await QueuedTask.Run(() =>
{
  MapDeviceLocationService.Instance.SetDeviceLocationEnabled(!enabled);
});

Get Current Map Device Location Options

var options = MapDeviceLocationService.Instance.GetDeviceLocationOptions();

var visibility = options.DeviceLocationVisibility;
var navMode = options.NavigationMode;
var trackUp = options.TrackUpNavigation;
var showBuffer = options.ShowAccuracyBuffer;

Check if The Current Device Location Is Enabled On The Map

if (MapDeviceLocationService.Instance.IsDeviceLocationEnabled)
{
  //The Device Location Source is Enabled
}

Set Current Map Device Location Options

//Must be on the QueuedTask.Run()

//Check there is a source first...
if (DeviceLocationService.Instance.GetSource() == null)
  //Setting DeviceLocationOptions w/ no Device Location Source
  //Will throw an InvalidOperationException
  return;

var map = MapView.Active.Map;
if (!MapDeviceLocationService.Instance.IsDeviceLocationEnabled)
  //Setting DeviceLocationOptions w/ no Device Location Enabled
  //Will throw an InvalidOperationException
  return;

MapDeviceLocationService.Instance.SetDeviceLocationOptions(
  new MapDeviceLocationOptions()
  {
    DeviceLocationVisibility = true,
    NavigationMode = MappingDeviceLocationNavigationMode.KeepAtCenter,
    TrackUpNavigation = true
  });

Zoom/Pan The Map To The Most Recent Location

//Must be on the QueuedTask.Run()

if (!MapDeviceLocationService.Instance.IsDeviceLocationEnabled)
  //Calling ZoomOrPanToCurrentLocation w/ no Device Location Enabled
  //Will throw an InvalidOperationException
  return;

// true for zoom, false for pan
MapDeviceLocationService.Instance.ZoomOrPanToCurrentLocation(true);

Add the Most Recent Location To A Graphics Layer

//var graphicsLayer = ... ;
//Must be on the QueuedTask.Run()

// get the last location
var pt = DeviceLocationService.Instance.GetCurrentSnapshot()?.GetPositionAsMapPoint();
if (pt != null)
{
  //Create a point symbol
  var ptSymbol = SymbolFactory.Instance.ConstructPointSymbol(
                    CIMColor.CreateRGBColor(125, 125, 0), 10, SimpleMarkerStyle.Triangle);
  //Add a graphic to the graphics layer
  graphicsLayer.AddElement(pt, ptSymbol);
  //unselect it
  graphicsLayer.ClearSelection();
}

Set map view to always be centered on the device location

var currentOptions = MapDeviceLocationService.Instance.GetDeviceLocationOptions();
if (currentOptions == null)
  return;

currentOptions.DeviceLocationVisibility = true;
currentOptions.NavigationMode = MappingDeviceLocationNavigationMode.KeepAtCenter;

await QueuedTask.Run(() =>
{
  MapDeviceLocationService.Instance.SetDeviceLocationOptions(currentOptions);
});

Subscribe to Location Snapshot event

private void SubscribeToSnapshotEvents()
{
  SnapshotChangedEvent.Subscribe(OnSnapshotChanged);
}
private void OnSnapshotChanged(SnapshotChangedEventArgs args)
{
  if (args == null)
    return;

  var snapshot = args.Snapshot as NMEASnapshot;
  if (snapshot == null)
    return;

  QueuedTask.Run(() =>
  {
    var pt = snapshot.GetPositionAsMapPoint();
    if (pt?.IsEmpty ?? true)
      return;

    // access properties
    var alt = snapshot.Altitude;
    var dt = snapshot.DateTime;
    var vdop = snapshot.VDOP;
    var hdop = snapshot.HDOP;
    // etc

    //TODO: use the snapshot
  });
}

Feature Masking

Get the Mask Geometry for a Feature

var featureLayer = MapView.Active.Map.GetLayersAsFlattenedList()
                           .OfType<BasicFeatureLayer>().FirstOrDefault();
if (featureLayer == null)
  return;

var mv = MapView.Active;

QueuedTask.Run(() =>
{
  using (var table = featureLayer.GetTable())
  {
    using (var rc = table.Search())
    {
      //get the first feature...
      //...assuming at least one feature gets retrieved
      rc.MoveNext();
      var oid = rc.Current.GetObjectID();

      //Use DrawingOutlineType.BoundingEnvelope to retrieve a generalized
      //mask geometry or "Box". The mask will be in the same SpatRef as the map
      //At 2.x - var mask_geom = featureLayer.QueryDrawingOutline(oid, mv, DrawingOutlineType.Exact);
      var mask_geom = featureLayer.GetDrawingOutline(oid, mv, DrawingOutlineType.Exact);

      //TODO - use the mask geometry...
    }
  }
});

Style Management

How to get a style in project by name

//Get all styles in the project
var ProjectStyles = Project.Current.GetItems<StyleProjectItem>();

//Get a specific style in the project by name
StyleProjectItem style = ProjectStyles.First(x => x.Name == "NameOfTheStyle");

How to create a new style

//Full path for the new style file (.stylx) to be created
string styleToCreate = @"C:\Temp\NewStyle.stylx";
await QueuedTask.Run(() => StyleHelper.CreateStyle(Project.Current, styleToCreate));

How to add a style to project

//For ArcGIS Pro system styles, just pass in the name of the style to add to the project
await QueuedTask.Run(() => StyleHelper.AddStyle(Project.Current, "3D Vehicles"));

//For custom styles, pass in the full path to the style file on disk
string customStyleToAdd = @"C:\Temp\CustomStyle.stylx";
await QueuedTask.Run(() => StyleHelper.AddStyle(Project.Current, customStyleToAdd));

How to remove a style from project

//For ArcGIS Pro system styles, just pass in the name of the style to remove from the project
await QueuedTask.Run(() => StyleHelper.RemoveStyle(Project.Current, "3D Vehicles"));

//For custom styles, pass in the full path to the style file on disk
string customStyleToAdd = @"C:\Temp\CustomStyle.stylx";
await QueuedTask.Run(() => StyleHelper.RemoveStyle(Project.Current, customStyleToAdd));

How to add a style item to a style

public Task AddStyleItemAsync(StyleProjectItem style, StyleItem itemToAdd)
{
  return QueuedTask.Run(() =>
  {
    if (style == null || itemToAdd == null)
      throw new System.ArgumentNullException();

    //Add the item to style
    style.AddItem(itemToAdd);
  });
}

How to remove a style item from a style

public Task RemoveStyleItemAsync(StyleProjectItem style, StyleItem itemToRemove)
{
  return QueuedTask.Run(() =>
  {
    if (style == null || itemToRemove == null)
      throw new System.ArgumentNullException();

    //Remove the item from style
    style.RemoveItem(itemToRemove);
  });
}

How to determine if a style can be upgraded

//Pass in the full path to the style file on disk
public async Task<bool> CanUpgradeStyleAsync(string stylePath)
{
  //Add the style to the current project
  await QueuedTask.Run(() => StyleHelper.AddStyle(Project.Current, stylePath));
  StyleProjectItem style = Project.Current.GetItems<StyleProjectItem>().First(x => x.Path == stylePath);

  //returns true if style can be upgraded
  return style.CanUpgrade;
}

How to determine if a style is read-only

//Pass in the full path to the style file on disk
public async Task<bool> IsReadOnly(string stylePath)
{
  //Add the style to the current project
  await QueuedTask.Run(() => StyleHelper.AddStyle(Project.Current, stylePath));
  StyleProjectItem style = Project.Current.GetItems<StyleProjectItem>().First(x => x.Path == stylePath);

  //returns true if style is read-only
  return style.IsReadOnly;
}

How to determine if a style is current

//Pass in the full path to the style file on disk
public async Task<bool> IsCurrent(string stylePath)
{
  //Add the style to the current project
  await QueuedTask.Run(() => StyleHelper.AddStyle(Project.Current, stylePath));
  StyleProjectItem style = Project.Current.GetItems<StyleProjectItem>().First(x => x.Path == stylePath);

  //returns true if style matches the current Pro version
  return style.IsCurrent;
}

How to upgrade a style

//Pass in the full path to the style file on disk
public async Task<bool> UpgradeStyleAsync(string stylePath)
{
  bool success = false;

  //Add the style to the current project
  await QueuedTask.Run(() => StyleHelper.AddStyle(Project.Current, stylePath));
  StyleProjectItem style = Project.Current.GetItems<StyleProjectItem>().First(x => x.Path == stylePath);

  //Verify that style can be upgraded
  if (style.CanUpgrade)
  {
    success = await QueuedTask.Run(() => StyleHelper.UpgradeStyle(style));
  }
  //return true if style was upgraded
  return success;
}

Symbols

How to construct a point symbol of a specific color and size

await QueuedTask.Run(() =>
{
  CIMPointSymbol pointSymbol = SymbolFactory.Instance.ConstructPointSymbol(ColorFactory.Instance.RedRGB, 10.0);
});

How to construct a point symbol of a specific color, size and shape

await QueuedTask.Run(() =>
{
  CIMPointSymbol starPointSymbol = SymbolFactory.Instance.ConstructPointSymbol(ColorFactory.Instance.RedRGB, 10.0, SimpleMarkerStyle.Star);
});

How to construct a point symbol from a marker

await QueuedTask.Run(() =>
{
  CIMMarker marker = SymbolFactory.Instance.ConstructMarker(ColorFactory.Instance.GreenRGB, 8.0, SimpleMarkerStyle.Pushpin);
  CIMPointSymbol pointSymbolFromMarker = SymbolFactory.Instance.ConstructPointSymbol(marker);
});

How to construct a point symbol from a file on disk

//The following file formats can be used to create the marker: DAE, 3DS, FLT, EMF, JPG, PNG, BMP, GIF
CIMMarker markerFromFile = await QueuedTask.Run(() => SymbolFactory.Instance.ConstructMarkerFromFile(@"C:\Temp\fileName.dae"));

CIMPointSymbol pointSymbolFromFile = SymbolFactory.Instance.ConstructPointSymbol(markerFromFile);

How to construct a point symbol from a in memory graphic

//Create a stream for the image
//At 3.0 you need https://www.nuget.org/packages/Microsoft.Windows.Compatibility
//System.Drawing

System.Drawing.Image newImage = System.Drawing.Image.FromFile(@"C:\PathToImage\Image.png");
var stream = new System.IO.MemoryStream();
newImage.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
stream.Position = 0;
//Create marker using the stream
CIMMarker markerFromStream = SymbolFactory.Instance.ConstructMarkerFromStream(stream);
//Create the point symbol from the marker
CIMPointSymbol pointSymbolFromStream = SymbolFactory.Instance.ConstructPointSymbol(markerFromStream);

How to construct a polygon symbol of specific color and fill style

CIMPolygonSymbol polygonSymbol = SymbolFactory.Instance.ConstructPolygonSymbol(ColorFactory.Instance.RedRGB, SimpleFillStyle.Solid);

How to construct a polygon symbol of specific color, fill style and outline

CIMStroke outline = SymbolFactory.Instance.ConstructStroke(ColorFactory.Instance.BlueRGB, 2.0, SimpleLineStyle.Solid);
CIMPolygonSymbol fillWithOutline = SymbolFactory.Instance.ConstructPolygonSymbol(ColorFactory.Instance.RedRGB, SimpleFillStyle.Solid, outline);

How to construct a polygon symbol without an outline

CIMPolygonSymbol fillWithoutOutline = SymbolFactory.Instance.ConstructPolygonSymbol(ColorFactory.Instance.RedRGB, SimpleFillStyle.Solid, null);

How to construct a line symbol of specific color, size and line style

CIMLineSymbol lineSymbol = SymbolFactory.Instance.ConstructLineSymbol(ColorFactory.Instance.BlueRGB, 4.0, SimpleLineStyle.Solid);

How to construct a line symbol from a stroke

CIMStroke stroke = SymbolFactory.Instance.ConstructStroke(ColorFactory.Instance.BlackRGB, 2.0);
CIMLineSymbol lineSymbolFromStroke = SymbolFactory.Instance.ConstructLineSymbol(stroke);

How to construct a multilayer line symbol with circle markers on the line ends

//These methods must be called within the lambda passed to QueuedTask.Run
var lineStrokeRed = SymbolFactory.Instance.ConstructStroke(ColorFactory.Instance.RedRGB, 4.0);
var markerCircle = SymbolFactory.Instance.ConstructMarker(ColorFactory.Instance.RedRGB, 12, SimpleMarkerStyle.Circle);
markerCircle.MarkerPlacement = new CIMMarkerPlacementOnVertices()
{
  AngleToLine = true,
  PlaceOnEndPoints = true,
  Offset = 0
};
var lineSymbolWithCircles = new CIMLineSymbol()
{
  SymbolLayers = new CIMSymbolLayer[2] { markerCircle, lineStrokeRed }
};

How to construct a multilayer line symbol with an arrow head on the end

//These methods must be called within the lambda passed to QueuedTask.Run
var markerTriangle = SymbolFactory.Instance.ConstructMarker(ColorFactory.Instance.RedRGB, 12, SimpleMarkerStyle.Triangle);
markerTriangle.Rotation = -90; // or -90
markerTriangle.MarkerPlacement = new CIMMarkerPlacementOnLine() { AngleToLine = true, RelativeTo = PlacementOnLineRelativeTo.LineEnd };

var lineSymbolWithArrow = new CIMLineSymbol()
{
  SymbolLayers = new CIMSymbolLayer[2] { markerTriangle,
              SymbolFactory.Instance.ConstructStroke(ColorFactory.Instance.RedRGB, 2)
          }
};

How to get symbol reference from a symbol

CIMPolygonSymbol symbol = SymbolFactory.Instance.ConstructPolygonSymbol(ColorFactory.Instance.RedRGB);

//Get symbol reference from the symbol
CIMSymbolReference symbolReference = symbol.MakeSymbolReference();

Modify a point symbol created from a character marker

//create marker from the Font, char index,size,color
var cimMarker = SymbolFactory.Instance.ConstructMarker(125, "Wingdings 3", "Regular", 6, ColorFactory.Instance.BlueRGB) as CIMCharacterMarker;
  var polygonMarker = cimMarker.Symbol;
  //modifying the polygon's outline and fill
  //This is the outline
  polygonMarker.SymbolLayers[0] = SymbolFactory.Instance.ConstructStroke(ColorFactory.Instance.GreenRGB, 2, SimpleLineStyle.Solid);
  //This is the fill
  polygonMarker.SymbolLayers[1] = SymbolFactory.Instance.ConstructSolidFill(ColorFactory.Instance.BlueRGB);
  //create a symbol from the marker 
  //Note this overload of ConstructPointSymbol does not need to be run within QueuedTask.Run.
  var pointSymbol = SymbolFactory.Instance.ConstructPointSymbol(cimMarker);

Get a List of Available Fonts

//Must use QueuedTask.Run(...)
//returns a tuple per font: (string fontName, List<string> fontStyles)
var fonts = SymbolFactory.Instance.GetAvailableFonts();
foreach(var font in fonts)
      {
  var styles = string.Join(",", font.fontStyles);
  System.Diagnostics.Debug.WriteLine($"{font.fontName}, styles: {styles}");
      }

Get/Set Default Font

//Must use QueuedTask.Run(...)
var def_font = SymbolFactory.Instance.DefaultFont;
System.Diagnostics.Debug.WriteLine($"{def_font.fontName}, styles: {def_font.styleName}");

//set default font - set through application options
//Must use QueuedTask
ApplicationOptions.TextAndGraphicsElementsOptions.SetDefaultFont("tahoma");
ApplicationOptions.TextAndGraphicsElementsOptions.SetDefaultFont("tahoma","bold");

Construct a Text Symbol With Options

QueuedTask.Run(() =>
{
  //using the default font
  var textSym1 = SymbolFactory.Instance.ConstructTextSymbol();
  var textSym2 = SymbolFactory.Instance.ConstructTextSymbol(
                     ColorFactory.Instance.BlueRGB, 14);

  //using a specific font
  var textSym3 = SymbolFactory.Instance.ConstructTextSymbol("Arial");
  var textSym4 = SymbolFactory.Instance.ConstructTextSymbol(
                    "Arial", "Narrow Bold");

  //or query available fonts to ensure the font is there
  var all_fonts = SymbolFactory.Instance.GetAvailableFonts();
  var font = all_fonts.FirstOrDefault(f => f.fontName == "Arial");
  if (!string.IsNullOrEmpty(font.fontName))
  {
    var textSym5 = SymbolFactory.Instance.ConstructTextSymbol(font.fontName);
    //or with a font+style
    var textSym6 = SymbolFactory.Instance.ConstructTextSymbol(
                                    font.fontName, font.fontStyles.First());
  }

  //overloads - font + color and size, etc
  var textSym7 = SymbolFactory.Instance.ConstructTextSymbol(
                  ColorFactory.Instance.BlueRGB, 14, "Times New Roman", "Italic");

  //custom symbol - black stroke, red fill
  var poly_symbol = SymbolFactory.Instance.ConstructPolygonSymbol(
    SymbolFactory.Instance.ConstructSolidFill(ColorFactory.Instance.RedRGB),
    SymbolFactory.Instance.ConstructStroke(ColorFactory.Instance.BlackRGB, 1));
  var textSym8 = SymbolFactory.Instance.ConstructTextSymbol(
          poly_symbol, 14, "Georgia", "Bold");

});

Create a Swatch for a given symbol

//Note: call within QueuedTask.Run()
CIMSymbol symbol = SymbolFactory.Instance.ConstructPointSymbol(ColorFactory.Instance.GreenRGB, 1.0, SimpleMarkerStyle.Circle);
  //You can generate a swatch for a text symbols also.
  var si = new SymbolStyleItem()
  {
      Symbol = symbol,
      PatchHeight = 64,
      PatchWidth = 64
  };
  return si.PreviewImage;

Lookup Symbol

//Note: Run within QueuedTask.Run
//Get the selection
var selection = featureLayer.GetSelection();
  //Get the first Object ID
  var firstOID = selection.GetObjectIDs().FirstOrDefault();
  //Determine whether the layer's renderer type supports symbol lookup.
  if (featureLayer.CanLookupSymbol())
  {
      //Looks up the symbol for the corresponding feature identified by the object id.
      var symbol = featureLayer.LookupSymbol(firstOID, MapView.Active);
      var jSon = symbol.ToJson(); //Create a JSON encoding of the symbol
      //Do something with symbol
  }

Symbol Search

How to search for a specific item in a style

public Task<SymbolStyleItem> GetSymbolFromStyleAsync(StyleProjectItem style, string key)
{
  return QueuedTask.Run(() =>
  {
    if (style == null)
        throw new System.ArgumentNullException();

    //Search for a specific point symbol in style
    SymbolStyleItem item = (SymbolStyleItem)style.LookupItem(StyleItemType.PointSymbol, key);
    return item;
  });
}

How to search for point symbols in a style

public Task<IList<SymbolStyleItem>> GetPointSymbolsFromStyleAsync(StyleProjectItem style, string searchString)
{
  if (style == null)
    throw new System.ArgumentNullException();

  //Search for point symbols
  return QueuedTask.Run(() => style.SearchSymbols(StyleItemType.PointSymbol, searchString));
}

How to search for line symbols in a style

public Task<IList<SymbolStyleItem>> GetLineSymbolsFromStyleAsync(StyleProjectItem style, string searchString)
{
  if (style == null)
    throw new System.ArgumentNullException();

  //Search for line symbols
  return QueuedTask.Run(() => style.SearchSymbols(StyleItemType.LineSymbol, searchString));
}

How to search for polygon symbols in a style

public async Task<IList<SymbolStyleItem>> GetPolygonSymbolsFromStyleAsync(StyleProjectItem style, string searchString)
{
  if (style == null)
    throw new System.ArgumentNullException();

  //Search for polygon symbols
  return await QueuedTask.Run(() => style.SearchSymbols(StyleItemType.PolygonSymbol, searchString));
}

How to search for colors in a style

public async Task<IList<ColorStyleItem>> GetColorsFromStyleAsync(StyleProjectItem style, string searchString)
{
  if (style == null)
    throw new System.ArgumentNullException();

  //Search for colors
  return await QueuedTask.Run(() => style.SearchColors(searchString));
}

How to search for color ramps in a style

public async Task<IList<ColorRampStyleItem>> GetColorRampsFromStyleAsync(StyleProjectItem style, string searchString)
{
  //StyleProjectItem can be "ColorBrewer Schemes (RGB)", "ArcGIS 2D"...
  if (style == null)
    throw new System.ArgumentNullException();

  //Search for color ramps
  //Color Ramp searchString can be "Spectral (7 Classes)", "Pastel 1 (3 Classes)", "Red-Gray (10 Classes)"..
  return await QueuedTask.Run(() => style.SearchColorRamps(searchString));
}

How to search for north arrows in a style

public Task<IList<NorthArrowStyleItem>> GetNorthArrowsFromStyleAsync(StyleProjectItem style, string searchString)
{
  if (style == null)
    throw new System.ArgumentNullException();

  //Search for north arrows
  return QueuedTask.Run(() => style.SearchNorthArrows(searchString));
}

How to search for scale bars in a style

public Task<IList<ScaleBarStyleItem>> GetScaleBarsFromStyleAsync(StyleProjectItem style, string searchString)
{
  if (style == null)
    throw new System.ArgumentNullException();

  //Search for scale bars
  return QueuedTask.Run(() => style.SearchScaleBars(searchString));
}

How to search for label placements in a style

public Task<IList<LabelPlacementStyleItem>> GetLabelPlacementsFromStyleAsync(StyleProjectItem style, string searchString)
{
  if (style == null)
    throw new System.ArgumentNullException();

  //Search for standard label placement
  return QueuedTask.Run(() => style.SearchLabelPlacements(StyleItemType.StandardLabelPlacement, searchString));
}

How to search for legends in a style

public Task<IList<LegendStyleItem>> GetLegendFromStyleAsync(StyleProjectItem style, string searchString)
{
  if (style == null)
    throw new System.ArgumentNullException();

  return QueuedTask.Run(() => style.SearchLegends(searchString));
}

How to search for legend items in a style

public Task<IList<LegendItemStyleItem>> GetLegendItemsFromStyleAsync(StyleProjectItem style, string searchString)
{
  if (style == null)
    throw new System.ArgumentNullException();

  return QueuedTask.Run(() => style.SearchLegendItems(searchString));
}

How to search for grids in a style

public Task<IList<GridStyleItem>> GetGridsFromStyleAsync(StyleProjectItem style, string searchString)
{
  if (style == null)
    throw new System.ArgumentNullException();

  return QueuedTask.Run(() => style.SearchGrids(searchString));
}

How to search for map surrounds in a style

public Task<IList<MapSurroundStyleItem>> GetMapSurroundsFromStyleAsync(StyleProjectItem style, string searchString)
{
  if (style == null)
    throw new System.ArgumentNullException();

  return QueuedTask.Run(() => style.SearchMapSurrounds(searchString));
}

How to search for table frames in a style

public Task<IList<TableFrameStyleItem>> GetTableFramesFromStyleAsync(StyleProjectItem style, string searchString)
{
  if (style == null)
    throw new System.ArgumentNullException();

  return QueuedTask.Run(() => style.SearchTableFrames(searchString));
}

How to search for table frame fields in a style

public Task<IList<TableFrameFieldStyleItem>> GetTableFrameFieldsFromStyleAsync(StyleProjectItem style, string searchString)
{
  if (style == null)
    throw new System.ArgumentNullException();

  return QueuedTask.Run(() => style.SearchTableFrameFields(searchString));
}

Feature Layer Symbology

How to set symbol for a feature layer symbolized with simple renderer

public Task SetFeatureLayerSymbolAsync(FeatureLayer ftrLayer, CIMSymbol symbolToApply)
{
  if (ftrLayer == null || symbolToApply == null)
    throw new System.ArgumentNullException();

  return QueuedTask.Run(() =>
  {

    //Get simple renderer from the feature layer
    CIMSimpleRenderer currentRenderer = ftrLayer.GetRenderer() as CIMSimpleRenderer;
    if (currentRenderer == null)
      return;

    //Set symbol's real world setting to be the same as that of the feature layer
    symbolToApply.SetRealWorldUnits(ftrLayer.UsesRealWorldSymbolSizes);

    //Update the symbol of the current simple renderer
    currentRenderer.Symbol = symbolToApply.MakeSymbolReference();
    //Update the feature layer renderer
    ftrLayer.SetRenderer(currentRenderer);
  });
}

How to apply a symbol from style to a feature layer

public Task SetFeatureLayerSymbolFromStyleItemAsync(
           FeatureLayer ftrLayer, SymbolStyleItem symbolItem)
{
  if (ftrLayer == null || symbolItem == null)
    throw new System.ArgumentNullException();

  return QueuedTask.Run(() =>
  {
    //Get simple renderer from the feature layer
    CIMSimpleRenderer currentRenderer = ftrLayer.GetRenderer() as CIMSimpleRenderer;
    if (currentRenderer == null)
      return;
    //Get symbol from the SymbolStyleItem
    CIMSymbol symbol = symbolItem.Symbol;

    //Set symbol's real world setting to be the same as that of the feature layer
    symbol.SetRealWorldUnits(ftrLayer.UsesRealWorldSymbolSizes);

    //Update the symbol of the current simple renderer
    currentRenderer.Symbol = symbol.MakeSymbolReference();
    //Update the feature layer renderer
    ftrLayer.SetRenderer(currentRenderer);
  });
}

How to apply a point symbol from a style to a feature layer

// var map = MapView.Active.Map;
// if (map == null)
//        return;
// var pointFeatureLayer =
//       map.GetLayersAsFlattenedList()
//          .OfType<FeatureLayer>()
//         .Where(fl => fl.ShapeType == esriGeometryType.esriGeometryPoint);
//   await ApplySymbolToFeatureLayerAsync(pointFeatureLayer.FirstOrDefault(), "Fire Station");

public Task ApplySymbolToFeatureLayerAsync(FeatureLayer featureLayer, string symbolName)
{
  return QueuedTask.Run(async () =>
  {
    //Get the ArcGIS 2D System style from the Project
    var arcGIS2DStyle =
  Project.Current.GetItems<StyleProjectItem>().FirstOrDefault(s => s.Name == "ArcGIS 2D");

    //Search for the symbolName style items within the ArcGIS 2D style project item.
    var items = await QueuedTask.Run(() =>
    arcGIS2DStyle.SearchSymbols(StyleItemType.PointSymbol, symbolName));

    //Gets the CIMSymbol
    CIMSymbol symbol = items.FirstOrDefault().Symbol;

    //Get the renderer of the point feature layer
    CIMSimpleRenderer renderer = featureLayer.GetRenderer() as CIMSimpleRenderer;

    //Set symbol's real world setting to be the same as that of the feature layer
    symbol.SetRealWorldUnits(featureLayer.UsesRealWorldSymbolSizes);

    //Apply the symbol to the feature layer's current renderer
    renderer.Symbol = symbol.MakeSymbolReference();

    //Appy the renderer to the feature layer
    featureLayer.SetRenderer(renderer);
  });
}

How to apply a color ramp from a style to a feature layer

public async Task ApplyColorRampAsync(FeatureLayer featureLayer, List<string> fields)
{

    StyleProjectItem style =
        Project.Current.GetItems<StyleProjectItem>()
            .FirstOrDefault(s => s.Name == "ColorBrewer Schemes (RGB)");
    if (style == null) return;
    var colorRampList = await QueuedTask.Run(() => 
                style.SearchColorRamps("Red-Gray (10 Classes)"));
    if (colorRampList == null || colorRampList.Count == 0) return;
    CIMColorRamp cimColorRamp = null;
    CIMRenderer renderer = null;
    await QueuedTask.Run(() =>
    {
        cimColorRamp = colorRampList[0].ColorRamp;
        var rendererDef = new UniqueValueRendererDefinition(fields, null, cimColorRamp);
        renderer = featureLayer?.CreateRenderer(rendererDef);
        featureLayer?.SetRenderer(renderer);
    });

}

Home

ProSnippets: MapAuthoring

Clone this wiki locally