因项目需要,需要做一个旋转工具,发现网上几乎都是利用IElement进行间接旋转。一番研究后,发现IRotateTracker接口可以实现旋转,但该接口有问题,第一次不能正常旋转,第二次才可以。通过先执行OnMouseMove,OnMouseUp方法后,可解决,代码如下:
public class CreateRotationPointTool: BaseTool
{
private IHookHelper _hookHelper;
private ISymbol _symbol;
private bool _rotateTrackerTrigger = false;
private IMovePointFeedback _pointFeedback;
private IRotateTracker _rotateTracker;
public IActiveView ActiveView { get; set; }
public override void OnCreate(object hook)
{
try
{
_hookHelper = new HookHelperClass();
_hookHelper.Hook = hook;
base.m_enabled = true;
}
catch
{
_hookHelper = null;
}
}
public override void OnClick()
{
IMarkerSymbol ms = new SimpleMarkerSymbol();
ms.Size = 100;
ISimpleMarkerSymbol sms = ms as ISimpleMarkerSymbol;
sms.Style = esriSimpleMarkerStyle.esriSMSCross;
_symbol = ms as ISymbol;
_symbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen;
_rotateTracker = new EngineRotateTracker();
_rotateTracker.Display = ActiveView.ScreenDisplay;
_rotateTracker.ClearGeometry();
IPoint curPoint = new PointClass();
curPoint.PutCoords(0, 0);
_rotateTracker.OnMouseMove(curPoint);
_rotateTracker.OnMouseUp();
base.OnClick();
}
public override void OnMouseDown(int Button, int Shift, int X, int Y)
{
IPoint curPoint = ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
if (Button == 1)
{
if (!_rotateTrackerTrigger)
{
if (_pointFeedback != null)
{
_pointFeedback.Stop();
_pointFeedback = null;
}
_rotateTracker.ClearGeometry();
_rotateTracker.Origin = curPoint;
_rotateTracker.AddPoint(curPoint, _symbol as IMarkerSymbol);
_rotateTracker.OnMouseDown();
_rotateTrackerTrigger = true;
}
else
{
if (_rotateTracker != null && _rotateTrackerTrigger)
{
bool rst = _rotateTracker.OnMouseUp();
if(rst)
CreateElement(_rotateTracker.Origin, _rotateTracker.Angle);
_rotateTrackerTrigger = false;
}
}
}
}
public override void OnMouseMove(int Button, int Shift, int X, int Y)
{
IPoint curPoint = ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
if (!_rotateTrackerTrigger)
{
if (_pointFeedback == null)
{
_pointFeedback = new MovePointFeedbackClass();
_pointFeedback.Display = ActiveView.ScreenDisplay;
_pointFeedback.Symbol = _symbol;
_pointFeedback.Start(curPoint, curPoint);
}
_pointFeedback.MoveTo(curPoint);
}
else
{
if(_rotateTracker != null)
_rotateTracker.OnMouseMove(curPoint);
}
}
public override void Refresh(int hDC)
{
if (_pointFeedback != null)
{
_pointFeedback.Refresh(hDC);
}
if (_rotateTracker != null && _rotateTrackerTrigger)
{
_rotateTracker.Refresh();
}
base.Refresh(hDC);
}
private void CreateElement(IGeometry pGeometry, double angle)
{
IMarkerSymbol ms = ((IClone)_symbol).Clone() as IMarkerSymbol;
ms.Angle = angle * (180 / Math.PI);//180/π×弧度
IMarkerElement pMarkerElement = new MarkerElementClass();
pMarkerElement.Symbol = ms;
IElement pElement = pMarkerElement as IElement;
pElement.Geometry = pGeometry;
ActiveView.GraphicsContainer.AddElement(pElement, 0);
IEnvelope pEnvelope = new EnvelopeClass();
pElement.QueryBounds(ActiveView.ScreenDisplay, pEnvelope);
ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, pEnvelope);
}
}
效果图: