Change symbol color by attribute for DictionaryRenderer/DictionaryStyle works in ArcGIS Pro, but not in Maps SDK

1093
10
Jump to solution
11-01-2023 06:51 AM
BjørnarSundsbø1
Occasional Contributor II

Using the latest version of the Map SDK for ..NET, I am attempting to use a DictionaryRenderer as described in this post: https://developers.arcgis.com/net/styles-and-data-visualization/display-symbols-with-a-dictionary-re....

I need to merge multiple symbols into one, with rotation and changed color based on feature/graphics attributes. I am using this on a GraphicsOverlay.

A basic example from ArcGIS pro

BjrnarSundsb1_0-1698852304365.png

Using the same Dictionary Style in ArcGIS Map SDK for .NET. They all use the default color of the symbol defined in ArcGIS Pro.

BjrnarSundsb1_1-1698852337530.png

 

Rotation and hide/show different symbols based on graphics attributes work, however, the color does not want to change based on attribute value, with the important part

 

 

 

//Draw the arrow
keys = keys + "arrowBasic;";
keys = keys + "po:layers_arrow|FillColor|" + _urgcolor +";";
keys = keys + "po:structure_arrow|Rotation|" + _rotangle + ";";

 

 

 

The arcade script is as follows

 

 

 

var keys;
var _urgcolor;
var _standstillcolor;

//calculate ROTATION ANGLE for right-pointing arrow
var _rotangle = (450-$feature.Bearing)%360;

//calculate COLOR for urgency
function urg_color_calc (rsn,utc) {
if(rsn == "Ute av drift"){
return "#03376F" //blue-black
}
if(rsn == "Ledig"){
return "#D330D1" //lilac
}
if(utc == "A"){
return "#E75E5B" //red
}
if(utc == "H"){
return "#FFD75E" //yellow  
}
if(utc == "V"){
return "#7DD455" //green
}
if(isEmpty(utc)){
return "#b3b3b3" //grey
}
return "#0000ff"; //super blue as fallback
}

_urgcolor = urg_color_calc($feature.ResourceStatusName, $feature.urgencytypecode);

//Draw the arrow
keys = keys + "arrowBasic;";
keys = keys + "po:layers_arrow|FillColor|" + _urgcolor +";";
keys = keys + "po:structure_arrow|Rotation|" + _rotangle + ";";

// Motion - show the dot if Resource is standing still
 _standstillcolor = "#808b96";
if($feature.isMoving <1){ 
	keys = keys + "pentagon3;";
}

// See if text should be displayed.
var showLabels = $config.text != 'OFF';
// Create the concatenated string of keys (separated with ";"). Add the label key if text is on.
if (showLabels) {
  keys = keys + "labelres";
  }

return keys;

 

 

 

 

 

In the style there is a symbol with the primitiveName 'layers_arrow' of which I would like to change the color. using FillColor or Color has no effect in ArcGIS Map SDK for .NET, but it does work in ArcGIS Pro.

 

Using the following code to get the JSON of the symbol

Symbol restaurantSymbol = style.GetSymbolAsync(attributes).Result;
var json = restaurantSymbol.ToJson();
 

 

 

 

 

{
	"symbolLayers": [
	  {
		"anchorPoint": {
		  "x": 0,
		  "y": 0
		},
		"billboardMode3D": "FaceNearPlane",
		"colorLocked": false,
		"depth3D": 0.0,
		"dominantSizeAxis3D": "Y",
		"enable": true,
		"frame": {
		  "xmax": 17,
		  "xmin": 0,
		  "ymax": 17,
		  "ymin": 0
		},
		"markerGraphics": [
		  {
			"geometry": {
			  "rings": [
				[
				  [
					17,
					10.01
				  ],
				  [
					13.75,
					0
				  ],
				  [
					3.25,
					0
				  ],
				  [
					0,
					10.01
				  ],
				  [
					8.49,
					16.19
				  ],
				  [
					17,
					10.01
				  ]
				]
			  ]
			},
			"symbol": {
			  "angleAlignment": "Map",
			  "symbolLayers": [
				{
				  "capStyle": "Round",
				  "color": [
					0,
					0,
					0,
					255
				  ],
				  "colorLocked": false,
				  "enable": true,
				  "joinStyle": "Round",
				  "lineStyle3D": "Strip",
				  "miterLimit": 10.0,
				  "type": "CIMSolidStroke",
				  "width": 1.0
				},
				{
				  "color": [
					230,
					0,
					0,
					255
				  ],
				  "colorLocked": false,
				  "enable": true,
				  "type": "CIMSolidFill"
				}
			  ],
			  "type": "CIMPolygonSymbol"
			},
			"type": "CIMMarkerGraphic"
		  }
		],
		"primitiveName": "structure_pentagon3",
		"respectFrame": true,
		"scaleSymbolsProportionally": true,
		"size": 10.0,
		"type": "CIMVectorMarker",
		"verticalOrientation3D": false
	  },
	  {
		"anchorPoint": {
		  "x": 0,
		  "y": 0
		},
		"billboardMode3D": "FaceNearPlane",
		"colorLocked": false,
		"depth3D": 0.0,
		"dominantSizeAxis3D": "Y",
		"enable": true,
		"frame": {
		  "xmax": 0,
		  "xmin": -14,
		  "ymax": 4.5,
		  "ymin": -4.47
		},
		"markerGraphics": [
		  {
			"geometry": {
			  "x": 0,
			  "y": 0
			},
			"symbol": {
			  "haloSize": 0,
			  "scaleX": 1,
			  "symbolLayers": [
				{
				  "anchorPoint": {
					"x": 0.5,
					"y": 0
				  },
				  "billboardMode3D": "FaceNearPlane",
				  "clippingPath": {
					"clippingType": "Intersect",
					"path": {
					  "rings": [
						[
						  [
							0.0,
							0.0
						  ],
						  [
							17.0,
							0.0
						  ],
						  [
							17.0,
							17.0
						  ],
						  [
							0.0,
							17.0
						  ],
						  [
							0.0,
							0.0
						  ]
						]
					  ]
					},
					"type": "CIMClippingPath"
				  },
				  "colorLocked": false,
				  "depth3D": 0.0,
				  "dominantSizeAxis3D": "Y",
				  "enable": true,
				  "frame": {
					"xmax": 17,
					"xmin": 0,
					"ymax": 17,
					"ymin": 0
				  },
				  "markerGraphics": [
					{
					  "geometry": {
						"rings": [
						  [
							[
							  17,
							  9.33
							],
							[
							  11.52,
							  14.77
							],
							[
							  11.52,
							  12.58
							],
							[
							  0,
							  12.58
							],
							[
							  0,
							  6.07
							],
							[
							  11.52,
							  6.07
							],
							[
							  11.52,
							  3.88
							],
							[
							  17,
							  9.33
							]
						  ]
						]
					  },
					  "symbol": {
						"angleAlignment": "Map",
						"symbolLayers": [
						  {
							"capStyle": "Round",
							"color": [
							  51,
							  51,
							  51,
							  255
							],
							"colorLocked": false,
							"enable": true,
							"joinStyle": "Round",
							"lineStyle3D": "Strip",
							"miterLimit": 10.0,
							"type": "CIMSolidStroke",
							"width": 0.0
						  },
						  {
							"color": [
							  230,
							  152,
							  0,
							  255
							],
							"colorLocked": false,
							"enable": true,
							"type": "CIMSolidFill"
						  }
						],
						"type": "CIMPolygonSymbol"
					  },
					  "type": "CIMMarkerGraphic"
					}
				  ],
				  "offsetY": -0.6666666666666666,
				  "respectFrame": true,
				  "scaleSymbolsProportionally": true,
				  "size": 14.0,
				  "type": "CIMVectorMarker",
				  "verticalOrientation3D": false
				}
			  ],
			  "type": "CIMPointSymbol"
			},
			"type": "CIMMarkerGraphic"
		  }
		],
		"primitiveName": "structure_arrow",
		"respectFrame": true,
		"rotation": 327.0,
		"scaleSymbolsProportionally": true,
		"size": 14.0,
		"type": "CIMVectorMarker",
		"verticalOrientation3D": false
	  }
	],
	"type": "CIMPointSymbol"
  }

 

 

 

 

In the JSON above, I can find primitive names "structure_arrow" which I change the rotation for, and "structure_pentagon3" which is displayed or hidden. Nowhere in the JSON of the symbol can I find anything with the primitiveName 'layers_arrow", which is the name set in ArcGIS Pro for the symbol.

 

The relevant section from DB Browser for SQLite. Interestingly, the name layer arrow is visible in the binary display of the arrowBasic content 

BjrnarSundsb1_1-1698851249871.png

 

 

 

0 Kudos
1 Solution

Accepted Solutions
PreetiMaske
Esri Contributor

Hi,

My reply is purely based on looking at the symbol json and the stylx files. I have a good guess what might be happening.

I think the issue is the where in the symbol structure the "layers_arrow" primitiveName is placed. 

When I view the symbol structure for the arrow in the ressurspil.stylx, I see that the "layers_arrow" primitiveName is at the marker graphic layer.  As you  mentioned, this is working in Pro but I have a suspicion that it might not be working in Native Maps SDK because most likely it is something we are missing support for.

For now, To override the color you can move the primitiveName to the CIMSolidFill of the embedded polygon symbol.  When the primitive override is placed at this level the name used will be property name of Color and not FillColor which is only used for at the marker graphic level.

I am attaching an updated stylx file with a new symbol called `My arrow`. Could you please try with this symbol and see if it works for you.

 

Thanks,

Preeti

View solution in original post

10 Replies
BjørnarSundsbø1
Occasional Contributor II

The style is available in this message. Had to zip because the forum didn't quite agree matching file extension vs format.

0 Kudos
PreetiMaske
Esri Contributor

Hi,

My reply is purely based on looking at the symbol json and the stylx files. I have a good guess what might be happening.

I think the issue is the where in the symbol structure the "layers_arrow" primitiveName is placed. 

When I view the symbol structure for the arrow in the ressurspil.stylx, I see that the "layers_arrow" primitiveName is at the marker graphic layer.  As you  mentioned, this is working in Pro but I have a suspicion that it might not be working in Native Maps SDK because most likely it is something we are missing support for.

For now, To override the color you can move the primitiveName to the CIMSolidFill of the embedded polygon symbol.  When the primitive override is placed at this level the name used will be property name of Color and not FillColor which is only used for at the marker graphic level.

I am attaching an updated stylx file with a new symbol called `My arrow`. Could you please try with this symbol and see if it works for you.

 

Thanks,

Preeti

BjørnarSundsbø1
Occasional Contributor II

Thank you so much @PreetiMaske for your response. I will have my Pro guy try it out tomorrow, as I will not be able to test it myself until Thursday. I'm very eager about the outcome 😁 

0 Kudos
BjørnarSundsbø1
Occasional Contributor II

I can't find the attachment though 😀

0 Kudos
ErikScavenius
New Contributor

Hi @PreetiMaske 

I'm @BjørnarSundsbø1 's colleague doing the PRO part of this. We got the stylx you tweaked to work in both PRO and SDK, but I don't see how I can "move the primitiveName to the CIMSolidFill of the embedded polygon symbol."

ErikScavenius_0-1699617311981.png

I can see that layers_arrow is no longer set on graphic layer

ErikScavenius_2-1699617846480.png

I don't however see where (in PRO) it is placed now. Can you please explain where/how in PRO you have placed the label  layers_arrow in order to place it on the "CIMSolidFill of the embedded polygon symbol" ?

Thanks! Regards,

Erik

I'm btw on Pro 3.2.0 and had to upgrade your style in order to open it (if that's related).

ErikScavenius_1-1699617805683.png

 

0 Kudos
hesmebye
New Contributor II

You really have to dig down into the settings 🙂

First you select 

hesmebye_0-1699883011853.png

"Format point symbol" in the menu abowe.

Then the dialog changes slightly 

hesmebye_2-1699883089295.png

 

Then you select "Format polygon symbol" in the menu below

hesmebye_3-1699883131589.png

 

Then you get to the right "level" and select the "Structure of the symbol" and you get the label for the solid fill available

hesmebye_4-1699883199411.png

Then you can set the label 🙂  - kind of nested thing...

 

 

ErikScavenius
New Contributor

Thanks @hesmebye . The procedure challenges my definition of user-friendliness, but it works and opens up great flexibility. Great (and appreciated) step-by-step illustrations 🙂

0 Kudos
PreetiMaske
Esri Contributor

Sorry about that. Here it is 🙂

0 Kudos
BjørnarSundsbø1
Occasional Contributor II

The workaround works with a few minor modifications to the arcade script.

//Draw the arrow
keys = keys + "my_arrow;";
keys = keys + "po:layers_arrow|Color|" + _urgcolor +";";
keys = keys + "po:structure_arrow|Rotation|" + _rotangle + ";";

The Color property was case sensitive, and I had to change to point to the new key for the symbol.

The JSON of the style.GetSymbolAsync() now contains layer_arrow, and the color logic is working . We will adapt the dictionary and symbology to expand to the real life sample with more complex (and prettier) symbology, with fingers crossed it works the same, though I have no reason to doubt it will.

Is the original "bug" with the placement of primitiveName a candidate for a near future release?

 

BjrnarSundsb1_0-1699450566760.png

 

0 Kudos