美文网首页
Micaps4二次开发(2)获取micaps主程序地图上鼠标位置

Micaps4二次开发(2)获取micaps主程序地图上鼠标位置

作者: metoceaner | 来源:发表于2020-03-22 21:23 被阅读0次

    背景

    micaps二次开发中,比较重要的功能就是和主程序地图进行交互。交互分为两种:

    • 向主程序地图区域添加元素;
    • 获取主程序地图区域信息;
      为了直观说明这个问题,这里给出micaps的主界面:


      二次开发交互示意图

      这里介绍一下,自己对获取主程序地图区域鼠标位置信息的理解 。

    获取地图上鼠标位置

    自定义一个交互的类 TyphoonPointSelectMapTool

     internal class TyphoonPointSelectMapTool : MapTool
        {
            private lyTyphoonPresenter _presenter;
    
            public TyphoonPointSelectMapTool(lyTyphoonPresenter presenter)
            {
                this._presenter = presenter;
            }
    
            public override void MouseDown(MouseButtonID button, int x, int y)
            {
                if (button == MouseButtonID.MB_Left)
                {
                    this._presenter.OnMouseDown(button, x, y);
                }
            }
    
            public override void MouseMove(MouseButtonID button, int x, int y)
            {
                this._presenter.OnMouseMove(x, y);
            }
    
            public override void MouseUp(MouseButtonID button, int x, int y)
            {
                this._presenter.OnMouseUp(button, x, y);
            }
    
            public override void MouseWheel(MouseButtonID button, int delta)
            {
            }
    
            protected override void OnActionCompleted()
            {
            }
    
            public override void OnActive()
            {
            }
    
            public override void OnDeactive()
            {
            }
        }
    

    自定义presenter类

     public void OnMouseUp(MouseButtonID button, int x, int y)
            {
                if (button == MouseButtonID.MB_Right)
                    {
                        this._showTempPoint = false;
                        this.FreeTempPointResource();
                    }
                    else
                    {
                        //左键是选择输入点
                        PointF point = this._presenter.ScrToGeography(x, y);
                        this._points.Add(point);
                        this._showTempPoint = true;
                    }
                     this.DisplayPoint(true);
            }
    
    
    

    至此,完成了获取主程序地图信息获取的功能编写
    那么如何触发这个功能呢?

    触发获取主程序地图信息功能

    在二次开发界面上,触发需要获取主界面位置信息的按钮时,执行如下函数:

     bool active = checkBoxMouseSelect.Checked;
     if (active)
     {
       ServiceLocator.Current.GetInstance<IMapManager>().DisableMapInputAction(CMA.MICAPS.Box2D.Input.InputActions.Pan);
     }
     else
     {
      ServiceLocator.Current.GetInstance<IMapManager>().EnableMapInputAction(CMA.MICAPS.Box2D.Input.InputActions.Pan);
     }
    this.SetTyphoonMapTool(this._typhoonMapTool, active);
    

    子函数:

     private void SetTyphoonMapTool(IMouseInputHandler tool, bool register)
            {
                ToolAction action = register ? ((ToolAction)4) : ((ToolAction)5);
                MapToolMessage message = new MapToolMessage(action);
                message.CustomMouseHandler=tool;
                MapToolMessage[] messageArray1 = new MapToolMessage[] { message };
                ServiceLocator.Current.GetInstance<IBus>().Publish<MapToolMessage>(messageArray1);
            }
    

    显示点到主程序地图上

    获取鼠标点后,能够将点位置实时显示到地图上,则可以快速响应用户的点击信息,这是一个很好的交互方式。
    如何显示,目前,我还没有找到画点的方式,查阅了很多资料,寻找到一种折中的办法,效果一般。具体实现如下:

     public void DisplayPoint(bool visible)
            {
                if (visible)
                {
                    if (this._points.Count >0)
                    {
                        this.FreePointResource();
                        DisplayTempPoint(_points[0]);
                       // 这里仅仅显示了一个点信息;
                    }
                }
                else
                {
                    this.FreePointResource();
                    this.FreeTempPointResource();
                }
            }
    
     private void DisplayTempPoint(PointF point)
            {
                if ((this._points.Count != 0) && this._showTempPoint)
                {
                    if (this._tempPoint == null)
                    {
                        this._tempPoint = new PointRenderable(8f, Color.Red);
                        this._tempPoint.Add(point.X,point.Y);
                         Device.Instance.ActiveScene.AddRenderable(this._tempPoint.MeshRenderable);
                    }
                    else
                    {
                        this._tempPoint.UpdatePostion(point.X, point.Y);
                    }
                }
            }
    
     public IRenderable MeshRenderable
            {
                get
                {
                    if (this._meshRenderable == null)
                    {
                        this._meshRenderable = this.CreateMeshRenderable();
                    }
                    return this._meshRenderable;
                }
            }
    
      private CMA.MICAPS.Box2D.Graphics.MeshRenderable CreateMeshRenderable()
            {
                /*
                 绘制点到micaps界面上,必须考虑投影的影响。vertebuffer中存储的是
                 屏幕坐标,直接将经纬度放入,在屏幕中绘制出来的几乎不变
                 添加经纬度转换后,则可以正确绘制。
                 遗留问题:
                 绘制出来的是方块,还不知道怎么修改
                */
    
                int num3;
                int count = this._points.Count;
                if (count == 0)
                {
                    return null;
                }
                Mesh mesh = new Mesh();
                mesh.MeshBuffer=new MeshBuffer();
                MeshPart part = new MeshPart(0L);
                mesh.AddPart(part);
                Material2D materiald = new Material2D();
                materiald.SurfaceState.point_size = _size;//.get_SurfaceState().point_size = this._size;
                materiald.BackColor = _color;//.set_BackColor(this._color);
                materiald.ForeColor = _color;
                mesh.SetMaterial(materiald);
                double num;
                double num2;           
                IMapProjection projection = ServiceLocator.Current.GetInstance<LayerManager>().CurrentMap.Projection;
               
    
                for (int i = 0; i < count; i = num3 + 1)
                {
                    PointF tf = this._points[i];
                    projection.FwdP((double)tf.X, (double)tf.Y, out num, out num2);
    
                    mesh.MeshBuffer.VertexBuffer.AppendFloat((float)num);
                    mesh.MeshBuffer.VertexBuffer.AppendFloat((float)num2);
                    num3 = i;
                }
                BufferOpInfo info = new BufferOpInfo
                {
                    offset = 0,
                    count = count,
                    mode = 0
                };
    
                info.mode = 0;
                part.BufferOpInfo=info;
                return new CMA.MICAPS.Box2D.Graphics.MeshRenderable(mesh);
            }
    
            public void UpdatePostion(float worldx, float worldy)
            {
                double num;
                double num2;
                IMapProjection projection = ServiceLocator.Current.GetInstance<LayerManager>().CurrentMap.Projection;
                projection.FwdP((double)worldx, (double)worldy, out num, out num2);
    
                VertexBuffer buffer = this._meshRenderable.Mesh.MeshBuffer.VertexBuffer;// ().MeshBuffer.VertexBuffer;
                IntPtr destination = buffer.Lock();
                float[] source = new float[] {(float) num, (float)num2 };
                Marshal.Copy(source, 0, destination, 2);
                buffer.Unlock();
                this._meshRenderable.RefreshVertexBuffer();
            }
    

    这里需要强调一下,地图具有投影信息,要注意地理坐标和屏幕坐标的转换,转换用如下:

     IMapProjection projection = ServiceLocator.Current.GetInstance<LayerManager>().CurrentMap.Projection;
      projection.FwdP((double)tf.X, (double)tf.Y, out num, out num2);
    
    

    最初没有注意这个问题,鼠标所选的点在屏幕上基本上没有改变,困扰了很久。
    以上是实现的主要函数。

    效果如下:

    效果图

    相关文章

      网友评论

          本文标题:Micaps4二次开发(2)获取micaps主程序地图上鼠标位置

          本文链接:https://www.haomeiwen.com/subject/etfbyhtx.html