I am trying to create a CIMUniqueValueRenderer from a table that contains JSON symbol definitions. The symbol definitions in that table were pulled from a stylx file.
I am trying to use CIMSymbolReference.FromJson() to deserialize each symbol definition, but it keeps failing with the cryptic error "Wrong type name". The documentation here is failing me.
A typical JSON string looks like this:
"{\"type\":\"CIMLineSymbol\",\"symbolLayers\":[{\"type\":\"CIMSolidStroke\",\"enable\":true,\"colorLocked\":true,\"primitiveName\":\"1.0\",\"capStyle\":\"Butt\",\"joinStyle\":\"Round\",\"lineStyle3D\":\"Strip\",\"miterLimit\":10,\"width\":0.43086614173228349,\"color\":{\"type\":\"CIMCMYKColor\",\"values\":[0,0,0,100,100]}}]}"
Can anyone tell me why CIMSymbolReference.FromJson() chokes on this?
Is there another way to get from a JSON symbol definition to a symbol I can use in a CIMUniqueValueClass?
Code excerpt:
await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() => {
using (Geodatabase geodatabase = new Geodatabase(DataHelper.connectionProperties)) {
QueryDef cfQDef = new QueryDef {
Tables = "CFSymbology",
PostfixClause = "order by key"
};
using (RowCursor rowCursor = geodatabase.Evaluate(cfQDef, false)) {
List<CIMUniqueValueClass> listUniqueValueClasses = new List<CIMUniqueValueClass>();
while (rowCursor.MoveNext()) {
using (Row row = rowCursor.Current) {
Debug.WriteLine(row["key"].ToString());
//create and load map unit
var cf = new CF();
cf.key = row["key"].ToString();
cf.symbol = row["symbol"].ToString();
//add it to our list
cfs.Add(cf);
//Create a "CIMUniqueValueClass" for the symbol and add it to the list of unique values.
//This is what creates the mapping from map unit to color
List<CIMUniqueValue> listUniqueValues = new List<CIMUniqueValue> {
new CIMUniqueValue {
FieldValues = new string[] { cf.key }
}
};
CIMUniqueValueClass uniqueValueClass = new CIMUniqueValueClass {
Editable = true,
Label = cf.key,
//Patch = PatchShape.Default,
Patch = PatchShape.AreaPolygon,
Symbol = CIMSymbolReference.FromJson(cf.symbol, null),
Visible = true,
Values = listUniqueValues.ToArray()
};
listUniqueValueClasses.Add(uniqueValueClass);
}
}
//Create a list of CIMUniqueValueGroup
CIMUniqueValueGroup uvg = new CIMUniqueValueGroup {
Classes = listUniqueValueClasses.ToArray(),
};
List<CIMUniqueValueGroup> listUniqueValueGroups = new List<CIMUniqueValueGroup> { uvg };
//Use the list to create the CIMUniqueValueRenderer
DataHelper.cfRenderer = new CIMUniqueValueRenderer {
UseDefaultSymbol = false,
Groups = listUniqueValueGroups.ToArray(),
Fields = new string[] { "key" }
};
//Set renderer in contactsandfaults layer. The try/catch is there because the first time through, this is called
//before the layer has been added to the map. We just ignore the error in that case.
try {
var cfLayer = MapView.Active.Map.GetLayersAsFlattenedList().First((l) => l.Name == "ContactsAndFaults") as FeatureLayer;
cfLayer.SetRenderer(DataHelper.cfRenderer);
} catch { }
}
}
});
Solved! Go to Solution.
Hi Douglas,
CIMSymbolReference.FromJson() can only de-serialize JSON that contains a CIMSymbolReference object. The message "Wrong type name" refers the type that has been serialized into your JSON string:
{
"type": "CIMLineSymbol",
...
If you look at the serialized JSON for a CIMSymbolReference you should see a JSON string looking like this:
{
"type": "CIMSymbolReference",
"symbol": {
"type": "CIMPolygonSymbol",
"symbolLayers": [
{
"type": "CIMSolidStroke",
"enable": true,
"capStyle": "Round",
"joinStyle": "Round",
"lineStyle3D": "Strip",
"miterLimit": 10,
"width": 1,
"color": {
"type": "CIMRGBColor",
"values": [
0,
0,
0,
100
]
}
},
{
"type": "CIMSolidFill",
....
Thanks for pointing this out. Wrapping the symbol JSON string with the CIMSymbolReference JSON string bits gets the job done.
It's not very elegant though. It would be nice if there were a FromJson() routine in CIMSymbol.
Hi Douglas,
CIMSymbolReference.FromJson() can only de-serialize JSON that contains a CIMSymbolReference object. The message "Wrong type name" refers the type that has been serialized into your JSON string:
{
"type": "CIMLineSymbol",
...
If you look at the serialized JSON for a CIMSymbolReference you should see a JSON string looking like this:
{
"type": "CIMSymbolReference",
"symbol": {
"type": "CIMPolygonSymbol",
"symbolLayers": [
{
"type": "CIMSolidStroke",
"enable": true,
"capStyle": "Round",
"joinStyle": "Round",
"lineStyle3D": "Strip",
"miterLimit": 10,
"width": 1,
"color": {
"type": "CIMRGBColor",
"values": [
0,
0,
0,
100
]
}
},
{
"type": "CIMSolidFill",
....
Thanks for pointing this out. Wrapping the symbol JSON string with the CIMSymbolReference JSON string bits gets the job done.
It's not very elegant though. It would be nice if there were a FromJson() routine in CIMSymbol.