arcpy.replaceDataSource in an mxd

303
3
02-14-2021 06:14 PM
JohnMcGlynn
Occasional Contributor

I have an mxd file with about 80 layers. Each layer has to be updated with a standard symbology and labeling. If I use the arcpy.ApplySymbologyFromLayer_management it only updates the symbology. I want to up update everything.

When I use the arcpy.mapping.UpdateLayer  function it does exactly what I want. However it changes the layer name and the data source. I'm trying to run UpdateLayer and then change the name and datasource back.

Unfortunately when I run Layer.replaceDataSource for a layer it changes all the layers in the map. 

This code is posted raw because I can't find the Code tag....

import arcpy, os

mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd,"Layers")[0]
layers = arcpy.mapping.ListLayers(mxd)
# Master featureclass names
PolylineMaster = 'PolylineMaster'
PointMaster = 'PointMaster'
PolygonMaster = 'PolygonMaster'
# Run each of point, polyline or polygon
doPoint = False
doPolyline = True
doPolygon = False

if doPoint == True:
lyrPtMaster = arcpy.mapping.ListLayers(mxd,PointMaster,df)[0]

if doPolyline == True:
lyrLineMaster = arcpy.mapping.ListLayers(mxd,PolylineMaster,df)[0]

if doPolygon == True:
lyrPolyMaster = arcpy.mapping.ListLayers(mxd,PolygonMaster,df)[0]

for lyr in layers:
lyrName = lyr.name

if lyrName == PolylineMaster or lyrName == PointMaster or lyrName == PolygonMaster:
continue
else:
print(lyrName)
desc = arcpy.Describe(lyr)
#path = arcpy.Describe(lyr).catalogPath # Full path - doesn't work

path = arcpy.Describe(lyr).path # GDB path
print(path)
if desc.shapeType == "Point" and doPoint == True:
arcpy.mapping.UpdateLayer(df,lyr,lyrPtMaster,False)
elif desc.shapeType == "Polyline" and doPolyline == True:
arcpy.mapping.UpdateLayer(df,lyr,lyrLineMaster,False)
elif desc.shapeType == "Polygon" and doPolygon == True:
arcpy.mapping.UpdateLayer(df,lyr,lyrPolyMaster,False)

# Reset the data source and the layer name - both of which have been changed to the Master
lyr.replaceDataSource(path,'FILEGDB_WORKSPACE',lyrName,True)
print(lyrName)
lyr.name = lyrName
print(lyr.name)
arcpy.RefreshActiveView()
arcpy.RefreshTOC()
del mxd

I am using ArcGIS 10.6

Can replaceDataSource be used to replace just one layer's data source?

Tags (1)
0 Kudos
3 Replies
DanPatterson
MVP Esteemed Contributor

Would it be possible for you to format your code to make it easier and to check for syntax errors.

Just saw the plea for code guidance.... here you have it... expand the . . . as in the link

Code formatting ... the Community Version - GeoNet, The Esri Community


... sort of retired...
0 Kudos
JohnMcGlynn
Occasional Contributor

Thanks Dan. This looks much better.

import arcpy, os

mxd = arcpy.mapping.MapDocument("CURRENT")  
df = arcpy.mapping.ListDataFrames(mxd,"Layers")[0]
layers = arcpy.mapping.ListLayers(mxd)
# Master featureclass names
PolylineMaster = 'PolylineMaster'
PointMaster = 'PointMaster'
PolygonMaster = 'PolygonMaster'
# Run each of point, polyline or polygon
doPoint = False
doPolyline = True
doPolygon = False

if doPoint == True:
    lyrPtMaster = arcpy.mapping.ListLayers(mxd,PointMaster,df)[0]

if doPolyline == True:
    lyrLineMaster = arcpy.mapping.ListLayers(mxd,PolylineMaster,df)[0]

if doPolygon == True:
    lyrPolyMaster = arcpy.mapping.ListLayers(mxd,PolygonMaster,df)[0]

for lyr in layers:
    lyrName = lyr.name
   
    if lyrName == PolylineMaster or lyrName == PointMaster or lyrName == PolygonMaster:
        continue
    else:
        print(lyrName)
        desc = arcpy.Describe(lyr)
        path = arcpy.Describe(lyr).catalogPath
        print(path)
        if desc.shapeType == "Point" and doPoint == True:
            arcpy.mapping.UpdateLayer(df,lyr,lyrPtMaster,False)
        elif desc.shapeType == "Polyline" and doPolyline == True:
            arcpy.mapping.UpdateLayer(df,lyr,lyrLineMaster,False)
        elif desc.shapeType == "Polygon" and doPolygon == True:
            arcpy.mapping.UpdateLayer(df,lyr,lyrPolyMaster,False)

        # Reset the data source and the layer name - both of which have been changed to the Master
        lyr.replaceDataSource(path,'FILEGDB_WORKSPACE',lyrName,True)
        print(lyrName)
        lyr.name = lyrName
        print(lyr.name)
arcpy.RefreshActiveView()
arcpy.RefreshTOC()
del mxd
0 Kudos
JeffK
by
Regular Contributor

I noticed in the examples they are saving the updated mxds as a copy.  Have you tried doing that and seeing if things are persisted?

I vaguely remember fixing some broken datasources in mxds a few years ago.  I can try to find the script and share it with you for some ideas but I think replaceDataSource didn't work and I ended up just replacing the layers path to make it stick.

0 Kudos