I am currently having difficulty with getting symbology to show in the Pro table of contents for a polygon layer that I have added to the map programmatically (in C#). When I attempt to click the drop-down button to see the symbology for the layer, which is a transparent blue outline for the polygons, I am unable to see anything in the table of contents. I also click on the Symbology option for the layer in order to bring up the Symbology dock pane and the symbol is not there either. There is, however, an error that displays at the top of the Symbology dock pane. There is clearly something wrong with this layer. The strange thing is that I have other layers that I create programmatically that do display their symbology without any problems. The only difference between them is that the layers that are working are written out to a file geodatabase on disk, whereas the layer that doesn't display symbology is an in-memory feature class that is not written to disk. Is there a known issue with symbology and in-memory feature classes? Could this be my problem? If so, are there any workarounds, or if not is there something that I could be doing wrong in creating this layer that would cause the transparent blue outline of the polygons to not display in the table of contents or the Symbology dock pane?
Solved! Go to Solution.
Hi,
Thanks for the code and the error string.
I don't see any problems with your feature class creation code nor the way you are constructing the renderer for the layer. But I do have concerns about the CreateCurrentImageryFootprintLayerDefinition method and how / where you are using the return CIMFeatureLayer value. - if at all.
Just to confirm that you are creating the layer using the LayerFactory CreateLayer method (https://pro.arcgis.com/en/pro-app/latest/sdk/api-reference/topic76685.html)
Here's an example of adding a feature class to a map
// get the fc
var fc = geodatabase.OpenDataset<FeatureClass>(name);
CIMRGBColor fillColor = new() { R = 0, G = 0, B = 255, Alpha = 0 };
CIMRGBColor outlineColor = new() { R = 0, G = 0, B = 255 };
CIMSolidStroke solidStroke = new() { Color = outlineColor, Width = 1.5 };
var polySymbol = ArcGIS.Desktop.Mapping.SymbolFactory.Instance.ConstructPolygonSymbol(fillColor, SimpleFillStyle.Null, solidStroke);
var rd = new ArcGIS.Desktop.Mapping.SimpleRendererDefinition()
{
Label ="Imagery footprints",
SymbolTemplate = polySymbol.MakeSymbolReference()
};
var fLayerParams = new ArcGIS.Desktop.Mapping.FeatureLayerCreationParams(fc)
{
Name = "Current Imagery Footprints",
RendererDefinition = rd,
};
var fLayer = ArcGIS.Desktop.Mapping.LayerFactory.Instance.CreateLayer<ArcGIS.Desktop.Mapping.FeatureLayer>(fLayerParams, ArcGIS.Desktop.Mapping.MapView.Active.Map);
We don't have every property available to set on the FeatureLayerCreationParams so if you need to update additional properties after the layer has been added then add the following
// update the rest of the layer properties as necessary
var fLayerDef = fLayer.GetDefinition() as CIMFeatureLayer;
// fLayerDef.ShowLegends = false; // this causes the warning
fLayerDef.Selectable = false;
fLayerDef.Description = "Current Custom Imagery Footprints";
fLayerDef.CustomProperties = new CIMStringMap[] { new() { Key = "IsCustomLayer", Value = "True" } };
fLayer.SetDefinition(fLayerDef);
In your particular case it appears that the ShowLegends is the property that is causing the Symbology Pane to display the warning. I believe that this should be true. If you wish to hide the symbol in the TOC then the best way to do that is to use the layer SetExpanded method (https://pro.arcgis.com/en/pro-app/latest/sdk/api-reference/topic11772.html)
Let me know if you have any additional questions.
Narelle
Narelle,
So, it turns out that the problem was not having ShowLegends and Expanded set to true. I made that change to set ShowLegends to true at one point, but it didn't work. I forgot that there was another method elsewhere in the code that set it back to false. That was what was causing my problem. I also didn't never had the Expanded property set to true. That was also an issue.
I had a feeling that the fix would be something simple that I was missing.
Thank you for all your help!
Hi,
Are you able to post the error that displays at the top of the Symbology pane.
Also any code with your symbology generation and the way the feature class is generated in the memory geodatabase.
Thanks
Narelle
Narelle,
Thank you for your response. The error message that shows up at the top of the Symbology pane simply says, "Requested operation could not be completed." I hope that is helpful.
The following is the code that I am using to create the in-memory feature class:
internal void CreateFeatureClass()
{
_datastoreFacade ??= DatastoreFacade.Create("CustomMemoryDatastore"); //If the datastore facade hasn't been initialized yet, then create it.
FeatureClassDescription featureClassDescription = GetFeatureClassDescription();
using (Geodatabase memGeodatabase = _datastoreFacade.ToDatastore<Geodatabase>())
{
SchemaBuilder schemaBuild = new(memGeodatabase);
//Check to see if the memory database has a feature class with the name we are after.
if (_datastoreFacade.HasDataset<FeatureClass>("Current_Imagery_Footprint"))
{
//If it already exists, then delete it so we can change it.
using (FeatureClass oldFeatureClass = _datastoreFacade.GetFeatureClass("Current_Imagery_Footprint"))
using (FeatureClassDefinition oldDef = oldFeatureClass.GetDefinition())
{
schemaBuild.Delete(new FeatureClassDescription(oldDef));
}
}
//Now create the new one.
schemaBuild.Create(featureClassDescription);
schemaBuild.Build();
}
_imageryCollectionChangedToken = ImageryCollectionChangedEvent.Subscribe(OnImageryCollectionChanged);
}
internal T ToDatastore<T>() where T : Datastore => OpenDatastore() as T;
internal bool HasDataset<T>(string datasetName) where T : Dataset
{
Dictionary<Type, Func<string, Definition>> definitionDict = new()
{
{typeof(CadDataset), (itemName) => GetDefinition<CadDatasetDefinition>(itemName) },
{typeof(FeatureDataset), (itemName) => GetDefinition<FeatureDatasetDefinition>(itemName) },
{typeof(ParcelFabric), (itemName) => GetDefinition<ParcelFabricDefinition>(itemName) },
{typeof(RasterBand), (itemName) => GetDefinition<RasterBandDefinition>(itemName) },
{typeof(RasterDataset), (itemName) => GetDefinition<RasterDatasetDefinition>(itemName) },
{typeof(AttributedRelationshipClass), (itemName) => GetDefinition<AttributedRelationshipClassDefinition>(itemName)},
{typeof(RelationshipClass), (itemName) => GetDefinition<RelationshipClassDefinition>(itemName)},
{typeof(Topology), (itemName) => GetDefinition<TopologyDefinition>(itemName)},
{typeof(FeatureClass), (itemName) => GetDefinition<FeatureClassDefinition>(itemName)},
{typeof(RealtimeTable), (itemName) => GetDefinition<RealtimeTableDefinition>(itemName)},
{typeof(Table), (itemName) => GetDefinition<TableDefinition>(itemName)},
{typeof(UtilityNetwork), (itemName) => GetDefinition<UtilityNetworkDefinition>(itemName)}
};
Definition definition = definitionDict[typeof(T)](datasetName);
return definition is not null;
}
private FeatureClassDescription GetFeatureClassDescription()
{
FeatureClassDescriptionBuilder featClassBuilder = new("Current_Imagery_Footprint");
featClassBuilder.AddGeometryField("shape", GeometryType.Polygon, SpatialReferences.WGS84);
featClassBuilder.AddObjectIDField();
//Now cycle through all the properties in the type and return field descriptions for them.
foreach (PropertyInfo prop in _metadataItemType.GetProperties())
{
if (prop.PropertyType == typeof(string) || prop.PropertyType == typeof(bool)) { featClassBuilder.AddStringField(prop.Name, prop.Name, 255); }
else if (prop.PropertyType == typeof(double)) { featClassBuilder.AddDoubleField(prop.Name, prop.Name, 0, 0); }
else if (prop.PropertyType == typeof(int)) { featClassBuilder.AddIntegerField(prop.Name, prop.Name, 0); }
else if (prop.PropertyType == typeof(DateTime)) { featClassBuilder.AddDateTimeField(prop.Name, prop.Name); }
else { continue; }
}
return featClassBuilder.Build();
}
private static CIMFeatureLayer CreateCurrentImageryFootprintLayerDefinition(FeatureClass currentFootprintFC)
{
//Get the CIMFeatureTable for this feature class.
CIMFeatureTable sourceFeatureTable = new()
{
DataConnection = currentFootprintFC.GetDataConnection(),
Editable = false
};
//Build the layer definition including the renderer to use.
CIMFeatureLayer featureLayerDefinition = new()
{
Name = "Current Imagery Footprints",
Description = "Current Custom Imagery Footprints",
Selectable = false, //Make the layer not selectable when clicking on the map.
FeatureTable = sourceFeatureTable,
Renderer = GetSimpleRenderer(),
ShowLegends = false,
URI = "CIMPATH=map/custom_current_imagery_footprints.json",
CustomProperties = new CIMStringMap[] { new() { Key = "IsCustomLayer", Value = "True" } }
};
return featureLayerDefinition;
}
private static CIMSimpleRenderer GetSimpleRenderer()
{
CIMRGBColor fillColor = new() { R = 0, G = 0, B = 255, Alpha = 0 };
CIMRGBColor outlineColor = new() { R = 0, G = 0, B = 255 };
CIMSolidStroke solidStroke = new() { Color = outlineColor, Width = 1.5 };
return new CIMSimpleRenderer()
{
Label = "Imagery Footprints",
Symbol = SymbolFactory.Instance.ConstructPolygonSymbol(fillColor, SimpleFillStyle.Null, solidStroke).MakeSymbolReference()
};
}
As you can tell, there is a lot of code that goes in to creating the in-memory feature class. I tried to include all of the necessary code. However, it is broken up into multiple classes, so I might have missed something. Please let me know if you need any further code or information.
Hi,
Thanks for the code and the error string.
I don't see any problems with your feature class creation code nor the way you are constructing the renderer for the layer. But I do have concerns about the CreateCurrentImageryFootprintLayerDefinition method and how / where you are using the return CIMFeatureLayer value. - if at all.
Just to confirm that you are creating the layer using the LayerFactory CreateLayer method (https://pro.arcgis.com/en/pro-app/latest/sdk/api-reference/topic76685.html)
Here's an example of adding a feature class to a map
// get the fc
var fc = geodatabase.OpenDataset<FeatureClass>(name);
CIMRGBColor fillColor = new() { R = 0, G = 0, B = 255, Alpha = 0 };
CIMRGBColor outlineColor = new() { R = 0, G = 0, B = 255 };
CIMSolidStroke solidStroke = new() { Color = outlineColor, Width = 1.5 };
var polySymbol = ArcGIS.Desktop.Mapping.SymbolFactory.Instance.ConstructPolygonSymbol(fillColor, SimpleFillStyle.Null, solidStroke);
var rd = new ArcGIS.Desktop.Mapping.SimpleRendererDefinition()
{
Label ="Imagery footprints",
SymbolTemplate = polySymbol.MakeSymbolReference()
};
var fLayerParams = new ArcGIS.Desktop.Mapping.FeatureLayerCreationParams(fc)
{
Name = "Current Imagery Footprints",
RendererDefinition = rd,
};
var fLayer = ArcGIS.Desktop.Mapping.LayerFactory.Instance.CreateLayer<ArcGIS.Desktop.Mapping.FeatureLayer>(fLayerParams, ArcGIS.Desktop.Mapping.MapView.Active.Map);
We don't have every property available to set on the FeatureLayerCreationParams so if you need to update additional properties after the layer has been added then add the following
// update the rest of the layer properties as necessary
var fLayerDef = fLayer.GetDefinition() as CIMFeatureLayer;
// fLayerDef.ShowLegends = false; // this causes the warning
fLayerDef.Selectable = false;
fLayerDef.Description = "Current Custom Imagery Footprints";
fLayerDef.CustomProperties = new CIMStringMap[] { new() { Key = "IsCustomLayer", Value = "True" } };
fLayer.SetDefinition(fLayerDef);
In your particular case it appears that the ShowLegends is the property that is causing the Symbology Pane to display the warning. I believe that this should be true. If you wish to hide the symbol in the TOC then the best way to do that is to use the layer SetExpanded method (https://pro.arcgis.com/en/pro-app/latest/sdk/api-reference/topic11772.html)
Let me know if you have any additional questions.
Narelle
Narelle,
So, it turns out that the problem was not having ShowLegends and Expanded set to true. I made that change to set ShowLegends to true at one point, but it didn't work. I forgot that there was another method elsewhere in the code that set it back to false. That was what was causing my problem. I also didn't never had the Expanded property set to true. That was also an issue.
I had a feeling that the fix would be something simple that I was missing.
Thank you for all your help!