Select to view content in your preferred language

Can Python respond to events? Want to fix data frame rotation issue.

860
4
Jump to solution
07-13-2012 06:06 AM
AndrewMeador
Occasional Contributor
I have read through some posts and found some Python code to help but it's not quite where I need it.

I am usind Data Driven Pages (DDP) with two data frames in ArcMap (ArcEditor) 10.1. The layout has two data frames. The first data frame ("Layers") is where parcels are drawn with annotation etc... The seond data frame ("Shadow") sits over "Layers" and shows only the parcel lines from the 'maps' surrounding the active 'map' in grey - with no annotations. Some of the 'maps' have to be rotated to fit properly and that is handled with a field called Rotation in the DDP index layer (DistMap in my case). So, when I move from page to page in the DDP toolbar, then "Layers" data frame rotates properly, but the "Shadow" data frame does not. "Shadow" data frame sets it's extent and scale from the "Layers" data frame - but ArcDesktop is lacking an option to also have the "Shadow" data frame to match the Rotation of the other data frame.

So I have found posts on this topic, but not the solution I'm looking for. I want the rotation to happen for the "Shadow" data frame when I move from page to page in the DDP toolbar. Code that I have found/modified so far is:

import arcpy
mxd = arcpy.mapping.MapDocument("CURRENT")
topDF = arcpy.mapping.ListDataFrames(mxd, "Layer")[0]
bottomDF = arcpy.mapping.ListDataFrames(mxd, "Shadow")[0]

for DDP_Page in range(1, (mxd.dataDrivenPages.pageCount)):
>>>>mxd.dataDrivenPages.currentPageID = DDP_Page
>>>>angle = mxd.dataDrivenPages.pageRow.getValue("MapGrid.Rotation") # Make sure to use the table.field format to work correctly
>>>>bottomDF.rotation = angle
>>>># arcpy.mapping.ExportToPDF(mxd, r"C:\project\Map_20k_B" + str(DDP_Page) + ".pdf") # Add this line to export the data page - rotated for pdf file

But, the problem here is that the last data driven page pagerow record sets the angle used by the mxd current map document - not the individual data pages in the data driven pages. So, then when you iterate through the data driven pages with the DDP, after running this script, the last angle used on the last DDP page is used for all the pages.

I'm thus thinking that the way to solve this would be to attach to an event - like a DDP_PageChanged type of event to call the Python code to change the page rotation as the pages are navigated in the DDP toolbar. I also understant that VBA support is going away and I need a solution that will work down the line. Is there a way to do this?

I have been using ArcGIS software for about 5 years now (since 9.2) - so I am pretty familiar with the software - but I don't have much experience coding with VBA or Python for things like this. My main coding in Arc stuff has been using VBA for labeling feature classes. I took a class in ArcObjects for .NET a coupole of years ago - however it was a broken course - mostly taught on VB6 - COM methods instead of .NET and the part covering setup of installers for your tools was covered extremely fast and brushed over - so if I have to create a new tool of do this with .NET verses VBA or Python - that's fine, but will need pretty detailed help.

Thanks!
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
ChrisFox3
Frequent Contributor
In ArcMap go to Customize > Extensions and make sure your extension is checked on. I need to follow-up on auto-load because I was under the impression that this property would take care of it, but i can reproduce the same where the extension is not automatically being enabled in the extensions dialog.

View solution in original post

0 Kudos
4 Replies
ChrisFox3
Frequent Contributor
You can work with application events with Python now at 10.1 with python add-ins. If I understand correctly you want to be able to move from page to page in ArcMap and have the rotation of a second data frame match that as the first. I was able to do this with a python add-in. If you read through the guide book linked above it will walk you through creating an add-in, but essentially this is what you would do:

1. Create a python add-in with an extension that implements pageIndexExtentChanged
2. Add the following code inside the pageIndexExtentChanged function:

    def pageIndexExtentChanged(self, new_id):
        mxd = arcpy.mapping.MapDocument("Current")
        df1, df2 = arcpy.mapping.ListDataFrames(mxd)
        df2.rotation = df1.rotation


In the code above df1 is my data frame with ddp enabled and df2 is the other data frame I want to have the same rotation.
0 Kudos
AndrewMeador
Occasional Contributor
I followed your suggestions. I ended up with a Python script as follows:

import arcpy
import pythonaddins

class MyDDPTools_clsSyncDataFrameRotation(object):
    """Implementation for DDPTools_addin.clsSyncDataFrameRotation (Extension)"""
    def __init__(self):
        # For performance considerations, please remove all unused methods in this class.
        self.enabled = True
    def pageIndexExtentChanged(self, new_id):
        mxd = arcpy.mapping.MapDocument("Current")
        df1, df2 = arcpy.mapping.ListDataFrames(mxd)
        df2.rotation = df1.rotation
        print "pageIndexExtentChanged Event"
        print "Rotation DF1: " + df1.rotation
        print "Rotation DF2: " + df2.rotation
        pass

class btnPrevPage(object):
    """Implementation for DDPTools_addin.btnPrevPage (Button)"""
    def __init__(self):
        self.enabled = True
        self.checked = False
    def onClick(self):
        mxd = arcpy.mapping.MapDocument("CURRENT")
        topDF = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]
        bottomDF = arcpy.mapping.ListDataFrames(mxd, "Shadow")[0]
       
        if mxd.dataDrivenPages.currentPageID > 1:
            mxd.dataDrivenPages.currentPageID = mxd.dataDrivenPages.currentPageID - 1
            bottomDF.rotation = topDF.rotation
            print "btnPrevPage"
            print "Rotation topDF: " + str(round(topDF.rotation,2))
            print "Rotation bottomDF: " + str(round(bottomDF.rotation,2))
        pass


I created a custom toolbar with a custom button (the lower class in the code) that would allow me to click a 'Previous' button and have it to adjust the rotation based on the button_click code. I also used your code and made it an add-in extension responding the the event you mentioned. My button works, but the pageIndexExtentChanged event does not seem to get called. The debug 'prints' in the code shows in the Python command window for my button, but nothing prints when using the Data Driven Pages Toolbar nav buttons to change pages. Maybe a different event I should code to?

Is there something else wrong that I did not see? I set the extension properties to load on application startup as well. Any ideas?

Thanks!
0 Kudos
ChrisFox3
Frequent Contributor
In ArcMap go to Customize > Extensions and make sure your extension is checked on. I need to follow-up on auto-load because I was under the impression that this property would take care of it, but i can reproduce the same where the extension is not automatically being enabled in the extensions dialog.
0 Kudos
AndrewMeador
Occasional Contributor
Chris, that did the trick. Customize...Extensions...Checked my custom extension. Now it works fine!

I removed the custom toolbar and button and ended with the following code:

import arcpy
import pythonaddins

class MyDDPTools_clsSyncDataFrameRotation(object):
    """Implementation for DDPTools_addin.clsSyncDataFrameRotation (Extension)"""
    def __init__(self):
        # For performance considerations, please remove all unused methods in this class.
        self.enabled = True
    def pageIndexExtentChanged(self, new_id):
        mxd = arcpy.mapping.MapDocument("Current")
        df1, df2 = arcpy.mapping.ListDataFrames(mxd)
        df2.rotation = df1.rotation
        # print "pageIndexExtentChanged Event"
        # print "Rotation DF1: " + str(round(df1.rotation, 2))
        # print "Rotation DF2: " + str(round(df2.rotation, 2))
        pass

I appreciate your help - hopefully others can see and use this as well.

Thanks!
0 Kudos