Issues in projection while defining data frame extent by coordinates

4675
10
02-05-2015 03:54 PM
BenjaminBauman
Occasional Contributor

I'm trying to set the following coordinates to a dataframe:

    custom_extent = {1:-87.678956, 2: -87.611652, 3:41.867129, 4:41.954932}

where `1` is key for `XMin`, `2` is key for `XMax`, `3` is key for `YMin`, and `4` is key for `YMax`

However, when I try to set the new extent up, the coordinates are not the results I expect. Here's a code snippet:

            print data_frame.extent.XMin                                        # prints 480718.855003

            original_spatial_reference = data_frame.spatialReference

            newExtent = data_frame.extent

            data_frame.spatialReference = arcpy.SpatialReference("WGS 1984")

            print data_frame.extent.XMin                                        # prints -87.6986700746

            newExtent.XMin, newExtent.XMax = custom_extent[1], custom_extent[2]

            newExtent.YMin, newExtent.YMax = custom_extent[3], custom_extent[4]

            data_frame.extent = newExtent                                    

            print data_frame.extent.XMin                                        # prints -93.500018925

            data_frame.spatialReference = original_spatial_reference

            print data_frame.extent.XMin                                        # prints -2.38749449402

Every printout does not match the desired `XMin`: `-87.678956`. Any thoughts?

Tags (2)
0 Kudos
10 Replies
DanPatterson_Retired
MVP Emeritus

The extent object normally defines the lower left and then the upper right, check that you have your numbers in the correct order  ArcGIS Help (10.2, 10.2.1, and 10.2.2)

0 Kudos
BenjaminBauman
Occasional Contributor

Dan, I''m not sure I follow.

When I reorder the dictionary keys in the following lines:

            newExtent.XMin, newExtent.XMax = custom_extent[1], custom_extent[2]

            newExtent.YMin, newExtent.YMax = custom_extent[3], custom_extent[4]

I still am not seeing satisfactory results. Is this what you are referring to?

0 Kudos
DanPatterson_Retired
MVP Emeritus

ok...not used to seeing extents that way...I have seen that issue before and I had to go into the layer properties and recalculate the extent of the layer manually and in some instances export the file to a new one before the extents in the new coordinate system are updated.  It appears that setting the extent object isn't enough and I haven't been able to find an arcpy property/method to update one.  I notice this translating coordinates  in an arbitrary World mercator projection centered around 0,0 then redefining the coordinate system to a modified transverse mercator shifted by 300,000 in X and 5,100,000 in Y.  Oddly, the lower extent was retained (around 0,0) yet the upper was correct.  So in short...not definitive answer but you aren't alone

0 Kudos
JasonSchwartz
New Contributor III

Ben,

There's a comment in the documentation for the Extent property of the DataFrame class:  "If the aspect ratio of the extent does not match the shape of the data frame, the final extent will be adjusted to fit the new extent within the shape of the data frame. In other words, if you set explicit X, Y coordinates, you may not get the same values returned if you attempt to read them later. "  <--I suspect this is what is partly the cause of what's happening.

A second contributing factor may be the dataFrame object is assigned out of an 'original_spatial_reference' into 'WGS 84' then back into the original spatial reference again. -- although there isn't print out of what the original is.

Here's my request: please print out the original_spatial_reference, the dataframe map units, and the elementWidth, elementHeight at each step in the routine: before you start, during the assignments, and before/after each spatial reference shift. -- The last two properties will let us look at the dataframe aspect ratio which is held constant during the assignment of Mins and Maxs. 

Lastly, while in WGS84, try setting the extent of your MXD by hand using those input values, then shift spatial references back to your original spatial reference and map units, then interrogate the MXD to look for those odd printed out values. (the ones that look like UTM meters and/or decimal degrees.)

Good news is that your custom_extent array and newExtents assignments are formatted correctly; there should be nothing wrong with these.

Please reply back with what printouts arcpy gives at each step and we'll proceed from there.

Jason S. aka JasonInVegas

0 Kudos
DanPatterson_Retired
MVP Emeritus

Interesting Jason, but I have experience weird extent behaviour when working solely with arcpy (ie no ArcMap open and no *.mxd referenced).  I will try to post a demo when I get off this iThingy and on to my desktop.

0 Kudos
BenjaminBauman
Occasional Contributor

Dan, I appreciate your help in all of this. I also tend to see differences in result when I'm using ArcPy with mxd set as "CURRENT" vs running ArcPy via a standalone script.

0 Kudos
BenjaminBauman
Occasional Contributor

Jason - the documentation makes sense in that regard - if the dimensions of the data frame differ from the received coordinates, naturally they're not going to be precise. However, as you know, this goes beyond that problem.

The following printout reflects a set of print statements done prior to every line seen above, with an additional set of print statements following the last line.

XMin 480718.855003

XMax 487765.034905

YMin -897522.367118

YMax -892753.723682

mapUnits Meters

spatialReference <geoprocessing spatial reference object object at 0x0D2102D8>

elementWidth 13.6918

elementHeight 9.2662

XMin 480718.855003

XMax 487765.034905

YMin -897522.367118

YMax -892753.723682

mapUnits Meters

spatialReference <geoprocessing spatial reference object object at 0x0D210428>

elementWidth 13.6918

elementHeight 9.2662

XMin 480718.855003

XMax 487765.034905

YMin -897522.367118

YMax -892753.723682

mapUnits Meters

spatialReference <geoprocessing spatial reference object object at 0x0D210410>

elementWidth 13.6918

elementHeight 9.2662

XMin -87.6986889715

XMax -87.6353211223

YMin 41.9155057359

YMax 41.9583911976

mapUnits DecimalDegrees

spatialReference <geoprocessing spatial reference object object at 0x0D210410>

elementWidth 13.6918

elementHeight 9.2662

XMin -87.6986889715

XMax -87.6353211223

YMin 41.9155057359

YMax 41.9583911976

mapUnits DecimalDegrees

spatialReference <geoprocessing spatial reference object object at 0x0D210410>

elementWidth 13.6918

elementHeight 9.2662

XMin -93.500046392

XMax -93.4999395774

YMin 50.1891561644

YMax 50.1892284534

mapUnits DecimalDegrees

spatialReference <geoprocessing spatial reference object object at 0x0D210410>

elementWidth 13.6918

elementHeight 9.2662

XMin -5.44407670288

XMax 6.44407996557

YMin -0.0228719610641

YMax 8.02267627373

mapUnits Meters

spatialReference <geoprocessing spatial reference object object at 0x0D210410>

elementWidth 13.6918

elementHeight 9.2662

I will try setting the extent manually tomorrow when I have more time.

0 Kudos
JasonSchwartz1
New Contributor

Hey Ben, this looks just like you described (and baffling to me.)  Can you sub-qurey into the spatialReference object  to printout more than the in-memory Object handle?  The goods (i.e. reason for this madness) may be contained therein.

How about including these properties: sO.projectionname; GCSname; linearunitcode <-- that one may be the key.

Good luck!

0 Kudos
BenjaminBauman
Occasional Contributor

Hey Jason, I've pretty much given up this approach in favor of a roundabout method of setting the dataframe extent by zooming to selected features. Perhaps I'll go about doing a printout of those properties at some point down the road, but for the time being, I've moved on to other things (partially out of frustration, and partially out of time constraints).

I'm shocked that something so simple could be such a challenge to implement.

0 Kudos