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.
I've made a script very similar, the print message is indicating the layer has been renamed, but the TOC includes no change. Is there a 'I'm not kidding, please really do this' command I'm missing? Thank you.
aprx = arcpy.mp.ArcGISProject('current')
am = aprx.activeMap
il_lyr_desc = arcpy.Describe(Input_Layer)
il_lyr_base = il_lyr_desc.baseName
for lyr in am.listLayers():
arcpy.AddMessage("> "+lyr.name+" "+str(Input_Layer.URI == lyr.URI))
if lyr.URI == Input_Layer.URI:
arcpy.AddMessage("> "+il_lyr_base)
arcpy.AddMessage("> "+lyr.name)
lyr.name = il_lyr_base
arcpy.AddMessage("> "+lyr.name)
break
import wishfulThinking
wishFulThinkin.doit()
If that doesn't work, ten I would approach it using the CIM. Check out this excellent video: https://www.youtube.com/watch?v=dzxKn5-OtVA&t=18s
I have been making use of the techniques described in the video to create some rather complicated layer symbology, but changing a map name would be quite simple. Spending an hour on the video may seem like a lot just to change a map name, but there is so much more you can do with those techniques that its well worth the time.
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.