7 votos

¿Cómo convertir coordenadas de mapa a coordenadas de diseño en un marco de datos girado?

Estoy tratando de convertir a Mapa de coordenadas X e y correspondientes a Diseño de coordenadas en una rotación del dataframe.

El código que se encuentra en este post funciona bien, pero sólo para rotar dataframes.

También he encontrado una modificación del código anterior en este post en Reddit, pero que no parece funcionar bien. Creo que el código estaba haciendo uso de una matriz de rotación como se discute en este post, pero sin éxito, en mi opinión.

Los resultados que obtengo son algo cerrar cuando el dataframe no gira mucho, pero exageran la mayor rotación.

Alguien ha tenido éxito definitivo con la conversión de las coordenadas X e y para el Diseño de coordenadas?

Estoy buscando una solución python dentro de ArcGIS. Estoy usando 10.3.1 Licencia Estándar.

5voto

Farid Cher Puntos 5306

Aquí hay una solución probada:

  1. Instalar comtypes y snippet102 ( ¿Cómo accedo a ArcObjects desde Python? ) Con su instalación de python

  2. use la siguiente función python (basada en los comtypes). Asegúrese de que ArcMap esté abierto. Se prueba con dataframes rotados.

Código de Python:

 def MapCoord_2_PageCoord(mapX,mapY):
    from snippets102 import GetLibPath, InitStandalone, NewObj,CType
    from comtypes.client import GetModule, CreateObject

    import comtypes.gen.esriFramework as esriFramework
    import comtypes.gen.esriArcMapUI as esriArcMapUI
    import comtypes.gen.esriCarto as esriCarto

    m = GetModule(GetLibPath() + "esriGeometry.olb")
    #ptInRealCoords =(486408.414,3577354.986)
    ptInRealCoords = CreateObject(m.Point, interface=m.IPoint)
    ptInRealCoords.PutCoords(mapX,mapY)

    pApp = NewObj(esriFramework.AppROT, esriFramework.IAppROT).Item(0)
    pDoc = pApp.Document
    pMxDoc = CType(pDoc, esriArcMapUI.IMxDocument)

    mapActiveView = CType(pMxDoc.FocusMap,esriCarto.IActiveView)
    pageLayoutActiveView = CType(pMxDoc.PageLayout,esriCarto.IActiveView)


    pDisTrans = mapActiveView.ScreenDisplay.DisplayTransformation
    deviceX, deviceY = pDisTrans.FromMapPoint(ptInRealCoords)

    pDisTrans = pageLayoutActiveView.ScreenDisplay.DisplayTransformation
    pageX,pageY = pDisTrans.ToMapPoint(deviceX, deviceY).QueryCoords()

    print pageX,pageY


MapCoord_2_PageCoord(486408.414,3577354.986)
 

5voto

FelixIP Puntos 4035

Diseño Original:

enter image description here

Secuencia de comandos:

import arcpy, os, traceback, sys,time
import numpy as np
from math import radians,sin,cos

try:
    def showPyMessage():
        arcpy.AddMessage(str(time.ctime()) + " - " + message)
    def Rotate(xM,yM,angle,xc,yc):
        x=xM-xc;y=yM-yc
        a=radians(angle)
        xN=cos(a)*x+sin(a)*y
        yN=-sin(a)*x+cos(a)*y
        return xN+xc,yN+yc
    def getCoeffs(df,angle):
        #get the data frame dimensions in map units
        df_map_w = df.elementWidth
        df_map_h = df.elementHeight
        df_map_x = df.elementPositionX
        df_map_y = df.elementPositionY
        #get the data frame projected coordinates
        min_x = df.extent.XMin
        min_y = df.extent.YMin
        max_x = df.extent.XMax
        max_y = df.extent.YMax
        A=[[min_x,min_y,1],
           [min_x,max_y,1],
           [max_x,max_y,1]]
        B=[df_map_x,df_map_x,df_map_x+df_map_w]
        A=np.array(A)
        B=np.array(B)
        #get x coefficients
        cX=np.linalg.solve(A,B)
        B=[df_map_y,df_map_y+df_map_h,df_map_y+df_map_h]
        B=np.array(B)
        #get y coefficients
        cY=np.linalg.solve(A,B)
        return (cX,cY)

    mxd = arcpy.mapping.MapDocument("CURRENT")
    df = arcpy.mapping.ListDataFrames(mxd)[0]

    angle=df.rotation
    df.rotation=0
    coeffs=getCoeffs(df,angle)
    df.rotation=angle

    cX=coeffs[0]
    cY=coeffs[1]
    coords=[[1742928.372, 6003489.49],
            [1743016.349, 6003489.49],
            [1743104.325, 6003489.49]]
    for i in range(3):
        x,y=coords[i]
        xP=x*cX[0]+y*cX[1]+cX[2]
        yP=x*cY[0]+y*cY[1]+cY[2]
        XC=df.elementPositionX+df.elementWidth/2
        YC=df.elementPositionY+df.elementHeight/2
        xP,yP=Rotate (xP,yP,-angle,XC,YC)
        elm = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT",chr(65+i))[0]
        elm.elementPositionX=xP
        elm.elementPositionY=yP
    arcpy.RefreshActiveView()


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()

Resultados:

enter image description here

enter image description here

Importante la configuración de diseño de punto de anclaje:

enter image description here

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