Select to view content in your preferred language

Arcpy inconsistent in setting layout map extents

1224
4
02-29-2012 06:11 AM
markdenil
Frequent Contributor
I have been using arcpy to set a layout data frame to one of several (39) different locations. The data frame parameters I am setting are map extents, rotation and scale, as well as page location, height and width. I also set some text labels and apply a definition query to certain data layers.

All of the parameters are (currently) saved in a pickled python dictionary. They will likely eventually migrate to a Geodatabase table, but in development the dictionary is convenient.

My problem is with setting the extents for the data frame object. Sometimes the extents set just fine (the frame takes the extents I specify), but often it does not. Sometimes the error is in both the X and Y, and sometimes in only one or the other. It is not consistent in which of the named extents is affected: any one particular map may be correct, wrong in X, wrong in Y, or wrong in both X and Y any particular time.

I have been testing the routine by looping through the process 1000 times, and in each iteration I select a random entry from the parameter dictionary. After each time the frame is set, I create a new data frame object and test the parameters against the values I had just used for setting it.

In 1000 iterations:
426 had no extent errors, and 574 had some error.
of the 574 errors:
279 were incorrect in both X and Y
138 were incorrect in X alone
157 were incorrect in Y alone

There were no errors in rotation, scale, height, width, or page location.
Other values from the dictionary (area long name and abbreviation) are also always correct.

The problem seems to be that setting the extent values do not always 'take'.

The setting code is quite straightforward:
##      set extent
    newExtent = df.extent
    newExtent.XMin = extent[0]
    newExtent.YMin = extent[1]
    newExtent.XMax = extent[2]
    newExtent.YMax = extent[3]
    df.extent = newExtent

df is the data frame object, and extent is a list of extent parameters saved in the dictionary entry.

Values from a previous loop are not being carried over. The wrong values, when they appear, are just plain wrong and seem unconnected with anything.

Why is the data frame object extent object so flaky?
Tags (2)
0 Kudos
4 Replies
JeffBarrette
Esri Regular Contributor
I believe we may have addressed this issue at 10.1.  The current work around (at 10.0) is to set the extent a second time:

##set extent
    newExtent = df.extent
    newExtent.XMin = extent[0]
    newExtent.YMin = extent[1]
    newExtent.XMax = extent[2]
    newExtent.YMax = extent[3]
    df.extent = newExtent

##set extent (AGAIN)
    newExtent = df.extent
    newExtent.XMin = extent[0]
    newExtent.YMin = extent[1]
    newExtent.XMax = extent[2]
    newExtent.YMax = extent[3]
    df.extent = newExtent


There were situations where the coordinates where too far outside the extent and the aspect ratios didn't align with the data frame extent.  Please try running the same code twice.  In the case with problem extent, the first time you set extent, it simply brings the extent into view but does NOT set it to the full data frame extent.  The second set extent appears to do this.

I really hope this helps,
Jeff
0 Kudos
markdenil
Frequent Contributor
It had occurred to me to try this, and some testing of the various assignments showed that I was correctly setting the newExtent object.
To wit, the tests like: if newExtent.XMin != extent[0]: do not find errors.

However, the problem seems to lie in assigning the modified newExtent values back into df.extent.
Testing the newExtent object properties against the data frame's extent object properties after the df.extent = newExtent assignment, as in: if newExtent.XMin != df.extent.XMIn, does often show an error (about half the time, on average).

I tried doing the df.extent = newExtent assignment a second time when I detected a mismatch between the newExtent properties and the dataframe extent properties, but this had no (noticeable) effect.

Admittedly, I am also changing the scale and rotation with most extent changes, but it does not seem that this has anything to do with the problem (or at least with the symptoms). My test routine keeps a log of each iteration, and even when the same region comes up consecutively in the random selection, the second time the data frame is set to the same properties (extent, rotation and scale) it is still wrong, just different. (oddly, if the extent was indeed set correctly the first time, and was set again to that same extent just immediately after, it stayed correct).

One area's extent was set to the following Y values in consecutive passes:
coord: Ymin, Ymax
values should be: 1674066.38781, 2277317.59431      
was set first to: -514299.354449, 88951.8520538
and then set to:  881509.119933, 1484760.32644
which just seems random...

The aspect ratio of the frame page size should not be the problem: I built the dictionary from previously composed individual data frames, showing the correct areas at the correct rotation and scale. All the parameters were captured from the individual data frames. Plus, when the extent sets correctly, as all regions eventually do, at least occasionally, the frames show what I had specified.

It looks like I will just have to sit tight and wait for 10.1... and hope this is fixed(?)

.... I may try grabing the data frame object again and setting that new df.extent a second time (because setting the same df.extent twice did not help). It will help pass the time until the 10.1 release.....

Thanks, though.
0 Kudos
markdenil
Frequent Contributor
Okay. using a second dataframe object has made a real difference.
As I mentioned; setting the first one twice did not help.
This way the test went from 500+ errors in 1000 tries to 2 to 6 errors in 1000.

    ##      set extent
    newExtent = df.extent
    newExtent.XMin = extent[0]
    newExtent.YMin = extent[1]
    newExtent.XMax = extent[2]
    newExtent.YMax = extent[3]
    df.extent = newExtent
    del newExtent

    ##      set extent a second time - v10 bug workaround
    df2 = arcpy.mapping.ListDataFrames(mxd, "MAIN_MAP")[0]
    anotherExtent = df2.extent
    anotherExtent.XMin = extent[0]
    anotherExtent.YMin = extent[1]
    anotherExtent.XMax = extent[2]
    anotherExtent.YMax = extent[3]
    df2.extent = anotherExtent
    del anotherExtent

    ##      set rotation and scale
    df.rotation = rotation
    df.scale = scale



It is still not perfect, but has certainly improved.
The rotation and scale have to be set AFTER the second extent setting. If set between times the errors skyrocketed, and scale errors were added to the mix.

... a useful workaround...
0 Kudos
JamesRamm
Deactivated User

Would just like to point out that this error still exists in arcgis 10.2

A work around I used is to set the extent, and save a temporary image file. Then delete the image file and set the extent again (using the same extent object). The extents of the dataframe will have changed.

It seems it is not particularly the data frame not 'capturing' the extents properly, but the extents themselves being wrong?

Also, simply setting the extents twice didnt work for me. I have to save the image inbetween. Could be an indicator of references hanging round/caches not being cleared or similar?

0 Kudos