ArcMap'ta Birleştirilmiş Alanın programlı olarak tanımlanması?


9

ArcMap'te iki veri kümesini birleştirmek için Tabloda kullanılan Birleştirme Alanını programlı olarak tanımlamak mümkün müdür ? Şu anda ArcGIS 10.0, SP5 kullanıyorum ve bir ArcPy çözümünü tercih ediyorum , ancak bir ArcPy çözümü mevcut değilse, diğer çözümlere karşı çıkmam.

Denediğim bir yöntem, tüm alanların arasında dolaşmak ve eşleşen bir "baseName" aramaktı, ama bu sadece her iki veritabanındaki alan adlarının aynı olmasını umduğunuz bir "eğitimli tahmin" dir.

Neyin peşinde olduğumun grafik gösterimi için, temel olarak "Giriş Birleştirme Alanı" ve "Çıktı Birleştirme Alanı" nı "Birleştirme Ekle" iletişim kutusunda görüldüğü gibi tanımlamak istiyorum.

"Girdi Birleştirme Alanı" ve "Çıktı Birleştirme Alanı" nasıl tanımlanır?

Bu, “Birleştirme” programlı olarak algılanabilir mi? , ancak bu durumda, iki (veya daha fazla) veri kümesini birleştirmek için kullanılan ALAN (lar) ı tanımlamak için işlevselliği genişletmek istiyorum.


Hangi ArcGIS sürümüyle çalışıyorsunuz? Ve özellikle bunu ArcObjects ile değil, arcpy ile yapmanın bir yolunu aradığınız etiketlere dayanarak varsayıyorum?
blah238

Şu anda ArcGIS 10.0, SP5 kullanıyorum. Ve evet, bir ArcPy çözümü arıyorum / umuyorum, ancak tek alternatifse bir ArcObjects çözümüne karşı çıkmam.
RyanKDalton

1
Muhtemelen bazı revelant belgeleri: edndoc.esri.com/arcobjects/9.2/ComponentHelp/esriGeoDatabase/… pRelClass içerir Bu, birleştirme tablolarını ve birleşim alanlarını ve aynı zamanda kardinaliteyi tanımlamak için kullanılan RelationshipClass'tır. Open yöntemi yeni bir RelQueryTable oluşturur veya bu sınıf zaten oluşturulmuşsa varolan bir RelQueryTable'a bir başvuru döndürür. Bu yöntemi çağırabilir ve thepRelClass ile ilgili referansı bulabilirsiniz
lewis

@ lewis, varolan bir RelQueryTable'a başvuru almak için fabrika nesnesini kullanmanıza gerek yoktur - cevabımı görün.
blah238

Yanıtlar:


8

Bir katmandaki tüm birleştirmeleri numaralandırmak ve hedef ve kaynak tablo adlarını ve birincil ve yabancı anahtarları listelemek için bu örneği temel alan bir ArcObjects yaklaşımı aşağıdadır:

  1. ILayerBir veya daha fazla birleşimi olan bir referans alın
  2. Dökme ILayeriçinIDisplayTable
  3. IDisplayTable.DisplayTableMülkü şuraya yayınlaIRelQueryTable
  4. Geçerli tablo bir IRelQueryTable:
    1. Muayene RelQueryTable's DestinationTableve SourceTableözelliklerini
    2. Kontrol OriginPrimaryKeyve OriginForeignKeyözelliklerini IRelQueryTable.RelationshipClassözelliği.
    3. Geçerli Geçerli Masayı RelQueryTables' SourceTablemülkiyet

Bu Python betiği ( comtypes ve bu yardımcı modülü kullanarak) en sondan en başa kadar tüm birleştirmelerden geçecek ve her birleştirme için hedef ve kaynak tablo adlarını, başlangıç ​​birincil anahtarını ve başlangıç ​​yabancı anahtarını yazacaktır:

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)

Üç birleştirmeli bir kaynak katmanı verildiğinde örnek çıktı:

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

Daha fazla bilgi için bkz . Python'dan ArcObjects'e nasıl erişirim?


Bu çok umut verici görünüyor. Comtypes paketini yükledim ve yardımcı fonksiyon kodu eklendi, ancak hatayı alıyorum "global name 'esriGeoDatabase' is not defined". Satırdan önceki kodda nerede / nasıl tanımlanmalıdır while CType(table, esriGeoDatabase.IRelQueryTable)?
RyanKDalton

Onu dahil etmedim, ancak bir noktada ihtiyacınız olan belirli ESRI nesne kitaplıklarının etrafındaki comtypes sarmalayıcılarını içe aktarmak zorundasınız. Yardımcı modülümü kullanmak kadar basit esriGeoDatabase = GetESRIModule("esriGeoDatabase").
blah238

Anladım, teşekkürler. Bu ArcMap'teki katmanlar için de geçerli olacak mı? Ben her katmanını geçirerek layerList = arcpy.mapping.ListLayers(mxd)içine listJoins(table)kod ama dışarı atlar whileaçıklamada.
RyanKDalton

Arcpy nesneleri ve comtypes nesneleri arasında döküm yapabileceğinizi düşünmüyorum, bu yüzden ILayer referansını ArcObjects üzerinden almanız gerekiyor. Kodu daha eksiksiz bir örnek içerecek şekilde güncelledim. Bu, ilgili satırları yorumlayarak / önerilerini kaldırarak hem işlem içinde hem de işlem dışında kullanılabilir olmalıdır.
blah238

Yaklaşıyor, gözden geçirme sabrınız için teşekkürler ... şimdi, bakmak istediğiniz gerçek harita belge dosyasını (* .mxd) nasıl gönderdiniz? app.Documentile geri geliyor'NoneType' object has no attribute 'Document'
RyanKDalton

1

Alanların tüm verilerini dizelere koyun, (onları sipariş ettikten sonra) bir bulanık sıkıştırma işleviyle karşılaştırın ve belirli bir hassasiyetle en iyi eşleşmeyi veya eşleşmeyi sağlayanları seçin.

Bu çözüm, bazı verilerin sığmayacağı zamandır. Her iki sütunun da her zaman uygun olacağını düşünüyorsanız, sıradan bir karşılaştırma işleviyle mükemmel bir eşleşme sipariş edin ve karşılaştırın.


0

Bunu dene:

  • Söz konusu veri kümesine bir xml / html meta veri dosyası yazmak için Meta Veri araç kümesindeki XSLT Dönüştürme aracını kullanın .

    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')
  • Meta veri dosyasında okumak ve Birleştirme Alanına Katıl aracının coğrafi işleme geçmişinden arama yapmak için bir HTML ayrıştırıcı kullanın

  • XSLT Dönüştürme aracından örnek çıktı

XSLT Dönüştürme aracından çıktı


1
Bu gerçekten vaat ettiğini düşündüğüm gerçekten akıllıca bir fikir, ancak testlerimden, bu sadece dosya "JoinField" adlı GP Aracı kullanılarak katılmışsa işe yarayacak gibi görünüyor, çünkü bu GP işlem geçmişinin bir parçası olarak yazılıyor o katman için. Kullanıcı, kullanıcı arabirimi aracılığıyla bir birleştirme oluşturduysa, JoinField işlem satırı çıktı dosyasında mevcut değildir. Harika bir fikir olsa!
RyanKDalton

1
Zaten bunun için GP geçmişine güvenmem. Bunu mümkün olan en kısa sürede silmeye çalışıyoruz, çünkü yinelenen işlemler için bir özellik sınıfını neredeyse kullanılamaz hale getiren büyük miktarda veriye hızla bağlanıyor.
blah238

-1

Birleştirilen tablo adları IFeatureLayer - IFeatureLayerDefinition nesnesinde bir dize olarak .. muhtemelen bence birleştirmek SQL ve böylece alan adlarını içerir.

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

Yoksa bu nesneye erişemiyorsanız?


IFeatureLayerDefinition"SQL'e katıl" ifadesini içermez, yalnızca DefinitionExpressionayarlanmışsa, özellik katmanının tanım sorgusunu ortaya çıkaran bir özelliğe sahiptir ; bu, hangi satırların görüntüleneceğini sınırlayan bir WHERE deyimidir.
blah238

RelationshipClassAncak, bir özelliği var , ama bu sadece en son katılmak ortaya koymaktadır düşünüyorum. Hepsini IRelQueryTablealmak için bunun yerine kullanmanız gerekir .
blah238

-2

alan adından bağımsız olarak eşleşen alanları bulmak için aşağıdaki gibi bir şey yapabilirsiniz:

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)

Hey, cevabımı kimin çaldı: Bana cevabımın yanlış olduğunu söyleyebilir misiniz? Teşekkürler.
mwil

1
Bu, sorulan soruya cevap gibi görünmüyor. Bulanık karşılaştırma cevabı ile aynı. Özdeş olan (hatta bulanık bir şekilde benzer) alanların, bir birleşimde gerçekten kullanılıp kullanılmadığı üzerinde hiçbir etkisi yoktur.
blah238
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.