2

I have a custom script tool that is supposed to set up a map layout, by adjusting the scale bar, north arrow, title, and legend. It is then supposed to reference a bookmark and export the layout as a PDF.

The problem is that when I use this tool in ModelBuilder it references the wrong bookmarks

I'm using this script tool in ModelBuilder for ArcGIS Pro. This model iterates through Urgent Care centers and its corresponding data one at a time (in alphabetical order by center name). I have bookmarks for every Urgent Care center, so my thought is that, if I can find a way for the model to reference the bookmarks in alphabetical order, then they will correspond with the correct Urgent Care center.

Could this be achieved via a table or list Index, or some kind of loop? Or is there a better way to go about this whole process?

Here is the code from the script tool I am using.

import arcpy

# input layer

lyr = arcpy.GetParameterAsText(0)

# input name of layout

p = arcpy.mp.ArcGISProject("CURRENT")
lyt = p.listLayouts("Layout_King")[0]

# Reposition the scale bar

scaleBar = lyt.listElements("MAPSURROUND_ELEMENT", "Scale Bar")[0]
mf = scaleBar.mapFrame
scaleBar.elementPositionX = mf.elementPositionX + 0.0
scaleBar.elementPositionY = mf.elementPositionY - 0.5

# Reposition the north arrow

northArrow = lyt.listElements("MAPSURROUND_ELEMENT", "North Arrow")[0]
mf = northArrow.mapFrame
northArrow.elementPositionX = mf.elementPositionX + 8.8
northArrow.elementPositionY = mf.elementPositionY + 0.7

# Align the title with the center of the map frame

title = lyt.listElements("TEXT_ELEMENT","Name of Map Text")[0]
mf = lyt.listElements('MAPFRAME_ELEMENT',"Map Frame")[0]
title.elementPositionX = mf.elementPositionX + (mf.elementWidth / 3.7)
title.elementPositionY = mf.elementPositionY + (mf.elementHeight / 0.98)

# Reposition the Legend and fix legend title

legend = lyt.listElements("LEGEND_ELEMENT", "Legend")[0]
legend.title = "Legend"
legend.elementPositionX = mf.elementPositionX + 7.7
legend.elementPositionY = mf.elementPositionY + 7.15

# setting layout to bookmark

aprx = arcpy.mp.ArcGISProject("Current")

# add name of layout

lyt = aprx.listLayouts("Layout_King")[0]
mf = lyt.listElements("MAPFRAME_ELEMENT")[0]

# add name of bookmark

bkmks = mf.map.listBookmarks("*")
for bkmk in bkmks:
  mf.zoomToBookmark(bkmk)
lyt.exportToPDF(r"C:\arcGIS_Shared\Exports" + "\\" + bkmk.name + ".pdf")

I tried the bkmks.sort() earlier, but it gives me this error:

Traceback (most recent call last):
  File "<string>", line 10, in <module>
TypeError: unorderable types: Bookmark() < Bookmark()

I also tried to print the bookmark list using:

bkmks = mf.map.listBookmarks("*") bkmks.sort() print (bkmks)

But it gives me this error:

 File "<string>", line 1
    bkmks = mf.map.listBookmarks("*") bkmks.sort() print (bkmks)
                                          ^
SyntaxError: invalid syntax
1

you need to sort the list first (this re orders the list items in alphabetical order

bkmks = mf.map.listBookmarks("*")
bkmks.sort()
for bkmk in bkmks:
    mf.zoomToBookmark(bkmk)
    lyt.exportToPDF(r"C:\arcGIS_Shared\Exports" + "\\" + bkmk.name + ".pdf")

also your function for listing bookmarks seems incorrect. remove the quotes "" around * that is telling python * is a string (which its not) I would remove it all together, its going to list all bookmarks by default.

bkmks = mf.map.listBookmarks()
for bkmk in bkmks:
  mf.zoomToBookmark(bkmk)
lyt.exportToPDF(r"C:\arcGIS_Shared\Exports" + "\\" + bkmk.name + ".pdf")
  • I tried the bkmks.sort() earlier, but it gives me this error..... Traceback (most recent call last): File "C:\arcGIS_Shared\PythonTest_2\Layout_Bookmark_Export_Script.py", line 43, in <module> bkmks.sort() TypeError: unorderable types: Bookmark() < Bookmark() Failed to execute (Layout Bookmark Export). – Matt A. Nov 21 '17 at 16:11
  • print the list and lets see what its giving you (it may be object IDs) – NULL.Dude Nov 21 '17 at 16:14
  • 3
    You can't simply bkmks.sort() - bkmks is a list, but its a list of Bookmark objects. You can sort on the name attribute by doing bkmks.sort(key=lambda x: x.name) to sort in place – KHibma Nov 21 '17 at 17:16
  • 2
    You can reverse it by: bkmks.sort(key=lambda x: x.name, reverse=True) – KHibma Nov 21 '17 at 17:50
  • 1
    post your entire code in a new question (please format it) you will need to use a for loop. for bkmk in bkmks: update dframe with bk and export... exact code will be provided in new question – NULL.Dude Nov 21 '17 at 19:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.