面积测量中最主要的接口就是INewPolygonFeedback。
下面就是AreaMeasure.cs的全部内容,这是将实现和调用分开,在外部通过
//自定义画多边形,测面积
ToolbarControl.AddItem(new AreaMeasure(), -1, -1, true, 0,
esriCommandStyles.esriCommandStyleIconOnly);
添加面积测量的功能。
AreaMeasure.cs的实现如下:
using System;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.ADF.CATIDs;
using System.Runtime.InteropServices;
namespace com.san30.wjcg.Commands
{
[ClassInterface(ClassInterfaceType.None)]
[Guid("5C214724-BFA2-4e8c-BC5D-775C67FA6F56")]
/// <summary>
/// 测量距离功能
/// </summary>
public class AreaMeasure : ICommand, ITool
{
#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);
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);
ControlsCommands.Unregister(regKey);
}
#endregion
#endregion
[DllImport("gdi32.dll")]
static extern bool DeleteObject(IntPtr hObject);//删除对象
private System.Drawing.Bitmap m_bitmap;//工具显示图标
private IntPtr m_hBitmap;//用于表示指针或者句柄的平台特殊类型
private IHookHelper m_pHookHelper;//句柄
private System.Windows.Forms.Cursor m_areaMeasureCur;//光标
private bool m_enabled;//是否可用
private bool m_check;//是否选中
private bool m_isMouseDown;//鼠标是否按下
private INewPolygonFeedback m_pNewPolyFeedback;//INewPolygonFeedback,控制新的多边形显示反馈
private IActiveView pActiveView;//视图
/// <summary>
///构造函数
/// </summary>
public AreaMeasure()
{
//Load resources
string[] res = GetType().Assembly.GetManifestResourceNames();
if (res.GetLength(0) > 0)
{
m_bitmap = new System.Drawing.Bitmap(GetType().Assembly.GetManifestResourceStream(GetType(), "AreaMeasure.bmp"));
if (m_bitmap != null)
{
m_bitmap.MakeTransparent(m_bitmap.GetPixel(1, 1));
m_hBitmap = m_bitmap.GetHbitmap();
}
}
m_pHookHelper = new HookHelperClass();
}
/// <summary>
/// 释构函数
/// </summary>
~AreaMeasure()
{
if (m_hBitmap.ToInt32() != 0)
DeleteObject(m_hBitmap);
m_pHookHelper = null;
m_check = false;
//m_measureCur = null;
}
#region ICommand Members
//点击
public void OnClick()
{
}
//消息 属性
public string Message
{
get
{
return "测量多边形面积";
}
}
//图标 属性
public int Bitmap
{
get
{
return m_hBitmap.ToInt32();
}
}
/// <summary>
/// 创建工具命令
/// </summary>
/// <param name="hook">hook句柄</param>
public void OnCreate(object hook)
{
m_pHookHelper.Hook = hook;
m_enabled = true;
m_check = false;
m_areaMeasureCur = new System.Windows.Forms.Cursor(GetType().Assembly.GetManifestResourceStream(GetType(), "Area Measure.cur"));
}
//标题 属性
public string Caption
{
get
{
return "测面积";
}
}
//提示 属性
public string Tooltip
{
get
{
return "测面积";
}
}
//HelpContextID 属性
public int HelpContextID
{
get
{
// TODO: Add AreaMeasure.HelpContextID getter implementation
return 0;
}
}
//工具名 属性
public string Name
{
get
{
return "Commands/AreaMeasure";
}
}
//是否选中 属性
public bool Checked
{
get
{
return m_check;
}
}
//是否可用 属性
public bool Enabled
{
get
{
return m_enabled;
}
}
//帮组文件 属性
public string HelpFile
{
get
{
// TODO: Add AreaMeasure.HelpFile getter implementation
return null;
}
}
//种类 属性
public string Category
{
get
{
return "Commands/AreaMeasure";
}
}
#endregion
#region ITool Members
/// <summary>
/// 鼠标按下事件
/// </summary>
/// <param name="button">button按钮</param>
/// <param name="shift">shift键</param>
/// <param name="x">屏幕X坐标</param>
/// <param name="y">屏幕Y坐标</param>
public void OnMouseDown(int button, int shift, int x, int y)
{
//Create a point in map coordinates
//IActiveView pActiveView = (IActiveView)m_pHookHelper.FocusMap;
m_isMouseDown = true;
if (pActiveView == null)
{
//Create a point in map coordinates
pActiveView = (IActiveView)m_pHookHelper.FocusMap;
}
//点
IPoint pPoint;
pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
//Check that user is not using an existing feedback
if( m_pNewPolyFeedback == null ){
// Create a symbol (and color) to use for the Feedback
//this is optional - a default symbol is used if none is given
ISimpleLineSymbol pSLineSymFeed;
//颜色
IRgbColor pRGB;
m_pNewPolyFeedback = new NewPolygonFeedbackClass();
//Get the new Feedback's symbol by reference
pSLineSymFeed = m_pNewPolyFeedback.Symbol as ISimpleLineSymbol;
pRGB = new RgbColorClass();
//Make a color
pRGB.Red = 140;
pRGB.Green = 140;
pRGB.Blue = 255;
//Setup the symbol with color and style
pSLineSymFeed.Color = pRGB;
pSLineSymFeed.Style= esriSimpleLineStyle.esriSLSDot;
//Set the new Feedback's Display and StartPoint
m_pNewPolyFeedback.Display = pActiveView.ScreenDisplay;
m_pNewPolyFeedback.Start(pPoint);
}
else{
//Otherwise use the current mouse location to add a vertex to the current feedback
m_pNewPolyFeedback.AddPoint(pPoint);
}
}
/// <summary>
/// 鼠标移动事件
/// </summary>
/// <param name="button">button按钮</param>
/// <param name="shift">shift键</param>
/// <param name="x">屏幕X坐标</param>
/// <param name="y">屏幕Y坐标</param>
public void OnMouseMove(int button, int shift, int x, int y)
{
if (!m_isMouseDown) return;
//Check if the user is currently using the feedback
if( m_pNewPolyFeedback!= null)
{
//Move the Feedback to the current mouse location
if (pActiveView == null)
{
//Create a point in map coordinates
pActiveView = (IActiveView)m_pHookHelper.FocusMap;
}
//坐标系中的点
IPoint pPoint;
pPoint = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
m_pNewPolyFeedback.MoveTo(pPoint);
}
}
/// <summary>
/// 鼠标放开事件
/// </summary>
/// <param name="button">button按钮</param>
/// <param name="shift">shift键</param>
/// <param name="x">屏幕X坐标</param>
/// <param name="y">屏幕Y坐标</param>
public void OnMouseUp(int button, int shift, int x, int y)
{
// TODO: Add AreaMeasure.OnMouseUp implementation
}
/// <summary>
/// 键盘按下事件
/// </summary>
/// <param name="keyCode">键编码</param>
/// <param name="shift">shift键</param>
public void OnKeyDown(int keyCode, int shift)
{
if (m_isMouseDown)
{
if (keyCode == 27)
{
m_isMouseDown = false;
m_pNewPolyFeedback = null;
m_pHookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewForeground, null, null);
}
}
}
/// <summary>
/// 键盘放开事件
/// </summary>
/// <param name="keyCode">键编码</param>
/// <param name="shift">shift键</param>
public void OnKeyUp(int keyCode, int shift)
{
if (m_isMouseDown)
{
if (keyCode == 27)
{
m_isMouseDown = false;
m_pNewPolyFeedback = null;
m_pHookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewForeground, null, null);
}
}
}
/// <summary>
/// 光标
/// </summary>
public int Cursor
{
get
{
return m_areaMeasureCur.Handle.ToInt32();
}
}
/// <summary>
/// 上下文菜单事件
/// </summary>
/// <param name="x">屏幕X坐标</param>
/// <param name="y">屏幕Y坐标</param>
/// <returns>bool</returns>
public bool OnContextMenu(int x, int y)
{
// TODO: Add AreaMeasure.OnContextMenu implementation
return false;
}
/// <summary>
/// 解除事件
/// </summary>
/// <returns>bool</returns>
public bool Deactivate()
{
return true;
}
/// <summary>
/// 刷新
/// </summary>
/// <param name="hdc">hdc</param>
public void Refresh(int hdc)
{
//Get a reference to the ActiveView
if (m_pHookHelper != null)
{
pActiveView = (IActiveView)m_pHookHelper.FocusMap;
}
}
/// <summary>
/// 双击事件
/// </summary>
public void OnDblClick()
{
//图形
IGeometry pGeompoly = null;
//Get the geometry (Polygon) returned from the feedback
if (m_pNewPolyFeedback != null)
{
pGeompoly = m_pNewPolyFeedback.Stop();
}
//' If it is valid then draw a Geompoly on the ActiveView using the
// DrawGeompoly procedure
if (pGeompoly != null)
{
//AddCreateElement(pGeompoly, pActiveView);
if (pGeompoly.GeometryType.Equals(esriGeometryType.esriGeometryPolygon))
{
DrawGeompoly(pGeompoly, pActiveView);
}
//pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
}
//' Set the feedback to nothing for the next use
m_pNewPolyFeedback = null;
}
/// <summary>
/// 画多边形
/// </summary>
/// <param name="pGeompoly"></param>
/// <param name="pAV"></param>
public void DrawGeompoly(IGeometry pGeompoly, IActiveView pAV)
{
if ((pGeompoly == null) || (pAV == null))
{
return;
}
//Takes an IGeometry and IActiveView
//in the ActiveView's BasicGraphicsLayer
//填充样式
ISimpleFillSymbol pSFillSym;
//文本样式
ITextSymbol pTextSymbol;
//填充颜色
IRgbColor pFillRGB;
//文本颜色
IRgbColor pTextRGB;
//多边形
IPolygon pPolygon = pGeompoly as IPolygon;
//多边形区域
IArea pArea = pPolygon as IArea;
//多边形中心点
IPoint pTextPoint = pArea.Centroid;
//多边形面积
double dArea = Math.Round(Math.Abs(pArea.Area),2);
//格式化
string strArea = string.Format("{0:N}", dArea);
strArea = strArea + " 平方米";
//Create a new RGBColor
pFillRGB = new RgbColorClass();
pFillRGB.Red = 110;
pFillRGB.Green = 40;
pFillRGB.Blue = 255;
//Create a new RGBColor
pTextRGB = new RgbColorClass();
pTextRGB.Red = 60;
pTextRGB.Green = 120;
pTextRGB.Blue = 230;
//Create a new SimpleFillSymbol and set its Color and Style
pSFillSym = new SimpleFillSymbolClass();
pSFillSym.Color = pFillRGB;
pSFillSym.Style = esriSimpleFillStyle.esriSFSSolid;
//Text Symbol
pTextSymbol = new ESRI.ArcGIS.Display.TextSymbolClass();
pTextSymbol.HorizontalAlignment = esriTextHorizontalAlignment.esriTHACenter;
pTextSymbol.VerticalAlignment = esriTextVerticalAlignment.esriTVACenter;
pTextSymbol.Size = 16;
pTextSymbol.Color = pTextRGB;
//pSymbol = pTextSymbol as ISymbol;
//pSymbol.ROP2 = esriRasterOpCode.esriROPBlack;
pTextSymbol.Text = strArea;
pAV.ScreenDisplay.StartDrawing(pAV.ScreenDisplay.hDC, -1);
//Use existing symbols and draw existing text and Polygon
pAV.ScreenDisplay.SetSymbol(pSFillSym as ISymbol);
pAV.ScreenDisplay.DrawPolygon(pGeompoly as IPolygon);
pActiveView.ScreenDisplay.SetSymbol(pTextSymbol as ISymbol);
pActiveView.ScreenDisplay.DrawText(pTextPoint, pTextSymbol.Text);
pAV.ScreenDisplay.FinishDrawing();
}
#endregion
}
}