¿Está cambiando la clase de entidad y los alias de campo en masa con ArcPy?

14

Tengo más de cien FC, cada uno con 10 o 20 atributos para agregar o cambiar los alias, dos o más veces al año. No hace falta decir que esto no es algo por lo que voy a gruñir. ¿Cómo puedo automatizar este proceso?

Se prefiere la solución de Python, pero utilizará cualquier cosa que funcione.

Tengo acceso a Arcgis 9.3.1 y 10 (nivel de licencia de ArcInfo).

    
pregunta matt wilkie 23.07.2010 - 21:04

5 respuestas

5

A partir de la versión 10.1 AlterAliasName () se puede usar para tablas de re-alias:

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

A partir de la versión 10.3 Alter Field se puede usar para re-alias campos:

table = r"C:\path\to\connection.sde\OWNER.TABLE"
arcpy.AlterField_management(table, "FIELD_NAME", new_field_alias="field_alias")
    
respondido por el Kelly Thomas 12.02.2016 - 09:43
8

Con la ayuda de Mark Cederholm, tengo una solución funcional que utiliza python y arcobjects . Es áspero alrededor de los bordes, pero hizo el trabajo. Después de seguir la receta en esa página, cree un nuevo script que use las funciones GetLibPath, NewObj, CType, OpenFeatureClass de snippets.py . También cree las tablas de búsqueda de cambio de nombre en formato .csv:

Búsqueda de alias campo a campo (att_code-name_lookup.csv):

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

Clase de entidad para búsqueda de alias de FC (fc_code-name_lookup.csv):

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

y el guión:

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()
    
respondido por el matt wilkie 20.08.2010 - 00:46
6

Este código me funciona en 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;
}
    
respondido por el Kirk Kuykendall 23.07.2010 - 22:43
3

Otra solución cortesía de Rob Clark :

  

Puede usar featureclass_to_featureclass con asignación de campo. sí eso   crea otra clase de entidad, pero podría tener un área de salida   para copiar datos y cambiar alias mientras lo hace.

EnPython,lasintaxisdelapartefield_mapescomplicada,asíqueinténteladeformainteractivaparaestablecerlosparámetrosdeformacorrecta,déjelofuncionar.Luego,vayaa ventana de resultados , haga clic y Copiar fragmento de python . Aquí hay un fragmento re-combinado en algo un poco más fácil de extender y reutilizar (se podría hacer más trabajo para separar las partes del mapa de campo y las propiedades):

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","#")
    
respondido por el matt wilkie 09.11.2011 - 21:17
2

Esta solución es para usuarios que usan el servidor SQL como geodatabase. Puedes cambiarlo manualmente por un comando de actualización de SQL. el nombre de todas las funciones se guarda en la tabla [sde]. [GDB_OBJECTCLASSES]. el nombre de alias establecido simplemente si cambia el valor de la columna de alias.

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

EDITAR: este método es un método rápido para cambiar el nombre de alias. pero usar IClassSchemaEdit es mejor porque en el método de actualización de SQL no puede usar el nombre de alias hasta que se restablezca el espacio de trabajo de la característica.

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
    
respondido por el Mehdi 10.02.2015 - 17:03

Lea otras preguntas en las etiquetas