Problem accessing ModelBuilder variable in a python script?

771
4
Jump to solution
07-25-2012 05:18 PM
IanThomas1
New Contributor III
Dear ArcPy & Python Folk,

I am trying to make a fairly simple model in ArcGIS10.1 ModelBuilder to do the following:

i) Iterate through a polygon feature layer (High_resolution.shp).
ii) As each new polygon is selected fire up a python script (Zoomer1.py) that zooms to the selected polygon and exports a Geojpeg

Model looks like this:

[ATTACH=CONFIG]16405[/ATTACH]

Code for the Zoomer1.py script looks like this:

import arcpy  mxd = arcpy.mapping.MapDocument("CURRENT") df = arcpy.mapping.ListDataFrames(mxd,"Imagery")[0] lyr = arcpy.mapping.ListLayers(mxd, "High_resolution", df)[0]  # Use the SelectLayerByAttribute tool to select and  # zoom to the selection  arcpy.SelectLayerByAttribute_management(lyr, "NEW_SELECTION", "AreaID = '%output_value%'") df.zoomToSelectedFeatures() arcpy.RefreshActiveView()  # Export the map to a .jpg  # Next Line Wrong! Outputs a jpeg actually called "test%output_value%.jpg" # outfile = "C:/Test/test" + "%output_value%" + ".jpg"  # Next Line Wrong! Gives Syntax error # outfile = "C:/Test/test" + %output_value% + ".jpg"  # Works.... outfile = "C:/Test/test1.jpg"  arcpy.mapping.ExportToJPEG(mxd, outfile, df, df_export_width=1600, df_export_height=1200, world_file=True)  # Clear the selection and refresh the active view arcpy.SelectLayerByAttribute_management(lyr, "CLEAR_SELECTION") arcpy.RefreshActiveView()


My problem:

I can not get the Exported Jpeg filename to change each time for a new polygon.
Ideally I would like a series of output jpegs for each poly: test1.jpg. test2.jpg, test3.jpg, etc....

Current script is not able to recognize the ModelBuilder variable %output_value% when trying to form the outfile name.

However, I can leave the output file as static name (eg. "C:/Test/test1.jpg") and then manually periodically check it:
It is working correctly and a new geojpeg for each polygon is being made (but unfortunately overwriting the previous jpeg).

Quite confused as this would indicate that the ModelBuilder variable is getting passed correctly to the Zommer1.py script eg:
"arcpy.SelectLayerByAttribute_management(lyr, "NEW_SELECTION", "Area = '%output_value%'")"
is working correctly....

So how do I successfully use the ModelBuilder %output_value% to make sequential filenames???
Or is there some other work-around? Didn't really expect this to be such a problem....


PS. I also observe that arcpy.RefreshActiveView() is also not updating the screen for each new polygon (which would be nice).

Many thanks in advance for your advice,

Ian Thomas
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
IanThomas1
New Contributor III
Dear ArcPy & Python Folk,

I now find the relevant help section here:

'>http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/Integrating_scripts_within_a_model/0...


which mentions setting up parameter properties on the script
and then shows the use of the following example setup code:

 import sys, string, os, arcgisscripting gp = arcgisscripting.create(9.3) tablePath = gp.GetParameterAsText(0)


But only provides just one example...
Little bit of ArcPy Voodoo there...
What exactly is "arcgisscripting" and where is this python module more fully documented?
Is this still the best way to do things in ArcGIS 10.1?
Where are there more examples of doing this?


I can now alter my script as follows:
import arcpy import sys, string, os, arcgisscripting gp = arcgisscripting.create(9.3)   mxd = arcpy.mapping.MapDocument("CURRENT") df = arcpy.mapping.ListDataFrames(mxd,"Imagery")[0] lyr = arcpy.mapping.ListLayers(mxd, "High_resolution", df)[0]  # Trying to get %output_value% as an in-script variable scriptVar = gp.GetParameterAsText(0)  # Use the SelectLayerByAttribute tool to select and  # zoom to the selection  arcpy.SelectLayerByAttribute_management(lyr, "NEW_SELECTION", "Area = '%output_value%'") df.zoomToSelectedFeatures() arcpy.RefreshActiveView()  outfile = "test" + scriptVar + ".jpg"  arcpy.mapping.ExportToJPEG(mxd, r"C:\Test\\" + outfile, df, df_export_width=1600, df_export_height=1200, world_file=True)  # Clear the selection and refresh the active view arcpy.SelectLayerByAttribute_management(lyr, "CLEAR_SELECTION") arcpy.RefreshActiveView() 



And I finally get a test1.jpg...test2.jpg...test3.jpg
indicating the ModelBuilder %output_value% has been successfully
passed to scriptVar one time also correctly zooming to the first polygon:)!!

Many thanks for the advice.

Ian

View solution in original post

0 Kudos
4 Replies
ChristopherThompson
Occasional Contributor III
This thread may provide the answer you're looking for, appears you have to pass those values using arcpy.GetParameter statements.

That said, you could probably use a search cursor or an update cursor like this within your zoomer script and accomplish the same thing (warning, i haven't tested this code, its purely conceptual at this point, so there are things you might have to explore and finesse to make it work exactly how you want it):

import arcpy

mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd,"Imagery")[0]
lyr = arcpy.mapping.ListLayers(mxd, "High_resolution", df)[0]

#Create a variable to hold the value you want to update in your table - can be set as a raw_input variable if you want to have
#the user input this at the beginning of the model run
#or you can hard code it in the script
value = 'XXX' 
#create an update cursor
rows = arcpy.UpdateCursor(lyr,'','','calcField;FeatID')
#step through each row of the cursor, and perform all the actions you want while pointed at that row
for row in rows:
    row.calcField = value #changes the value of the calcField attribute but doesn't make it permanent 
    rows.updateRows(row) #updates the row so the change is permanent
    arcpy.SelectLayerByAttribute_management(lyr, "NEW_SELECTION", '\"AreaID\" =' + row.FeatID)
    df.zoomToSelectedFeatures()
    arcpy.RefreshActiveView()
    outfile = "C:/Test/test1.jpg"
    arcpy.mapping.ExportToJPEG(mxd, outfile, df, df_export_width=1600, df_export_height=1200, world_file=True)
    arcpy.SelectLayerByAttribute_management(lyr, "CLEAR_SELECTION")
    arcpy.RefreshActiveView()
0 Kudos
IanThomas1
New Contributor III
Greetings Chris,

Many thanks for the advice....
Unfortunately I'm not sure yet how your suggested solutions can be implimented for my particular problem.

I actually need to eventually implant my python script in a much larger model...so I really need the ModelBuilder to do the "Iteration Feature Selection" (and other things) before firing up the python script. With this requirement in mind creating a cursor inside the script itself instead is unfortunately not a useable solution.

Regarding your other suggestion:

I have tried using arcpy.GetParameterAsText(0) but without success. Actually still really struggling to find out how to do this properly...it would seem a very good thing to be able to do in so many other situations as well not just for this particular problem.

Specifically I could summarize my problem to a more general question:

My model (in ModelBuilder) keeps updating a variable, %output_value%, that is the only precondition to a python script (also in the model).  How do you successfully pass that variable (from ModelBuilder to the python script) so that it becomes an in-script variable (eg. InScriptVar) equal to the new value of  %output_value%  each time the python script is called.

The following attempt unfortunately does not appear to work... 
InScriptVar = arcpy.GetParameterAsText(0)


Result InScriptVar does not receive anything....

PS. Incidentally what is the easiest way/trick to see what is going on with variables inside a python script when it is executing embedded inside of a ModelBuilder workflow?

Many thanks again for all your advice.

Ian
0 Kudos
IanThomas1
New Contributor III
Dear ArcPy & Python Folk,

I now find the relevant help section here:

'>http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/Integrating_scripts_within_a_model/0...


which mentions setting up parameter properties on the script
and then shows the use of the following example setup code:

 import sys, string, os, arcgisscripting gp = arcgisscripting.create(9.3) tablePath = gp.GetParameterAsText(0)


But only provides just one example...
Little bit of ArcPy Voodoo there...
What exactly is "arcgisscripting" and where is this python module more fully documented?
Is this still the best way to do things in ArcGIS 10.1?
Where are there more examples of doing this?


I can now alter my script as follows:
import arcpy import sys, string, os, arcgisscripting gp = arcgisscripting.create(9.3)   mxd = arcpy.mapping.MapDocument("CURRENT") df = arcpy.mapping.ListDataFrames(mxd,"Imagery")[0] lyr = arcpy.mapping.ListLayers(mxd, "High_resolution", df)[0]  # Trying to get %output_value% as an in-script variable scriptVar = gp.GetParameterAsText(0)  # Use the SelectLayerByAttribute tool to select and  # zoom to the selection  arcpy.SelectLayerByAttribute_management(lyr, "NEW_SELECTION", "Area = '%output_value%'") df.zoomToSelectedFeatures() arcpy.RefreshActiveView()  outfile = "test" + scriptVar + ".jpg"  arcpy.mapping.ExportToJPEG(mxd, r"C:\Test\\" + outfile, df, df_export_width=1600, df_export_height=1200, world_file=True)  # Clear the selection and refresh the active view arcpy.SelectLayerByAttribute_management(lyr, "CLEAR_SELECTION") arcpy.RefreshActiveView() 



And I finally get a test1.jpg...test2.jpg...test3.jpg
indicating the ModelBuilder %output_value% has been successfully
passed to scriptVar one time also correctly zooming to the first polygon:)!!

Many thanks for the advice.

Ian

0 Kudos
ChristopherThompson
Occasional Contributor III
My apologies, I apparently didn't provide you a link to another post as i intended in my earlier response.  The link that I think providesthe answer you are looking for: http://forums.arcgis.com/threads/23570-how-to-pass-a-variable-to-a-python-script-in-model-builder see if that helps.  You were on the right track i think, just need to use a different method than GetParameterAsText.
0 Kudos