MapFrame and using exportToPNG(), is this a bug?

1109
9
Jump to solution
04-22-2022 07:00 AM
DuncanHornby
MVP Notable Contributor

All,

I came across this Q&A on GIS Stack exchange, the poster wanted to export the MapFrame in a layout to a PNG which was zoomed to a feature defined by a definition query, but it creates a much large extent of output when exported .

Someone answered, but their code does not really work. I adapted their code to adjust the extent of the MapView and camera objects, but like the original poster I too end up exporting a much larger PNG.

So my question is, is this by design or a bug in ArcPro 2.9.2 arcpy? If the MapFrame is showing a zoomed in section of the data I would have expected the export process to export only that?

The code is this:

 

 

 

import arcpy
arcpy.env.overwriteOutput = True

myPrj = arcpy.mp.ArcGISProject('current')
myLayout = myPrj.listLayouts("FirstPrintLayout")[0]
mapframe = myLayout.listElements("MAPFRAME_ELEMENT", "Map Frame 1")[0]

for lyr in mapframe.map.listLayers("River Centreline 2006"):
    if lyr.supports("DEFINITIONQUERY"):
        print(lyr.name, ' has defQuery ', lyr.definitionQuery)
        print ('Excellent! So now lets get the extents')
        mapExtent = mapframe.getLayerExtent(lyr)

        print (f'5 - mapFrame  XMin extents: {mapExtent.XMin}')
        print (f'Ymin {mapExtent.YMin}')
        print (f'XMax {mapExtent.XMax}')
        print (f'YMax {mapExtent.YMax}')
        
        mapframe.camera.setExtent(mapExtent)
        
        theMapView = myPrj.activeView # This line expects the Map to be Active Not Layout.
        theMapView.panToExtent(mapExtent)
               
        # Export Map Frame
        mapframe.exportToPNG(out_png='c:\Temp\outimg.png', resolution=60)
        print('Export completed!')

 

 

 

 

Note: my sample data is in British National Grid

0 Kudos
1 Solution

Accepted Solutions
JeffBarrette
Esri Regular Contributor

Duncan,  we figured it out.  MapFrames were hard-coded to pageunits=inches and you were using mm.  The extent was so far off because of the conversion from units to pixel space, etc.  We should have this fixed in Pro 3.0.   So the work around continues to be what I suggested above or changing your page units to inches (which I know is not something you may want to do).  Thank you so much for reporting this.  I'm surprised it took so long to be discovered.

Jeff - Layout and arcpy.mp teams.

View solution in original post

0 Kudos
9 Replies
JeffBarrette
Esri Regular Contributor

Hello Duncan,  I can NOT reproduce the issue.  The script successfully sets the MF extent by zooming to the features that match the Def Query. For me the exported PNG extent matches the MapFrame extent I see on the layout. 

Lines 21 and 22 do not make sense to me in the context of  exporting a MapFrame.  You must be running the script with the LayoutView active instead of the map view.  If I activate the MapView and run your script, it all works as expected:  The MapView extent is only panned, while the MapFrame extent is zoomed to the QueryDef features.

I tried all this on 2.9.  If you could provide more detail, I'd be happy to look futher.

Jeff - Layout and arcpy.mp teams

0 Kudos
DuncanHornby
MVP Notable Contributor

Jeff,

Thanks for looking into this issue. Lines 21 & 22 were my attempt to see if the MapView was in some way overriding the MapFrame extent which gets sets by the definition query extent.

I wonder if the format of the data is in someway influencing the export process? E.g. is it a shapefile or geodatabase featureclass or do polygons work but not points?

How were you running the script, in the python console (as I had) or via notebook?

I will have another go and try it with some other dataset and report back.

0 Kudos
JeffBarrette
Esri Regular Contributor

I was running your code in the Python Window.  You are more than welcome to send me a small PPKX so I can ensure we don't have an extent bug. 

jbarrette@esri.com - Layout and arcpy.mp teams

0 Kudos
DuncanHornby
MVP Notable Contributor

@JeffBarrette ,

Here is a map package with a totally different dataset. I have applied a def query on one polygon (PID = 26), then run the code below:

 

import arcpy
arcpy.env.overwriteOutput = True

myPrj = arcpy.mp.ArcGISProject('current')
myLayout = myPrj.listLayouts("FirstPrintLayout")[0]
mapframe = myLayout.listElements("MAPFRAME_ELEMENT", "Map Frame 1")[0]

for lyr in mapframe.map.listLayers("fcTestData"):
    if lyr.supports("DEFINITIONQUERY"):
        print(lyr.name, ' has defQuery ', lyr.definitionQuery)
        print ('Excellent! So now lets get the extents')
        
        # Select zoom to then clear selection on the polygon defined in definition query
        sql = "PID = 26"
        arcpy.SelectLayerByAttribute_management(lyr,'NEW_SELECTION',sql)        
        mapExtent = mapframe.getLayerExtent(lyr,True)
        arcpy.SelectLayerByAttribute_management(lyr, "CLEAR_SELECTION")

        print (f'5 - mapFrame  XMin extents: {mapExtent.XMin}')
        print (f'Ymin {mapExtent.YMin}')
        print (f'XMax {mapExtent.XMax}')
        print (f'YMax {mapExtent.YMax}')
        
        mapframe.camera.setExtent(mapExtent)
                       
        # Export Map Frame
        mapframe.exportToPNG(out_png='c:\Temp\outimg.png', resolution=60)
        print('Export completed!')

 

 

I have modified the code slightly to zoom into the selected feature

sql = "PID = 26"
arcpy.SelectLayerByAttribute_management(lyr,'NEW_SELECTION',sql)
mapExtent = mapframe.getLayerExtent(lyr,True)
arcpy.SelectLayerByAttribute_management(lyr, "CLEAR_SELECTION")

So I open the project, open Python console and paste the above code in and run it. The output is an png zoomed to the extent of the layer, not the zoomed in selected feature, BUT the map fame has zoomed in, you can see this in the layout.  It seems to me that export process is not honouring the extent the map frame is displaying but that of the layer?

0 Kudos
JeffBarrette
Esri Regular Contributor

Thanks Duncan.  I can reproduce the issue with your data / script.  If I apply your scripting logic to data I have, I can NOT reproduce.  I will continue to dig.  I'm curious, is this the only data you can reproduce the issue with? 

Also - are you getting unusually slow export times?  For me, it is even slower if I modify your script to work outside of the application.

0 Kudos
DuncanHornby
MVP Notable Contributor

Jeff,

I've only tried to replicate the original problem (as highlighted on GIS SE) with 2 completely different datasets (both British National Grid). So I assume if I try a third dataset I would get the same problem.

For the record I'm using ArcPro 2.9.2 on a Windows 10 machine with 16GB of ram.

Yes when I ran it as a script in the python console I noticed it took a long time to complete, much longer than expected. If you export the whole layout using the Export Layout button on the Share tab it takes about 4 seconds...

It seems to me that the exporttoPNG() is not working correctly when its the mapframe that is being exported rather than the whole layout.

0 Kudos
JeffBarrette
Esri Regular Contributor

Duncan,

We have your repro steps and we are looking into it.  In the meantime, a possible workaround it so customize the size of the Layout to be the same size as the MapFrame and then export the Layout instead of the MapFrame.  The layout is exporting with the proper map frame extent as you indicate.

0 Kudos
JeffBarrette
Esri Regular Contributor

Duncan,  we figured it out.  MapFrames were hard-coded to pageunits=inches and you were using mm.  The extent was so far off because of the conversion from units to pixel space, etc.  We should have this fixed in Pro 3.0.   So the work around continues to be what I suggested above or changing your page units to inches (which I know is not something you may want to do).  Thank you so much for reporting this.  I'm surprised it took so long to be discovered.

Jeff - Layout and arcpy.mp teams.

0 Kudos
DuncanHornby
MVP Notable Contributor

Jeff, thats great news. To be fair it was @Maxcot on GIS SE who discovered it. I recognised it as odd behaviour, not what I would have expected and something that needed resolving, hence me bringing it up on this forum. I personally have never attempted to export just a map frame usually for me it would be the whole layout.

0 Kudos