Input:
Script:
import arcpy, traceback, os, sys, time
from arcpy import env
import numpy as np
env.overwriteOutput = True
outFolder=arcpy.GetParameterAsText(0)
env.workspace = outFolder
dpi=2000
tempf=r'in_memory\many'
sj=r'in_memory\sj'
## ERROR HANDLING
def showPyMessage():
arcpy.AddMessage(str(time.ctime()) + " - " + message)
try:
mxd = arcpy.mapping.MapDocument("CURRENT")
allLayers=arcpy.mapping.ListLayers(mxd,"*")
ddp = mxd.dataDrivenPages
df = arcpy.mapping.ListDataFrames(mxd)[0]
SR = df.spatialReference
## GET LEGEND ELEMENT
legendElm = arcpy.mapping.ListLayoutElements(mxd, "LEGEND_ELEMENT", "myLegend")[0]
# GET PAGES INFO
thePagesLayer = arcpy.mapping.ListLayers(mxd,ddp.indexLayer.name)[0]
fld = ddp.pageNameField.name
# SHUFFLE THROUGH PAGES
for pageID in range(1, ddp.pageCount+1):
ddp.currentPageID = pageID
aPage=ddp.pageRow.getValue(fld)
arcpy.RefreshActiveView()
## DEFINE WIDTH OF legend IN MAP UNITS..
E=df.extent
xmin=df.elementPositionX;xmax=xmin+df.elementWidth
x=[xmin,xmax];y=[E.XMin,E.XMax]
aX,bX=np.polyfit(x, y, 1)
w=aX*legendElm.elementWidth
## and COMPUTE NUMBER OF ROWS FOR FISHNET
nRows=(E.XMax-E.XMin)//w
## DEFINE HEIGHT OF legend IN MAP UNITS
ymin=df.elementPositionY;ymax=ymin+df.elementHeight
x=[ymin,ymax];y=[E.YMin,E.YMax]
aY,bY=np.polyfit(x, y, 1)
h=aY*legendElm.elementHeight
## and COMPUTE NUMBER OF COLUMNS FOR FISHNET
nCols=(E.YMax-E.YMin)//h
## CREATE FISHNET WITH SLIGHTLY BIGGER CELLS (due to different aspect ratio between legend and dataframe)
origPoint='%s %s' %(E.XMin,E.YMin)
yPoint='%s %s' %(E.XMin,E.YMax)
endPoint='%s %s' %(E.XMax,E.YMax)
arcpy.CreateFishnet_management(tempf, origPoint,yPoint,
"0", "0", nCols, nRows,endPoint,
"NO_LABELS", "", "POLYGON")
arcpy.DefineProjection_management(tempf, SR)
## CHECK CORNER CELLS ONLY
arcpy.SpatialJoin_analysis(tempf, tempf, sj, "JOIN_ONE_TO_ONE",
match_option="SHARE_A_LINE_SEGMENT_WITH")
nCorners=0
with arcpy.da.SearchCursor(sj, ("Shape@","Join_Count")) as cursor:
for shp, neighbours in cursor:
if neighbours!=3:continue
nCorners+=1; N=0
for lyr in allLayers:
if not lyr.visible:continue
if lyr.isGroupLayer:continue
if not lyr.isFeatureLayer:continue
## CHECK IF THERE ARE FEATURES INSIDE CORNER CELL
arcpy.Clip_analysis(lyr, shp, tempf)
result=arcpy.GetCount_management(tempf)
n=int(result.getOutput(0))
N+=n
if n>0: break
## IF NONE, CELL FOUND; COMPUTE PAGE COORDINATES FOR LEGEND AND BREAK
if N==0:
tempRaster=outFolder+os.sep+aPage+".png"
e=shp.extent;X=e.XMin;Y=e.YMin
x=(X-bX)/aX;y=(Y-bY)/aY
break
if nCorners==0: N=1
## IF NO CELL FOUND PLACE LEGEND OUTSIDE DATAFRAME
if N>0:
x=df.elementPositionX+df.elementWidth
y=df.elementPositionY
legendElm.elementPositionY=y
legendElm.elementPositionX=x
outFile=outFolder+os.sep+aPage+".png"
arcpy.AddMessage(outFile)
arcpy.mapping.ExportToPNG(mxd,outFile)
except:
message = "\n*** PYTHON ERRORS *** "; showPyMessage()
message = "Python Traceback Info: " + traceback.format_tb(sys.exc_info()[2])[0]; showPyMessage()
message = "Python Error Info: " + str(sys.exc_type)+ ": " + str(sys.exc_value) + "\n"; showPyMessage()
KELUARAN:
CATATAN: Untuk setiap halaman dalam skrip halaman yang didorong data, upaya untuk menemukan ruang yang cukup di sudut bingkai data untuk menempatkan Legend (disebut myLegend) tanpa mencakup lapisan fitur apa pun yang terlihat. Script menggunakan fishnet untuk mengidentifikasi sel sudut. Dimensi sel sedikit lebih besar dari dimensi Legenda dalam unit tampilan data. Sel sudut adalah sel yang memiliki batas dengan 3 tetangga. Jika tidak ada sudut atau ruang ditemukan, Legenda ditempatkan di luar kerangka data pada halaman tata letak.
Sayangnya saya tidak tahu bagaimana mengelola permintaan definisi halaman. Poin yang ditampilkan pada awalnya tersebar di sekitar tingkat RECTANGLE, dengan beberapa dari mereka tidak memiliki hubungan dengan halaman. Arcpy masih melihat seluruh lapisan, meskipun saya menerapkan kueri definisi (kecocokan) ke poin.