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
}
}
ArcEngine通过制图表达 实现河流渐
最新推荐文章于 2022-05-22 15:10:36 发布