8 votos

Añadir capa a mxd abierto usando ArcObjects desde fuera del documento de mapa choca con ArcMap

Tengo una base de datos de Access (MS Access 2010) que permite a los usuarios introducir una variedad de información sobre el tratamiento del suelo, incluyendo puntos, líneas o polígonos asociados que los usuarios pueden seleccionar y la base de datos se cargaría como parte del proyecto, a una geodatabase maestra, y permitiría al usuario ver las características en un ArcMap. En Arc 9.3 todo esto se realizaba con VBA y funcionaba bien. Debido a la actualización a Arc 10, VBA ya no es una opción y he estado aprendiendo a programar en python y llamar a los comandos a través de Access utilizando la función Shell. Casi he completado todo excepto la capacidad de permitir a los usuarios añadir su característica al documento actual de ArcMap. Aquí están los pasos que deben ocurrir.

1) El usuario hace clic en un botón del programa Access que identifica la(s) característica(s) de interés.

2) Access determina si el mxd correcto está abierto y, si no lo está, lo abre (el documento suele estar abierto, por lo que este paso suele ser innecesario)

3) El Python script se abre usando el comando shell de Python, identifica el mxd correcto y abierto, y añade la característica al documento abierto de ArcMap

He probado tanto arcpy como ArcObjects. Puedo ejecutar arcpy dentro del mapa abierto, pero la apertura de un archivo Python a través de VBA en MS Access no manipula el mxd abierto. El foro de ESRI me sugirió que trabajara con ArcObjects. He encontrado y utilizado el código para identificar y manipular la capa ya cargada en el documento de ArcMap de interés, pero estoy completamente atascado en la forma de identificar y añadir una nueva capa. Aquí está el código hasta ahora, creo que va a funcionar si puedo identificar correctamente el archivo de capa en la última sección de código. Por lo menos todo se ejecuta sin el pMap.AddLayer(FC) cerca de la parte inferior del código, pero soy un ecologista y no un programador de formación por lo que puede haber algo más que me estoy perdiendo. Cualquier ayuda se agradece.

Actualización: Ahora estoy muy cerca. Puedo identificar la característica en la geodatabase pero ahora ArcMap se bloquea al intentar añadir los datos al mapa y me genera el error COMError: (-2147467259, 'Unspecified error', (None, None, None, 0, None)). Sin embargo, mi salida parece identificar la característica correcta. No estoy seguro de por qué ArcMap se bloquea. Por favor, ayuda, estoy muy cerca.

import arcpy
from arcpy import env
import os
import sys
import comtypes.gen.esriArcMapUI as esriArcMapUI
import comtypes.gen.esriCarto as esriCarto
import comtypes.gen.esriGeoDatabase as esriGeoDatabase
import comtypes.gen.esriFramework as esriFramework
import comtypes.gen.esriSystem as esriSystem
import comtypes.gen.esriDataSourcesFile as DataSourcesFile

#Eventaully these will be the arguments that call the feature
#test = sys.argv[0]
#Name = sys.argv[1]
#Alias = sys.argv[2]

def NewObj(MyClass, MyInterface):
    from comtypes.client import CreateObject
    try:
        ptr = CreateObject(MyClass, interface=MyInterface)
        return ptr
    except:
        return None

def CType(obj, interface):
    try:
        newobj = obj.QueryInterface(interface)
        return newobj
    except:
        return None

def GetApp():
    """Get a hook into the current session of ArcMap""" 
    #from comtypes.gen import esriFramework
    pAppROT = NewObj(esriFramework.AppROT, esriFramework.IAppROT)
    if pAppROT is not None:
        iCount = pAppROT.Count 
        if iCount == 0: 
            print 'No ArcGIS application currently running.  Terminating ...' 
            return None 
        for i in range(iCount): 
            pApp = pAppROT.Item(i)  #returns IApplication on AppRef
            print pApp.Name
            if pApp.Name == 'ArcMap': 
                print "ArcMap found"
                pDoc = pApp.Document
                print pDoc.Title
                if pDoc.Title == "CreateShapefile10x.mxd" or pDoc.Title == "CreateShapefile10x":
                    return pApp 
    print 'No ArcMap session is running at this time.' 
print "No AppROT found"
print "Failed"
return None

pApp = GetApp()

try:
    pDoc = pApp.Document
    pMxDoc = CType(pDoc, esriArcMapUI.IMxDocument)
    pMap = pMxDoc.FocusMap
    if pMap.Name == "LTDL Layers":

        ###New Code###

        sPath = r"Y:\LTDL_Data\LTDL_Files\Abate_Seeding_1965\Abate_Seeding_1965.gdb"
        sPath1 = r"Abate_Seeding_1965"
        pWSF = NewObj(esriDataSourcesGDB.FileGDBWorkspaceFactory, esriGeoDatabase.IWorkspaceFactory)
        print pWSF
        pWS = pWSF.OpenFromFile(sPath, 0)
        pDS = CType(pWS, esriGeoDatabase.IDataset)

        print "Workspace name: " + pDS.BrowseName
        print "Workspace category: " + pDS.Category

        FWSS = CType(pWS, esriGeoDatabase.IFeatureWorkspace)
        FL = NewObj(esriCarto.FeatureLayer, esriCarto.IFeatureLayer)
        FL.FeatureClass = FWSS.OpenFeatureClass(sPath1)
        print FL
        print FL.FeatureClass.AliasName
        LAN = CType(FL, esriCarto.ILayer)
        LAN.Name = FL.FeatureClass.AliasName + ": Project Boundary"
        print LAN.Name

        ###New Code###

        pMap.AddLayer(FC)
        pLayout = pMxDoc.PageLayout
        pActiveView = CType(pLayout, esriCarto.IActiveView)
        pActiveView.Refresh()
        pMxDoc.UpdateContents
    print "Done"
except:
    print "Failed"

2voto

Flinkman Puntos 4821

Estás añadiendo una capa "FC" a tu mapa que debería ser "FL" o "LAN". Tanto la capa de características como la capa deberían funcionar.

Tenga en cuenta que el mapa puede estar en la vista de datos en lugar de la vista de diseño, en cuyo caso pMxDoc.PageLayout es incorrecto... No puedo decir qué es pLayout ya que no está definido en el bloque de código.

Sería más seguro utilizar IMXDocument.FocusMap ya que éste podría ser de tipo layout o data view.

asumiendo que pApp es IApplication:

IMxDocument pDoc = (IMxDocument) pApp.Document;
IMap pMap = pDoc.FocusMap;
pMap.AddLayer(LAN);

OR

(pApp.Document as IMxDocument).FocusMap.AddLayer(LAN);

Suelo hacerlo en las tres líneas para que no sea tan confuso para el lector.

  • oops! eso era C#, mi error! El VB no es demasiado difícil de trabajar a partir de aquí como usted ya está hasta el pMap = pMxDoc.FocusMap.

p.d. Personalmente, prefiero atenuar mis objetos, ya que facilita la comprensión de lo que ocurre:

dim pMxDoc as IMxDocument = ctype(pApp.Document, IMxDocument)
dim pMap as IMap = pMxDoc.FocusMap

Así, el lector sabe con certeza qué es cada objeto.

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