ApplySymbologyFromLayer GeoProcessing Tool

4057
30
Jump to solution
06-19-2019 11:09 AM
BrianBulla
Occasional Contributor III

Hi,

I'm trying to update the layers of a map by running the ApplySymbologyFromLayer GeoProcessing tool through some .NET code.  For a while, there was a reported BUG-000106281 about this, but it is apparently fixed in 2.3.

But.....I still cannot get it to work.  Is there something wrong with my code?  All of my .lyr files are located on a network drive.  I get a NULL Reference Exception at the .ExecuteToolAsync line.

Thanks,

                Map map = MapView.Active.Map;

                pBar.Minimum = 0;
                pBar.Maximum = map.Layers.Count;

                this.Cursor = Cursors.Wait;

                GPExecuteToolFlags flags = GPExecuteToolFlags.GPThread;

                foreach (Layer layer in map.GetLayersAsFlattenedList().OfType<FeatureLayer>())
                {   
                    var gpresult = await Geoprocessing.ExecuteToolAsync("ApplySymbologyFromLayer_management", new string[] { layer.Name.ToString(), @"K:\DSM Shared\ArcMap Symbology\10.2 Schema\Editing Symbols\" + layer.Name.ToString() + ".lyr" }, null, null, flags);
                    pBar.Value = pBar.Value + 1;
                }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
Tags (2)
0 Kudos
30 Replies
UmaHarano
Esri Regular Contributor

Hi Brian

The Lyrx file you attached has a CIMSimpleRenderer.  Just to confirm - when you get the renderer from your LayerDefinition, are you casting it to CIMSimpleRenderer?

The code snippet above was using UniqueValueRenderer.

Thanks

Uma

0 Kudos
GKmieliauskas
Esri Regular Contributor

Hi Brian,

Do you use SetColorizer as in code sample of Uma? You need to use SetRenderer for CIMSimpleRenderer. I had the same problem. 

0 Kudos
BrianBulla
Occasional Contributor III

Ah, ok.  I see.  I guess I will need to check the lyrx file first to determine what renderer to use and then assign the proper one to it.  Obvious now that I think about it.

Thanks for the help!

0 Kudos
UmaHarano
Esri Regular Contributor

Hi

I see the same issue with the old lyr file - I have informed the developer about this. I will let you know when this gets addressed.

With lyrx files, I was able to apply the symbology with the "Classify" colorizer - I did not load the lyrx file. Can you please explain the issues you are having?

Thanks

Uma

0 Kudos
GKmieliauskas
Esri Regular Contributor

Hi Uma,

I have tried your snippet on grid rasters.

I can send you grid and lyrx if you need.

0 Kudos
UmaHarano
Esri Regular Contributor

Hi

Yes, please do send it - I can check it out to see what is happening.

Thanks

Uma

0 Kudos
GKmieliauskas
Esri Regular Contributor

Hi Uma,

I attached data for testing

0 Kudos
UmaHarano
Esri Regular Contributor

Hi,

This is what I did -

In the zip file there was a prediction.lyr file.  At this point in 2.4, the new methods to apply symbology using the layer definitions from a .lyr doesn't work with 2.4. This will hopefully be fixed soon.

I added the prediction.lyr to Pro, fixed the data source by pointing to the grid layer you sent.  I then saved it as a lyrx file. I have attached this lyrx file as FS-Prediction.lyrx. This lyrx file had a CIMRasterClassifyColorizer.

I then used the code below to apply the symbology from FS-Prediction.lyrx to the grid you sent and it worked for me.  Note: the lyrx was not loaded in Pro when I did this.

protected override async void OnClick()
        {
            var lyrs = MapView.Active.Map.GetLayersAsFlattenedList().OfType<RasterLayer>();           
            await ModifyLayerSymbologyFromLyrFileAsync(lyrs, @"C:\Users\uma2526\Documents\ArcGIS\Projects\RasterColorizer\FS-Prediction.lyrx");
        }

        private static async Task ModifyLayerSymbologyFromLyrFileAsync(IEnumerable<RasterLayer> featureLayers, string layerFile)
        {
            await QueuedTask.Run(() =>
            {
                foreach (var featureLayer in featureLayers)
                {
                    //Get the Layer Document from the lyrx file
                    var lyrDocFromLyrxFile = new LayerDocument(layerFile);
                    var cimLyrDoc = lyrDocFromLyrxFile.GetCIMLayerDocument();

                    //Get the renderer from the layer file
                    //This lyr file has a unique value renderer.
                    var rendererFromLayerFile = ((CIMRasterLayer)cimLyrDoc.LayerDefinitions[0]).Colorizer as CIMRasterClassifyColorizer;

                    //Apply the renderer to the feature layer
                    featureLayer?.SetColorizer(rendererFromLayerFile);
                }

            });
        }

Please let me know if this is similar to the workflow you are want.

Thanks

Uma

0 Kudos
GKmieliauskas
Esri Regular Contributor

Hi Uma,

Sorry, I have copied lyr file from old folder.

There is one difference in our code: I create layer from scratch, you take layer from the map.

Your code works in my testing button too.

My code:

RasterLayer rastLayer = (RasterLayer)LayerFactory.Instance.CreateLayer(new Uri(path), currentCont, -1, layerName);

var lyrDocFromLyrxFile = new LayerDocument(sLyrPath);

var cimLyrDoc = lyrDocFromLyrxFile.GetCIMLayerDocument();

//Get the renderer from the layer file

var rendererFromLayerFile = ((CIMRasterLayer)cimLyrDoc.LayerDefinitions[0]).Colorizer;

//Apply the renderer to the feature layer

rastLayer?.SetColorizer(rendererFromLayerFile);

currentCont - usually group layer

Thanks

0 Kudos
UmaHarano
Esri Regular Contributor

Hi

The problem is that when you are applying the symbology, the layer has not been added to the map yet. When I tested the workflow in your snippet, I see the same issue.

Try this:

1. Create the layer and await.

2. Then apply the symbology.

This code does this:

protected override async void OnClick()
{
            string url = @"E:\Stuff\ApplySymbology\fs1";
            var lyrFile = @"C:\Users\uma2526\Documents\ArcGIS\Projects\RasterColorizer\FS-Prediction.lyrx";
            var rasterLyr = await QueuedTask.Run(() =>
            {
                return (RasterLayer)LayerFactory.Instance.CreateLayer(new Uri(url), MapView.Active.Map);
            });
            await QueuedTask.Run(() => {
                var lyrDocFromLyrxFile = new LayerDocument(lyrFile);
                var cimLyrDoc = lyrDocFromLyrxFile.GetCIMLayerDocument();
                //Get the renderer from the layer file
                var rendererFromLayerFile = ((CIMRasterLayer)cimLyrDoc.LayerDefinitions[0]).Colorizer as CIMRasterClassifyColorizer;
                //Apply the renderer to the feature layer
                rasterLyr?.SetColorizer(rendererFromLayerFile);
            });
            
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Thanks

Uma