-
利用
ArcEngine
实现距离量测
,
面积量测的功能已很简单
,
< br>相信众多的
ArcGIS
爱好者都能写
< br>.
但单纯的实现功能总觉得欠什么
.
< br>本人喜欢改代码
,
喜欢优化代码
,
在原有的功能基础上总喜欢
润色
p>
使之更好看
.
前一
整子在玩
skyline
时看到
skyline
的测距功能能实时显示量测的距离
,
于是联想到之前自己用
C#+ArcEngin
e
写的测距功能
.
何不也优化一下自
己代码
?
想到就做到
.
最近手有点痒
,
算练练手
.
废话少说
,
先附上效果图
:
说明
:
1.
本功能的特点在于在量测的过称当中实时显示量测距离
,
并将结
果实时显示在测距上方
.
在显
示窗体上
也显示量测的总距离
.
要点
:
1.
INewLineFeedback
负责画线
;
2.
在
OnMouseDown
p>
事件中计算量测距离
,
并向
GraphicsContainer
添加线和节点的
Element;
3.
在
OnMou
seUp
事件中实时计算距离随鼠标移动后产生的新距离
.
4.
将节点
,
量测值
,
线的
element
都分别存入到节点组和轨迹线组
(IGroupElement),<
/p>
即用
IGroupElem
ent
同一管理这些
element;
最后将这些
groupelement
又添加到一个总的
< br>groupelement.
这样做的目的在于好控制这些
element,
特别是启动新的量测或取消量测功能
时可以
控制这些
element,
而不必去用
AllElements
来清除这些
elem
< br>ent,
使用
AllElements
< br>会将所有的
element
删除
.
5.
量测值
element
为
ITextElement,
由于
他停靠在轨迹线的上方
,
因此需要对量测值
elem
ent
进行一定角度的旋转
,
旋转角度由轨迹线的方向角决定
.
6.
绘制
elem
< br>ent
之后的刷新问题也是比较重要的
.
刷新范围一定要控制好
,
太小了
,
添加的
elem
ent
显示不出来
,
太大了
,
浪费
. (
实在不好控制就刷新整个<
/p>
extent
吧
,
呵呵
)
核心代码如下
:
1.
TrackLine
类
//=========================
========
功能测距
================
==========
//
描述
:<
/p>
实时显示测量距离
,
节点位置
,
总长度
//
编程
: Jin
开发时间
:2009.8.10-2009.8.11
//
特点
:
实时计算
量测距离
.
//
缺点
:
由于采用
element
做为显示内容
,
地图进行放大缩小操作后并不能很好
//
控制量测值
elem
ent
和轨迹线
element
之间的
距离间隔
.
//====================
===============================================
using
System;
using
g;
using
pServices;
using
asses;
using
using
ls;
using
using
abase;
using
y;
using
ry;
using
namespace
_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 =
ageLayoutControl
;
//localizable text
base
.m_toolTip =
;
//localizable
text
base
.m_name =
;
//unique id,
non-localizable (e.g.
yCategory_MyTool
try
{
//
// TODO: change
resource name if necessary
//
string
bitmapResourceName =
GetType().Name +
;
base
.m_bitmap =
new
Bitmap(GetType(),
bitmapResourceN
ame);
base
.m_cursor =
new
(GetTy
pe(),
GetType().Name +
);
}
catch
(Exception ex)
{
ine(e,
id
Bitmap
);
}
}
public
MeasureMsgInfo
MsgInfo
{
set
{
_MsgInfo = value;
_osing +=
new
FormClosingEventHandler(
m
sgInfo_FromClosing);
}
}
#region
Overriden Class
Methods
///
///
Occurs when this tool is
created
///
///
Instance of the
application
public
override
void
OnCreate(
object
hook)
{
try
{
m_hookHelper =
new
HookHelperClass();
m_ = hook;
if
(m_View ==
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_View
as
IGraphi
csContainer;
ment(m_Elements
as
IElement,
0
);
ment(m_TraceElement
as
IElement,
0
);
ment(m_VertexElement
as
IElement,
0
);
ment(m_LabelElement
as
IElement,
0
);
//
添加到
m_Elements
中
ementToGroup(m_VertexElement
as
IElement,
m_Eleme
nts);
ementToGroup(m_LabelElement
as
IElement,
m_Elemen
ts);
ementToGroup(m_TraceElement
as
IElement,
m_Elemen
ts);
}
///
///
Occurs when this tool is
clicked
///
public
override
void
OnClick()
{
Init();
}
void
msgInfo_FromClosing(
object
sender, FormClosingEventArg
s e)
{
DeleteAllElements();
_MsgInfo =
null
;
//throw new
Exception(
lemented.
}
public
override
void
OnMouseDown(
int
Button,
int
Shift,
in
t
X,
int
Y)
{
if
(Button ==
2
)
return
;
IPoint pt = m_y
oint(X, Y);
IGraphicsContainer g = m_csCo
ntainer;
IEnvelope pEnvBounds =
null
;
//
获取上
一次轨迹线的范围
,
以便确定刷新范围
try
{
if
(m_TraceLine !=
null
)
{
m_nvelope(pEnvBounds);
(
4
,
4
,
true
);
//
< br>矩形框向四周扩大
4
倍
(
大于
2
倍就行
),<
/p>
目的是为了保证有充足的刷新区域
}
else
pEnvBounds = m_;
}
catch
{
pEnvBounds = m_;
}
#region
启动画线
if
(m_NewLineFeedback ==
null
)
{
//
移除
element
RemoveElements();
//
刷新
m_lRefresh(esriViewDrawPh
ewGraphics,
null
,
null
);
ts();
m_NewLineFeedback =
new
NewLineFeedbackClass();
m_y = m_View.S
creenDisplay;
//
必须先得到
symbol,
后设置
symbol
ISimpleLineSymbol simpleLineSymbol =
m_NewLineFeedbac
as
ISimpleLineSymbol;
= SD
ot;
=
1
;
= TransColorToAEColor(
ue);
m_(pt);
}
else
{
m_nt(pt);
}
if
(m_ptColl ==
null
)
{
m_ptColl =
new
PolylineClass();
}
//
记录节点
object
obj = g;
m_nt(pt,
ref
obj,
ref
obj);
#endregion
#region
绘制结点
try
{
IElement vertexElement
= CreateElement(pt);
//
g =
m_View
as
IGraphicsContainer;
//ment(vertexElement, 0);
//ementToGroup(vertexElement,
m_VertexElemen
t);
m_ment(vertexElement);
//
刷新
m_lRefresh(esriViewDrawPh
ewGraphics,
vertexElement, pEnvBounds);
}
catch
{ }
#endregion
try
{
if
(m_ount >=
2
)
{
IPoint fromPt =
m__Point(m_
Count -
2
);
//
倒数第二个点
IPoint toPt =
m__Point(m_o
unt -
1
);
//
最后第一个点
ILine line =
new
LineClass();
rds(fromPt, toPt);
#region
绘制轨迹线
try
{
object
missing = g;
ISegmentCollection segColl =
new
PolylineClas
s();
ment(line
as
ISegment,
ref
miss
ing,
ref
missing);
IElement traceElement =
CreateElement(segCol
l
as
IPolyline);
//
g
= m_View
as
IGraphicsConta
iner;
//ment(traceElement, 0);
//ementToGroup(traceElement,
m_TraceE
lement);
m_ment(traceElement);
m_lRefresh(esriVi
ewGraphics,
traceElement, pEnvBounds);
}
catch
{ }
#endregion
#region
计算单线的长度
p>
,
并将结果显示在单线中点偏上上面
try
{
double
angle =
if
((angle > ( /
2
) && angle <
(Math.P
I)) || (angle > - && angle < -(
/
2
)))
//
大于
90
度小于等
于
180
angle +=
//
标注点
Y
值偏移量
double
d_OffsetY =
m_
ints(
9
);
//
标注点
double
d_CenterX = (fromPt.X
+ toPt.X) /
2
;
double
d_CenterY = (fromPt.Y
+ toPt.
Y) /
2
+
d_OffsetY;
//
向上偏移
IPoint labelPt =
new
PointClass();
rds(d_CenterX, d_CenterY);
ITextElement
txtElement = CreateTextElement(l
ng(
));
IElement labelelement = txtElement
as
IElemen
t;
ry = labelPt;
object
oElement =
(
object
)labelelement;