ArcEngine通过制图表达 实现河流渐

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.ADF.BaseClasses;
using ESRI.ArcGIS.ADF.CATIDs;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Framework;
using ESRI.ArcGIS.ArcMapUI;
using ESRI.ArcGIS.Carto;
using System.Windows.Forms;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Display;


namespace RiverTapered
{
    /// <summary>
    /// Command that works in ArcMap/Map/PageLayout
    /// </summary>
    [Guid("38558b1f-b52c-4901-b27d-539c40170237")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("RiverTapered.CmdRiverTapered")]
    public sealed class CmdRiverTapered : BaseCommand
    {
        #region COM Registration Function(s)
        [ComRegisterFunction()]
        [ComVisible(false)]
        static void RegisterFunction(Type registerType)
        {
            // Required for ArcGIS Component Category Registrar support
            ArcGISCategoryRegistration(registerType);


            //
            // TODO: Add any COM registration code here
            //
        }


        [ComUnregisterFunction()]
        [ComVisible(false)]
        static void UnregisterFunction(Type registerType)
        {
            // Required for ArcGIS Component Category Registrar support
            ArcGISCategoryUnregistration(registerType);


            //
            // TODO: Add any COM unregistration code here
            //
        }


        #region ArcGIS Component Category Registrar generated code
        /// <summary>
        /// Required method for ArcGIS Component Category registration -
        /// Do not modify the contents of this method with the code editor.
        /// </summary>
        private static void ArcGISCategoryRegistration(Type registerType)
        {
            string regKey = string.Format("HKEY_CLASSES_ROOT//CLSID//{{{0}}}", registerType.GUID);
            MxCommands.Register(regKey);
            ControlsCommands.Register(regKey);
        }
        /// <summary>
        /// Required method for ArcGIS Component Category unregistration -
        /// Do not modify the contents of this method with the code editor.
        /// </summary>
        private static void ArcGISCategoryUnregistration(Type registerType)
        {
            string regKey = string.Format("HKEY_CLASSES_ROOT//CLSID//{{{0}}}", registerType.GUID);
            MxCommands.Unregister(regKey);
            ControlsCommands.Unregister(regKey);
        }


        #endregion
        #endregion


        #region 变量常量


        private IHookHelper m_hookHelper = null;
        private IApplication m_Application;
        private IMxDocument m_MxDoc;
        private IMap m_Map;
        private IActiveView m_ActiveView;


        private const string RULE_FIELD_NAME = "RuleId";//规则字段名称
        private const string OVERRIDE_FIELD_NAME = "Override";//覆盖字段名称
        private const string REP_CLASS_POSTFIX = "_Rep";//要素类表达名称后缀


        #endregion


        #region 入口函数


        public CmdRiverTapered()
        {
            base.m_category = "制图表达"; //localizable text
            base.m_caption = "河流渐变";  //localizable text 
            base.m_message = "This should work in ArcMap/MapControl/PageLayoutControl";  //localizable text
            base.m_toolTip = "使选择的线要素有渐变效果";  //localizable text
            base.m_name = "河流渐变";   //unique id, non-localizable (e.g. "MyCategory_MyCommand")


            try
            {
                string bitmapResourceName = GetType().Name + ".bmp";
                base.m_bitmap = new Bitmap(GetType(), bitmapResourceName);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap");
            }
        }


        /// <summary>
        /// Occurs when this command is created
        /// </summary>
        /// <param name="hook">Instance of the application</param>
        public override void OnCreate(object hook)
        {
            if (hook == null) return;


            try
            {
                m_hookHelper = new HookHelperClass();
                m_hookHelper.Hook = hook;
                if (m_hookHelper.ActiveView == null)
                {
                    m_hookHelper = null;
                }
            }
            catch
            {
                m_hookHelper = null;
            }


            base.m_enabled = m_hookHelper != null;


            // TODO:  Add other initialization code
            m_Application = hook as IApplication;
        }


        /// <summary>
        /// Occurs when this command is clicked
        /// </summary>
        public override void OnClick()
        {
            // TODO: Add CmdRiverTapered.OnClick implementation
            m_MxDoc = m_Application.Document as IMxDocument;
            m_Map = m_MxDoc.FocusMap;
            m_ActiveView = m_Map as IActiveView;


            if (!CheckInput()) return;


            //获取所选要素对应的要素类
            IFeatureClass pFeatCls = GetFeatureClass();
            //设置要素的表达
            IRepresentationClass pRepClass = SetFeatureRep(pFeatCls);
            //使用制图表达符号化当前要素图层
            SetRepRenderer(pFeatCls, pRepClass);
        }


        #endregion


        #region 输入检查


        /// <summary>
        /// 检查选择集是否为空,是否都是线要素,是否都属于同一个图层
        /// </summary>
        /// <returns></returns>
        private bool CheckInput()
        {
            if (m_Map.SelectionCount < 1)
            {
                ShowMessage("请选择至少一个线要素!");
                return false;
            }


            ISelection pSelection = m_Map.FeatureSelection;
            string strErrorInfo = "";
            if (HasNonLineOrMultiLayers(pSelection, ref strErrorInfo))
            {
                ShowMessage(strErrorInfo);
                return false;
            }


            return true;
        }


        /// <summary>
        /// 判断选择集中是否包含指定的几何类型。暂未使用。
        /// </summary>
        /// <param name="pSelection"></param>
        /// <param name="geoType"></param>
        /// <returns></returns>
        private bool HasGeometryType(ISelection pSelection, esriGeometryType geoType)
        {
            IEnumFeature pEnumFeature = (IEnumFeature)pSelection;
            pEnumFeature.Reset();
            IFeature pFeature = pEnumFeature.Next();
            while (pFeature != null)
            {
                if (pFeature.ShapeCopy.GeometryType == geoType)
                {
                    return true;
                }


                pFeature = pEnumFeature.Next();
            }


            return false;
        }


        /// <summary>
        /// 检查选择集中是否有非线要素,是否属于多个图层
        /// </summary>
        /// <param name="pSelection"></param>
        /// <param name="strError"></param>
        /// <returns></returns>
        private bool HasNonLineOrMultiLayers(ISelection pSelection, ref string strError)
        {
            strError = "";


            IEnumFeature pEnumFeature = (IEnumFeature)pSelection;
            pEnumFeature.Reset();
            IFeature pFeature = pEnumFeature.Next();
            string fcName = GetFeatClsName(pFeature.Class as IFeatureClass);//要素类名称
            while (pFeature != null)
            {
                if (pFeature.ShapeCopy.GeometryType != esriGeometryType.esriGeometryLine &&
                    pFeature.ShapeCopy.GeometryType != esriGeometryType.esriGeometryPolyline)
                {
                    strError = "您只能选择线要素!";
                    return true;
                }


                string strClassName = GetFeatClsName(pFeature.Class as IFeatureClass);
                if (strClassName != fcName)
                {
                    strError = "您只能选择同一个线图层的要素!";
                    return true;
                }


                pFeature = pEnumFeature.Next();
            }


            return false;
        }


        #endregion


        #region 制图表达


        /// <summary>
        /// 创建或打开表达类,并设置要素的表达规则
        /// </summary>
        /// <param name="pFeatCls"></param>
        /// <returns></returns>
        private IRepresentationClass SetFeatureRep(IFeatureClass pFeatCls)
        {
            if (pFeatCls == null) return null;


            try
            {
                IRepresentationClass pRepClass = null;
                string strAction = "获取";
                if (!HasRepClass(pFeatCls))
                {
                    pRepClass = CreateRepClass(pFeatCls);
                    strAction = "创建";
                }
                else
                {
                    pRepClass = OpenRepClass(pFeatCls);
                }


                if (pRepClass == null)
                {
                    ShowMessage(strAction + "要素类表达失败!");
                    return pRepClass;
                }


                //开启编辑进程
                IWorkspaceEdit pWksEdit = GetWorkspace(pFeatCls) as IWorkspaceEdit;
                if (!pWksEdit.IsBeingEdited())
                {
                    pWksEdit.StartEditing(true);
                    pWksEdit.StartEditOperation();
                }


                IEnumFeature pEnumFeature = (IEnumFeature)m_Map.FeatureSelection;
                pEnumFeature.Reset();
                IFeature pFeature = pEnumFeature.Next();
                int ruleIdIndex = pRepClass.RuleIDFieldIndex;
                //遍历要素,设置RuleId属性
                while (pFeature != null)
                {
                    pFeature.set_Value(ruleIdIndex, 1);//此处1可能会变化
                    pFeature.Store();//保存对要素的编辑


                    pFeature = pEnumFeature.Next();
                }


                //保存编辑并停止编辑进程
                pWksEdit.StopEditOperation();
                pWksEdit.StopEditing(true);


                return pRepClass;
            }
            catch (Exception ex)
            {
                return null;
            }
        }


        /// <summary>
        /// 检查给定要素类是否存在表达类
        /// </summary>
        /// <param name="pFeatClass"></param>
        /// <returns></returns>
        private bool HasRepClass(IFeatureClass pFeatClass)
        {
            IWorkspace pWorkspace = GetWorkspace(pFeatClass);
            IRepresentationWorkspaceExtension pRepWSExt = GetRepWSExt(pWorkspace);
            bool bHasRepClass = pRepWSExt.get_FeatureClassHasRepresentations(pFeatClass);


            return bHasRepClass;
        }


        /// <summary>
        /// 创建表达类
        /// </summary>
        /// <param name="pFeatClass"></param>
        /// <returns></returns>
        private IRepresentationClass CreateRepClass(IFeatureClass pFeatClass)
        {
            if (pFeatClass == null) return null;


            try
            {
                IWorkspace pWorkspace = GetWorkspace(pFeatClass);


                //创建表达类时应停止编辑进程
                IWorkspaceEdit pWksEdit = pWorkspace as IWorkspaceEdit;
                if (pWksEdit.IsBeingEdited())
                {
                    pWksEdit.StopEditOperation();
                    pWksEdit.StopEditing(true);
                }


                IRepresentationWorkspaceExtension pRepWSExt = GetRepWSExt(pWorkspace);


                //创建河流渐变规则
                IRepresentationRule pRiverTaperedRule = CreateRiverTaperedRule();
                IRepresentationRules pRules = new RepresentationRules();
                pRules.Add(pRiverTaperedRule);
                //创建要素类表达
                string strRepClassName = GetRepClassName(pFeatClass);
                IRepresentationClass pRepClass = pRepWSExt.CreateRepresentationClass(pFeatClass,
                    strRepClassName, RULE_FIELD_NAME, OVERRIDE_FIELD_NAME, false, pRules, null);


                return pRepClass;
            }
            catch (Exception ex)
            {
                return null;
            }
        }


        /// <summary>
        /// 打开指定要素类的表达类
        /// </summary>
        /// <param name="pFeatClass"></param>
        /// <returns></returns>
        private IRepresentationClass OpenRepClass(IFeatureClass pFeatClass)
        {
            if (pFeatClass == null) return null;


            try
            {
                IWorkspace pWorkspace = GetWorkspace(pFeatClass);
                IRepresentationWorkspaceExtension pRepWSExt = GetRepWSExt(pWorkspace);
                //根据表达类名称,打开已有的表达类
                string strRepClassName = GetRepClassName(pFeatClass);
                IRepresentationClass pRepClass = pRepWSExt.OpenRepresentationClass(strRepClassName);


                return pRepClass;
            }
            catch (Exception ex)
            {
                return null;
            }
        }


        /// <summary>
        /// 根据要素类名称生成对应的表达类名称
        /// </summary>
        /// <param name="pFeatClass"></param>
        /// <returns></returns>
        private string GetRepClassName(IFeatureClass pFeatClass)
        {
            string featClsName = GetFeatClsName(pFeatClass);
            string strRepClassName = featClsName + REP_CLASS_POSTFIX;
            return strRepClassName;
        }


        /// <summary>
        /// 创建河流渐变表达规则
        /// </summary>
        /// <returns></returns>
        private IRepresentationRule CreateRiverTaperedRule()
        {
            try
            {
                //创建颜色
                IRgbColor pColor = new RgbColor();
                pColor.Red = 0;
                pColor.Green = 0;
                pColor.Blue = 250;


                //设置线符号属性
                ILineStroke pLineStroke = new LineStrokeClass();
                IGraphicAttributes pGALineStroke = pLineStroke as IGraphicAttributes;
                pGALineStroke.set_Value(0, 2);//Width
                pGALineStroke.set_Value(1, esriLineCapStyle.esriLCSRound);//Caps
                pGALineStroke.set_Value(2, esriLineJoinStyle.esriLJSRound);//Joins 
                pGALineStroke.set_Value(3, pColor);//Color


                //创建基本线符号
                IBasicLineSymbol pBasicLineSymbol = new BasicLineSymbolClass();
                pBasicLineSymbol.Stroke = pLineStroke;


                //渐变效果
                IGeometricEffect pTaperedPolygon = new GeometricEffectTaperedPolygon();
                IGraphicAttributes pGATaperedPolygon = pTaperedPolygon as IGraphicAttributes;
                pGATaperedPolygon.set_Value(0, 1);//From Width
                pGATaperedPolygon.set_Value(1, 3);//To Width
                pGATaperedPolygon.set_Value(2, 0);//Width


                //平滑效果
                IGeometricEffect pSmooth = new GeometricEffectSmooth();
                IGraphicAttributes pGASmooth = pSmooth as IGraphicAttributes;
                pGASmooth.set_Value(0, 1);//Flat Tolerance


                //为基本线符号添加渐变效果和平滑效果
                IGeometricEffects pGeoEffects = pBasicLineSymbol as IGeometricEffects;
                pGeoEffects.Add(pTaperedPolygon);
                pGeoEffects.Add(pSmooth);


                //将符号效果加入表达规则中
                IBasicSymbol pSymbolLayer = pBasicLineSymbol as IBasicSymbol;
                IRepresentationRule pRepRule = new RepresentationRuleClass();
                pRepRule.InsertLayer(0, pSymbolLayer);


                return pRepRule;
            }
            catch (Exception ex)
            {
                return null;
            }
        }


        /// <summary>
        /// 获取要素类表达对应的工作空间扩展
        /// </summary>
        /// <param name="pWorkspace"></param>
        /// <returns></returns>
        private IRepresentationWorkspaceExtension GetRepWSExt(IWorkspace pWorkspace)
        {
            IWorkspaceExtensionManager pExtManager = pWorkspace as IWorkspaceExtensionManager;
            UID pUID = new UID();
            pUID.Value = "{FD05270A-8E0B-4823-9DEE-F149347C32B6}";
            IWorkspaceExtension pWksExt = pExtManager.FindExtension(pUID);
            IRepresentationWorkspaceExtension pRepWSExt = pWksExt as IRepresentationWorkspaceExtension;
            return pRepWSExt;
        }


        /// <summary>
        /// 将制图表达作为要素图层的符号化效果
        /// </summary>
        /// <param name="pFeatCls"></param>
        /// <param name="pRepClass"></param>
        private void SetRepRenderer(IFeatureClass pFeatCls, IRepresentationClass pRepClass)
        {
            if (pFeatCls == null || pRepClass == null) return;


            IFeatureLayer pFeatLayer = GetFeatureLayer(pFeatCls);
            IGeoFeatureLayer pGeoFeatLayer = pFeatLayer as IGeoFeatureLayer;
            if (!(pGeoFeatLayer.Renderer is IRepresentationRenderer))
            {
                IRepresentationRenderer pRepRenderer = new RepresentationRendererClass();
                pRepRenderer.RepresentationClass = pRepClass;
                pGeoFeatLayer.Renderer = pRepRenderer as IFeatureRenderer;
            }


            m_ActiveView.Refresh();//刷新以显示符号化效果
        }


        #endregion


        #region 其他方法


        /// <summary>
        /// 获取当前选择集所属的要素类
        /// </summary>
        /// <returns></returns>
        private IFeatureClass GetFeatureClass()
        {
            IEnumFeature pEnumFeature = (IEnumFeature)m_Map.FeatureSelection;
            pEnumFeature.Reset();
            IFeature pFeature = pEnumFeature.Next();


            IFeatureClass pFeatCls = null;
            if (pFeature != null)
            {
                pFeatCls = pFeature.Class as IFeatureClass;
            }


            return pFeatCls;
        }


        /// <summary>
        /// 根据要素类获取地图上对应的要素图层
        /// </summary>
        /// <param name="pFeatCls"></param>
        /// <returns></returns>
        private IFeatureLayer GetFeatureLayer(IFeatureClass pFeatCls)
        {
            string fcName = GetFeatClsName(pFeatCls).ToUpper();
            int layerCount = m_Map.LayerCount;
            //遍历地图图层
            for (int index = 0; index < layerCount; index++)
            {
                IFeatureLayer pFeatLayer = m_Map.get_Layer(index) as IFeatureLayer;
                if (pFeatLayer == null || pFeatLayer.FeatureClass == null) continue;
                //比较图层的要素类名称
                string strFCName = GetFeatClsName(pFeatLayer.FeatureClass);
                if (strFCName.ToUpper() == fcName)
                {
                    return pFeatLayer;
                }
            }


            return null;
        }


        /// <summary>
        /// 根据要素类获取工作空间
        /// </summary>
        /// <param name="pFeatClass"></param>
        /// <returns></returns>
        private IWorkspace GetWorkspace(IFeatureClass pFeatClass)
        {
            IDataset pDataset = pFeatClass as IDataset;
            return pDataset.Workspace;
        }


        private void ShowMessage(string strMsg)
        {
            string strTitle = "提示";
            MessageBox.Show(strMsg, strTitle);
        }


        /// <summary>
        /// 获取要素类的物理名称,不包含用户名
        /// </summary>
        /// <param name="pFeatClass"></param>
        /// <returns></returns>
        private string GetFeatClsName(IFeatureClass pFeatClass)
        {
            IDataset pDataset = pFeatClass as IDataset;
            string featClsName = pDataset.Name;
            if (featClsName.Contains("."))//SDE的要素类名称可能包含“用户名.”
            {
                featClsName = featClsName.Split(new char[] { '.' })[1];
            }


            return featClsName;
        }


        #endregion
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值