FeatureLayer.SetDefinition Broken?

634
6
02-21-2017 06:04 PM
Highlighted
Regular Contributor

I would expect the following code to essentially clone the top layer in the map.  It does create a new featurelayer that points to the Uri, but calling SetDefinition has no discernible effect.

private void Test()
{
    var def = MapView.Active.Map.Layers[0].GetDefinition() as CIMFeatureLayer;
    var conn = def.FeatureTable.DataConnection as CIMStandardDataConnection;
    var folder = conn.WorkspaceConnectionString.Split('=')[1];
    if (conn.WorkspaceFactory != WorkspaceFactory.Shapefile)
        throw new Exception("test only works with shapefile layers");
    var url = Path.Combine(folder, conn.Dataset + ".shp");
    var fLayer = LayerFactory.CreateFeatureLayer(new Uri(url), MapView.Active.Map, 1);
    fLayer.SetName("my layer");
    // name remains "my layer" Setdefinition has no discernible effect
    fLayer.SetDefinition(def);
}

Tags (1)
Reply
0 Kudos
6 Replies
Highlighted
Regular Contributor

Here's a simpler example.  SetDefinition doesn't do anything from what I can tell.

private void Test()
{
    var def = MapView.Active.Map.Layers[0].GetDefinition() as CIMFeatureLayer;
    var fLayer = LayerFactory.CreateLayer(def.FeatureTable.DataConnection,MapView.Active.Map) as FeatureLayer;
    fLayer.SetName("my layer");
    // name remains "my layer" Setdefinition has no discernable effect
    fLayer.SetDefinition(def);
}
Reply
0 Kudos
Highlighted
Esri Contributor

Get and Set definition are a transactional pair. That is, you have to "get" a layer's definition, change it, then "set" it (or commit it) back to the repository. Think of it like a record in a database. It has an id and some other identifier information. It cannot be shared. In your code above I would imagine that the layer in

MapView.Active.Map.Layers[0]

will have had its name changed to "my layer". Ditto for the code sample above.

Reply
0 Kudos
Highlighted
Esri Contributor

Actually, I looked closer at your code. In retrospect, it looks like you may be overwriting your change. For 

MapView.Active.Map.Layers[0] 
to have been changed you would have needed to have updated its definition before the
set (on flayer). Either way, the key is you have to get a definition, change it, then
set it back.
Reply
0 Kudos
Highlighted
Regular Contributor

Thanks for replying Charles.

When I open a .lyrx file in a text editor, I see that it contains a CIMLayerDocument, which has a list of CIMLayers (e.g. CIMFeatureLayer etc.)  When I choose to add data and select a .lyrx file behind the scenes Pro is turning definitions into layers.  I want to be able to do something similar.  Is this functionality exposed by the API?

If not, I think Esri really needs to add another overload to LayerFactory.CreateLayer which accepts a CIMLayer definition.

Otherwise, if there is a bug in SetDefinition, perhaps I could accomplish this once the bug is fixed.

Reply
0 Kudos
Highlighted
Esri Contributor

Use LayerFactory.CreateLayer directly with the layer file....or....is that not doing what you want?

https://github.com/Esri/arcgis-pro-sdk/wiki/ProSnippets-MapAuthoring#create-and-add-a-layer-to-the-a...

Reply
0 Kudos
Highlighted
Regular Contributor

I think I resolved this by setting the URI of the definition to that of the newly created layer before applying.

Any known ill side-effects from doing this?

def.URI = fLayer.GetDefinition().URI;
fLayer.SetDefinintion(def);
Reply
0 Kudos