c#+ArcEngine93实现实时显示测距结果功能
2009-08-11 10:16
477 查看
利用ArcEngine实现距离量测,面积量测的功能已很简单,相信众多的ArcGIS爱好者都能写. 但单纯的实现功能总觉得欠什么.本人喜欢改代码,喜欢优化代码,在原有的功能基础上总喜欢"润色",使之更好看.前一整子在玩skyline时看到 skyline 的测距功能能实时显示量测的距离,于是联想到之前自己用C#+ArcEngine 写的测距功能.何不也优化一下自己代码? 想到就做到.最近手有点痒,算练练手.
废话少说,先附上效果图:
TrackLine
//=================================功能测距==========================
//描述:实时显示测量距离,节点位置,总长度
//编程: Jin 开发时间:2009.8.10-2009.8.11
//特点:实时计算量测距离.
//缺点: 由于采用element做为显示内容,地图进行放大缩小操作后并不能很好
// 控制量测值element和轨迹线element之间的距离间隔.
//===================================================================
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.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;
using System.Windows.Forms;
namespace MhGis.GisTool.Pb_Toolbar
{
class TrackLine : BaseTool
{
private IHookHelper m_hookHelper = null;
private INewLineFeedback m_NewLineFeedback = null;
private IPointCollection m_ptColl; //记录节点
private MeasureMsgInfo _MsgInfo = null;
private IPolyline m_TraceLine = null; //完整的轨迹线
//
private IGroupElement m_Elements = null; //用于保存包含此功能产生的所有Element
private IGroupElement m_TraceElement = null; //测距轨迹线
private IGroupElement m_VertexElement = null; //结点
private IGroupElement m_LabelElement = null; // 距离标记
public TrackLine()
{
//
// TODO: Define values for the public properties
//
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_MyTool")
try
{
//
// TODO: change resource name if necessary
//
string bitmapResourceName = GetType().Name + ".bmp";
base.m_bitmap = new Bitmap(GetType(), bitmapResourceName);
base.m_cursor = new System.Windows.Forms.Cursor(GetType(), GetType().Name + ".cur");
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap");
}
}
public MeasureMsgInfo MsgInfo
{
set
{
_MsgInfo = value;
_MsgInfo.FormClosing += new FormClosingEventHandler(msgInfo_FromClosing);
}
}
#region Overriden Class Methods
/// <summary>
/// Occurs when this tool is created
/// </summary>
/// <param name="hook">Instance of the application</param>
public override void OnCreate(object hook)
{
try
{
m_hookHelper = new HookHelperClass();
m_hookHelper.Hook = hook;
if (m_hookHelper.ActiveView == null)
{
m_hookHelper = null;
}
}
catch
{
m_hookHelper = null;
}
if (m_hookHelper == null)
base.m_enabled = false;
else
base.m_enabled = true;
// TODO: Add other initialization code
}
void Init()
{
//初始化
m_Elements = new GroupElementClass();
m_TraceElement = new GroupElementClass();
m_VertexElement = new GroupElementClass();
m_LabelElement = new GroupElementClass();
//初始化,并添加到GraphicsContainer
IGraphicsContainer g = m_hookHelper.ActiveView as IGraphicsContainer;
g.AddElement(m_Elements as IElement, 0);
g.AddElement(m_TraceElement as IElement, 0);
g.AddElement(m_VertexElement as IElement, 0);
g.AddElement(m_LabelElement as IElement, 0);
//添加到m_Elements中
g.MoveElementToGroup(m_VertexElement as IElement, m_Elements);
g.MoveElementToGroup(m_LabelElement as IElement, m_Elements);
g.MoveElementToGroup(m_TraceElement as IElement, m_Elements);
}
/// <summary>
/// Occurs when this tool is clicked
/// </summary>
public override void OnClick()
{
Init();
}
void msgInfo_FromClosing(object sender, FormClosingEventArgs e)
{
DeleteAllElements();
_MsgInfo = null;
//throw new Exception("The method or operation is not implemented.");
}
public override void OnMouseDown(int Button, int Shift, int X, int Y)
{
if (Button == 2)
return;
IPoint pt = m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
IGraphicsContainer g = m_hookHelper.ActiveView.GraphicsContainer;
IEnvelope pEnvBounds = null;
//获取上一次轨迹线的范围,以便确定刷新范围
try
{
if (m_TraceLine != null)
{
m_TraceLine.QueryEnvelope(pEnvBounds);
pEnvBounds.Expand(4, 4, true); //矩形框向四周扩大4倍(大于2倍就行),目的是为了保证有充足的刷新区域
}
else
pEnvBounds = m_hookHelper.ActiveView.Extent;
}
catch
{
pEnvBounds = m_hookHelper.ActiveView.Extent;
}
#region 启动画线
if (m_NewLineFeedback == null)
{
//移除element
RemoveElements();
//刷新
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
Application.DoEvents();
m_NewLineFeedback = new NewLineFeedbackClass();
m_NewLineFeedback.Display = m_hookHelper.ActiveView.ScreenDisplay;
//必须先得到symbol,后设置symbol
ISimpleLineSymbol simpleLineSymbol = m_NewLineFeedback.Symbol as ISimpleLineSymbol;
simpleLineSymbol.Style = esriSimpleLineStyle.esriSLSDot;
simpleLineSymbol.Width = 1;
simpleLineSymbol.Color = TransColorToAEColor(Color.Blue);
m_NewLineFeedback.Start(pt);
}
else
{
m_NewLineFeedback.AddPoint(pt);
}
if (m_ptColl == null)
{
m_ptColl = new PolylineClass();
}
//记录节点
object obj = Type.Missing;
m_ptColl.AddPoint(pt, ref obj, ref obj);
#endregion
#region 绘制结点
try
{
IElement vertexElement = CreateElement(pt);
//
g = m_hookHelper.ActiveView as IGraphicsContainer;
//g.AddElement(vertexElement, 0);
//g.MoveElementToGroup(vertexElement, m_VertexElement);
m_VertexElement.AddElement(vertexElement);
//刷新
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, vertexElement, pEnvBounds);
}
catch
{ }
#endregion
try
{
if (m_ptColl.PointCount >= 2)
{
IPoint fromPt = m_ptColl.get_Point(m_ptColl.PointCount - 2); //倒数第二个点
IPoint toPt = m_ptColl.get_Point(m_ptColl.PointCount - 1); //最后第一个点
ILine line = new LineClass();
line.PutCoords(fromPt, toPt);
#region 绘制轨迹线
try
{
object missing = Type.Missing;
ISegmentCollection segColl = new PolylineClass();
segColl.AddSegment(line as ISegment, ref missing, ref missing);
IElement traceElement = CreateElement(segColl as IPolyline);
//
g = m_hookHelper.ActiveView as IGraphicsContainer;
//g.AddElement(traceElement, 0);
//g.MoveElementToGroup(traceElement, m_TraceElement);
m_TraceElement.AddElement(traceElement);
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, traceElement, pEnvBounds);
}
catch
{ }
#endregion
#region 计算单线的长度,并将结果显示在单线中点偏上上面
try
{
double angle = line.Angle;
if ((angle > (Math.PI / 2) && angle < (Math.PI)) || (angle > -Math.PI && angle < -(Math.PI / 2))) // 大于90度小于等于180
angle += Math.PI;
//标注点Y值偏移量
double d_OffsetY = m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromPoints(9);
//标注点
double d_CenterX = (fromPt.X + toPt.X) / 2;
double d_CenterY = (fromPt.Y + toPt.Y) / 2 + d_OffsetY; //向上偏移
IPoint labelPt = new PointClass();
labelPt.PutCoords(d_CenterX, d_CenterY);
ITextElement txtElement = CreateTextElement(line.Length.ToString("0.00"));
IElement labelelement = txtElement as IElement;
labelelement.Geometry = labelPt;
object oElement = (object)labelelement;
//根据角度旋转
TransformByRotate(ref oElement, labelPt, angle);
////添加到GraphicsContainer
//g.AddElement(labelelement, 0);
////移到m_LabelElement组中
//g.MoveElementToGroup(labelelement, m_LabelElement);
//添加到组
m_LabelElement.AddElement(labelelement);
//刷新
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, labelelement, pEnvBounds);
}
catch
{ }
#endregion
}
}
catch
{ }
}
public override void OnMouseMove(int Button, int Shift, int X, int Y)
{
if (m_NewLineFeedback == null)
return;
IPoint pt = m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
m_NewLineFeedback.MoveTo(pt);
if (m_ptColl.PointCount == 0)
return;
double d_Total = 0;
double d_segment = 0;
IPoint lastPt = m_ptColl.get_Point(m_ptColl.PointCount - 1);
ILine line = new LineClass();
line.PutCoords(lastPt, pt);
//节距离
d_segment = line.Length;
_MsgInfo.Segment = d_segment;
try
{
IPolyline polyline = m_ptColl as IPolyline;
if (polyline.IsEmpty)
{
d_Total = d_segment;
}
else
{
d_Total = polyline.Length + d_segment;
}
}
catch
{
}
//赋值给总长度
_MsgInfo.Total = d_Total;
}
public override void OnDblClick()
{
if (m_NewLineFeedback == null)
return;
//绘制线与多边形几何图形时,双击结束绘制
try
{
m_TraceLine = m_NewLineFeedback.Stop();
if (m_TraceLine == null)
return;
}
catch
{ }
finally
{
Recycle();
}
}
#endregion
//回收
public void Recycle()
{
m_NewLineFeedback = null;
m_ptColl.RemovePoints(0, m_ptColl.PointCount);
m_ptColl = null;
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, m_hookHelper.ActiveView.Extent);
}
/// <summary>
/// 从组中删除所有元素
/// </summary>
/// <param name="groupElement"></param>
void RemoveElementFromGroupElement(IGroupElement groupElement)
{
if (groupElement == null || groupElement.ElementCount == 0)
return;
try
{
IGraphicsContainer g = m_hookHelper.ActiveView.GraphicsContainer;
for (int index = 0; index < groupElement.ElementCount; index++)
{
IElement tmp_Ele = groupElement.get_Element(index);
if (tmp_Ele is IGroupElement)
RemoveElementFromGroupElement(tmp_Ele as IGroupElement);
else
{
try
{
groupElement.DeleteElement(tmp_Ele);
}
catch
{
}
finally
{
tmp_Ele = null;
}
}
}
//groupElement.ClearElements();
}
catch
{ }
finally
{
//刷新
IEnvelope pEnvBounds = null;
//获取上一次轨迹线的范围,以便确定刷新范围
try
{
if (m_TraceLine != null)
{
m_TraceLine.QueryEnvelope(pEnvBounds);
pEnvBounds.Expand(4, 4, true); //矩形框向四周扩大4倍(大于2倍就行),目的是为了保证有充足的刷新区域
}
else
pEnvBounds = m_hookHelper.ActiveView.Extent;
}
catch
{
pEnvBounds = m_hookHelper.ActiveView.Extent;
}
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, pEnvBounds);
}
}
/// <summary>
/// 移除节点,标注和轨迹线Element
/// </summary>
void RemoveElements()
{
try
{
//刷新一次
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, m_hookHelper.ActiveView.Extent);
IGraphicsContainer g = m_hookHelper.ActiveView.GraphicsContainer;
#region 1-new
//RemoveElementFromGroupElement(m_Elements);
#endregion
#region 2
m_LabelElement.ClearElements();
m_VertexElement.ClearElements();
m_TraceElement.ClearElements();
#endregion
}
catch
{
}
finally
{
//刷新一次
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, m_hookHelper.ActiveView.Extent);
}
}
/// <summary>
/// 删除所有与此相关的元素
/// </summary>
public void DeleteAllElements()
{
//m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
IGraphicsContainer g = m_hookHelper.ActiveView.GraphicsContainer;
RemoveElementFromGroupElement(m_Elements);
try
{
g.DeleteElement(m_Elements as IElement);
}
catch
{ }
finally
{
m_TraceElement = null;
m_LabelElement = null;
m_VertexElement = null;
m_Elements = null;
//最后再刷新一次
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
}
}
/// <summary>
/// 将系统颜色转换为IColor
/// </summary>
/// <param name="color"></param>
/// <returns></returns>
ESRI.ArcGIS.Display.IColor TransColorToAEColor(Color color)
{
IRgbColor rgb = new RgbColorClass();
rgb.RGB = color.R + color.G * 256 + color.B * 65536;
return rgb as IColor;
}
/// <summary>
/// 按指定的角度旋转
/// </summary>
/// <param name="obj"></param>
/// <param name="originPt"></param>
/// <param name="rotate"></param>
void TransformByRotate(ref object obj, IPoint originPt, double rotate)
{
if (obj == null && originPt == null)
return;
try
{
ITransform2D transform2D = obj as ITransform2D;
if (transform2D == null)
return;
transform2D.Rotate(originPt, rotate);
}
catch
{ }
}
#region 创建Element
/// <summary>
/// 创建一个TextElement
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
ITextElement CreateTextElement(string text)
{
//创建一个TextSymbol
ITextSymbol txtSymbol = new TextSymbolClass();
//设置字体
Font dispFont = new Font("Arial", 10, FontStyle.Regular);
txtSymbol.Font = (stdole.IFontDisp)ESRI.ArcGIS.ADF.COMSupport.OLE.GetIFontDispFromFont(dispFont);
//设置属性
txtSymbol.Color = TransColorToAEColor(Color.Red); //颜色
//创建一个TextElement
ITextElement txtElement = new TextElementClass();
txtElement.Symbol = txtSymbol;
txtElement.Text = text;
return txtElement;
}
/// <summary>
/// 绘制几何图形
/// </summary>
/// <param name="geoType"></param>
/// <param name="geometry"></param>
/// <returns></returns>
ESRI.ArcGIS.Carto.IElement CreateElement(ESRI.ArcGIS.Geometry.IGeometry geometry)
{
IElement element = null;
try
{
switch (geometry.GeometryType)
{
case esriGeometryType.esriGeometryPolyline://Polyline线
ISimpleLineSymbol simpleLineSymbol = m_NewLineFeedback.Symbol as ISimpleLineSymbol;
ILineElement lineElement = new LineElementClass();
lineElement.Symbol = simpleLineSymbol as ILineSymbol;
element = lineElement as IElement;
element.Geometry = geometry;
break;
case esriGeometryType.esriGeometryPoint:
//设置结点符号
IRgbColor pRGB = new RgbColorClass();
pRGB.Red = 255;
pRGB.Green = 0;
pRGB.Blue = 0;
ISimpleMarkerSymbol pSimpleMarkSymbol = new SimpleMarkerSymbolClass();
pSimpleMarkSymbol.Color = pRGB as IColor;
pSimpleMarkSymbol.Size = 2;
pSimpleMarkSymbol.Style = esriSimpleMarkerStyle.esriSMSSquare;
IMarkerElement pMarkerElement = new MarkerElementClass();
pMarkerElement.Symbol = pSimpleMarkSymbol as IMarkerSymbol;
element = pMarkerElement as IElement;
element.Geometry = geometry as IGeometry;
break;
}
}
catch
{ }
return element;
}
#endregion
}
}
废话少说,先附上效果图:
TrackLine
//=================================功能测距==========================
//描述:实时显示测量距离,节点位置,总长度
//编程: Jin 开发时间:2009.8.10-2009.8.11
//特点:实时计算量测距离.
//缺点: 由于采用element做为显示内容,地图进行放大缩小操作后并不能很好
// 控制量测值element和轨迹线element之间的距离间隔.
//===================================================================
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.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;
using System.Windows.Forms;
namespace MhGis.GisTool.Pb_Toolbar
{
class TrackLine : BaseTool
{
private IHookHelper m_hookHelper = null;
private INewLineFeedback m_NewLineFeedback = null;
private IPointCollection m_ptColl; //记录节点
private MeasureMsgInfo _MsgInfo = null;
private IPolyline m_TraceLine = null; //完整的轨迹线
//
private IGroupElement m_Elements = null; //用于保存包含此功能产生的所有Element
private IGroupElement m_TraceElement = null; //测距轨迹线
private IGroupElement m_VertexElement = null; //结点
private IGroupElement m_LabelElement = null; // 距离标记
public TrackLine()
{
//
// TODO: Define values for the public properties
//
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_MyTool")
try
{
//
// TODO: change resource name if necessary
//
string bitmapResourceName = GetType().Name + ".bmp";
base.m_bitmap = new Bitmap(GetType(), bitmapResourceName);
base.m_cursor = new System.Windows.Forms.Cursor(GetType(), GetType().Name + ".cur");
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap");
}
}
public MeasureMsgInfo MsgInfo
{
set
{
_MsgInfo = value;
_MsgInfo.FormClosing += new FormClosingEventHandler(msgInfo_FromClosing);
}
}
#region Overriden Class Methods
/// <summary>
/// Occurs when this tool is created
/// </summary>
/// <param name="hook">Instance of the application</param>
public override void OnCreate(object hook)
{
try
{
m_hookHelper = new HookHelperClass();
m_hookHelper.Hook = hook;
if (m_hookHelper.ActiveView == null)
{
m_hookHelper = null;
}
}
catch
{
m_hookHelper = null;
}
if (m_hookHelper == null)
base.m_enabled = false;
else
base.m_enabled = true;
// TODO: Add other initialization code
}
void Init()
{
//初始化
m_Elements = new GroupElementClass();
m_TraceElement = new GroupElementClass();
m_VertexElement = new GroupElementClass();
m_LabelElement = new GroupElementClass();
//初始化,并添加到GraphicsContainer
IGraphicsContainer g = m_hookHelper.ActiveView as IGraphicsContainer;
g.AddElement(m_Elements as IElement, 0);
g.AddElement(m_TraceElement as IElement, 0);
g.AddElement(m_VertexElement as IElement, 0);
g.AddElement(m_LabelElement as IElement, 0);
//添加到m_Elements中
g.MoveElementToGroup(m_VertexElement as IElement, m_Elements);
g.MoveElementToGroup(m_LabelElement as IElement, m_Elements);
g.MoveElementToGroup(m_TraceElement as IElement, m_Elements);
}
/// <summary>
/// Occurs when this tool is clicked
/// </summary>
public override void OnClick()
{
Init();
}
void msgInfo_FromClosing(object sender, FormClosingEventArgs e)
{
DeleteAllElements();
_MsgInfo = null;
//throw new Exception("The method or operation is not implemented.");
}
public override void OnMouseDown(int Button, int Shift, int X, int Y)
{
if (Button == 2)
return;
IPoint pt = m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
IGraphicsContainer g = m_hookHelper.ActiveView.GraphicsContainer;
IEnvelope pEnvBounds = null;
//获取上一次轨迹线的范围,以便确定刷新范围
try
{
if (m_TraceLine != null)
{
m_TraceLine.QueryEnvelope(pEnvBounds);
pEnvBounds.Expand(4, 4, true); //矩形框向四周扩大4倍(大于2倍就行),目的是为了保证有充足的刷新区域
}
else
pEnvBounds = m_hookHelper.ActiveView.Extent;
}
catch
{
pEnvBounds = m_hookHelper.ActiveView.Extent;
}
#region 启动画线
if (m_NewLineFeedback == null)
{
//移除element
RemoveElements();
//刷新
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
Application.DoEvents();
m_NewLineFeedback = new NewLineFeedbackClass();
m_NewLineFeedback.Display = m_hookHelper.ActiveView.ScreenDisplay;
//必须先得到symbol,后设置symbol
ISimpleLineSymbol simpleLineSymbol = m_NewLineFeedback.Symbol as ISimpleLineSymbol;
simpleLineSymbol.Style = esriSimpleLineStyle.esriSLSDot;
simpleLineSymbol.Width = 1;
simpleLineSymbol.Color = TransColorToAEColor(Color.Blue);
m_NewLineFeedback.Start(pt);
}
else
{
m_NewLineFeedback.AddPoint(pt);
}
if (m_ptColl == null)
{
m_ptColl = new PolylineClass();
}
//记录节点
object obj = Type.Missing;
m_ptColl.AddPoint(pt, ref obj, ref obj);
#endregion
#region 绘制结点
try
{
IElement vertexElement = CreateElement(pt);
//
g = m_hookHelper.ActiveView as IGraphicsContainer;
//g.AddElement(vertexElement, 0);
//g.MoveElementToGroup(vertexElement, m_VertexElement);
m_VertexElement.AddElement(vertexElement);
//刷新
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, vertexElement, pEnvBounds);
}
catch
{ }
#endregion
try
{
if (m_ptColl.PointCount >= 2)
{
IPoint fromPt = m_ptColl.get_Point(m_ptColl.PointCount - 2); //倒数第二个点
IPoint toPt = m_ptColl.get_Point(m_ptColl.PointCount - 1); //最后第一个点
ILine line = new LineClass();
line.PutCoords(fromPt, toPt);
#region 绘制轨迹线
try
{
object missing = Type.Missing;
ISegmentCollection segColl = new PolylineClass();
segColl.AddSegment(line as ISegment, ref missing, ref missing);
IElement traceElement = CreateElement(segColl as IPolyline);
//
g = m_hookHelper.ActiveView as IGraphicsContainer;
//g.AddElement(traceElement, 0);
//g.MoveElementToGroup(traceElement, m_TraceElement);
m_TraceElement.AddElement(traceElement);
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, traceElement, pEnvBounds);
}
catch
{ }
#endregion
#region 计算单线的长度,并将结果显示在单线中点偏上上面
try
{
double angle = line.Angle;
if ((angle > (Math.PI / 2) && angle < (Math.PI)) || (angle > -Math.PI && angle < -(Math.PI / 2))) // 大于90度小于等于180
angle += Math.PI;
//标注点Y值偏移量
double d_OffsetY = m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.FromPoints(9);
//标注点
double d_CenterX = (fromPt.X + toPt.X) / 2;
double d_CenterY = (fromPt.Y + toPt.Y) / 2 + d_OffsetY; //向上偏移
IPoint labelPt = new PointClass();
labelPt.PutCoords(d_CenterX, d_CenterY);
ITextElement txtElement = CreateTextElement(line.Length.ToString("0.00"));
IElement labelelement = txtElement as IElement;
labelelement.Geometry = labelPt;
object oElement = (object)labelelement;
//根据角度旋转
TransformByRotate(ref oElement, labelPt, angle);
////添加到GraphicsContainer
//g.AddElement(labelelement, 0);
////移到m_LabelElement组中
//g.MoveElementToGroup(labelelement, m_LabelElement);
//添加到组
m_LabelElement.AddElement(labelelement);
//刷新
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, labelelement, pEnvBounds);
}
catch
{ }
#endregion
}
}
catch
{ }
}
public override void OnMouseMove(int Button, int Shift, int X, int Y)
{
if (m_NewLineFeedback == null)
return;
IPoint pt = m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
m_NewLineFeedback.MoveTo(pt);
if (m_ptColl.PointCount == 0)
return;
double d_Total = 0;
double d_segment = 0;
IPoint lastPt = m_ptColl.get_Point(m_ptColl.PointCount - 1);
ILine line = new LineClass();
line.PutCoords(lastPt, pt);
//节距离
d_segment = line.Length;
_MsgInfo.Segment = d_segment;
try
{
IPolyline polyline = m_ptColl as IPolyline;
if (polyline.IsEmpty)
{
d_Total = d_segment;
}
else
{
d_Total = polyline.Length + d_segment;
}
}
catch
{
}
//赋值给总长度
_MsgInfo.Total = d_Total;
}
public override void OnDblClick()
{
if (m_NewLineFeedback == null)
return;
//绘制线与多边形几何图形时,双击结束绘制
try
{
m_TraceLine = m_NewLineFeedback.Stop();
if (m_TraceLine == null)
return;
}
catch
{ }
finally
{
Recycle();
}
}
#endregion
//回收
public void Recycle()
{
m_NewLineFeedback = null;
m_ptColl.RemovePoints(0, m_ptColl.PointCount);
m_ptColl = null;
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, m_hookHelper.ActiveView.Extent);
}
/// <summary>
/// 从组中删除所有元素
/// </summary>
/// <param name="groupElement"></param>
void RemoveElementFromGroupElement(IGroupElement groupElement)
{
if (groupElement == null || groupElement.ElementCount == 0)
return;
try
{
IGraphicsContainer g = m_hookHelper.ActiveView.GraphicsContainer;
for (int index = 0; index < groupElement.ElementCount; index++)
{
IElement tmp_Ele = groupElement.get_Element(index);
if (tmp_Ele is IGroupElement)
RemoveElementFromGroupElement(tmp_Ele as IGroupElement);
else
{
try
{
groupElement.DeleteElement(tmp_Ele);
}
catch
{
}
finally
{
tmp_Ele = null;
}
}
}
//groupElement.ClearElements();
}
catch
{ }
finally
{
//刷新
IEnvelope pEnvBounds = null;
//获取上一次轨迹线的范围,以便确定刷新范围
try
{
if (m_TraceLine != null)
{
m_TraceLine.QueryEnvelope(pEnvBounds);
pEnvBounds.Expand(4, 4, true); //矩形框向四周扩大4倍(大于2倍就行),目的是为了保证有充足的刷新区域
}
else
pEnvBounds = m_hookHelper.ActiveView.Extent;
}
catch
{
pEnvBounds = m_hookHelper.ActiveView.Extent;
}
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, pEnvBounds);
}
}
/// <summary>
/// 移除节点,标注和轨迹线Element
/// </summary>
void RemoveElements()
{
try
{
//刷新一次
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, m_hookHelper.ActiveView.Extent);
IGraphicsContainer g = m_hookHelper.ActiveView.GraphicsContainer;
#region 1-new
//RemoveElementFromGroupElement(m_Elements);
#endregion
#region 2
m_LabelElement.ClearElements();
m_VertexElement.ClearElements();
m_TraceElement.ClearElements();
#endregion
}
catch
{
}
finally
{
//刷新一次
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, m_hookHelper.ActiveView.Extent);
}
}
/// <summary>
/// 删除所有与此相关的元素
/// </summary>
public void DeleteAllElements()
{
//m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
IGraphicsContainer g = m_hookHelper.ActiveView.GraphicsContainer;
RemoveElementFromGroupElement(m_Elements);
try
{
g.DeleteElement(m_Elements as IElement);
}
catch
{ }
finally
{
m_TraceElement = null;
m_LabelElement = null;
m_VertexElement = null;
m_Elements = null;
//最后再刷新一次
m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
}
}
/// <summary>
/// 将系统颜色转换为IColor
/// </summary>
/// <param name="color"></param>
/// <returns></returns>
ESRI.ArcGIS.Display.IColor TransColorToAEColor(Color color)
{
IRgbColor rgb = new RgbColorClass();
rgb.RGB = color.R + color.G * 256 + color.B * 65536;
return rgb as IColor;
}
/// <summary>
/// 按指定的角度旋转
/// </summary>
/// <param name="obj"></param>
/// <param name="originPt"></param>
/// <param name="rotate"></param>
void TransformByRotate(ref object obj, IPoint originPt, double rotate)
{
if (obj == null && originPt == null)
return;
try
{
ITransform2D transform2D = obj as ITransform2D;
if (transform2D == null)
return;
transform2D.Rotate(originPt, rotate);
}
catch
{ }
}
#region 创建Element
/// <summary>
/// 创建一个TextElement
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
ITextElement CreateTextElement(string text)
{
//创建一个TextSymbol
ITextSymbol txtSymbol = new TextSymbolClass();
//设置字体
Font dispFont = new Font("Arial", 10, FontStyle.Regular);
txtSymbol.Font = (stdole.IFontDisp)ESRI.ArcGIS.ADF.COMSupport.OLE.GetIFontDispFromFont(dispFont);
//设置属性
txtSymbol.Color = TransColorToAEColor(Color.Red); //颜色
//创建一个TextElement
ITextElement txtElement = new TextElementClass();
txtElement.Symbol = txtSymbol;
txtElement.Text = text;
return txtElement;
}
/// <summary>
/// 绘制几何图形
/// </summary>
/// <param name="geoType"></param>
/// <param name="geometry"></param>
/// <returns></returns>
ESRI.ArcGIS.Carto.IElement CreateElement(ESRI.ArcGIS.Geometry.IGeometry geometry)
{
IElement element = null;
try
{
switch (geometry.GeometryType)
{
case esriGeometryType.esriGeometryPolyline://Polyline线
ISimpleLineSymbol simpleLineSymbol = m_NewLineFeedback.Symbol as ISimpleLineSymbol;
ILineElement lineElement = new LineElementClass();
lineElement.Symbol = simpleLineSymbol as ILineSymbol;
element = lineElement as IElement;
element.Geometry = geometry;
break;
case esriGeometryType.esriGeometryPoint:
//设置结点符号
IRgbColor pRGB = new RgbColorClass();
pRGB.Red = 255;
pRGB.Green = 0;
pRGB.Blue = 0;
ISimpleMarkerSymbol pSimpleMarkSymbol = new SimpleMarkerSymbolClass();
pSimpleMarkSymbol.Color = pRGB as IColor;
pSimpleMarkSymbol.Size = 2;
pSimpleMarkSymbol.Style = esriSimpleMarkerStyle.esriSMSSquare;
IMarkerElement pMarkerElement = new MarkerElementClass();
pMarkerElement.Symbol = pSimpleMarkSymbol as IMarkerSymbol;
element = pMarkerElement as IElement;
element.Geometry = geometry as IGeometry;
break;
}
}
catch
{ }
return element;
}
#endregion
}
}
相关文章推荐
- c#+ArcEngine93实现实时显示测距结果功能
- c#+ArcEngine93实现实时显示测距结果功能
- 实现类似于百度实时搜索将结果在下拉框中显示的功能
- 使用json实现查询条件传回Action进行hql语句拼接查询实现在结果中查询功能在datagrid中显示查询结果
- Android搜索实时显示功能实现
- 利用ARCGIS FLEX API实现实时内插并显示结果图
- 如何实现searchBar显示实时检索结果
- easyui-combobox---ajax获取数据库JSON数据,实现搜索框实时显示模糊搜索结果
- 【GUI设计】:实现脚掌压力实时显示功能
- 原生js实现音乐播放器功能,可以实时显示歌词并且高亮当前句
- android5.0以上实现录屏功能,并将录屏内容在相册中显示!(unity调用android方法)
- jQuery Easyui Treegrid实现显示checkbox功能
- 输入框密码切换显示或隐藏功能的实现
- IReport+JasperReports实现Flash报表显示(带查询功能)
- 高级部分(百度地图四)实时定位功能的实现
- ASP.NET实现投票结果的图片进度条显示
- 实现iPhone电子书的分页显示功能(附代码)
- ImageView的使用,实现本地图片的适屏显示和裁剪功能。
- 使用Windows服务实现投票结果的自动发送功能
- Lucene.Net如何实现搜索结果分类统计功能