Tratando de encontrar una manera programación (arcpy) mover la leyenda si se intercepta los elementos dentro de un marco de datos, en el escenario de abajo, si la leyenda oculta de la vista de la ZONA de interés, entonces quiero que se mueva a una esquina diferente hasta que no es un problema. Esto tiene que estar en la parte superior del marco de datos en contraposición a hacer el marco de datos más pequeñas y acaba de poner en los laterales.
Respuestas
¿Demasiados anuncios?Entradas: Secuencia de comandos:
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()
NOTAS: Para cada página en las páginas controladas por datos de secuencia de comandos en el intento de encontrar suficiente espacio en dataframe esquinas para colocar la Leyenda (llamado myLegend) sin cubrir visible en la capa de entidades. Secuencia de comandos utiliza la red para identificar la esquina de las células. Celular dimensión es ligeramente mayor que la Leyenda de la dimensión en la vista de datos de las unidades. La celda de la esquina es el que comparte una frontera con 3 vecinos. Si no hay esquinas o sala, la Leyenda se coloca fuera de dataframe en la página de diseño.
Lamentablemente no sé cómo administrar la página de definición de consulta. Los puntos que se muestran fueron originalmente repartidas por todo el RECTÁNGULO de la medida, con algunos de ellos de no tener ninguna asociación con las páginas. Arcpy todavía se ve en toda la capa, aunque he aplicado la definición de la consulta (partido) a los puntos.
La forma en que yo haría sería crear una "leyenda elemento" en función de la clase que representa la leyenda del elemento en el mismo sistema de coordenadas que esas características.
De esa manera usted podría utilizar Seleccionar Capa Por Ubicación para probar si la leyenda elemento se superpone con cualquiera de las funciones, y moverlo si lo hace.
Su no-trivial, pero muy factible y hay un Q&A en este sitio (Convertir punto de XY a las unidades de página XY utilizando arcpy?) que podría ser utilizado para trabajar la parte más difícil de la conversión entre una página y un mapa de coordenadas.