Thêm lớp để mở mxd bằng ArcObjects từ bên ngoài tài liệu bản đồ gặp sự cố ArcMap


8

Tôi có cơ sở dữ liệu Access (MS Access 2010) cho phép người dùng nhập nhiều thông tin xử lý đất bao gồm các điểm, đường hoặc đa giác liên quan mà người dùng có thể chọn và cơ sở dữ liệu sẽ tải như một phần của dự án, vào cơ sở dữ liệu địa lý chính, và cho phép người dùng xem các tính năng trong ArcMap. Trong Arc 9.3, tất cả đã được hoàn thành với VBA và hoạt động tốt. Do nâng cấp lên Arc 10, VBA không còn là một tùy chọn nữa và tôi đã học cách lập trình trong python và gọi các lệnh thông qua Access bằng tính năng Shell. Tôi gần như đã hoàn thành mọi thứ trừ khả năng cho phép người dùng thêm tính năng của họ vào tài liệu ArcMap hiện tại. Dưới đây là các bước nên xảy ra.

1) Người dùng nhấp vào nút trong chương trình Access xác định (các) tính năng quan tâm.

2) Truy cập xác định nếu mxd chính xác đang mở và nếu không mở nó (tài liệu thường mở nên bước này thường không thành công)

3) Tập lệnh Python mở bằng lệnh shell Python, xác định mxd chính xác và mở và thêm tính năng vào tài liệu ArcMap mở

Tôi đã thử cả Arcpy và ArcObjects. Tôi có thể chạy arcpy trong bản đồ mở nhưng mở tệp Python qua VBA trong MS Access không thao tác với mxd mở. Diễn đàn ESRI gợi ý rằng tôi làm việc với ArcObjects. Tôi đã tìm và sử dụng mã để xác định và thao tác lớp đã được tải trong tài liệu ArcMap quan tâm nhưng tôi hoàn toàn bế tắc về cách xác định và thêm một lớp mới. Đây là mã cho đến nay, tôi nghĩ nó sẽ hoạt động nếu tôi có thể xác định chính xác tệp lớp trong phần cuối của mã. Ít nhất là tất cả chạy mà không có pMap.AddLayer (FC) ở gần cuối mã, nhưng tôi là một nhà sinh thái học và không phải là lập trình viên bằng cách đào tạo nên có thể thiếu một cái gì đó khác. Bất kỳ trợ giúp sẽ được đánh giá cao.

Cập nhật: Tôi bây giờ rất gần. Tôi có thể xác định tính năng trong cơ sở dữ liệu địa lý nhưng bây giờ ArcMap gặp sự cố khi cố thêm dữ liệu vào bản đồ và tôi tạo ra lỗi: COMError: (-2147467259, 'Lỗi không xác định', (Không, Không, Không, 0, Không)) . Tuy nhiên, đầu ra của tôi xuất hiện để xác định tính năng chính xác. Tôi không chắc tại sao ArcMap bị sập. Xin hãy giúp đỡ, tôi rất gần.

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
Hãy thử sử dụng IObjectFactory để tạo singleton nhà máy trong không gian làm việc theo đúng quy trình như trong câu hỏi này: ArcMap / ArcObjects - Vẽ đồ họa trên màn hình: Giải thích hoặc hướng dẫn cho các phương thức Draw / Refresh / PartialRefresh?
blah238

Đã thử thêm phần tử atext như mô tả và nó vẫn bị lỗi. pFact = CType (pApp, esriFramework.IObjectFactory) GraphicsContainer = pMxDoc.ActiveView.GraphicsContainer textEuity = CType (pFact.Create ("esriCarto.TextEemony esriCarto.esriViewGraphics, Không, Không). Tiếp theo tôi đã thêm một lớp trống không có nguồn dữ liệu và sử dụng mapAdmin2.FireChangeFeatureClass (OFL, NFC) để gán nguồn dữ liệu. ArcMap bắt đầu và sau đó sụp đổ và tắt như trước.
dùng6287

1
Câu hỏi này có lẽ nên được đóng lại vì có vẻ như tác giả đã mất hứng thú.
blah238

Câu trả lời:


2

Bạn đang thêm một lớp "FC" vào bản đồ của mình phải là "FL" hoặc "LAN". Lớp tính năng hoặc lớp nên hoạt động.

Xin lưu ý rằng bản đồ có thể ở chế độ xem dữ liệu thay vì chế độ xem bố cục trong trường hợp pMxDoc.PageLayout không chính xác ... Tôi không thể biết pLayout là gì vì nó không được xác định trong khối mã.

Sẽ an toàn hơn khi sử dụng IMXDocument.F FocusMap vì đây có thể là kiểu bố cục hoặc dạng xem dữ liệu.

giả sử pApp là ứng dụng:

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

OR

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

Tôi thường làm nó trên ba dòng để nó không gây nhầm lẫn cho người đọc.

  • Giáo sư! đó là C #, xấu của tôi! VB không quá khó để xử lý từ đây vì bạn đã sẵn sàng với pMap = pMxDoc.F FocusMap.

ps Cá nhân tôi thích làm mờ các đối tượng của mình, nó giúp dễ dàng tìm ra những gì đang xảy ra:

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

Bằng cách đó, người đọc biết chắc chắn mỗi đối tượng là gì.


Bên cạnh câu hỏi này đã hơn một năm rưỡi, nó nằm trong Python + comtypes, không phải C # hay VB.NET. Và tôi nghĩ rằng điều FC có lẽ chỉ là một lỗi đánh máy trong câu hỏi chứ không phải là mã thực tế, vì sẽ có một NameErrorthay thế.
blah238

3
Tôi đã không nhìn vào chủ đề bao nhiêu tuổi, điều đó không quan trọng đối với người đọc tiếp theo tìm thấy ở đây từ google giống như tôi đã nhiều lần ... rất nhiều lần tôi cảm thấy mình nên tham gia. Một câu hỏi là một câu hỏi và vì những độc giả tiếp theo vì tôi cảm thấy nên chỉ ra lỗi rõ ràng.
Michael Promotionson
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.