การเปลี่ยนคลาสคุณลักษณะและชื่อแทนฟิลด์เป็นกลุ่มโดยใช้ ArcPy?


14

ฉันมี FCs มากกว่าหนึ่งร้อยแต่ละตัวมี 10 หรือ 20 คุณลักษณะเพื่อเพิ่มหรือเปลี่ยนนามแฝงปีละสองครั้งขึ้นไป ไม่จำเป็นต้องพูดแบบนี้ไม่ใช่สิ่งที่ฉันจะทำในสิ่งที่ไม่ดี ฉันจะทำให้กระบวนการนี้เป็นอัตโนมัติได้อย่างไร

แนะนำให้ใช้โซลูชัน Python แต่จะใช้ทุกอย่างที่ทำงานได้

ฉันมีสิทธิ์เข้าถึง Arcgis 9.3.1 และ 10 (ระดับสิทธิ์การใช้งาน ArcInfo)


1
ฉันพบ [ตัวอย่างการพัฒนาคลาสของสคีมา] [1] ตัวอย่างนักพัฒนา v9.3 สำหรับ ArcCatalog มันเปลี่ยนนามแฝงสำหรับคลาสคุณลักษณะที่เลือกเป็นค่าฮาร์ดโค้ดในสคริปต์ ดังนั้นไม่ใช่กระบวนการแบทช์ แต่มุ่งไปในทิศทางนั้น [1]: resources.esri.com/help/9.3/ArcGISDesktop/com/samples/…
matt wilkie

เกี่ยวข้อง (บล็อกการสร้างรากฐาน): gis.stackexchange.com/questions/80/…
matt wilkie

คำตอบ:


7

ในฐานะของเวอร์ชัน 10.1 AlterAliasName () สามารถใช้เพื่อ re-alias tables:

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

ในฐานะของเวอร์ชัน 10.3 Alter Fieldสามารถใช้ในการ re-alias field:

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

8

ด้วยความช่วยเหลือจากมาร์ค Cederholm ฉันมีวิธีการทำงานโดยใช้หลามและ ArcObjects มันขรุขระรอบ ๆ ขอบ แต่ก็ทำงานเสร็จแล้ว หลังจากทำตามสูตรบนหน้าเว็บที่สร้างสคริปต์ใหม่ซึ่งใช้ฟังก์ชั่นจากGetLibPath, NewObj, CType, OpenFeatureClass snippets.pyสร้างตารางการค้นหาการเปลี่ยนชื่อในรูปแบบ. csv ด้วย:

การค้นหาฟิลด์ไปที่ฟิลด์ชื่อแทน (att_code-name_lookup.csv):

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

คลาสคุณลักษณะของการค้นหา FC Alias ​​(fc_code-name_lookup.csv):

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

และสคริปต์:

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()

นี่ใกล้เคียงกับสิ่งที่ฉันต้องการ (อัปเดตชื่อแทนฟิลด์) ส่วนของตัวอย่างของ OpenFeatureClass เป็นอย่างไร รหัสของมาร์คไม่มีชิ้นส่วนนั้น ขอบคุณ

สวัสดี Jasperoid: คุณสามารถแสดงความคิดเห็นในคำตอบเฉพาะได้โดยคลิกที่ลิงก์ 'เพิ่มความคิดเห็น' ฉันได้ย้ายข้อมูลคำตอบของคุณไปที่คำตอบนี้แล้ว
scw

@ Jasperiod ฉันย้ายส่วนย่อยของ Mark ไปยังโมดูลที่ฉันเรียกว่าparcoซึ่งเป็นที่ OpenFeatureClass ด้วย ฉันจำไม่ได้ว่าสร้างมันขึ้นมาเอง แต่บางทีฉันก็ทำได้ อย่างไรก็ตามมีมันอยู่ที่เส้น 125
matt wilkie

6

รหัสนี้ใช้ได้กับฉันใน 9.3.1 ...

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;
}

ขอบคุณ Kirk คุณไม่รู้หรอกว่าฉันพยายามคิดเรื่องนี้นานแค่ไหน ฉันเดาว่านี่คือ C # หรือ
matt wilkie

1
ใช่ C # ไม่ได้ทดสอบกับชุดคุณสมบัติเด่น แต่ควรใช้งานได้
Kirk Kuykendall

3

โซลูชันอื่นของ Rob Clark :

คุณสามารถใช้featureclass_to_featureclassกับการแมปฟิลด์ ใช่มันสร้างคลาสคุณสมบัติอื่น แต่คุณสามารถมีพื้นที่เอาท์พุทเพื่อคัดลอกข้อมูลและเปลี่ยนนามแฝงในขณะที่มันกำลังทำอยู่

กล่องโต้ตอบ FC ถึง FC พร้อมคุณสมบัติเปิด (จากเมนูบริบท)

ในไพ ธ อนนั้นไวยากรณ์ของชิ้นfield_mapส่วนนั้นยุ่งยากดังนั้นเมื่อผ่านการโต้ตอบเพื่อตั้งค่าพารามิเตอร์แบบตรงปล่อยให้มันรัน จากนั้นไปที่หน้าต่างผลลัพธ์คลิก r และคัดลอกข้อมูลงูใหญ่ ต่อไปนี้เป็นตัวอย่างข้อมูลที่รวมกันใหม่เป็นสิ่งที่ง่ายต่อการขยายและนำกลับมาใช้ใหม่อีกเล็กน้อย (อาจมีการทำงานมากขึ้นเพื่อแยกส่วนของแผนผังฟิลด์และคุณสมบัติ):

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

โซลูชันนี้สำหรับผู้ใช้ที่ใช้เซิร์ฟเวอร์ SQL เป็นฐานข้อมูลภูมิศาสตร์ คุณสามารถเปลี่ยนได้ด้วยตนเองโดยคำสั่ง SQL update ชื่อคุณสมบัติทั้งหมดบันทึกใน [sde] ตาราง [GDB_OBJECTCLASSES] ชื่อนามแฝงตั้งค่าถ้าคุณเปลี่ยนค่าคอลัมน์นามแฝง

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

แก้ไข: วิธีนี้เป็นวิธีที่รวดเร็วสำหรับการเปลี่ยนชื่อนามแฝง แต่การใช้ IClassSchemaEdit ดีกว่าเพราะในวิธีการอัปเดต sql คุณไม่สามารถใช้ชื่อนามแฝงได้จนกว่าจะรีเซ็ตพื้นที่ทำงานฟีเจอร์

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
ชัดเจนแล้วตอนนี้ที่ฉันคิดเกี่ยวกับมัน! แนวทางเดียวกันควรเป็นไปได้โดยใช้ Personal GDB (Access .mdb) หรือตัวเลือกการจัดเก็บ RDBMS ใด ๆ เช่นกัน
matt wilkie

เพื่อค้นหาใน RDBMS อื่นฉันคิดว่าเป็นการดีกว่าที่จะคัดลอกข้อมูลสำรองจาก RDBMS ของคุณแล้วเปลี่ยนชื่อนามแฝงโดย ArcCatalog จากนั้นเปรียบเทียบฐานข้อมูลปัจจุบันกับข้อมูลสำรองที่คุณสามารถดูการเปลี่ยนแปลงและหาตำแหน่งที่บันทึกชื่อแทน
Mehdi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.