Agregar capa para abrir mxd usando ArcObjects desde fuera del documento de mapa bloquea ArcMap


8

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

1) El usuario hace clic en un botón en el programa de Access que identifica las características de interés.

2) Access determina si el mxd correcto está abierto y si no lo abre (el documento generalmente está abierto, por lo que este paso a menudo no es necesario)

3) La secuencia de comandos de Python se abre con el comando de shell de Python, identifica el mxd correcto y abierto, y agrega características al documento abierto de ArcMap

He intentado tanto arcpy como ArcObjects. Puedo ejecutar arcpy dentro del mapa abierto, pero abrir 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 código para identificar y manipular la capa ya cargada en el documento de ArcMap de interés, pero estoy completamente atascado en cómo identificar y agregar una nueva capa. Aquí está el código hasta ahora, creo que funcionará si puedo identificar correctamente el archivo de capa en la última sección del código. Al menos todo funciona sin el pMap.AddLayer (FC) cerca de la parte inferior del código, pero soy un ecologista y no un programador por capacitación, por lo que puede haber algo más que me falta. Cualquier ayuda sería apreciada.

Actualización: ahora estoy muy cerca. Puedo identificar la entidad en la geodatabase pero ahora ArcMap se bloquea al intentar agregar los datos al mapa y genero el error: COMError: (-2147467259, 'Error no especificado', (Ninguno, Ninguno, Ninguno, 0, Ninguno)) . Sin embargo, mi salida parece identificar la característica correcta. No estoy seguro de por qué ArcMap se bloquea. Por favor ayuda, estoy tan 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"

1
Intente usar IObjectFactory para crear el singleton de fábrica del espacio de trabajo en el proceso correcto como en esta pregunta: ArcMap / ArcObjects - Dibujar gráficos en pantalla: ¿Explicación o tutorial para los métodos de Draw / Refresh / PartialRefresh?
blah238

Intenté agregar un elemento de texto como se describe y aún arrojó un error. pFact = CType (pApp, esriFramework.IObjectFactory) graphicsContainer = pMxDoc.ActiveView.GraphicsContainer textElement = CType (pFact.Create ("esriCarto.TextElement"), esriCarto. esriCarto.esriViewGraphics, Ninguno, Ninguno). Luego agregué una capa vacía sin fuente de datos y usé mapAdmin2.FireChangeFeatureClass (OFL, NFC) para asignar una fuente de datos. ArcMap comenzó y luego se bloqueó y cerró como antes.
user6287

1
Esta pregunta probablemente debería cerrarse ya que parece que el autor ha perdido interés.
blah238

Respuestas:


2

Está agregando una capa "FC" a su mapa que debería ser "FL" o "LAN". La capa de entidades o 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 usar IMXDocument.FocusMap, ya que podría ser de tipo de diseño o vista de datos.

suponiendo que pApp es IApplication:

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

OR

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

Por lo general, lo hago en las tres líneas, por lo que no es tan confuso para el lector.

  • ¡Uy! eso fue C #, mi mal! El VB no es demasiado difícil de resolver desde aquí, ya que estás preparado para pMap = pMxDoc.FocusMap.

PD: Personalmente prefiero atenuar mis objetos, hace que sea más fácil resolver lo que está sucediendo:

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

De esa manera, el lector sabe con certeza qué es cada objeto.


Además de que esta pregunta tiene más de un año y medio, está en los tipos de Python +, no en C # o VB.NET. Y creo que lo de FC probablemente fue solo un error tipográfico en la pregunta en lugar del código real, ya que habría habido un error NameError.
blah238

3
No miré cuántos años tenía el hilo, eso no es importante para el próximo lector que encuentre el camino aquí desde google como lo he hecho muchas veces ... tantas veces sentí que debería unirme. Una pregunta es una pregunta y, por el bien de los lectores, sentí que debía señalar el error obvio.
Michael Stimson
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.