マップドキュメントの外部からArcObjectsを使用してmxdを開くレイヤーを追加すると、ArcMapがクラッシュします


8

ユーザーが選択できる関連ポイント、ライン、またはポリゴンを含むさまざまな土地利用情報をユーザーが入力できるAccessデータベース(MS Access 2010)があり、データベースはプロジェクトの一部としてマスタージオデータベースに読み込まれます。ユーザーがArcMapでフィーチャを表示できるようにします。Arc 9.3では、これはすべてVBAで実現され、うまく機能しました。Arc 10へのアップグレードにより、VBAはオプションではなくなり、Pythonでプログラミングし、シェル機能を使用してAccessからコマンドを呼び出す方法を学習しました。ユーザーが現在のArcMapドキュメントに機能を追加できるようにする機能を除いて、ほぼすべて完了しました。発生するはずの手順は次のとおりです。

1)ユーザーは、関心のある機能を識別するAccessプログラムのボタンをクリックします。

2)Accessは、正しいmxdが開いているかどうかを判断し、開いていない場合はそれを開きます(通常、ドキュメントは開いているため、この手順は不要です)。

3)Pythonスクリプトは、Pythonシェルコマンドを使用して開き、正しい開いているmxdを識別し、開いているArcMapドキュメントに機能を追加します。

私はarcpyとArcObjectsの両方を試しました。開いているマップ内でarcpyを実行できますが、MS AccessでVBAを介してPythonファイルを開いても、開いているmxdを操作できません。ESRIフォーラムから、ArcObjectsを使用するよう提案されました。対象のArcMapドキュメントに既にロードされているレイヤーを特定して操作するためのコードを見つけて使用しましたが、新しいレイヤーを特定して追加する方法に完全に行き詰まっています。これがこれまでのコードですが、コードの最後のセクションでレイヤーファイルを正しく識別できれば機能すると思います。少なくとも、コードの下部にあるpMap.AddLayer(FC)なしですべて実行されますが、私は生態学者であり、トレーニングを行うプログラマーではないため、他に何か不足している可能性があります。任意の助けいただければ幸いです。

更新:私は今とても近くにいます。ジオデータベースでフィーチャを識別できますが、マップにデータを追加しようとするとArcMapがクラッシュし、次のエラーが発生します:COMError:(-2147467259、 'Unspecified error'、(None、None、None、0、None)) 。ただし、私の出力は正しい機能を識別しているように見えます。ArcMapがクラッシュする理由がわかりません。助けてください、私はとても近いです。

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
IObjectFactoryを使用して、この質問のように正しいプロセスでワークスペースファクトリシングルトンを作成してみてください。ArcMap / ArcObjects-画面上のグラフィックスの描画:Draw / Refresh / PartialRefreshメソッドの説明またはチュートリアル?
blah238

説明どおりにテキスト要素を追加しようとしましたが、それでもエラーが発生しました。pFact = CType(pApp、esriFramework.IObjectFactory)graphicsContainer = pMxDoc.ActiveView.GraphicsContainer textElement = CType(pFact.Create( "esriCarto.TextElement")、esriCarto.ITextElement)graphicsContainer.AddElement(textElement、0)pMxDoc.ActiveView.PartialRefresh esriCarto.esriViewGraphics、なし、なし)。次に、データソースのない空のレイヤーを追加し、mapAdmin2.FireChangeFeatureClass(OFL、NFC)を使用してデータソースを割り当てました。以前と同様に、ArcMapが起動し、その後クラッシュしてシャットダウンしました。
user6287 2012年

1
作者が興味を失ったように見えるので、この質問はおそらく閉じるべきです。
blah238 2013年

回答:


2

「FL」または「LAN」であるはずのレイヤー「FC」をマップに追加しています。フィーチャレイヤーまたはレイヤーのいずれかが機能します。

マップがレイアウトビューではなくデータビューにある可能性があることに注意してください。その場合、pMxDoc.PageLayoutは正しくありません... pLayoutはコードブロックで定義されていないため、何とは言えません。

IMXDocument.FocusMapは、レイアウトタイプまたはデータビューのいずれかであるため、使用する方が安全です。

pAppがIApplicationであると仮定します。

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

OR

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

私は通常3行でそれを行うので、読者にとってそれほど混乱しないようにします。

  • おっとっと!それはC#でした。VBは、すでにpMap = pMxDoc.FocusMapに達しているので、ここから作業するのはそれほど難しくありません。

ps私は個人的にオブジェクトを暗くすることを好みます、それは何が起こっているのかを理解するのをより簡単にします:

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

そうすれば、読者は各オブジェクトが何であるかを確実に知ることができます。


この質問は1年半以上経過していることに加えて、C# VB.NET ではなく、Python + comtypeにあります。そして、FCの問題は、実際のコードではなく、おそらくタイプミスだったと思いますNameError
blah238 2013年

3
私はスレッドが何歳であるかを見ていませんでした。これは、Googleから次の方法で見つけた次の読者にとって重要ではありません。質問は質問です。次の読者のために、明らかな誤りを指摘する必要があると感じました。
Michael Stimson 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.