Hello,
I am working on an automated map script that will allow me to import a Shapefile, assign it a pre-defined symbology, zoom to a layer and export a map. I am having one issue when I bring in my input file. I am using the addDataFromPath() function to bring in my data, and it indeed brings it in fine. However, the file shows up in my table of contents and legend with the text "_Layer2", "_Layer3" etc, after the name of the file I bring it.
I would like to simply rename what is in my legend and TOC to something I want such as "Project Area" or "AOI", etc.
Does anyone here have the experience with arcpy.mp to get that to work?
Thank you for your time!
Solved! Go to Solution.
Hi @ParkGIS307 ,
You can use the following code snippet to rename feature layers in TOC using arcpy:
aprx = arcpy.mp.ArcGISProject("CURRENT")
map = aprx.listMaps()[0]
for lyr in map.listLayers():
print(lyr.name)
# Here this renames a layer that has a keyword "Building" in it to "BuildingFootprint" in TOC
if "Building" in lyr.name:
layerName = str(lyr.name)
lyr.name = lyr.name.replace(layerName, "BuildingFootprint")
print(f"Layer renamed to: {lyr.name}")
this can be extended to more layers.
I hope that is insightful.
"name" in the CIM layer class is read/write
Layer—ArcGIS Pro | Documentation
did you try it?
My knowledge on CIM syntax is scant. So I have not tried it yet. I will read up on it more though.
Hi @ParkGIS307 ,
You can use the following code snippet to rename feature layers in TOC using arcpy:
aprx = arcpy.mp.ArcGISProject("CURRENT")
map = aprx.listMaps()[0]
for lyr in map.listLayers():
print(lyr.name)
# Here this renames a layer that has a keyword "Building" in it to "BuildingFootprint" in TOC
if "Building" in lyr.name:
layerName = str(lyr.name)
lyr.name = lyr.name.replace(layerName, "BuildingFootprint")
print(f"Layer renamed to: {lyr.name}")
this can be extended to more layers.
I hope that is insightful.
Is there any way to identify a layer without using the name? Sometimes, I have different layers the same name. It's not common, but I sometimes need to (ie when I have a scale dependency and I want the visible layer to have the same label in the legend. Is there a way to identify the specific, actually selected layer from the layer list, like with an id?
Thank you,
Randy McGregor
Hi @RandyMcGregor_BMcD ,
layer objects have a property named "URI" which "is a unique identifier for a layer in a project." I use it for the exact case you described.
If you want to use it in combination with the "specific, actually selected layer from the layer list" I suppose using the MapView.GetSelectedLayers() method from the SDK should do the trick, as it returns the highlighted layer(s) in the TOC. Then compare the URI of the returned layer with the URIs of the layers in the TOC for further analysis. Works like a charm for me:
p = arcpy.mp.ArcGISProject("CURRENT")
m = p.activeMap
layers_toc = m.listLayers()
for layer in layers_toc:
if layer.URI == returned_layer.URI: # returned layer from SDK-method
# do something
Hope that helps
This looks like something I have been trying to d for a while now, but I'm very confused by MapView.GetSelectedLayers() - that's a call in the .Net SDK. How do you use that in a python script? I didn't think that was possible..
You are right, it's a call in the SDK not in python. My previous answer wasn't clear on that, sorry. Basically a Button in an .Net SDK Add-In first retrieves the highlighted layer(s) in the TOC via the SDK (MapView.GetSelectedLayers()) and then executes a tool within a python-Toolbox with the Layer-URI passed as the tool parameter (it is the only parameter in this custom tool):
var layer = MapView.Active.GetSelectedLayers();
var len = layer.Count;
for (int i = 0; i < layer.Count; i++)
{
var param = layer[i];
var toolbox_path = @"[path\to\toolbox].pyt";
var tool_path = System.IO.Path.Combine(toolbox_path, "[Tool]");
var args = Geoprocessing.MakeValueArray(string.Format("{0}", param.URI));
Geoprocessing.ExecuteToolAsync(tool_path, args);
}
In the tool the passed URI then gets compared to the URI of each layer in the TOC, as layers have the URI-property (see my answer above and layer) and when they are identical you found your layer-object corresponding to the highlighted layer(s) in the TOC and from there you can work with the layer-object.
It's a bit of a workaround, but we needed to create Add-Ins anyway so it was totally worth the few extra lines to solve our problems.
Thank's for the clarification! So you are basically .net is in the driver's seat pushing the layer down to python instead of python pulling it in. Most of the tools I developed in .net using ArcObjects relied on the selected layer as an input, but developing .net for Pro seems to take at least twice as much effort so I started doing python notebooks and was looking for a way to keep the same workflow and avoid hardcoding or building python toolboxes. I'll keep this workaround in mind, but If I go to the trouble of creating an addin, I'd probably just keep going and have it do the whole task.
Yes! 100% this works. It's exactly what I was hoping for. Thank you!