Loop to make layers and create maps

729
10
03-05-2012 08:14 AM
EvaJenkins
New Contributor
Hi,

I have a python script (arcpy) that is used to create a list of unique values of a field, then I want to loop through those values and make a feature layer for each, update map text, update symbology, and export to a PDF.  So far, the issue seems to be linking the value of the field in the feature class with the value in the unique values list.  The script appears to work aside from this (i.e. exports nice maps with no data).  Can anyone help me with that link and the where clause in the MakeFeatureLayer tool?


import arcpy.mapping

arcpy.env.overwriteOutputs = True

inFC = r"F:\DATA\PROJECTS\RUBL\layers\RUBL.gdb\National_bothtimeperiods"
inField = "survey_month"

mxd = arcpy.mapping.MapDocument(r"F:\DATA\PROJECTS\RUBL\workspaces\RUBL_National_Monthly.mxd")
df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]
outloc = r"F:\DATA\PROJECTS\RUBL\maps\Month"

sourcelayer = arcpy.mapping.ListLayers(mxd, "Survey Records", df)[0]

valueList = []
rows = arcpy.SearchCursor(inFC)
for row in rows:
  aVal = row.getValue(inField)
  if aVal not in valueList:
    valueList.append(aVal)

del row, rows
print valueList


for value in valueList:
  #make feature layer where survey_month field equals the current value in the unique list
 
  lyrbase = "MonthLyr"
  val = str(value)
  lyrname = lyrbase + value

 
  arcpy.MakeFeatureLayer_management(inFC, lyrname, "[survey_month] = value")
  arcpy.RefreshTOC()
 
 
  #update symbology based on layer in mxd

  for lyr in arcpy.mapping.ListLayers(mxd, lyrname,df):
    arcpy.mapping.UpdateLayer(df, lyrname, sourcelayer, True)

  #change the text element to read the month of the current unique value
  for elm in arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "Month"):
    elm.text = "Month: " + value
   
  #export to PDF with settings
  outfile = outloc + value
  arcpy.mapping.ExportToPDF(mxd, outfile, data_frame="PAGE_LAYOUT", resolution=300, image_quality="BEST", colorspace="CMYK", image_compression="LZW", convert_markers="True", embed_fonts="True")

  #remove the current layer so that the next can be created and mapped correctly
  for df in arcpy.mapping.ListDataFrames(mxd):
    for lyr in arcpy.mapping.ListLayers(mxd, lyrname, df):
      arcpy.mapping.RemoveLayer(df, lyr)
Tags (2)
0 Kudos
10 Replies
BruceNielsen
Occasional Contributor III
The statement 'val = str(value)' implies that value is not a string, but on the next line 'lyrname = lyrbase + value' you're trying to append it onto the end of a string. Do you want to use 'lyrname = lyrbase + val' instead?
0 Kudos
MathewCoyle
Frequent Contributor
This is probably more what you want. I assume you aren't looking for an attribute of "value". Also, I am not sure if the square brackets are needed.
where =  "[survey_month] = " + value
arcpy.MakeFeatureLayer_management(inFC, lyrname, where)
0 Kudos
EvaJenkins
New Contributor
The statement 'val = str(value)' implies that value is not a string, but on the next line 'lyrname = lyrbase + value' you're trying to append it onto the end of a string. Do you want to use 'lyrname = lyrbase + val' instead?


Yes, you are right, the layername should have the string version attached
0 Kudos
EvaJenkins
New Contributor
This is probably more what you want. I assume you aren't looking for an attribute of "value". Also, I am not sure if the square brackets are needed.
where =  "[survey_month] = " + value
arcpy.MakeFeatureLayer_management(inFC, lyrname, where)


I tried this solution but I'm getting an error as follows:

Traceback (most recent call last):
  File "F:\DATA\PROJECTS\RUBL\docs\month_mapping.py", line 34, in <module>
    where = "[survey_month] = " + value
TypeError: cannot concatenate 'str' and 'float' objects
0 Kudos
EvaJenkins
New Contributor
This is probably more what you want. I assume you aren't looking for an attribute of "value". Also, I am not sure if the square brackets are needed.
where =  "[survey_month] = " + value
arcpy.MakeFeatureLayer_management(inFC, lyrname, where)


oh, I think that is because I was using the float value not the one converted to a string, used the val variable instead with your solution but am still getting no data showing up on the final map...
0 Kudos
MathewCoyle
Frequent Contributor
If it is a string field it will need to be formatted as such. Something like this should work.
where =  "[survey_month] = '" + value + "'"

You can try building a sample query in arcmap to get your formatting down.
0 Kudos
EvaJenkins
New Contributor
If it is a string field it will need to be formatted as such. Something like this should work.
where =  "[survey_month] = '" + value + "'"

You can try building a sample query in arcmap to get your formatting down.


My problem is that it is not a string field...it is a double with values between 1 and 12 for month.
0 Kudos
MathewCoyle
Frequent Contributor
Try posting the code you are using now with the
 tags so it is formatted properly.


If it is just 1-12, you could just use an integer, but that is beside the point. Have you put an arcpy.RefreshActiveView() in after you add your layers?
0 Kudos
EvaJenkins
New Contributor
Try posting the code you are using now with the
 tags so it is formatted properly.

If it is just 1-12, you could just use an integer, but that is beside the point. Have you put an arcpy.RefreshActiveView() in after you add your layers?



Is there a special way to format a variable to be read as an integer within a where clause?  I added in the refresh function, but still get blank outputs (supposedly because nothing "equals the variable")....


valueList = []
rows = arcpy.SearchCursor(inFC)
for row in rows:
  aVal = row.getValue(inField)
  if aVal not in valueList:
    valueList.append(aVal)
del row, rows
print valueList


for value in valueList:
  #make feature layer where survey_month field equals the current value in the unique list 
  lyrbase = "MonthLyr"
  val = str(value) #this is done just so I can use it for naming
  lyrname = lyrbase + val
 
  arcpy.MakeFeatureLayer_management(inFC, lyrname, "[survey_month] = value")
  arcpy.RefreshActiveView()
0 Kudos