2010년 4월 25일 일요일

[ArcObjects]선택된 Feature를 Graphic Element로 변환

ArcObjects Code Snippet입니다.

ArcMap에서 피쳐를 선택한 후 TOC(Table Of Contents)에서 레이어 선택 후 선택한 피쳐를 그래픽으로 변환하기 Command 구현하기

위 주제를 프로그래밍 하기 위해서는 다음의 ArcObejcts 학습이 필요합니다.
처음 접하시는 분은 이 순서대로 ArcObjects를 공부하시면 도움이 될 듯 하네요.

 - IColor의 이해
 - ISymbol의 이해
 - Graphic Element의 이해
 - IFeatureLayer, IFeatureSelection, SelectionSet의 이해
 - IFeatureCursor, IFeature의 이해

▣ Marker Element 생성
private IElement GetMarkerElement(IPoint geometry, IMarkerSymbol symbol, string elementName)
{
    IMarkerElement markerElement = new MarkerElementClass();
    markerElement.Symbol = symbol;

    IElement element = (IElement)markerElement;
    element.Geometry = geometry;

    if (! string.IsNullOrEmpty(elementName))
    {
        IElementProperties elementProp = (IElementProperties)element;
        elementProp.Name = elementName;
    }

    return element;
}
▣ Line Element 생성
private IElement GetLineElement(IPolyline geometry, ILineSymbol symbol, string elementName)
{
    ILineElement lineElement = new LineElementClass();
    lineElement.Symbol = symbol;

    IElement element = (IElement)lineElement;
    element.Geometry = geometry;

    if (!string.IsNullOrEmpty(elementName))
    {
        IElementProperties elementProp = (IElementProperties)element;
        elementProp.Name = elementName;
    }

    return element;
}
▣ Polygon FillShape Element 생성
private IElement GetPolygonElement(IPolygon geometry, IFillSymbol symbol, string elementName)
{
    IFillShapeElement fillShapeElement = new PolygonElementClass();
    fillShapeElement.Symbol = symbol;

    IElement element = (IElement)fillShapeElement;
    element.Geometry = geometry;
   
    if (!string.IsNullOrEmpty(elementName))
    {
        IElementProperties elementProp = (IElementProperties)element;
        elementProp.Name = elementName;
    }

    return element;
}
▣ 선택된 피쳐의 Shape을 이용하여 Element 생성 후 지도에 추가
아래 코드에서는 Symbol을 생성하지 않고 FeatureLayer의 FeatureRenderer를 이용하여 각 피쳐별 Symbol을 얻어서 사용한다는 것을 눈여겨 보세요.
private void SelectedFeaturesToGraphics(IMap targetMap, IFeatureLayer featureLayer)
{
    IActiveView activeView = (IActiveView)targetMap;
    IGraphicsContainer graphicsCon = (IGraphicsContainer)activeView;

    IGeoFeatureLayer geoFeatureLayer = (IGeoFeatureLayer)featureLayer;
    IFeatureRenderer featureRenderer = geoFeatureLayer.Renderer;
    IFeatureSelection featureSelection = (IFeatureSelection)featureLayer;
    ISelectionSet selectionSet = featureSelection.SelectionSet;

    if (selectionSet.Count == 0)
        return;

    ICursor cursor = null;
    selectionSet.Search(null, true, out cursor);

    IFeatureCursor featureCursor = (IFeatureCursor)cursor;
    IFeature feature = featureCursor.NextFeature();         
    while (feature != null)
    {
        IGeometry geometry = feature.ShapeCopy;
        ISymbol symbol = featureRenderer.get_SymbolByFeature(feature);
        string elementName = string.Format("{0}_{1}", featureLayer.Name, feature.OID);
        IElement element = null;

        switch (geometry.GeometryType)
        {
            case esriGeometryType.esriGeometryPoint:
                element = this.GetMarkerElement((IPoint)geometry, (IMarkerSymbol)symbol, elementName);
                graphicsCon.AddElement(element, 0);
                break;
            case esriGeometryType.esriGeometryPolyline:
                element = this.GetLineElement((IPolyline)geometry, (ILineSymbol)symbol, elementName);
                graphicsCon.AddElement(element, 0);
                break;
            case esriGeometryType.esriGeometryPolygon:
                element = this.GetPolygonElement((IPolygon)geometry, (IFillSymbol)symbol, elementName);
                graphicsCon.AddElement(element, 0);
                break;
        }
        feature = featureCursor.NextFeature();
    }
    System.Runtime.InteropServices.Marshal.ReleaseComObject(cursor);

    activeView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
}
▣ Function 사용법
위 Function을 이용하여 IMap 및 Map에 추가된 Feature Layer중 선택된 피쳐를 Graphic Element로 변환하기 위한 사용법은 다음과 같습니다.
IMap targetMap = GetFocusMap();
IFeatureLayer featureLayer = (IFeatureLayer)targetMap.get_Layer(0);

SelectedFeaturesToGraphics(this.Application.FocusMap, featureLayer);