Save To PDF Script Prints at Wrong Scale

869
6
08-27-2013 04:46 AM
PatrickKielty
New Contributor III
I am trying to use the SaveT To PDF Example by Ismael. I successfully set up the template for my use. My issue, is the scale at which the PDF prints. In the MXD, the Layout is set to the County but the PDF prints at the State scale (see attached). I am thinking the script is using the extent of all layers to determine the scale, and since I am using a Definition Query on a layer, the extent is that of the entire layer.
Below is the code. Anybody have any suggestions as to how to force the script to maintain the scale set in the Layout Window? Thanks.

import arcpy
import os

arcpy.env.overwriteOutput = True

def main():

    arcpy.AddMessage("  Collecting input parameters")

    # Get Initial Coordinates
    xMin = arcpy.GetParameterAsText(0)
    if xMin == '#' or not xMin:
        arcpy.AddError("Cannot proceed if xMin is not passed")

    yMin = arcpy.GetParameterAsText(1)
    if yMin == '#' or not yMin:
        arcpy.AddError("Cannot proceed if yMin is not passed")

    xMax = arcpy.GetParameterAsText(2)
    if xMax == '#' or not xMax:
        arcpy.AddError("Cannot proceed if xMax is not passed")

    yMax = arcpy.GetParameterAsText(3)
    if yMax == '#' or not yMax:
        arcpy.AddError("Cannot proceed if yMax is not passed")

    xMin = float(xMin)
    yMin = float(yMin)
    xMax = float(xMax)
    yMax = float(yMax)

    # Get the input spatial reference
    srValIn = arcpy.GetParameterAsText(4)
    if srValIn == '#' or not srValIn:
        arcpy.AddError("Cannot proceed if the Spatial Reference of your extent is not passed")
    srIn = arcpy.CreateObject('SpatialReference')
    srIn.loadFromString(srValIn)

    # Get Layout Folder
    LayoutsFolderPath = arcpy.GetParameterAsText(5)
    if LayoutsFolderPath == '#' or not LayoutsFolderPath:
        arcpy.AddError("Cannot proceed if the Layout Folder is not passed")
        return

    # Get template document
    Layout = arcpy.GetParameterAsText(6)
    if Layout == '#' or not Layout:
        arcpy.AddError(Layout + " does not exist. File not found:" + mxdName)
        return

    mxdName = os.path.join(LayoutsFolderPath, Layout)
    if not (os.path.exists(mxdName)):
        arcpy.AddError(Layout + " does not exist. File not found:" + mxdName)
        return

    mapDoc = arcpy.mapping.MapDocument(mxdName)

    # Get the requested scale
    mapScale = arcpy.GetParameterAsText(7)
    if mapScale == '#' or not mapScale:
        mapScale = 0 # provide a default value if unspecified
    mapScale = float(mapScale)
   
    # layers only or layers and attributes
    attributesFlag = arcpy.GetParameterAsText(8)
    if attributesFlag.lower() == 'true':
        layers_string = "LAYERS_AND_ATTRIBUTES"
    else:
        layers_string = "LAYERS_ONLY"

    # Get the requested Map Title
    title = arcpy.GetParameterAsText(9)
    if title == '#' or not title:
        title = " " # provide a default value if unspecified


    # Get pdf file path to create
    outputPDFPath = arcpy.GetParameterAsText(10)
    if outputPDFPath == '#' or not outputPDFPath:
        arcpy.AddError("Cannot proceed without specifying an output path for the pdf file")
        return

    # Build the extent in the Layout document
    dataFrame = arcpy.mapping.ListDataFrames(mapDoc)[0]

    arcpy.AddMessage("  Processing Map Extent")
    dataFrame.extent = calculateExtent_Original(xMin,xMax,yMin,yMax,dataFrame,srIn)
   
    # Set the scale if necessary
    if mapScale > 0:
        arcpy.AddMessage("  Setting scale to: " + str(mapScale))
        dataFrame.scale = mapScale

    # Set the Map title
    if title != " ":
        for elm in arcpy.mapping.ListLayoutElements(mapDoc, "TEXT_ELEMENT"):
            if elm.text == "Map Title":
               elm.text = title

    # Export
    arcpy.AddMessage("  Saving as PDF")
    arcpy.mapping.ExportToPDF(mapDoc,outputPDFPath, layers_attributes=layers_string)

def calculateExtent_Original(xMin,xMax,yMin,yMax,dataFrame,srIn):
    # Make input extent coordinates in the same sr as the data frame
    pntInLL = arcpy.Point()
    pntInLL.X = xMin
    pntInLL.Y = yMin

    pntInUR = arcpy.Point()
    pntInUR.X = xMax
    pntInUR.Y = yMax

    pntGeomInLL = arcpy.PointGeometry(pntInLL,srIn)
    pntGeomInUR = arcpy.PointGeometry(pntInUR,srIn)

    pntGeomList = []
    pntGeomList.append(pntGeomInLL)
    pntGeomList.append(pntGeomInUR)

    arcpy.CopyFeatures_management(pntGeomList, "in_memory/extentPnts")
    rows = arcpy.SearchCursor("in_memory/extentPnts", "", dataFrame.spatialReference)

    rows.reset()
    row = rows.next()
    newPntLL = row.shape.getPart(0)

    row = rows.next()
    newPntUR = row.shape.getPart(0)

    myExtent = arcpy.CreateObject('Extent', newPntLL.X, newPntLL.Y, newPntUR.X, newPntUR.Y)
#arcpy.AddMessage("New extent: %s %s %s %s" % (myExtent.XMin, myExtent.YMin, myExtent.XMax, myExtent.YMax))

    return myExtent


if __name__ == "__main__":
    main()
Tags (2)
0 Kudos
6 Replies
MathewCoyle
Frequent Contributor
How are you inputting your xMin, yMin, etc. values into your script? Are they manually entered or automatic from your layer? What specifically are you trying to isolate as your extent?

Also.
http://forums.arcgis.com/threads/48475-Please-read-How-to-post-Python-code
0 Kudos
markdenil
Occasional Contributor III
You set the dataframe scale
dataFrame.scale = mapScale
but you never actually apply it to the view.

try sticking an
arcpy.RefreshActiveView()
in there before exporting


BTW   Please use the CODE tags (the # formating button) when posting code!
0 Kudos
PatrickKielty
New Contributor III
How are you inputting your xMin, yMin, etc. values into your script? Are they manually entered or automatic from your layer? What specifically are you trying to isolate as your extent?

Also.
http://forums.arcgis.com/threads/48475-Please-read-How-to-post-Python-code


Thanks for your Reply Matthew,
I am trying to enter them automatically.
I am trying to isolate the County Boundary as my extent. The county boundary is a "definition query".

I am using this tool found on ArcGIS.com as my base http://www.arcgis.com/home/item.html?id=442e1c7ff64240af8f41825f567e60d0
0 Kudos
MattSayler
Occasional Contributor II
You could also set up Data Driven Pages using the county feature class (or make a separate grid). That would give you a few options for how to set the scale.
0 Kudos
dannyrecthor
New Contributor
why not try some third party software to do this , iam using an pdf processing programme to do anything with pdf including save pdf , i think it's great, you may have a try, good luck!
0 Kudos
deleted-user-MS0lE1F_0-sy
Occasional Contributor
# Define Map (mxd) Document Location.
mxd = arcpy.mapping.MapDocument("MapLocation")

# Define Map Data Frame.
df = arcpy.mapping.ListDataFrames(mxd, "NameOfDataframe")[0]

# Select County Layer, Zoom to Layer.
arcpy.SelectLayerByAttribute_management("CountyLayer","NEW_SELECTION")
df.zoomToSelectedFeatures()

# Define scale of dataframe to match the county layer you zoomed to.
df.scale = df.scale
# If that did not work this should.
scale = df.scale
df.scale = scale

# This will set the Reference Scale to match the df.scale, if you want.
df.referenceScale = df.scale

# Clear the Selection, So its not blue on the pdf export.
arcpy.SelectLayerByAttribute_management("CountyLayer","CLEAR_SELECTION")

# Refresh the Active View.
arcpy.RefreshActiveView
0 Kudos