Adicionar camada para abrir o mxd usando o ArcObjects de fora do documento do mapa trava o ArcMap


8

Eu tenho um banco de dados do Access (MS Access 2010) que permite aos usuários inserir uma variedade de informações de tratamento do solo, incluindo pontos, linhas ou polígonos associados que os usuários podem selecionar e o banco de dados carregaria como parte do projeto em um banco de dados mestre, e permitir que o usuário visualize os recursos em um ArcMap. No Arc 9.3, tudo isso foi realizado com o VBA e funcionou bem. Devido à atualização para o Arc 10, o VBA não é mais uma opção e eu tenho aprendido a programar em python e chamar os comandos pelo Access usando o recurso Shell. Quase concluí tudo, exceto a capacidade de permitir que os usuários adicionem seus recursos ao documento atual do ArcMap. Aqui estão as etapas que devem ocorrer.

1) O usuário clica em um botão no programa Access que identifica o (s) recurso (s) de interesse.

2) O acesso determina se o mxd correto está aberto e se não o abre (o documento geralmente está aberto, portanto essa etapa geralmente não é necessária)

3) O script Python é aberto usando o comando shell Python, identifica o mxd correto e aberto e adiciona recurso ao documento aberto do ArcMap

Eu tentei o arcpy e o ArcObjects. Posso executar o arcpy no mapa aberto, mas a abertura de um arquivo Python via VBA no MS Access não manipula o mxd aberto. O fórum da ESRI sugeriu que eu trabalhasse com o ArcObjects. Eu encontrei e usei o código para identificar e manipular a camada já carregada no documento de interesse do ArcMap, mas estou completamente empolgada em como identificar e adicionar uma nova camada. Aqui está o código até agora, acho que funcionará se eu conseguir identificar corretamente o arquivo de camada na última seção do código. Pelo menos, tudo é executado sem o pMap.AddLayer (FC) próximo à parte inferior do código, mas eu sou um ecologista e não um programador treinando, para que possa estar faltando outra coisa. Qualquer ajuda seria apreciada.

Atualização: agora estou muito perto. Posso identificar o recurso no geodatabase, mas agora o ArcMap falha ao tentar adicionar os dados ao mapa e giro o erro: COMError: (-2147467259, 'Erro não especificado', (Nenhum, Nenhum, Nenhum, 0, Nenhum)) . No entanto, minha saída parece identificar o recurso correto. Não sei ao certo por que o ArcMap está travando. Por favor, ajude, eu estou tão perto.

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
Tente usar IObjectFactory para criar o singleton de fábrica da área de trabalho no processo correto, como nesta pergunta: ArcMap / ArcObjects - Desenho de gráficos na tela: Explicação ou tutorial para os métodos Draw / Refresh / PartialRefresh?
precisa saber é o seguinte

Tentou adicionar um elemento de texto como descrito e ainda gerava um erro. pFact = CType (pApp, esriFramework.IObjectFactory) graphicsContainer = pMxDoc.ActiveView.GraphicsContainer textElement = CType (pFact.Create ("esriCarto.TextElement"), esriCarto.ITextElement) graphicsContainer.AddElement (textElement, 0) esriCarto.esriViewGraphics, Nenhum, Nenhum). Em seguida, adicionei uma camada vazia sem fonte de dados e usei mapAdmin2.FireChangeFeatureClass (OFL, NFC) para atribuir uma fonte de dados. O ArcMap foi iniciado e depois travou e desligou como antes.
User6287 13/03/12

1
Essa pergunta provavelmente deve ser encerrada, pois parece que o autor perdeu o interesse.
blah238

Respostas:


2

Você está adicionando uma camada "FC" ao seu mapa, que deve ser "FL" ou "LAN". A camada de recurso ou a camada deve funcionar.

Esteja ciente de que o mapa pode estar na exibição de dados em vez da exibição de layout. Nesse caso, pMxDoc.PageLayout está incorreto ... Não sei dizer o que é pLayout, pois não está definido no bloco de código.

Seria mais seguro usar o IMXDocument.FocusMap, pois isso poderia ser do tipo de layout ou visualização de dados.

assumindo que pApp é IApplication:

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

OR

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

Eu costumo fazer isso nas três linhas, para que não seja tão confuso para o leitor.

  • oops! isso foi c #, meu mal! O VB não é muito difícil de resolver daqui, pois você já está com o pMap = pMxDoc.FocusMap.

ps Eu pessoalmente prefiro escurecer meus objetos, fica mais fácil descobrir o que está acontecendo:

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

Dessa forma, o leitor sabe com certeza o que é cada objeto.


Além dessa pergunta ter mais de um ano e meio, ela está no Python + comtypes, não em C # ou VB.NET. E acho que a coisa do FC provavelmente foi apenas um erro de digitação na pergunta, e não o código real, como teria ocorrido NameError.
blah238

3
Eu não olhei quantos anos o tópico tinha, isso não é importante para o próximo leitor que encontrar aqui o caminho do google, assim como já fiz muitas vezes ... tantas vezes que senti que deveria participar. Uma pergunta é uma pergunta e, para o próximo leitor, senti que deveria apontar o erro óbvio.
Michael Stimson
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.