Hi everyone- I have an idea and I am just starting to learn Python so I would like to know if my idea can be executed using Python... So I have a polygon shapefile with 1000 polygons. Each polygon is a field/farm, the attribute table has the name of the owner and his/her address. I also happen to have a raster image that cover the same geography (satellite image). I want to print a brochure/newsletter to send it to these clients. In the front page of the brochure I will have texts and the address of the client (for postage). In the back, I want to print the clipped raster using the polygon for each field (each client has one corresponding polygon) as the clipping extent. Can I make a Python script that will my client specific brochures, so that the front of the brochure has the name and address of the client, and the back of the brochure has an image of the field (from the satellite raster image). I want to spend time and learn about this idea but I thought to ask first if such a task is possible using python/arcmap. Thanks. Esam
Solved! Go to Solution.
Yes I use Python extensively with my templates. I had to create the same set of three maps for several hundred polygon features, so I set up a template for each of the three maps I need, and used python to make a feature layer of each polygon ID in turn, zoom to it, then control each text elements already in the templates with data from the attribute table accessed via a search cursor. All the layers I need for each map already exist in the templates and I have them turned on and off via python depending on other attributes. So in the end I created ~2000 map documents and pdfs for the several hundred geometries in my feature class.
I could post a sample code for working with one of the templates if you wanted to see what it looked like, the arcpy mapping module has a good amount of control for controlling elements within map documents. I wouldn't post more than 1 though, since the code gets a bit long.
Hello there, Thanks for the help. Can you please explain what you mean by template in your first sentence.
Thanks
By template I mean I have a map document or set of map documents that have all the layers, text elements, layout elements etc already loaded into them that will be used for each type of map I need. Thus I can use the same map templates over and over again and all will be assured to have the same features, same text elements, same layouts. I have a python script that iterates over features in a feature class, zooms to each features, symbolizes them, turns on and off various layers saved in each map, and controls my text and layout elements based on values in the attribute table. I then save a copy of the created map in folders and export them to pdf.
Actually I'm currently working on a script to move my existing maps to a new template, some of the layout elements have changed and I need to adjust my existing maps. Its been fun so far and almost done that one. I will say that have a deliberate naming scheme for layers, layout elements, and map names have made the work substantially easier.
Hi Ian
I would like to see a sample of code so you can post it please.
Kelvin!
I don't mind posting the whole thing actually. Not quite as many comments as I would like in it, but if you have questions about how any of it works let me know.
The following script loops through features in a single shapefile or gdb with the particular fields I need, and uses those field values with several premade map templates to create a series of 3 maps for each feature in the shapefile or FC. Each template already has all layers needed saved to it, as well as text elements created and named, but the values of these elements will change according to the field values. All filepaths have been replaced with a generic filepath/ for my sake. Important to note, I had to make a specific folder structure for how I wanted all the maps and pdfs saved prior to running this script, there are other ways to make sure they are created as a script such as this runs, but making it prior was easier.
#Importing Modules import arcpy, time #Checking start time print time.time() #Permanent Variables shp = r"filepath\Export_Output.shp" symbologyLayer = r"filepath\Test.lyr" symbologyLayer2 = r"filepath\Test2.lyr" outlayer = shp + "_lyr" Month = "February" Year = "2015" OutputLoc = r"filepath" + "\\" DPI = 200 #fields from feature class that will be used for text elements/file naming fields = [ "Acreage", "City", "County" , "Name" , "State", "ED_Region", "ID"] #Looping through each record in shapefile or feature class with arcpy.da.SearchCursor(shp, fields) as cursor: for row in cursor: if row[4] == "MS": pass else: SiteName = row[3] State = row[4] City = row[1] County = row[2] Acres = row[0] Region = row[5] Hectares = str(int(int(Acres) * .4047)) Acres = str(int(Acres)) ID = row[6] #Optional output additions for additional subfolders. Output = OutputLoc + Region + "\\" + County + "\\" FileName = County + "_" + SiteName + "_" + str(ID) Title = "Aerial Imagery & FEMA 100 Year Floodplain" Fullpath = Output + FileName #Assembling Map - Selecting MXD, Dataframe, and New Layer for Aerial Map w/floodplain mxd = arcpy.mapping.MapDocument(r"filepath\AerialLetterTemplate.mxd") df = arcpy.mapping.ListDataFrames(mxd,"*")[0] newlayer = arcpy.mapping.Layer(shp) print "adding layer" arcpy.mapping.AddLayer(df, newlayer, "TOP") Layer = arcpy.mapping.ListLayers(mxd, newlayer.name)[0] #Selecting by Attribute, Zooming to Feature, and Setting Scale arcpy.SelectLayerByAttribute_management(Layer, "NEW_SELECTION", ' "Name" = ' + "'" + SiteName + "'" ) #Symbology from default lyr file arcpy.ApplySymbologyFromLayer_management (Layer, symbologyLayer) df.zoomToSelectedFeatures() print "Zooming to scale" #I set all my scales by multiples of 1200, engineers love this, I take the initial zoom scale, round it to nearest integer, then zoom it out an additional 1200 df.scale = ((round(df.scale / 1200.0) * 1200) + 1200) if df.scale == 8400: df.scale = 9600 arcpy.SelectLayerByAttribute_management(Layer, "CLEAR_SELECTION") #Editting Text Elements, names for text elements are hardcoded into the map print "Setting Text Elements" Layer2 = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT" , "Site Name and Size") [0] Layer2.text = SiteName + "\n" + " \n+/-" + Acres + " Acres \n +/-" + Hectares + " Hectares" Layer3 = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT" , "Title") [0] Layer3.text = Title + "\n" + SiteName + "\n" + City + ", " + State + " (" + County + " Co.)" Layer4 = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT" , "Prepared by Date") [0] Layer4.text = "Prepared " + Month + " " + Year + " by:" arcpy.RefreshActiveView() #Saving and Exporting Map print "Saving Map" print Fullpath + "_Aerial.mxd" #mxd.saveACopy(OutputLoc + SiteName +" - Aerial.mxd") mxd.saveACopy(Fullpath + "_Aerial.mxd") print "Saving PDF" #arcpy.mapping.ExportToPDF(mxd, OutputLoc + SiteName + " _ Aerial.pdf", "Page_Layout", 640, 480, DPI) arcpy.mapping.ExportToPDF(mxd, Fullpath + "_Aerial.pdf", "Page_Layout", 640, 480, DPI) print "Save Complete!" del Layer; del Layer2; del Layer3; del Layer4; del mxd print time.time() print "Next Map" #Assembling Map - Selecting MXD, Dataframe, and New Layer mxd = arcpy.mapping.MapDocument(r"filepath\TopoLetterTemplate.mxd") df = arcpy.mapping.ListDataFrames(mxd,"*")[0] arcpy.mapping.AddLayer(df, newlayer, "TOP") Layer = arcpy.mapping.ListLayers(mxd, newlayer.name)[0] arcpy.ApplySymbologyFromLayer_management (Layer, symbologyLayer) print Layer.name Title = "USGS Topo Map & NWI Wetlands" arcpy.SelectLayerByAttribute_management(Layer, "NEW_SELECTION", ' "Name" = ' + "'" + SiteName + "'" ) #Applying Symbology from default lyr file arcpy.ApplySymbologyFromLayer_management (Layer, symbologyLayer) df.zoomToSelectedFeatures() df.scale = ((round(df.scale / 1200.0) * 1200) + 1200) if df.scale == 8400: df.scale = 9600 arcpy.SelectLayerByAttribute_management(Layer, "CLEAR_SELECTION") #Setting Layer and Text Elements WetlandLayer = arcpy.mapping.ListLayers(mxd, "*" + State, df)[0] WetlandLayer.visible = True Layer2 = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT" , "Site Name and Size") [0] Layer2.text = SiteName + "\n" + " \n+/-" + Acres + " Acres \n+/-" + Hectares + " Hectares" Layer3 = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT" , "Title") [0] Layer3.text = Title + "\n" + SiteName + "\n" + City + ", " + State + " (" + County + " Co.)" Layer4 = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT" , "Prepared by Date") [0] Layer4.text = "Prepared " + Month + " " + Year + " by:" arcpy.RefreshActiveView() #mxd.saveACopy(OutputLoc + SiteName +" - Aerial.mxd") mxd.saveACopy(Fullpath + "_Topo.mxd") print "Saving PDF" #arcpy.mapping.ExportToPDF(mxd, OutputLoc + SiteName + " - Aerial.pdf", "Page_Layout", 640, 480, DPI) arcpy.mapping.ExportToPDF(mxd, Fullpath + "_Topo.pdf", "Page_Layout", 640, 480, DPI) del Layer; del Layer2; del Layer3; del Layer4; del WetlandLayer; del mxd mxd = arcpy.mapping.MapDocument(r"filepath\LocationLetterTemplate.mxd") Title = "Site Location Map" #This map has multiple dataframes, which I need to loop through for df in arcpy.mapping.ListDataFrames(mxd): if df.name == "Area Map": arcpy.mapping.AddLayer(df, newlayer, "TOP") Layer = arcpy.mapping.ListLayers(mxd, newlayer.name)[0] OutLayer = "OutLayer_lyr1" print Layer.name arcpy.SelectLayerByAttribute_management(Layer, "NEW_SELECTION", ' "Name" = ' + "'" + SiteName + "'" ) print "Making Feature Layer" arcpy.MakeFeatureLayer_management(Layer, OutLayer) OutLayer2 = arcpy.mapping.Layer(OutLayer) arcpy.mapping.AddLayer(df, OutLayer2, "TOP") print "Removing Old Layer" Layer3 = arcpy.mapping.ListLayers(mxd, OutLayer2)[0] #Applying Symbology from default lyr file arcpy.ApplySymbologyFromLayer_management (Layer3, symbologyLayer) df.zoomToSelectedFeatures() df.scale = 126720 arcpy.SelectLayerByAttribute_management(Layer, "CLEAR_SELECTION") arcpy.mapping.RemoveLayer(df, Layer) del Layer; elif df.name == "Inset": arcpy.mapping.AddLayer(df, newlayer, "TOP") Layer = arcpy.mapping.ListLayers(mxd, newlayer.name, df)[0] OutLayerA = "OutLayer_lyr2" print Layer.name arcpy.SelectLayerByAttribute_management(Layer, "NEW_SELECTION", ' "Name" = ' + "'" + SiteName + "'" ) #Applying Symbology from default lyr file arcpy.MakeFeatureLayer_management(Layer, OutLayerA) OutLayerC = arcpy.mapping.Layer(OutLayerA) arcpy.mapping.AddLayer(df, OutLayerC, "TOP") OutLayerB = arcpy.mapping.ListLayers(mxd, OutLayerC.name)[0] arcpy.ApplySymbologyFromLayer_management (OutLayerB, symbologyLayer2) df.zoomToSelectedFeatures() df.scale = 2300000 arcpy.SelectLayerByAttribute_management(Layer, "CLEAR_SELECTION") arcpy.mapping.RemoveLayer(df, Layer) del OutLayer2; del OutLayerC; del OutLayerB; del Layer3 else: continue Layer3 = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT" , "Title") [0] Layer3.text = Title + "\n" + SiteName + "\n" + City + ", " + State + " (" + County + " Co.)" Layer4 = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT" , "Prepared by Date") [0] Layer4.text = "Prepared " + Month + " " + Year + " by:" arcpy.RefreshActiveView() #mxd.saveACopy(OutputLoc + SiteName +" - Aerial.mxd") mxd.saveACopy(Fullpath + "_Location.mxd") print "Saving PDF" #arcpy.mapping.ExportToPDF(mxd, OutputLoc + SiteName + " - Aerial.pdf", "Page_Layout", 640, 480, DPI) arcpy.mapping.ExportToPDF(mxd, Fullpath + "_Location.pdf", "Page_Layout", 640, 480, DPI) del Layer; del Layer3; del Layer4; del mxd; arcpy.Delete_management(OutLayer) arcpy.Delete_management(OutLayerA) print time.time() del shp
Hi Aicam, you can have any layers you want in your project, including a raster image, and they will all remain visible on every pdf.
Hi Sephe
Do you know if DDP would work on two data frames for the same layout simultaneously?
Thanks