3

I am trying to update a map based on a pre-built mxd template. However, after everything ran successfully (python code below), the shapefile that was updated did not show up on the map. Its symbology was also changed from "Quantities: Graduated colors" to "Features: Single symbol".

What did I do wrong?

enter image description here

Steps that I did:

  • Read the original shapefile in the mxd template.
  • Copied that shapefile to a new one.
  • Added a csv file then joined it with the newly created shapefile.
  • Updated existing field in the new feature with the values in the csv file.
  • Change the data source from the original shapefile to the new one.
  • Refreshed TOC and ActiveView then exported to a new mxd file.

I opened the new mxd file. The data source is correctly updated to the new file. Values in the attribute table were also correct but the shapefile did not appear in the layout view.

import os
import ntpath
import arcpy
from arcpy import env 

arcpy.env.overwriteOutput = True

### set project directory
project_dir = os.path.expanduser('~/Projects/')
mxd_dir = os.path.join(project_dir, 'GIS/mxd/')
gis_dir = os.path.join(project_dir, 'GIS/shapefile')
env.workspace = os.path.join(project_dir, gis_dir)

year = '2019'
dframe = 'Baseline'   
csv_file = 'sample.csv'

### open mxd template file
mxd_file = "my_template.mxd"
full_path = os.path.join(mxd_dir + mxd_file)
mxd = arcpy.mapping.MapDocument(full_path)

### list data frame in the mxd file
df = arcpy.mapping.ListDataFrames(mxd, dframe)[0]

### list layers
layers = arcpy.mapping.ListLayers(df)

### this is the shapefile in the template with a customized legend/symbology
inFeatures = os.path.join(gis_dir, "Q_" + dframe + ".shp")
print(inFeatures)

### make a copy
outFeatures = os.path.join(gis_dir, "output", "Q_" + dframe + "_" + year + ".shp")
arcpy.CopyFeatures_management(in_features = inFeatures, out_feature_class = outFeatures)        

### join then do field calculator on the new feature 
arcpy.MakeFeatureLayer_management(in_features = outFeatures, out_layer = 'new_lyr')        
arcpy.MakeTableView_management(in_table = csv_file, out_view = 'csv_ec')
arcpy.AddJoin_management(in_layer_or_view = 'new_lyr', in_field = 'ID', join_table = 'csv_ec', join_field = 'ID')        
arcpy.CalculateField_management('new_lyr', 
                                "Q_" + dframe + "_" + year + ".Q", "!" + "Q_" + dframe + ".csv" + ".Q_new!", 
                                "PYTHON")
### remove all joins
arcpy.RemoveJoin_management('new_lyr')

### update data source
for lyr in layers:
    if dframe in lyr.name:
        lyr.replaceDataSource(os.path.join(gis_dir, "output", dframe), "SHAPEFILE_WORKSPACE", 
                              os.path.splitext(ntpath.basename(outFeatures))[0])

### update Layout View
arcpy.RefreshTOC()
arcpy.RefreshActiveView()

### save to new mxd file
new_mxd = "new_Q_" + year.upper() + ".mxd"
new_mxd_path = os.path.join(mxd_dir + new_mxd)
mxd.saveACopy(new_mxd)

### clean up the MapDocument object by deleting it
del mxd

This question has an open bounty worth +50 reputation from Tung ending in 10 hours.

This question has not received enough attention.

  • I'm not sure if it's the best way to do it, but how I've done it in the past was to save a template layer and apply it to my output with arcpy.ApplySymbologyFromLayer_management(layer, template_layer.lyr). Also, did you check your geoprocessing options to make sure 'Add results of geoprocessing operations to the display' is checked? – geodranic Nov 6 at 12:48
  • Thanks @geodranic! I did try arcpy.ApplySymbologyFromLayer_management(layer, template_layer.lyr) but nothing happened. If I did every calculation on the original shapefile inFeatures then the template was updated as expected. However, the original feature was overwritten which is not ideal. – Tung Nov 6 at 13:47
0

The problem could be related to your lyr.replaceDataSource assignments. The first argument should be pointing to the workspace, not the data or non-existing folder or existing folder without the right data in it. Previously you create your copy in GIS/shapefile/output but then you are looking for another folder, GIS/shapefile/output/Baseline, which might exist (but may not have the right copy of your data).

I would recommend changing lyr.replaceDataSource(os.path.join(gis_dir, "output", dframe), ... with lyr.replaceDataSource(arcpy.os.path.dirname(outFeatures), ....

Still, cannot understand this though,

The data source is correctly updated to the new file

.

  • Thanks for the help! The data source is correctly updated to the new file meant that when I opened the new edited mxd file, the data source of the feature layer in the current ArcGIS data frame was pointed to the new shapefile (outFeatures). Note that If I did every calculation on the original shapefile inFeatures then the template was updated as expected. I got the correct output that I wanted. However, the original feature was overwritten which is not ideal. – Tung 14 hours ago

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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