Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I want to make a copy of a layer in the ArcMap TOC (passed to my script as a Feature Layer), assign the copy a new name, set a definition query on it, and then add the copied Feature Layer back into the TOC. This is easily achieved manually via the ArcMap interface, but I'm yet to discover how to achieve this programatically.

My application of this is to take an input layer, then effectively split the layer by attributes in a specified field, creating a new Feature Layer for each unique attribute in the input. Thus the number of output Feature Layers will vary depending on the input data. All output Feature Layers will be added to a specified group layer.

The following code almost achieves this, but if I then try and change the name of the copied layer (via ArcPy), the names of both the original layer in the TOC, and the copy of that layer (now in the new group layer) are changed. Note that this code also includes adding of a new Group Layer to the TOC (using a template LYR file on disc), into which the copied layer is inserted)

mxd = arcpy.mapping.MapDocument('CURRENT')
df = arcpy.mapping.ListDataFrames(mxd, dataFrameName)[0]
inputLayer = arcpy.mapping.ListLayers(mxd, inFC, df)[0] #this is the Layer from the TOC     specified by the user

#Add empty group layer to TOC
groupLayer = arcpy.mapping.Layer("<File path to LYR file>\EmptyGroupLayerTemplate.lyr")
arcpy.mapping.AddLayer(df, groupLayer, "TOP")

targetGroupLayer = arcpy.mapping.ListLayers(mxd, "EmptyGroupLayerTemplate", df)[0]

#Add copy of feature layer into the new Group Layer
arcpy.mapping.AddLayerToGroup(df, targetGroupLayer, inputLayer, "AUTO_ARRANGE")

I have tried ensuring that I get a reference to only the new copy of the layer, by ensuring the layer name is proceeded by the group layer name:

for layer in layerList:
  if layer.isGroupLayer and layer.name == groupLayer.name:
    for subLayer in layer:
      if subLayer.name == inputLayer.name:
        #Change this layers name
        subLayer.name = outName
        arcpy.RefreshTOC()

..and I have also tried:

for lyr in arcpy.mapping.ListLayers(mxd):
  #If layers long name contains the new grouplayer name..
  if lyr.longName.find(groupname + "\\") != -1:
    #'-1' when string not found       
    inputLayerFullName = groupname + "\\" + inputLayerName       
    if  lyr.name == inputLayerFullName:
      lyr.name = "NewLayerName" 
      arcpy.RefreshTOC()

...both these techniques do rename the copied layer, but they ALSO rename the original layer, regardless of where it is in the TOC.

It feels like I am working with a reference type rather than a value type in this respect, but I cannot see how to work with the layer object in another way? Seems that the issue lays with the fact that both Feature Layers (in the TOC) have the same name; reference one by name, yet both get updated.

I've tried making a copy of the input Feature Layer, assigning the copy a new name, then add this to the TOC, but the code errors executing AddLayerToGroup():

arcpy.MakeFeatureLayer_management(inputLayer, "TestFeatureLayer")
arcpy.mapping.AddLayerToGroup(df, targetGroupLayer, "TestFeatureLayer", "AUTO_ARRANGE")

I'm yet to try saving the original Feature Layer to a LYR file on disc, then changing the properties of the LYR file, and adding that back into the TOC, but I'd prefer not to go down this route as I dont really want to save any data to disc. After all, this operation is achieved within the ArcMap GUI without saving to disc, so it should be possible via Arcpy (or ArcObjects if necessary) too.

Any ideas on how to achieve this functionality would be greatly appreciated (using ArcGIS 10.0). Cheers.

share|improve this question
1  
Is there a particular reason you want to not write to disc? –  gm70560 May 9 '13 at 16:56
    
I can understand the "not write to disc" requirement (see my Answer) in point 1 but I am unclear why you would want/expect data in in_memory workspaces to persist between ArcMap/ArcPy sessions (your point 2). –  PolyGeo May 9 '13 at 21:04
    
I don't want to write to disc as I don't want to create new Feature Classes unnecessarily. The application I have in mind for this would result in the generation of many Feature Classes each time the script were run; I think that would be a very messy solution. The ArcMap functionality I describe in my question is exactly what I want to achieve (but programatically), and as that workflow manages to not write to disc, I feel sure there must be a way to achieve this programatically. –  user17992 May 10 '13 at 8:31
    
" I am unclear why you would want/expect data in in_memory workspaces to persist between ArcMap/ArcPy sessions (your point 2). – PolyGeo". ....no, I agree, and I see this part of my question is a little confusing. I was clutching at straws a bit, trying to think how a new Feature Layer could be added. On further thinking about this, a Feature Layer is more a property of the map document, as that is the only domain it exists in. –  user17992 May 10 '13 at 8:38
    
If I understand your question, you are just trying to (programmatically) create a new layer that still references the original layers' underlying source and just apply a new def query, symbology, etc to the new layer? You want to avoid creating a new file on disk, correct? –  RyanDalton Jul 9 '13 at 19:22

4 Answers 4

Might be a bit late to the party but here you go...

def CopyPasteLayer(CopyLayer, PastedLayerName):
 mxd = arcpy.mapping.MapDocument("Current")
 df = arcpy.mapping.ListDataFrames(mxd)[0]
 CopyLayerList = [arcpy.mapping.Layer(str(CopyLayer))]
 for CopyLayer in CopyLayerList:
     CopyLayer.name = str(PastedLayerName)
     arcpy.mapping.AddLayer(df, CopyLayer, "AUTO_ARRANGE")
 arcpy.RefreshTOC()
 arcpy.RefreshActiveView()

'CopyLayer' argument is the name of the layer as it appears in the ToC which you want to make a copy of

'PastedLayerName' argument is the name of the layer as you want it to appear in the ToC once pasted.

Use Example:

CopyPasteLayer("SitesToCopy", "PastedSites")

Keep in mind that this is all happening the the ToC and thus in-memory, so if you close your ArcMap session, that pasted layer will be lost unless you save it.

share|improve this answer

Your requirement is not identical to one I have, but it has some key elements in common with it, so I am going to offer it as an answer.

I use in_memory workspaces to speed up some Python script tools that get published as Geoprocessing Services significantly. The tools open MXDs and perform, among other things, an ExportToPDF. In the MXD there is a layer that references a dataset stored on disk.

At runtime a new dataset gets created with the same schema as that above, so that it can replace it as the data source but, given a choice, I would like that new dataset to ONLY be written to the in_memory workspace.

The solution I seek, which would also clear your main hurdle I think, is to allow ArcPy's replaceDataSource of a layer to use a dataset stored in_memory. I have raised this in the ArcGIS Discussion Forums and elsewhere on Stack Exchange GIS but it looks like the only way it is likely to be addressed is by getting many more votes for the ArcGIS Idea I submitted on it.

Note that there already appears to be an ArcObjects way to do this which is by using an InMemoryWorkspaceFactory.

share|improve this answer
    
Thanks for your reply PolyGeo. However, I don’t want to change the data source of my input Feature Layer, but instead make a copy of it, assign the copy a new name, set a definition query, and then add the copied Feature Layer back into the TOC. Sorry if this was not clear from my original post. –  user17992 May 10 '13 at 8:47
    
Are you saying that you are NOT looking to use an in_memory workspace? Without that in the equation this becomes much more doable. Certainly, adding layers, setting definition queries on them, and changing their names at runtime via ArcPy are things that I do frequently. The only slight unknown would be using layer groups in that workflow but I would expect that to work fine too. Perhaps you can revise your question to make the precise workflow you are after clearer? –  PolyGeo May 10 '13 at 9:14
    
PolyGeo, please see my revised question above. Sorry for not being clearer in my original question. My 'in-memory' ideas were distracting from the main question. –  user17992 May 10 '13 at 11:13
    
I think the question requires further revision to simplify it. If you allow a single *.lyr file (about 20Kb) to be written to disk then I think it is easy - if not, it needs an ArcGIS Idea. –  PolyGeo Jul 18 '13 at 2:05

I've just tinkered around with python and I did this, is this what you want?

arcpy.env.addOutputsToMap = False
mxd = arcpy.mapping.MapDocument('CURRENT')
df = arcpy.mapping.ListDataFrames(mxd, "Inset Map")[0]

# Create a featurelayer with just 1 polygon in it and call it wales
res = arcpy.MakeFeatureLayer_management("Coastline","wales","FID = 3")

# Add to map
arcpy.mapping.AddLayer(df,res.getOutput(0))

I then ran your name changing code and it changed only the wales layer name, I have to admit I did not test it on data in a grouplayer.

share|improve this answer

I'm not sure if you solved your problem but I was having the same problem. I think using a layer file is the only way to solve this problem. First save a layer file with the correct source and symbology that you want. Create a layer of it, change the layer name and other properties you want and then add it to the map. You'll have to create a new layer from the layer file every time before adding it to the map but it worked for me. Something like this.

mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.listDataFrames(mxd)[0]
layer_names = ["test1", "test2", "test3"]
for layer in layer_names:
    lyr = arcpy.mapping.Layer("path to layer file\Layer Test.lyr")
    lyr.name = layer
    arcpy.mapping.AddLayer(df, lyr)
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.