I have been trying to save the CIMFeatureLayer, Renderer, Symbol as text and load it later. But all failed with error like can not create instance of abstract class.
Here is an example code with CIMFeatureLayer:
var cimLayer = mapLayer.GetDefinition() as CIMFeatureLayer;
String xmlSymbology = JsonConvert.SerializeObject(cimLayer);
CIMFeatureLayer layer2 = JsonConvert.DeserializeObject<CIMFeatureLayer>(xmlSymbology);
mapLayer.SetDefinition(layer2);
What's the best practice for this task with ArcGIS Pro SDK?
Solved! Go to Solution.
Lyrx is a pure text solution - xml:
{
"type" : "CIMLayerDocument",
"version" : "1.1.0",
"build" : 3219,
"layers" : [
"CIMPATH=map/meteoritesuk.xml"
],
"layerDefinitions" : [
{
"type" : "CIMFeatureLayer",
"name" : "MeteoritesUK",
"uRI" : "CIMPATH=map/meteoritesuk.xml",
"sourceModifiedTime" : {
"type" : "TimeInstant"
},
"description" : "MeteoritesUK",
"layerElevation" : {
"type" : "CIMLayerElevationSurface",
"mapElevationID" : "{D9EFA120-D6D6-4152-8711-6765DCCF05C5}"
},
"expanded" : true,
"layerType" : "Operational",
"showLegends" : true,
"visibility" : true,
"displayCacheType" : "Permanent",
"maxDisplayCacheAge" : 5,
"showPopups" : true,
"autoGenerateFeatureTemplates" : true,
"featureTable" : {
"type" : "CIMFeatureTable",
"displayField" : "NAME",
"editable" : true,
"dataConnection" : {
"type" : "CIMStandardDataConnection",
"workspaceConnectionString" : "DATABASE=.\\SDK.gdb",
"workspaceFactory" : "FileGDB",
"dataset" : "MeteoritesUK",
"datasetType" : "esriDTFeatureClass"
},
"studyAreaSpatialRel" : "esriSpatialRelUndefined",
"searchOrder" : "esriSearchOrderSpatial"
},
Hi,
I would recommend you use Esri lyrx format to save layer and load it later. More info here.
Hi,
Thank you for the reply! For my case, a pure text solution would be way better as it doesn't require change of existing addin architecture as all of other info are saved as a xml. In ArcMap, we had this solution
// Save renderer as hex
hex = SaveToHex((ESRI.ArcGIS.esriSystem.IPersistStream)(((ESRI.ArcGIS.Carto.IGeoFeatureLayer)layerObj).Renderer));
// Load renderer from hex
renderer = LoadFromHex(data);
((ESRI.ArcGIS.Carto.IGeoFeatureLayer)layerObj).Renderer = (ESRI.ArcGIS.Carto.IFeatureRenderer)renderer;
Is there an equivalent class of IGeoFeatureLayer in ArcGIS Pro SDK?
Lyrx is a pure text solution - xml:
{
"type" : "CIMLayerDocument",
"version" : "1.1.0",
"build" : 3219,
"layers" : [
"CIMPATH=map/meteoritesuk.xml"
],
"layerDefinitions" : [
{
"type" : "CIMFeatureLayer",
"name" : "MeteoritesUK",
"uRI" : "CIMPATH=map/meteoritesuk.xml",
"sourceModifiedTime" : {
"type" : "TimeInstant"
},
"description" : "MeteoritesUK",
"layerElevation" : {
"type" : "CIMLayerElevationSurface",
"mapElevationID" : "{D9EFA120-D6D6-4152-8711-6765DCCF05C5}"
},
"expanded" : true,
"layerType" : "Operational",
"showLegends" : true,
"visibility" : true,
"displayCacheType" : "Permanent",
"maxDisplayCacheAge" : 5,
"showPopups" : true,
"autoGenerateFeatureTemplates" : true,
"featureTable" : {
"type" : "CIMFeatureTable",
"displayField" : "NAME",
"editable" : true,
"dataConnection" : {
"type" : "CIMStandardDataConnection",
"workspaceConnectionString" : "DATABASE=.\\SDK.gdb",
"workspaceFactory" : "FileGDB",
"dataset" : "MeteoritesUK",
"datasetType" : "esriDTFeatureClass"
},
"studyAreaSpatialRel" : "esriSpatialRelUndefined",
"searchOrder" : "esriSearchOrderSpatial"
},
That's wonderful! Do you have any sample code for this? Thank you in advance!
Savint to lyrx:
LayerDocument layerDocument = new LayerDocument(layer);
layerDocument.Save(@"c:\Data\MyLayerDocument.lyrx");
Opening from lyrx:
//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);
Modifying existing layer symbology using lyrx:
private static async Task ModifyLayerSymbologyFromLyrFileAsync(FeatureLayer featureLayer, string layerFile)
{
await QueuedTask.Run(() => {
//Does layer file exist
if (!System.IO.File.Exists(layerFile))
return;
//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 CIMSimpleRenderer;
if (rendererFromLayerFile == null)
return;
//Apply the renderer to the feature layer
featureLayer?.SetRenderer(rendererFromLayerFile);
});
}
Thank you so much!