3

I'm in the process of writing a script that will iterate through multiple MXDs and extract the data from layers that are turned on and only data that is within the data frame extent.

Some of the MXDs may have data frames that are not visible on the page. I don't want to extract the data from these data frames. So, I want to write a function that will test whether a data frame is within the page extent.

My first thought was to access the dimensions of the page layout using the page size property of the Map Document. Then I would iterate through each data frame and test the X and Y position and compare them to the page dimensions. In theory, this seemed like a good idea. However, I noticed that the positions change when the anchor point is changed.

Take the following example of an A4 page with four data frames. Two on the page and two off the page:

enter image description here

Focusing on the data frame on the left, I can see that it's off the page. When I look at the X position of the data frame, I can see that it is negative which seems to tell me that it is off the page.

enter image description here

Changing the anchor point, changes the X position:

enter image description here

and

enter image description here

I thought about adding the X position to the width. In the first example, when the anchor is set to bottom left, the X position plus the width is still negative, which would tell me that the data frame is off the page. However, if the anchor point is in the middle, or right, the sum of X position and width is positive, which would falsely indicate that the data frame is on the page.

This gets further complicated when the dataframe is partially overlapping the page. I also haven't gotten into the dataframe on the right or testing Y position, though the logic would be similar.

So, my question is, does there exist a method in arcpy to test if a data frame is on or overlaps a page extent?

I'm using ArcGIS Desktop 10.4.1 Basic.

12
  • Looks like there is an ArcGIS idea for this.
    – Fezter
    Commented May 17, 2017 at 1:23
  • 1
    I'm not sure whether this helps but perhaps you could make the anchor point irrelevant by always keeping/moving the data frame off the page by at least its width (for off page left/right) or height (for off page top/bottom).
    – PolyGeo
    Commented May 17, 2017 at 1:39
  • Another idea is to use the data frame's visible property to turn on/off instead of, or in addition to, moving them on/off the page. That way you have something simple and reliable to test for.
    – PolyGeo
    Commented May 17, 2017 at 1:53
  • @PolyGeo, I think that is only available in Pro. This would be exactly what I need.
    – Fezter
    Commented May 17, 2017 at 1:58
  • 1
    Still think it's a deficiency with the software. I wish there were methods like "contains", "disjoint","within", etc. like there are with extent objects.
    – Fezter
    Commented May 17, 2017 at 5:30

1 Answer 1

2

The following script will a) detect if a data frame is definitely on the page, and b) detect if a data frame might be on the page, based on a page width + data frame width calculation.

import arcpy
mxd = arcpy.mapping.MapDocument("CURRENT")
dfs = arcpy.mapping.ListDataFrames(mxd)
pagewidth = round(mxd.pageSize.width, 2)
pageheight = round(mxd.pageSize.height, 2)

for df in dfs:
    if df.name != 'Layers':
        apx = df.elementPositionX
        apy = df.elementPositionY
        w = df.elementWidth
        h = df.elementHeight
        maxheightbuffer = pageheight + h
        minheightbuffer = 0 - h
        maxwidthbuffer = pagewidth + w
        minwidthbuffer = 0 - w
        i = 0
        if (apx > 0 and apx < pagewidth) or (apy > 0 and apy < pageheight):
            arcpy.AddWarning("Data frame {0} is on the page!!".format(df.name))
        else:
            if apx > minwidthbuffer and apx < maxwidthbuffer:
                i += 1
            if apy > minheightbuffer and apy < maxheightbuffer:
                i += 1
            if i == 2:
                arcpy.AddMessage("Data frame {0} is within page buffer".format(df.name))
            else:
                arcpy.AddMessage("Data frame {0} is OK".format(df.name))

It does this by adding a width buffer and a height buffer to the actual page size, and determining if the data frame element could be within that those buffers based on the anchor point position and width/height of the element.

It can determine whether the anchor point is definitely on the page (if elementPositionX or elementPositionY is between 0 and the page width or height then it's on the page), so will give a Warning message. If the anchor point isn't on the page, then it applies the buffer to determine whether it's possible that some part of the frame might be on the page.

enter image description here

  • DF 'One' has anchor point bottom-left
  • DF 'Two' bottom-right
  • DF 'Three' bottom-left
  • DF 'Four' bottom-right

enter image description here

Basically, to be sure you'd need each element to be at least the buffer width from the page. The script could be modified to enforce this fairly easily, but this example at least tells you of the possibility.

2
  • This is great. It's similar to a solution that I've been working on. However, I didn't think of applying a page buffer. However, if you change the anchor point for DF Three to top right, it falsely states that it is within the page buffer and not on the page. Pretty close though. I'm thinking that there is a near zero chance that there will be data frames that partially overlap the page anyway, so I might not worry too much about them and just test for ones either on or off.
    – Fezter
    Commented May 18, 2017 at 22:32
  • @Fezter for your df 3 example that is what I'd expect. It is just detecting the position of the anchor point, so if the anchor point isn't on the page but is in the buffer it will say it's in the buffer.
    – Midavalo
    Commented May 18, 2017 at 23:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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