ArcPy kullanarak özellik sınıfı ve alan takma adlarını toplu olarak değiştirme?


14

Her biri yılda iki veya daha fazla kez takma ad eklemek veya değiştirmek için 10 veya 20 özelliğe sahip yüzün üzerinde FC'm var. Söylemeye gerek yok, bu benim yolumdan homurdanacağım bir şey değil. Bu işlemi nasıl otomatikleştirebilirim?

Python çözümü tercih etti, ancak işe yarayan her şeyi kullanacak.

Arcgis 9.3.1 ve 10'a (ArcInfo lisans düzeyi) erişimim var.


1
ArcCatalog için [Özellik Sınıfı Şemasını Düzenle] [1] v9.3 geliştirici örneğini buldum. Seçilen özellik sınıflarının diğer adını kodda sabit olarak kodlanmış değere değiştirir. Yani bir toplu işlem değil, o yönde ilerledi. [1]: resources.esri.com/help/9.3/ArcGISDesktop/com/samples/…
matt wilkie

related (vakıf yapı taşı): gis.stackexchange.com/questions/80/…
matt wilkie

Yanıtlar:


7

10.1 sürümünden itibaren AlterAliasName () , tabloları yeniden takma ad olarak kullanmak için kullanılabilir:

table = r"C:\path\to\connection.sde\OWNER.TABLE"
arcpy.AlterAliasName(table, "table_alias")

Sürüm 10.3'ten itibaren Alanı Değiştirmek alanları değiştirmek için kullanılabilir:

table = r"C:\path\to\connection.sde\OWNER.TABLE"
arcpy.AlterField_management(table, "FIELD_NAME", new_field_alias="field_alias")

8

Mark Cederholm'un yardımıyla python ve arcobjects kullanarak çalışan bir çözümüm var . Kenarlarda pürüzlü, ama işi tamamladı. Bu sayfadaki tarifi takip ettikten sonra, GetLibPath, NewObj, CType, OpenFeatureClassişlevlerini kullanan yeni bir komut dosyası oluşturun snippets.py. Ayrıca yeniden adlandırma arama tablolarını .csv biçiminde oluşturun:

Tarladan Alan Takma Araması (att_code-name_lookup.csv):

Attrib_Name,Alias_Name
CODE,Specification Code
VALDATE,Validity Date
...

FC Alias ​​aramasına özellik sınıfı (fc_code-name_lookup.csv):

"FC_Name","AliasName"
"BS_1250009_0","Navigational Aid"
"BS_1370009_2","Residential Area"
...

ve senaryo:

import sys
sys.path.append('k:/code')
from snippets import GetLibPath, NewObj, CType, OpenFeatureClass
sWorkingDir = "k:/code/"
sFileGDB = sWorkingDir + "blank_canvec.gdb"
sResourceDir = "k:/code/"
sFCAliasFile = sResourceDir + "fc_code-name_lookup.csv"
sAttAliasFile = sResourceDir + "att_code-name_lookup.csv"
sProduct = "ArcEditor"

def BuildFieldAliasLookup():
    lookup = {}
    f = open(sAttAliasFile, "r")
    bFirst = True
    for line in f:
        # Skip first line
        if bFirst:
            bFirst = False
            continue
        sTokens = line.replace('"','').split(',')
        sFieldName = sTokens[0]
        sAlias = sTokens[1]
        lookup[sFieldName] = sAlias
    return lookup

def AlterAlias():
    # Initialize
    from comtypes.client import GetModule
    import arcgisscripting
    sLibPath = GetLibPath()
    GetModule(sLibPath + "esriGeoDatabase.olb")
    GetModule(sLibPath + "esriDataSourcesGDB.olb")
    import comtypes.gen.esriGeoDatabase as esriGeoDatabase
    gp = arcgisscripting.create(9.3)

    try:
        gp.setproduct(sProduct)
    except:
        gp.AddMessage(gp.GetMessages(2))

    # Build field alias lookup table
    AttrLookup = BuildFieldAliasLookup()
    # Open alias file and loop through lines
    f = open(sFCAliasFile, "r")
    bFirst = True
    for line in f:
        # Skip first line
        if bFirst:
            bFirst = False
            continue
        sTokens = line.replace('"','').split(',')
        sFCName = sTokens[0]
        sAlias = sTokens[1]
        print "Processing: ", sFCName
        # Open feature class
        try:
            pFC = OpenFeatureClass(sFCName)
        except:
            print "Could not open ", sFCName
            continue
        # Alter feature class alias
        try:
            pSE = CType(pFC, esriGeoDatabase.IClassSchemaEdit)
            pSE.AlterAliasName(sAlias)
        except:
            print "Error altering class alias"
            continue
        # Alter field aliases
        try:
            for sKey in AttrLookup.keys():
                i = pFC.FindField(sKey)
                if i == -1:
                    continue
                sAlias = AttrLookup[sKey]
                pSE.AlterFieldAliasName(sKey, sAlias)
        except:
            print "Error altering field aliases"
    print "Done."

print 'Field <--> Alias lookup table is:', BuildFieldAliasLookup()
print AlterAlias()

Bu çok ihtiyacım olan yakın (alan takma güncelleniyor). Parçacıkların OpenFeatureClass kısmı neye benziyor? Mark'ın kodunda bu parça yok. Teşekkürler

Merhaba Jasperoid: 'yorum ekle' bağlantısını tıklayarak belirli bir cevap hakkında yorum yapabilirsiniz, yanıtınızı bu yanıta taşıdım.
scw

@Jasperiod, Mark'ın snippet'lerinin çoğunu OpenFeatureClass'ın da bulunduğu parco dediğim bir modüle taşıdım. Kendim yarattığımı hatırlamıyorum ama belki de yaptım. Her neyse, 125. satırda .
matt wilkie

6

Bu kod benim için 9.3.1'de çalışıyor ...

public static void TestAlterAlias(IApplication app)
{
    // make a dictionary of old/new names
    Dictionary<string, string> nameDict = new Dictionary<string, string>(StringComparer.CurrentCultureIgnoreCase);
    nameDict.Add("qsectionalias", "qsectionalias2");
    nameDict.Add("sursysalias", "sursysalias2");
    string[] directories =  System.IO.Directory.GetDirectories(@"D:\Projects\EmpireOil\data",@"*.gdb",
        System.IO.SearchOption.TopDirectoryOnly);
    foreach(string dir in directories)
    {
        List<IName> fcnames = GetFCNames(dir);
        foreach (IName fcName in fcnames)
        {
            ChangeFieldAliases(fcName, nameDict);
        }
    }
}

public static void ChangeFieldAliases(IName fcName, Dictionary<string, string> aliasDict)
{
    IFeatureClass fc = (IFeatureClass)fcName.Open();
    IClassSchemaEdit3 cse = (IClassSchemaEdit3)fc;
    ((ISchemaLock)fc).ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);
    SortedList<string, string> changeList = new SortedList<string, string>();
    for (int i = 0; i < fc.Fields.FieldCount; i++)
    {
        string fldName = fc.Fields.get_Field(i).Name;
        string alias = fc.Fields.get_Field(i).AliasName;
        if (aliasDict.ContainsKey(alias))
        {
            changeList.Add(fldName, aliasDict[alias]);
            // set it blank for now, to avoid problems if two fields have same aliasname.
            cse.AlterFieldAliasName(fldName, "");
        }
    }

    // change the alias
    foreach (KeyValuePair<string, string> kvp in changeList)
        cse.AlterFieldAliasName(kvp.Key, kvp.Value);
    ((ISchemaLock)fc).ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock);
}

public static List<IName> GetFCNames(string wsPath)
{
    List<IName> names = new List<IName>();
    IWorkspaceFactory wsf = new ESRI.ArcGIS.DataSourcesGDB.FileGDBWorkspaceFactoryClass();
    IWorkspace ws = wsf.OpenFromFile(wsPath, 0);
    IEnumDatasetName enumName = ws.get_DatasetNames(esriDatasetType.esriDTAny);
    enumName.Reset();
    IDatasetName dsName = null;
    while ((dsName = enumName.Next()) != null)
    {
        if(dsName is IFeatureClassName)
            names.Add((IName)dsName);
        else if(dsName is IFeatureDatasetName)
        {
            IEnumDatasetName enumName2 = dsName.SubsetNames;
            enumName2.Reset();
            IDatasetName dsName2;
            while((dsName2=enumName2.Next())!= null)
            {
                if(dsName2 is IFeatureClassName)
                    names.Add((IName)dsName2);
            }
        }
    }
    return names;
}

teşekkürler Kirk, ne kadar zamandır anlamaya çalıştığımı bilmiyorsun. Sanırım bu C # mı?
matt wilkie

1
Evet C#. Yine de özellik veri kümeleri ile test etmedi, ama çalışması gerekir.
Kirk Kuykendall

3

Rob Clark'ın izniyle bir başka çözüm :

Alan eşlemeyle featureclass_to_featureclass kullanabilirsiniz . Evet, başka bir özellik sınıfı oluşturur, ancak bunu yaparken verileri kopyalamak ve takma adları değiştirmek için bir çıkış alanınız olabilir.

Özellikler açıkken FC'den FC'ye iletişim kutusu (bağlam menüsünden)

Python'da field_mapparçanın sözdizimi zordur, bu yüzden parametreleri düz ayarlamak için bir kez etkileşimli olarak geçin, çalışmasına izin verin. Sonra sonuçlar penceresine gidin , python snippet'ini r-tıklayın ve kopyalayın . İşte bir parçacık, uzatılması ve yeniden kullanılması biraz daha kolay bir şeyde yeniden birleştirildi (alan haritasının ve özelliklerinin parçalarını ayırmak için daha fazla çalışma yapılabilir):

inFC = 'e:/Canvec/fix.gdb/HD_1480009_2'
outFC = 'HD_with_aliases'
out_wspace = 'e:/canvec/fix.gdb'
where_clause = '#'      # use default
config_keyword = '#'    #    "

# build field map
fmap_out_att = 'CODE /\Specification code/\ '  # field and alias name
fmap_properties = 'true true false 4 Long 0 0 ,First,#,'  # field properties
fmap_in_att = 'e:/Canvec/fix.gdb/HD_1480009_2,CODE,-1,-1'  # input FC and field

# construct the complete field map
field_map = fmap_out_att + fmap_properties + fmap_in_att
   # results in:
   # "CODE /\Specification code/\ true true false 4 Long 0 0 ,First,#,e:/Canvec/fix.gdb/HD_1480009_2,CODE,-1,-1"


arcpy.FeatureClassToFeatureClass_conversion(inFC, out_wspace, outFC, 
        where_clause, field_map, config_keyword)

# the template command copied from Results window, used for building above
# arcpy.FeatureClassToFeatureClass_conversion("e:/Canvec/fix.gdb/HD_1480009_2","e:/canvec/fix.gdb","HD_with_aliases3","#","CODE /\Specification code/\ true true false 4 Long 0 0 ,First,#,e:/Canvec/fix.gdb/HD_1480009_2,CODE,-1,-1","#")

2

Bu çözüm, SQL sunucusunu coğrafi veritabanı olarak kullanan kullanıcılar içindir. SQL güncelleme komutuyla manuel olarak değiştirebilirsiniz. tüm özelliklerin adı [sde]. [GDB_OBJECTCLASSES] tablosuna kaydedilir. diğer ad sütun adını değiştirirseniz ayarlanır.

UPDATE [sde].[sde].[GDB_OBJECTCLASSES] 
SET AliasName = 'an alias name' 
WHERE Name='your feature class name'

EDIT: Bu yöntem, diğer ad adını değiştirmek için hızlı bir yöntemdir. ancak sqlass güncelleme yönteminde sıfırlama özelliği çalışma alanına kadar diğer ad kullanamazsınız çünkü IClassSchemaEdit kullanmak daha iyidir.

Public Sub SetAliasName(FeatureClass As IFeatureClass, AliasName As String)
        Dim abjTable As ITable = FeatureClass
        Dim objClass As IObjectClass = abjTable
        Dim edit As IClassSchemaEdit = objClass
        edit.AlterAliasName(AliasName)
End Sub

1
Şimdi düşündüğüm kadar açık! Aynı yaklaşım Kişisel GDB (Access .mdb) veya RDBMS depolama seçeneklerinden herhangi biri kullanılarak da mümkün olmalıdır.
matt wilkie

diğer RDBMS bulmak için ben RDBMS bir yedek kopyalamak ve daha sonra ArcCatalog tarafından takma adını değiştirmek ve daha sonra mevcut veritabanını yedek ile karşılaştırmak daha iyi olduğunu düşünüyorum değişiklikleri görebilirsiniz ve takma ad nerede kaydetmek bulabilirsiniz.
Mehdi
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.