프로그래밍 방식으로 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. 캐스트 ILayerIDisplayTable
  3. IDisplayTable.DisplayTable속성을 캐스트IRelQueryTable
  4. 현재 테이블이 IRelQueryTable:
    1. RelQueryTableDestinationTableSourceTable속성 검사
    2. 속성의 OriginPrimaryKeyOriginForeignKey속성을 검사하십시오 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.