ArcPy를 사용하여 피처 클래스 및 필드 별칭을 일괄 변경합니까?


14

1 년에 두 번 이상 별칭을 추가하거나 변경하기 위해 각각 10 개 또는 20 개의 속성이있는 100 개가 넘는 FC가 있습니다. 말할 필요도없이, 이것은 내가 지나칠 길은 아닙니다. 이 프로세스를 자동화하려면 어떻게해야합니까?

파이썬 솔루션은 선호하지만 작동하는 모든 것을 사용합니다.

Arcgis 9.3.1 및 10 (ArcInfo 라이센스 레벨)에 액세스 할 수 있습니다.


1
ArcCatalog 용 [Edit Feature Class Schema] [1] v9.3 개발자 샘플을 찾았습니다. 선택한 피쳐 클래스의 별명을 스크립트에 하드 코딩 된 값으로 변경합니다. 따라서 배치 프로세스가 아니라 그 방향으로 향했습니다. [1] : resources.esri.com/help/9.3/ArcGISDesktop/com/samples/…
matt wilkie

관련 (기초 빌딩 블록) : gis.stackexchange.com/questions/80/…
matt wilkie

답변:


7

버전 10.1 부터 AlterAliasName () 을 사용하여 테이블을 다시 앨리어싱 할 수 있습니다.

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

버전 10.3부터 필드 변경을 사용하여 필드 를 다시 앨리어싱 할 수 있습니다.

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

8

Mark 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 별명 검색에 대한 기능 클래스 (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;
}

커크 고마워, 내가 얼마나 오랫동안 이것을 알아 내려고 노력했는지 전혀 모른다 나는 이것이 C #이라고 생각하고 있습니까?
매트 윌키

1
예, C # featuredatasets로 테스트하지는 않았지만 작동합니다.
Kirk Kuykendall

3

Rob Clark의 또 다른 솔루션 :

fieldmap 과 함께 featureclass_to_featureclass 를 사용할 수 있습니다 . 예. 다른 피쳐 클래스를 작성하지만 데이터를 복사하고 수행하는 동안 별명을 변경하기위한 출력 영역이있을 수 있습니다.

상황에 맞는 메뉴에서 속성이 열린 FC 대 FC 대화 상자

파이썬에서는 field_map부품 의 구문 이 까다로워 대화 형으로 한 번 통과하여 매개 변수를 똑바로 설정하고 실행하십시오. 그런 다음 결과 창으로 이동하여 r- 클릭하고 python snippet 복사 하십시오 . 다음은 약간 더 쉽게 확장하고 재사용 할 수있는 스 니펫으로 다시 결합 된 스 니펫입니다 (필드 맵과 속성 조각을 분리하기 위해 더 많은 작업을 수행 할 수 있음).

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 Server를 지오 데이터베이스로 사용하는 사용자를위한 것입니다. SQL 업데이트 명령으로 수동으로 변경할 수 있습니다. 모든 기능의 이름은 [sde]. [GDB_OBJECTCLASSES] 테이블에 저장됩니다. 별명 열 값을 변경하는 경우 별명 이름이 설정됩니다.

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

편집 :이 방법은 별칭 이름을 변경하는 빠른 방법입니다. 그러나 SQL 업데이트 방법에서는 기능 작업 공간을 재설정 할 때까지 별칭 이름을 사용할 수 없기 때문에 IClassSchemaEdit를 사용하는 것이 좋습니다.

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 스토리지 옵션을 사용하여 동일한 접근 방식을 사용할 수 있어야합니다.
매트 윌키

다른 RDBMS에서 찾을 수 있도록 RDBMS에서 백업을 복사 한 다음 ArcCatalog로 별칭 이름을 변경 한 다음 현재 데이터베이스를 백업과 비교하여 변경 사항을 확인하고 aliasname이 저장된 위치를 찾으십시오.
Mehdi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.