Building proper syntax for importing .lyr symbology for Feature Layer

3433
15
02-10-2017 11:54 AM
ThomasCox
Occasional Contributor

I hesitate to throw another syntax question out so quickly following a recent similar syntax request. Up until this week I had been able to pretty well navigate syntax required by the various pro tools. However, I am struggling with applying symbology from a manually classified .lyr file to a feature layer. Through the sdk I am attempting to use the tool “ApplySymbologyFromLayer_management”. 

I have successfully used this tool in code to apply symbology to a raster layer using the following:

var gpresult = await Geoprocessing.ExecuteToolAsync("ApplySymbologyFromLayer_management", new string[] { rasterLayer.Name, strPathToLyrFile });

I have interactively used the tool in the Pro session without issue for the feature layer.  I noticed that when I specify the target .lyr file interactively, the Type field, the Source Field, and the Target Field are automatically assigned to the correct values. (Displayed in Attachment).  This initially led me to believe that I might not need to provide the symbology field arguments. However, when I used the same approach for the feature layer with the classified .lyr file, I received the error:

      {<msg code="309" type="100">ERROR 000309: The value is not a field
      ERROR 000309: The value is not a field</msg>}

 

I have looked at various documentation pages such as:

http://pro.arcgis.com/en/pro-app/tool-reference/data-management/apply-symbology-from-layer.htm, which provides python syntax examples.   Based off the help page, I started by building this:

string strTestArgs = "[VALUE_FIELD, gridcode, gridcode]";

var gpresult = await Geoprocessing.ExecuteToolAsync("ApplySymbologyFromLayer_management", new string[] { rasterLayer.Name, strPathToLyrFile, strTestArgs });

I have tried numerous sytax versions of the argument string to pass to the tool in code but can’t seem to find the proper format.  All the versions of the argument string I have passed produced either:

{<msg code="309" type="100">ERROR 000309: The value is not a field

or

{<msg code="800" type="100">ERROR 000800: The value is not a member of VALUE_FIELD | NORMALIZATION_FIELD | EXCLUSION_CLAUSE_FIELD | CHART_RENDERER_PIE_SIZE_FIELD | ROTATION_XEXPRESSION_FIELD | ROTATION_YEXPRESSION_FIELD | ROTATION_ZEXPRESSION_FIELD | TRANSPARENCY_EXPRESSION_FIELD | TRANSPARENCY_NORMALIZATION_FIELD | SIZE_EXPRESSION_FIELD | COLOR_EXPRESSION_FIELD | PRIMITIVE_OVERRIDE_EXPRESSION_FIELD.
ERROR 000309: The value is not a field

Any assistance of how to construct the string for the symbology field arguments would be appreciated.

 

 

 

 

Tags (1)
0 Kudos
15 Replies
MaxMax2
Occasional Contributor II

Hi Thomas,

Help for Apply Symbology From Layer gives clear example of how you need to specify symbology_fields parameter:

[["VALUE_FIELD", "#", "MyValueField"],["NORMALIZATION_FIELD", "#", "MyNormalizationField"]]

Each field descriptor (Field type, Source field, Match field) must be surrounded by square brackets. List of fields descriptors must be surrounded by square brackets too. So the correct code for your task is:

var inLayer = rasterLayer.Name;
var inSymbologyLayer = strPathToLyrFile;
var symbologyFields = "[[\"VALUE_FIELD\", \"gridcode\", \"gridcode\"]]";

var parameters = Geoprocessing.MakeValueArray(inLayer,
                                              inSymbologyLayer,
                                              symbologyFields);

var gpResult = await Geoprocessing.ExecuteToolAsync("ApplySymbologyFromLayer_management",
                                                    parameters,
                                                    null,
                                                    CancelableProgressor.None,
                                                    GPExecuteToolFlags.Default);
0 Kudos
ThomasCox
Occasional Contributor

ApplySymbologyFromLayer_management InterActive

ApplySymbologyFromLayer_management - Interactive Results

Max,

Thanks (again!) I appreciate your help.  Unfortunately, I still am unable to apply the symbology from the .lyr file in code. This task has become a surprisingly frustrating obstacle.

Through my earlier testing, I had built a symbology fields var with the same syntax you provided. However, I assumed I had introduced some error into the bit I built and used the example you kindly provided. As usual, the following error wn:

{<msg code="800" type="100">ERROR 000800: The value is not a member of VALUE_FIELD | NORMALIZATION_FIELD | EXCLUSION_CLAUSE_FIELD | CHART_RENDERER_PIE_SIZE_FIELD | ROTATION_XEXPRESSION_FIELD | ROTATION_YEXPRESSION_FIELD | ROTATION_ZEXPRESSION_FIELD | TRANSPARENCY_EXPRESSION_FIELD | TRANSPARENCY_NORMALIZATION_FIELD | SIZE_EXPRESSION_FIELD | COLOR_EXPRESSION_FIELD | PRIMITIVE_OVERRIDE_EXPRESSION_FIELD.

ERROR 000309: The value is not a field

ERROR 000309: The value is not a field</msg>}

 

var inLayer = pDissFeatLayerTest.Name;

var inSymbologyLayer = strPathToLayerFile;

var symbologyFields = "[[\"VALUE_FIELD\", \"gridcode\", \"gridcode\"]]";

var parameters = Geoprocessing.MakeValueArray(inLayer,

                 inSymbologyLayer,

                 symbologyFields);

 

var gpResult = await Geoprocessing.ExecuteToolAsync("ApplySymbologyFromLayer_management",

                                          parameters,

                     null,

                     CancelableProgressor.None,

                     GPExecuteToolFlags.Default);

 

I have placed breakpoints in the process to examine the values of the arguments.  Everything appears in order.  I examined the symbologyFields variable in code and it is producing what appears to be correct syntax:

       

               [["VALUE_FIELD", "gridcode", "gridcode"]]

In code, prior to execution, I test for the existence of the .lyr file used in the inSymbologyLayer argument. So I know my path syntax is correct.

I am retrieving the feature layer in code and it is returning the valid feature layer for the inLayer argument.

I have included some screen shots from Pro.  One shot shows the feature class table along with the ApplySymbologyFromLayer management tool.  The second shot shows the successful results of the tool.

Any insight or suggestions would be appreciated.

0 Kudos
MaxMax2
Occasional Contributor II

Thomas,

You are right, I tested my code and it really raises the error you described. I noticed that if I specify symbology_fields like "\"VALUE_FIELD\" \"gridcode\" \"gridcode\"" then tool is succesfully completed at the second time. I didn't check if result is correct but tool completes without errors.

This tool is kind of mystic in case of using it from code. Someone from ArcGIS Pro SDK team definitely should clarify how to use Apply Symbology From Layer tool from the .NET code. It's obviously in their interest to describe different aspects of working with their product. And it's really strange to me that no one from the Pro SDK team didn't leave any comment in this thread...

GKmieliauskas
Esri Regular Contributor

Hi Thomas,

Have you solved that problem? I have the same situation with lyrx with unique value renderer inside.

0 Kudos
ThomasCox
Occasional Contributor

Hi Gintautas,

My apologies for overlooking this.  I was hoping someone from ESRI would weigh in.

My current work around is a little kludgy.  In code I ended up adding a pre-baked .lyrx file to the map that had the symbology I wanted.  I then retrieved the feature layer the .lyrx pointed to (even though it was a 'broken' link.  I then retrieved the feature layer I wanted to assign the symbology to.  I then run the following queued task:

public Task SetFeatureLayerRendererFromDiffFeatureLayer(FeatureLayer ftrLayer, FeatureLayer ftrLayerToSet)

{

   return QueuedTask.Run(() =>

      {

      CIMClassBreaksRenderer classBrakesRend = ftrLayer.GetRenderer() as CIMClassBreaksRenderer;

            ftrLayerToSet.SetRenderer(classBrakesRend);

      });

}

Following this, I remove the 'intermediate' feature layer. In this case ftrLayer from the map.  I keep the contents closed during this process so it is not as visually intrusive. I would like to know if the approach I was initially using does not work because of a 'bug' or I am incorrectly using the api.  I am using a class breaks renderer, though I would think it would work with a unique value renderer as well.

 

 

0 Kudos
GKmieliauskas
Esri Regular Contributor

Hi Thomas,

Thank you for reply. I work on R&D with ArcGIS Pro programming now, so I will wait for solution from ArcGIS Pro Documentation team because It works from ArcGIS Pro Geoprocessing window.

0 Kudos
ThomasCox
Occasional Contributor

Hi Gintautas,

I have also used the Geoprocessing tool "ApplySymbologyFromLayer_management" to apply a renderer to a raster layer.  It has been a while since I was working with this approach. I believe I recall having some heartburn with it regarding feature layers, probably something glitch on my end.  The following worked for me.

var gpresult = await Geoprocessing.ExecuteToolAsync("ApplySymbologyFromLayer_management", new string[] { rasterLayer.Name, strPathToLyrFile });

0 Kudos
GKmieliauskas
Esri Regular Contributor

Hi Thomas,

Geoprocessing tool "ApplySymbologyFromLayer_management" with raster layer works for me too, but I have tested not all of the renderers. I have tried only Classify renderer. What kind of renderers have you tried?

0 Kudos
BrianBulla
Occasional Contributor III

Hi,

I'm trying to get something similar to this to work, but cannot seem to get the code to work.  Can you offer any advice??

My layer file is on a network drive, and I am trying to update a specific layer in my map:

var gpresult = await Geoprocessing.ExecuteToolAsync("ApplySymbologyFromLayer_management", new string[] { "GISWRKS1.WORKS.WAT_Hydrant", @"K:\DSM Shared\ArcMap Symbology\TEST\Editing Symbols\GISWRKS1.WORKS.WAT_Hydrant.lyrx" });

I don't get any errors...it just doesn't do anything.