zoukankan      html  css  js  c++  java
  • DIY自己的GIS程序(2)——局部刷新

    • 绘制线过移动鼠标程中绘制临时线段防闪烁

      参考OpenS-CAD想实现绘制线的功能。希望实现绘制线的过程,在移动线的时候没有闪烁和花屏。但是出现了问题,困扰了2天,前天熬的太晚,搞得现在精力都没有恢复。现在终于把问题搞清楚了:

      第一个问题:没有给背景图片赋颜色,此时相当于透明。所以每次将图片局部范围重绘产生严重的花屏,绘制的线段残留在屏幕上,将透明的东西绘制是不可能将移动过程中产生的临时线段擦除的。

      第二个问题:用当前移动产生的线段包围盒来重绘,其实在本次鼠标移动过程中,应该将上次产生的残留擦除,用上次的包围盒局部重绘。

      以下是自己写的一个控件的雏形:

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Drawing;
      4 using System.Windows.Forms;
      5 using RGeos.Geometry;
      6 using System.Drawing.Imaging;
      7 
      8 namespace RGeos.PluginEngine
      9 {
     10     public partial class UcMapControl2 : UserControl, IRMapControl
     11     {
     12         private ITool mCurrentTool = null;
     13 
     14         public ITool CurrentTool
     15         {
     16             get { return mCurrentTool; }
     17             set { mCurrentTool = value; }
     18         }
     19         public REnvelope mExtent { get; set; }
     20         public Map mMap { get; set; }
     21 
     22         private PointF m_panOffset = new PointF(25, -25);
     23 
     24         public PointF PanOffset
     25         {
     26             get { return m_panOffset; }
     27             set { m_panOffset = value; }
     28         }
     29         private PointF m_dragOffset = new PointF(0, 0);
     30 
     31         public PointF DragOffset
     32         {
     33             get { return m_dragOffset; }
     34             set { m_dragOffset = value; }
     35         }
     36         public UcMapControl2()
     37         {
     38             InitializeComponent();
     39             mMap = new Map();
     40             this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
     41             this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
     42         }
     43 
     44         bool m_staticDirty = true;
     45         //缓存图片?
     46         Bitmap m_staticImage = null;
     47         System.Drawing.Drawing2D.SmoothingMode m_smoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed;
     48         protected override void OnPaint(PaintEventArgs e)
     49         {
     50             Tracing.StartTrack(Program.TracePaint);
     51             #region old
     52             e.Graphics.SmoothingMode = m_smoothingMode;
     53             Rectangle cliprectangle = e.ClipRectangle;
     54             if (m_staticImage == null)
     55             {
     56                 cliprectangle = ClientRectangle;
     57                 m_staticImage = new Bitmap(ClientRectangle.Width, ClientRectangle.Height);
     58                 //m_staticImage.Save("D:\a.png", ImageFormat.Png);
     59                 m_staticDirty = true;
     60             }
     61             //绘制在背景图片上
     62             Graphics BitMapGc = Graphics.FromImage(m_staticImage);
     63             BitMapGc.SmoothingMode = m_smoothingMode;
     64             //绘制背景,注意如果不设将为透明色
     65             BitMapGc.Clear(Color.White);
     66             //this.BackgroundLayer.Draw(dcStatic, r);
     67             //if (m_model.GridLayer.Enabled)
     68             //    m_model.GridLayer.Draw(dcStatic, r);
     69             //绘制十字丝
     70             RPoint rCenterPoint = new RPoint(0, 0, 0);
     71             PointF nullPoint = Transform.ToScreen(rCenterPoint, this);
     72             BitMapGc.DrawLine(Pens.Blue, nullPoint.X - 10, nullPoint.Y, nullPoint.X + 10, nullPoint.Y);
     73             BitMapGc.DrawLine(Pens.Blue, nullPoint.X, nullPoint.Y - 10, nullPoint.X, nullPoint.Y + 10);
     74             if (m_staticDirty)
     75             {
     76                 m_staticDirty = false;
     77 
     78                 List<ILayer> layers = mMap.Layers;
     79                 for (int layerindex = layers.Count - 1; layerindex >= 0; layerindex--)
     80                 {
     81                     //if (layers[layerindex].Visible)
     82                     //layers[layerindex].Draw();
     83                 }
     84                 BitMapGc.Dispose();
     85             }
     86             //绘制背景图片
     87             e.Graphics.DrawImage(m_staticImage, cliprectangle, cliprectangle, GraphicsUnit.Pixel);
     88             //绘制新建对象
     89             //if (m_newObject != null)
     90             //    m_newObject.Draw(dc, r);
     91             #endregion
     92             Tracing.EndTrack(Program.TracePaint, "OnPaint complete");
     93 
     94         }
     95 
     96         protected override void OnResize(EventArgs e)
     97         {
     98             base.OnResize(e);
     99             if (m_lastCenterPoint != null && Width != 0)
    100                 SetCenterScreen(Transform.ToScreen(m_lastCenterPoint, this), false);
    101             m_lastCenterPoint = CenterPointUnit();
    102             m_staticImage = null;
    103             Invalidate();
    104         }
    105         RPoint m_lastCenterPoint;
    106         /// <summary>
    107         /// 设置画布到屏幕的中心
    108         /// </summary>
    109         /// <param name="rPoint">直角坐标系坐标</param>
    110         public void SetCenter(RPoint unitPoint)
    111         {
    112             PointF point = Transform.ToScreen(unitPoint, this);
    113             m_lastCenterPoint = unitPoint;
    114             SetCenterScreen(point, false);
    115         }
    116 
    117         protected void SetCenterScreen(PointF screenPoint, bool setCursor)
    118         {
    119             float centerX = ClientRectangle.Width / 2;
    120             m_panOffset.X += centerX - screenPoint.X;
    121 
    122             float centerY = ClientRectangle.Height / 2;
    123             m_panOffset.Y += centerY - screenPoint.Y;
    124 
    125             if (setCursor)
    126                 Cursor.Position = this.PointToScreen(new Point((int)centerX, (int)centerY));
    127             Invalidate();
    128         }
    129         public RPoint CenterPointUnit()
    130         {
    131             RPoint p1 = Transform.ToUnit(new PointF(0, 0), this);
    132             RPoint p2 = Transform.ToUnit(new PointF(this.ClientRectangle.Width, this.ClientRectangle.Height), this);
    133             RPoint center = new RPoint();
    134             center.X = (p1.X + p2.X) / 2;
    135             center.Y = (p1.Y + p2.Y) / 2;
    136             return center;
    137         }
    138         protected override void OnMouseUp(MouseEventArgs e)
    139         {
    140             base.OnMouseUp(e);
    141 
    142         }
    143         int n = 0;
    144         PointF p1;
    145         PointF TempPoint2;//缓存移动过程中产生的第二个点,上一移动过程中
    146         protected override void OnMouseMove(MouseEventArgs e)
    147         {
    148             base.OnMouseMove(e);
    149 
    150             Rectangle invalidaterect = Rectangle.Empty;
    151             if (n < 1)
    152             {
    153 
    154             }
    155             else
    156             {
    157                 //REnvelope env = mNewLine.GetBoundingBox();
    158                 //mNewLine.P1 = new RPoint(e.X, e.Y, 0);
    159 
    160                 double xmin = Math.Min(p1.X, TempPoint2.X);
    161                 double ymin = Math.Min(p1.Y, TempPoint2.Y);
    162                 double w = Math.Abs(p1.X - TempPoint2.X);
    163                 double h = Math.Abs(p1.Y - TempPoint2.Y);
    164                 invalidaterect = new Rectangle((int)xmin, (int)ymin, (int)w, (int)h);
    165                 invalidaterect.Inflate(2, 2);
    166 
    167                 Pen pen = new Pen(Color.Red);
    168                 //擦除上次移动绘制的线,通过重绘上次移动范围区域的缓存图片实现
    169                 RepaintStatic(invalidaterect);
    170                 //Bitmap m_staticImage2 = new Bitmap(invalidaterect.Width, invalidaterect.Height);
    171                 //m_staticImage2.Save("D:\adfghj.png", ImageFormat.Png);
    172                 pen.EndCap = System.Drawing.Drawing2D.LineCap.Round;
    173                 pen.StartCap = System.Drawing.Drawing2D.LineCap.Round;
    174                 Graphics dc = Graphics.FromHwnd(Handle);
    175                 dc.SmoothingMode = m_smoothingMode;
    176                 Point p2 = new Point(e.X, e.Y);
    177                 dc.DrawLine(pen, p1, p2);
    178                 dc.Dispose();
    179                 TempPoint2 = p2;
    180                 //Invalidate();
    181                 //DoInvalidate(false, invalidaterect);
    182 
    183             }
    184         }
    185         protected override void OnMouseDown(MouseEventArgs e)
    186         {
    187             n++;
    188             if (n <= 1)
    189             {
    190                 //mNewLine = new RSegment();
    191                 //mNewLine.P0 = new RPoint(e.X, e.Y, 0);
    192                 //mNewLine.P1 = new RPoint();
    193                 //初始化两个点,注意此处两点相同。
    194                 p1 = new PointF(e.X, e.Y);
    195                 TempPoint2 = new Point(e.X, e.Y);
    196                 Invalidate(true);
    197             }
    198             base.OnMouseDown(e);
    199         }
    200         public void DoInvalidate(bool dostatic, Rectangle rect)
    201         {
    202             if (dostatic)
    203                 m_staticDirty = true;
    204             Invalidate(rect);
    205         }
    206         /// <summary>
    207         /// 局部刷新,重新绘制图片Bitmap无效区域
    208         /// </summary>
    209         /// <param name="r"></param>
    210         public void RepaintStatic(Rectangle r)
    211         {
    212             if (m_staticImage == null)
    213                 return;
    214             Graphics dc = Graphics.FromHwnd(Handle);
    215             if (r.X < 0) r.X = 0;
    216             if (r.X > m_staticImage.Width) r.X = 0;
    217             if (r.Y < 0) r.Y = 0;
    218             if (r.Y > m_staticImage.Height) r.Y = 0;
    219 
    220             if (r.Width > m_staticImage.Width || r.Width < 0)
    221                 r.Width = m_staticImage.Width;
    222             if (r.Height > m_staticImage.Height || r.Height < 0)
    223                 r.Height = m_staticImage.Height;
    224             dc.DrawImage(m_staticImage, r, r, GraphicsUnit.Pixel);
    225             Image temp = new Bitmap(m_staticImage);
    226             Graphics gc = Graphics.FromImage(temp);
    227             gc.DrawLine(Pens.Blue, r.Location, new Point(r.Location.X + r.Width, r.Location.Y + r.Height));
    228             gc.Dispose();
    229             temp.Save("d:\AAAA.png", ImageFormat.Png);
    230             m_staticImage.Save("d:\BBBB.png", ImageFormat.Png);
    231             dc.Dispose();
    232         }
    233         public float ScreenHeight()
    234         {
    235             return (float)(Transform.ToUnit(this.ClientRectangle.Height, this as IRMapControl));
    236         }
    237         private float mZoom = 1.0f;
    238         public float Zoom
    239         {
    240             get
    241             {
    242                 return mZoom;
    243             }
    244             set
    245             {
    246                 mZoom = value;
    247             }
    248         }
    249     }
    250 }
    UcMapControl2

       今年的一个目标:完成一个开源项目

      参考:http://www.codeproject.com/Articles/6238/Canvas-implementation-for-C

  • 相关阅读:
    c++ stack 适配器
    错误记录
    css3动画,制作跑步运动,画笔画圆,之类的连贯性动作的方法
    关于$.cookie
    JavaScript中常见易犯的小错误
    关于内存泄漏
    Javascript的异步编程方法
    JavaScript中this关键词的四种指向
    javascript之回调函数小知识
    移动端的兼容性
  • 原文地址:https://www.cnblogs.com/yhlx125/p/3498528.html
Copyright © 2011-2022 走看看