1年に2回以上、エイリアスを追加または変更するための10個または20個の属性を持つFCが100個以上あります。言うまでもなく、これは私が自分の道をうなりだすものではありません。このプロセスを自動化するにはどうすればよいですか?
Pythonソリューションが優先されますが、機能するものなら何でも使用します。
Arcgis 9.3.1および10(ArcInfoライセンスレベル)にアクセスできます。
1年に2回以上、エイリアスを追加または変更するための10個または20個の属性を持つFCが100個以上あります。言うまでもなく、これは私が自分の道をうなりだすものではありません。このプロセスを自動化するにはどうすればよいですか?
Pythonソリューションが優先されますが、機能するものなら何でも使用します。
Arcgis 9.3.1および10(ArcInfoライセンスレベル)にアクセスできます。
回答:
バージョン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")
Mark Cederholmの助けを借りて、pythonと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()
このコードは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;
}
ロブ・クラークの好意による別のソリューション:
フィールドマッピングでfeatureclass_to_featureclassを使用できます。はい、別のフィーチャクラスを作成しますが、データをコピーしてエイリアスを変更するための出力領域を作成するだけで済みます。
Pythonでは、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","#")
このソリューションは、ジオデータベースとしてSQLサーバーを使用するユーザー向けです。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