Ich habe eine Access-Datenbank (MS Access 2010), mit der Benutzer eine Vielzahl von Landbehandlungsinformationen eingeben können, einschließlich zugehöriger Punkte, Linien oder Polygone, die Benutzer auswählen können. Die Datenbank wird dann als Teil des Projekts in eine Master-Geodatabase geladen. und ermöglichen Sie dem Benutzer, die Features in einer ArcMap anzuzeigen. In Arc 9.3 wurde dies alles mit VBA erreicht und funktionierte gut. Aufgrund des Upgrades auf Arc 10 ist VBA keine Option mehr und ich habe gelernt, wie man in Python programmiert und die Befehle über Access mithilfe der Shell-Funktion aufruft. Ich habe fast alles abgeschlossen, bis auf die Möglichkeit, Benutzern das Hinzufügen ihrer Funktion zum aktuellen ArcMap-Dokument zu ermöglichen. Hier sind die Schritte, die ausgeführt werden sollten.
1) Der Benutzer klickt im Access-Programm auf eine Schaltfläche, mit der die gewünschten Funktionen identifiziert werden.
2) Der Zugriff bestimmt, ob der richtige mxd geöffnet ist und wenn nicht, wird er geöffnet (das Dokument ist normalerweise geöffnet, sodass dieser Schritt häufig nicht erforderlich ist).
3) Das Python-Skript wird mit dem Python-Shell-Befehl geöffnet, identifiziert das richtige und geöffnete mxd und fügt dem geöffneten ArcMap-Dokument eine Funktion hinzu
Ich habe sowohl arcpy als auch ArcObjects ausprobiert. Ich kann arcpy innerhalb der geöffneten Map ausführen, aber das Öffnen einer Python-Datei über VBA in MS Access manipuliert das geöffnete mxd nicht. Das ESRI-Forum schlug vor, mit ArcObjects zu arbeiten. Ich habe Code gefunden und verwendet, um Layer zu identifizieren und zu bearbeiten, die bereits in das ArcMap-Dokument von Interesse geladen wurden, bin aber völlig fest davon überzeugt, wie man einen neuen Layer identifiziert und hinzufügt. Hier ist der Code, ich denke, es wird funktionieren, wenn ich die Layer-Datei im letzten Codeabschnitt korrekt identifizieren kann. Zumindest läuft alles ohne den pMap.AddLayer (FC) am Ende des Codes, aber ich bin ein Ökologe und kein ausgebildeter Programmierer, sodass mir möglicherweise noch etwas fehlt. Jede Hilfe wäre dankbar.
Update: Ich bin jetzt sehr nah dran. Ich kann das Feature in der Geodatabase identifizieren, aber jetzt stürzt ArcMap ab, wenn versucht wird, die Daten zur Karte hinzuzufügen, und ich generiere den Fehler: COMError: (-2147467259, 'Nicht angegebener Fehler', (Keine, Keine, Keine, 0, Keine)) . Meine Ausgabe scheint jedoch die richtige Funktion zu identifizieren. Ich bin mir nicht sicher, warum ArcMap abstürzt. Bitte helfen Sie, ich bin so nah.
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"
quelle
Antworten:
Sie fügen Ihrer Karte eine Ebene "FC" hinzu, die "FL" oder "LAN" sein sollte. Entweder der Feature-Layer oder der Layer sollte funktionieren.
Beachten Sie, dass sich die Karte möglicherweise in der Datenansicht anstelle der Layoutansicht befindet. In diesem Fall ist pMxDoc.PageLayout falsch ... Ich kann nicht sagen, was pLayout ist, da es nicht im Codeblock definiert ist.
Es wäre sicherer, IMXDocument.FocusMap zu verwenden, da dies entweder ein Typlayout oder eine Datenansicht sein kann.
Angenommen, pApp ist IApplication:
Normalerweise mache ich das in den drei Zeilen, damit es für den Leser nicht so verwirrend ist.
ps Ich persönlich ziehe es vor, meine Objekte zu dimmen. Dadurch ist es einfacher herauszufinden, was passiert:
Auf diese Weise weiß der Leser mit Sicherheit, was jedes Objekt ist.
quelle
NameError
stattdessen einen gegeben hätte.