IOError trying to change PICTURE_ELEMENT sourceImage

2349
6
Jump to solution
06-19-2014 06:53 AM
LucasScharenbroich
Occasional Contributor
This question is cross-posted here.

I recently ran into this issue after I published a Geoprocessing Task to a production server.

My geoprocessing python code is an enhanced Web Map Print service that loads a map via the arcpy.mapping.ConvertWebMapToMapDocument function and either sets the sourceImage of a PICTURE_ELEMENT or moves it off of the page. The published GP Service works correctly on a development server, but returns the following error when running on the production server.

Unable to complete operation. Error executing tool.:   Traceback (most recent call last):     File "<ags_folder>\PythonWebPrint.GPServer\extracted\v101\my_toolboxes\service.py", line 643, in <module> main()    File "<ags_folder>\PythonWebPrint.GPServer\extracted\v101\my_toolboxes\service.py", line 634, in main (message, output_file, image_files) = execute(web_map_json, output_format, layout_template, layout_template2, georef_info, quality)    File "<ags_folder>\PythonWebPrint.GPServer\extracted\v101\my_toolboxes\service.py", line 482, in execute staticLegend.sourceImage = legendPath    File "c:\program files\arcgis\server\arcpy\arcpy\arcobjects\_base.py", line 87, in _set return setattr(self._arc_object, attr_name, cval(val))   IOError: Cannot set path based on current settings.   Failed to execute (PythonWebPrint). Failed to execute (Python Web Print).


Here is the relevant python code:

            elements = arcpy.mapping.ListLayoutElements(mxd, 'PICTURE_ELEMENT', "StaticLegend")             if len(elements) > 0:                 # Get the picture                 staticLegend = elements[0]                  if web_map_object.has_key("staticLegend"):                     legendPath = os.path.join(template_path, "legends", web_map_object["staticLegend"])                     staticLegend.sourceImage = legendPath                 else:                     # Cannot actually delete things, so just move it off the page                     staticLegend.elementPositionX = -100


I have verified that the correct file path is being used, and that the file exists and that the folder and file permissions are identical to the MXD files being loaded by the arcpy.mapping.ConvertWebMapToMapDocument function.

Any ideas as to the source of or how to fix this issue, or other diagnostics that I can perform?
0 Kudos
1 Solution

Accepted Solutions
LucasScharenbroich
Occasional Contributor
It shouldn't be an issue. I'd just sort of try some things at this point, one of which would be to save the image as a PNG. I'd also do  some diagnostic messaging just in case:

 
              if web_map_object.has_key("staticLegend"):                     legendPath = os.path.join(template_path, "legends", web_map_object["staticLegend"])                     arcpy.AddMessage("Setting legend to {0} -- is file? {1}".format(legendPath, os.path.isfile(legendPath)))                     staticLegend.sourceImage = legendPath



Solved! The call to os.path.isfile was returning false, which put me on the right track.  The critical difference between the development server and the production server was that, on the production server, the folder of MXD templates is located on a different drive than the AGS install (Drive 😧 ).

Although the relative path to the file was correct, it was not getting joined to the drive letter correctly, which caused python to look for the file relative to the current working directory of drive D:, as stated in python's os.path.join docs.

The path that was created was "D: path\\to\\my\\image.jpg", but needed to be "D:\\path\\to\\my\\image.jpg".

Thanks for all of your help; even though everything I had posted was not related to the underlying problem at all! 🙂

View solution in original post

0 Kudos
6 Replies
JasonScheirer
Occasional Contributor III
Does the map document have data-driven pages enabled? Is the picture element set to either 1) use a field as the image path or 2) use an attachment as the image source? If so, that is the reason you can't set the image path.
0 Kudos
LucasScharenbroich
Occasional Contributor
Does the map document have data-driven pages enabled? Is the picture element set to either 1) use a field as the image path or 2) use an attachment as the image source? If so, that is the reason you can't set the image path.


Data Driven Pages are not enabled and the Picture Source is set to "Simple Path".

I did notice that the MXD on the production server had the "Save Image as Part of Document" option checked while the test server MXD did not. I unchecked that option on the production MXD, but received the same error.
0 Kudos
JasonScheirer
Occasional Contributor III
Hmm. The only way other you'd get that particular error message is if arcgis either could not find or could not open the image file.
0 Kudos
LucasScharenbroich
Occasional Contributor
Hmm. The only way other you'd get that particular error message is if arcgis either could not find or could not open the image file.


Can it cause a problem if I try to set the sourceImage to a different file format than was originally saved in the MXD, e.g. create a PICTURE_ELEMENT from a PNG and then set the sourceImage to a JPEG?
0 Kudos
JasonScheirer
Occasional Contributor III
It shouldn't be an issue. I'd just sort of try some things at this point, one of which would be to save the image as a PNG. I'd also do  some diagnostic messaging just in case:

 
              if web_map_object.has_key("staticLegend"):
                    legendPath = os.path.join(template_path, "legends", web_map_object["staticLegend"])
                    arcpy.AddMessage("Setting legend to {0} -- is file? {1}".format(legendPath, os.path.isfile(legendPath)))
                    staticLegend.sourceImage = legendPath
0 Kudos
LucasScharenbroich
Occasional Contributor
It shouldn't be an issue. I'd just sort of try some things at this point, one of which would be to save the image as a PNG. I'd also do  some diagnostic messaging just in case:

 
              if web_map_object.has_key("staticLegend"):                     legendPath = os.path.join(template_path, "legends", web_map_object["staticLegend"])                     arcpy.AddMessage("Setting legend to {0} -- is file? {1}".format(legendPath, os.path.isfile(legendPath)))                     staticLegend.sourceImage = legendPath



Solved! The call to os.path.isfile was returning false, which put me on the right track.  The critical difference between the development server and the production server was that, on the production server, the folder of MXD templates is located on a different drive than the AGS install (Drive 😧 ).

Although the relative path to the file was correct, it was not getting joined to the drive letter correctly, which caused python to look for the file relative to the current working directory of drive D:, as stated in python's os.path.join docs.

The path that was created was "D: path\\to\\my\\image.jpg", but needed to be "D:\\path\\to\\my\\image.jpg".

Thanks for all of your help; even though everything I had posted was not related to the underlying problem at all! 🙂
0 Kudos