프로그래밍 방식으로 ArcMap에서 조인 필드를 식별합니까?


9

ArcMap에서 두 데이터 셋을 함께 테이블 조인하는 데 사용되는 조인 필드 를 프로그래밍 방식으로 식별 할 수 있습니까? 현재 ArcGIS 10.0, SP5를 사용하고 있으며 ArcPy 솔루션을 선호 하지만 ArcPy 솔루션을 사용할 수없는 경우 다른 솔루션에 반대하지 않습니다.

내가 시도한 한 가지 방법은 모든 필드를 반복하고 일치하는 "baseName"을 찾는 것이지만 두 데이터베이스의 필드 이름이 동일하기를 희망하는 "교육받은 추측"입니다.

내가 무엇을했는지 그래픽으로 표현하기 위해 기본적으로 "조인 추가"대화 상자에서 볼 수 있듯이 "입력 조인 필드"및 "출력 조인 필드"를 식별하려고하지만 실제로는 사실입니다.

"입력 조인 필드"및 "출력 조인 필드"를 식별하는 방법은 무엇입니까?

이것은 “Join”을 프로그래밍 방식으로 감지 할 수 있습니까? 그러나이 경우에는 두 개 이상의 데이터 세트를 함께 결합하는 데 사용되는 FIELD를 식별하기 위해 기능을 확장하고 싶습니다.


어떤 버전의 ArcGIS를 사용하고 있습니까? 그리고 태그를 기반으로 ArcObject가 아닌 arcpy 로이 작업을 수행하는 방법을 구체적으로 찾고 있다고 가정합니다.
— blah238

현재 ArcGIS 10.0, SP5를 사용하고 있습니다. 그리고 네, ArcPy 솔루션을 찾고 있습니다.하지만 이것이 유일한 대안이라면 ArcObjects 솔루션에 반대하지는 않습니다.
— RyanKDalton

1
다음은 관련 문서 일 수 있습니다. edndoc.esri.com/arcobjects/9.2/ComponentHelp/esriGeoDatabase/… pRelClass 와 관련됨 이것은 조인 테이블과 조인 필드 및 카디널리티를 정의하는 데 사용되는 RelationshipClass입니다. Open 메소드는 새 RelQueryTable을 작성하거나 해당 클래스가 이미 작성된 경우 기존 RelQueryTable에 대한 참조를 리턴합니다. 이 메소드를 호출하고 pRelClass와 관련된 참조를 찾을 수 있습니다
— lewis

@lewis, 팩토리 객체를 사용하여 기존 RelQueryTable에 대한 참조를 얻을 필요는 없습니다. 내 답변을 참조하십시오.
— blah238

답변:


8

다음은이 예제를 기반으로하는 ArcObjects 방식 으로 레이어의 모든 조인을 열거하고 대상 및 소스 테이블 이름과 기본 및 외래 키를 나열합니다.

  1. ILayer하나 이상의 조인이 있는에 대한 참조 가져 오기
  2. 캐스트 ILayer로IDisplayTable
  3. IDisplayTable.DisplayTable속성을 캐스트IRelQueryTable
  4. 현재 테이블이 IRelQueryTable:
    1. RelQueryTable의 DestinationTable및 SourceTable속성 검사
    2. 속성의 OriginPrimaryKey및 OriginForeignKey속성을 검사하십시오 IRelQueryTable.RelationshipClass.
    3. 현재 현재 테이블을 설정 RelQueryTable의 ' SourceTable재산

이 Python 스크립트 ( comtypes 및이 도우미 모듈 사용 )는 최신에서 가장 빠른 모든 조인을 거치며 각 조인의 대상 및 소스 테이블 이름, 원본 기본 키 및 원본 외래 키를 인쇄합니다.

from ESRICOMHelpers import * # helper module from https://gis.stackexchange.com/a/5082/753
esriArcMapUI = GetESRIModule("esriArcMapUI")
esriCarto = GetESRIModule("esriCarto")
esriGeoDatabase = GetESRIModule("esriGeoDatabase")

def listJoins(table):
    while CType(table, esriGeoDatabase.IRelQueryTable):
        relQueryTable = CType(table, esriGeoDatabase.IRelQueryTable)
        destTable = relQueryTable.DestinationTable
        sourceTable = relQueryTable.SourceTable
        destDataset = CType(destTable, esriGeoDatabase.IDataset)
        sourceDataset = CType(sourceTable, esriGeoDatabase.IDataset)
        relClass = relQueryTable.RelationshipClass
        print destDataset.Name, sourceDataset.Name, relClass.OriginPrimaryKey, relClass.OriginForeignKey
        table = sourceTable

if __name__ == "__main__":
    #app = GetCurrentApp() # Use if run in-process
    app = GetApp("ArcMap") # Use if run in a standalone script
    mxd = CType(app.Document, esriArcMapUI.IMxDocument)

    # Gets the first layer in the active data frame
    map = mxd.FocusMap
    lyr = map.Layer[0]

    # Need to get the "display table" to access the joins
    displayTable = CType(lyr, esriCarto.IDisplayTable).DisplayTable

    # List the layer's joined tables
    listJoins(displayTable)

세 개의 조인이있는 소스 레이어가 제공된 예제 출력 :

join_table_3 master_fc_join_table_1_join_table_2 JOIN_ID_3 master_fc.MASTER_ID
join_table_2 master_fc_join_table_1 JOIN_ID_2 master_fc.MASTER_ID
join_table_1 master_fc JOIN_ID_1 MASTER_ID

자세한 내용 은 Python에서 ArcObject에 액세스하는 방법을 참조하십시오 .


이것은 매우 유망 해 보입니다. comtypes 패키지가 설치되고 도우미 함수 코드가 추가되었지만 오류가 발생 "global name 'esriGeoDatabase' is not defined"합니다. 행 앞의 코드에서 어디서 / 어떻게 정의해야 while CType(table, esriGeoDatabase.IRelQueryTable)합니까?
— RyanKDalton 18

나는 그것을 포함시키지 않았지만 어느 시점에서 필요한 특정 ESRI 객체 라이브러리 주위에 comtypes 래퍼를 가져와야합니다. 내 도우미 모듈을 사용하면 간단합니다 esriGeoDatabase = GetESRIModule("esriGeoDatabase").
— blah238

감사합니다 ArcMap의 레이어에서도 작동합니까? 각 레이어를 코드 layerList = arcpy.mapping.ListLayers(mxd)로 전달 listJoins(table)하지만 while명령문 에서 생략 합니다.
— RyanKDalton

나는 당신이 arcpy 객체와 comtypes 객체 사이에 캐스트 할 수 있다고 생각하지 않으므로 ArcObjects를 통해 ILayer 참조를 얻어야합니다. 더 완전한 예제를 포함하도록 코드를 업데이트했습니다. 이것은 관련 라인에 주석을 달거나 주석을 해제하여 프로세스 안팎에서 사용할 수 있어야합니다.
— blah238

좀 더 가까이 다가 가서 연습 해 주셔서 감사합니다. 이제보고 싶은 실제지도 문서 파일 (* .mxd)을 어떻게 보냈습니까? app.Document으로 돌아 오기'NoneType' object has no attribute 'Document'
— RyanKDalton

1

필드의 모든 데이터를 문자열로 묶고 (주문한 후) 퍼지 비교 기능과 비교하고 특정 정밀도를 가장 잘 맞추거나 일치시키는 사람들을 선택하십시오.

이 솔루션은 일부 데이터가 적합하지 않은 경우입니다. 두 열이 항상 적합하다고 생각되면 주문하고 비교하여 일반 비교 기능과 완벽하게 일치하십시오.


0

이 시도:

  • 메타 데이터 도구 세트 에서 XSLT 변환 도구를 사용하여 해당 데이터 세트 에 대한 xml / html 메타 데이터 파일을 작성하십시오.

    arcpy.XSLTransform_conversion(r'X:\temp\Scratch.gdb\fc_FeatureToPoint',"C:\Program Files\ArcGIS\Desktop10.1\Metadata\Stylesheets\ArcGIS.xsl", r'X:\temp\Metadata.html')
  • HTML 구문 분석기 를 사용 하여 메타 데이터 파일을 읽고 필드 결합 도구의 지리 처리 히스토리에서 결합 필드를 검색하십시오.

  • XSLT 변환 도구의 샘플 출력

XSLT 변환 도구의 출력


1
그것은 내가 실제로 약속했다고 생각하는 정말 영리한 생각이지만, 테스트에서, 파일이 GP 프로세스 히스토리의 일부로 쓰여지기 때문에 "JoinField"라는 GP 도구를 사용하여 파일을 결합한 경우에만 작동하는 것처럼 보입니다. 그 층을 위해. 사용자가 UI를 통해 결합을 작성한 경우 JoinField 프로세스 행이 출력 파일에 존재하지 않습니다. 그래도 좋은 생각입니다!
— RyanKDalton

1
어쨌든 나는 GP 역사에 의존하지 않을 것입니다. 반복되는 프로세스의 경우 기능 클래스를 거의 사용할 수 없게 만드는 대량의 데이터에 빠르게 마운트되기 때문에 가능한 빨리 삭제하려고합니다.
— blah238

-1

결합 된 테이블 이름은 IFeatureLayer-IFeatureLayerDefinition 객체에 문자열로 표시됩니다. 아마도 결합 SQL과 필드 이름이 포함되어 있다고 생각합니다.

http://edndoc.esri.com/arcobjects/8.3/diagrams/Map%20Layer%20Object%20Model.pdf

아니면 해당 개체에 액세스 할 수없는 것입니까?


IFeatureLayerDefinition"join SQL"을 포함하지 않으면 DefinitionExpression, 표시되는 행을 제한하는 WHERE 절인 기능 계층의 정의 쿼리 (설정된 경우)를 노출 하는 특성 만 있습니다 .
— blah238

그것은 가지고 RelationshipClass있지만, 속성을,하지만 난이 가장 최근에 가입 노출 생각합니다. IRelQueryTable그것들을 모두 얻으려면 대신 사용해야 합니다.
— blah238

-2

필드 이름에 관계없이 일치하는 필드를 찾으려면 다음과 같이 할 수 있습니다.

import arcpy

fc = r"temp/RiversJoined.shp"

fldList1 = [f.name for f in arcpy.ListFields(fc)]
fldList2 =[g.name for g in arcpy.ListFields(fc)]

for f in fldList1:
    values1 = [f_row[0] for f_row in arcpy.da.SearchCursor(fc, (f))]
    for g in fldList2:
        values2 = [g_row[0] for g_row in arcpy.da.SearchCursor(fc,(g))]
        #compare field values
        #get names of matching fields
        if (fldList2.index(g) != fldList1.index(f) and values1 == values2):
            print "match: " + str(g) + " match: "+ str(f)

내 대답을 두드리는 사람에게 이봐 : 내 대답에 무슨 문제가 있는지 말해 줄 수 있니? 감사.
— mwil

1
요청한대로 질문에 답변하지 않는 것 같습니다. 퍼지 비교 답변과 동일합니다. 필드가 동일하거나 심지어 유사하게 유사하더라도 실제로 조인에 사용되었는지 여부와 관계가 없습니다.
— blah238
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.