8 votos

Mover leyenda si se superpone a las características dentro del marco de datos mediante ArcPy

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.

enter image description here

7voto

FelixIP Puntos 4035

Entradas: enter image description here 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()

SALIDA: enter image description here

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.

3voto

UnkwnTech Puntos 21942

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.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X