ArcGIS Engineを用いたシェープファイル操作の実践例

シェープファイルのフィールド名変更処理

以下のメソッドは、フィールド名を変更する際の実用的なアプローチを示しています。既存フィールドの値を保持しながら、新しいフィールドを追加し、古いフィールドを削除します。


public bool RenameFieldInFeatureClass(IFeatureClass targetFeatureClass, string originalName, string updatedName)
{
    bool operationStatus = false;
    try
    {
        using (ComReleaser resourceManager = new ComReleaser())
        {
            if (targetFeatureClass == null) return false;
            ITable dataTable = targetFeatureClass as ITable;
            IFields fieldCollection = targetFeatureClass.Fields;
            IField targetField = null;

            for (int position = 0; position < fieldCollection.FieldCount; position++)
            {
                targetField = fieldCollection.get_Field(position);
                if (targetField.Name.Equals(originalName, StringComparison.OrdinalIgnoreCase))
                {
                    IField newField = new FieldClass();
                    IFieldEdit fieldEditor = newField as IFieldEdit;
                    fieldEditor.Name_2 = updatedName;
                    fieldEditor.AliasName_2 = updatedName;
                    fieldEditor.Type_2 = targetField.Type;
                    fieldEditor.Length_2 = targetField.Length;
                    fieldEditor.Precision_2 = targetField.Precision;
                    fieldEditor.Scale_2 = targetField.Scale;
                    dataTable.AddField(newField);
                    break;
                }
            }

            int newFieldIndex = dataTable.FindField(updatedName);
            int oldFieldIndex = dataTable.FindField(originalName);

            if (newFieldIndex == -1 || oldFieldIndex == -1) return false;
            ICursor updateCursor = dataTable.Update(null, false);
            resourceManager.ManageLifetime(updateCursor);

            IRow currentRow = null;
            while ((currentRow = updateCursor.NextRow()) != null)
            {
                object originalValue = currentRow.get_Value(oldFieldIndex);
                currentRow.set_Value(newFieldIndex, originalValue);
                updateCursor.UpdateRow(currentRow);
            }
            dataTable.DeleteField(targetField);
        }
        operationStatus = true;
    }
    catch (Exception ex)
    {
        operationStatus = false;
    }
    return operationStatus;
}

フィールド間での値の一括コピー

指定したフィールドの値を別のフィールドに一括でコピーする方法です。


public bool CopyFieldValues(string layerIdentifier, string sourceField, string destinationField)
{
    bool successFlag = false;
    try
    {
        using (ComReleaser comManager = new ComReleaser())
        {
            IFeatureClass spatialLayer = GetFeatureClassByName(layerIdentifier);
            if (spatialLayer == null) return false;

            int sourceIndex = spatialLayer.Fields.FindField(sourceField);
            int destinationIndex = spatialLayer.Fields.FindField(destinationField);
            if (sourceIndex == -1 || destinationIndex == -1) return false;

            IQueryFilter filter = new QueryFilterClass();
            filter.SubFields = spatialLayer.OIDFieldName + "," + sourceField + "," + destinationField;
            IFeatureCursor updateCursor = spatialLayer.Update(filter, false);
            IFeature currentFeature = updateCursor.NextFeature();

            while (currentFeature != null)
            {
                currentFeature.set_Value(destinationIndex, currentFeature.get_Value(sourceIndex));
                updateCursor.UpdateFeature(currentFeature);
                currentFeature = updateCursor.NextFeature();
            }
        }
        successFlag = true;
    }
    catch (Exception ex)
    {
        successFlag = false;
    }
    return successFlag;
}

選択セットからの新規レイヤー生成

特定の条件に基づいて選択されたフィーチャから、新しいレイヤーを作成します。


IFeatureLayer baseLayer = new FeatureLayerClass();
baseLayer.FeatureClass = inputFeatureClass;

IFeatureSelection selectionInterface = baseLayer as IFeatureSelection;
IQueryFilter selectionFilter = new QueryFilterClass();
selectionFilter.WhereClause = "AREA_CODE LIKE '" + regionCode + "%'";
selectionInterface.SelectFeatures(selectionFilter, esriSelectionResultEnum.esriSelectionResultNew, false);

ISelectionSet selectedSet = selectionInterface.SelectionSet;
IFeatureLayer resultLayer = null;
if (selectedSet.Count > 0)
{
    IFeatureLayerDefinition layerDefinition = baseLayer as IFeatureLayerDefinition;
    resultLayer = layerDefinition.CreateSelectionLayer(inputFeatureClass.AliasName, true, "", "");
}

フィルタ適用後のレイヤー表示範囲への自動ズーム

フィルタが適用されたレイヤーの全フィーチャを表示するために、ビューの範囲を自動調整します。


IEnvelope displayExtent = new EnvelopeClass();
IEnumGeometryBind geometryEnumerator = new EnumFeatureGeometryClass();
geometryEnumerator.BindGeometrySource(null, filteredFeatureClass);
IEnumGeometry geometryEnum = (IEnumGeometry)geometryEnumerator;

IGeometryFactory geometryFactory = new GeometryEnvironment() as IGeometryFactory;
IGeometry combinedGeometry = geometryFactory.CreateGeometryFromEnumerator(geometryEnum);
displayExtent.Union(combinedGeometry.Envelope);

Marshal.ReleaseComObject(combinedGeometry);
Marshal.ReleaseComObject(geometryFactory);
Marshal.ReleaseComObject(geometryEnum);

mapControl.ActiveView.FullExtent = displayExtent;

タグ: ArcGIS Engine C# シェープファイル フィールド操作 レイヤー管理

7月28日 01:01 投稿