ArcEngine旋转IRotateTracker

针对ArcGIS中旋转工具的问题,本文介绍了一种解决方案,通过使用IRotateTracker接口并结合特定方法调用,解决了初次旋转失败的bug,实现了地图元素的准确旋转。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

因项目需要,需要做一个旋转工具,发现网上几乎都是利用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);
        }
    }

 效果图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值