• 一步一步手写GIS开源项目-(2)地图平移缩放实现


    系列文章目录

    一步一步手写GIS开源项目-(1)500行代码实现基础GIS展示功能

    一步一步手写GIS开源项目-(2)地图平移缩放实现

    项目github地址:https://github.com/HuHongYong/ATtuingMap

    1. 地图平移

    地图平移分为三步:

    1鼠标按下-首先要取得鼠标按下地图的屏幕坐标,以及保存这时候的地图图片。

    /// <summary>
    /// 鼠标按下
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    
    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
         //鼠标按下的屏幕坐标位置
         _mousedrag = e.Location;
         //鼠标按下,为了区分普通鼠标移动和鼠标按下移动
         _mousedragging = true;
         //当前地图 图片
         _mousedragImg = pictureBox1.Image;
    }

    2鼠标移动-平移过程对上一步的地图图片进行切割,以模拟地图拖放效果。如图:

    image

    /// <summary>
    /// 鼠标移动
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
         var point = Transform.MapToWorld(new PointF(e.X, e.Y), myMap);
         label1.Text = $"坐标X:{point.X}  Y:{point.Y}";
         //拖动已有图像
         if (_mousedragging)
         {
             Bitmap _dragImg1 = new Bitmap(pictureBox1.Width, pictureBox1.Height);
             Graphics g = Graphics.FromImage(_dragImg1);
             g.Clear(Color.Transparent);
    
            //图片裁剪
             g.DrawImageUnscaled(_mousedragImg,
                                 new System.Drawing.Point(e.Location.X - _mousedrag.X,
                                                          e.Location.Y - _mousedrag.Y));
             g.Dispose();
             pictureBox1.Image = _dragImg1;
         }
    }

    3鼠标弹起-zoom地图缩放不变,只需重新定位地图中心点,对地图进行重新绘制。

    image

    /// <summary>
    /// 鼠标弹起事件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
         //地图的新中心
         System.Drawing.Point pnt = new System.Drawing.Point(pictureBox1.Width / 2 + (_mousedrag.X - e.Location.X),
                                                pictureBox1.Height / 2 + (_mousedrag.Y - e.Location.Y));
         //修改鼠标拖动后的地图中心空间坐标点
         myMap.Center = Transform.MapToWorld(pnt, myMap);
         pictureBox1.Image = myMap.GetMap();
         //取消鼠标拖动
         _mousedragging = false;
    }

    2.地图缩放

    地图缩放比较难理解,这里我们以下图的例子为例,黑色边框为地图可视区域,红色矩形代表的地图上的一个矢量图形,这时候鼠标在左上角或者任意一点,如图1、2,

    image     4

    滚动鼠标滚轮对地图进行放大,这是展示不同鼠标点放大后的地图如图3、4

    image    6

          我们知道地图的两个核心要素为zoom和新的地图中心点坐标,zoom=zoom*缩放倍数,新的地图中心点坐标怎么算呢?我们可以通过第5、6图进行简单的转化便可以算出。

    首先通过把地图中心点定位到鼠标点,鼠标点的空间坐标已经知道,可以从六张图中看出,鼠标点到未来中心点的紫色线是恒定的,那我们知道了未来中心点的屏幕坐标,便可以求出他的未来中心点的空间坐标。实现代码如下:

    image    5

    /// <summary>
    /// 鼠标滚轮触发缩放地图事件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void MapImage_Wheel(object sender, MouseEventArgs e)
    {
         //重新定位鼠标位置为中心点
         myMap.Center = Transform.MapToWorld(new System.Drawing.Point(e.X, e.Y), myMap);
         //e.Delta常数,鼠标滚轮滚一下
         double scale = (e.Delta / 120.0);
         //缩放1.2倍
         double scaleBase = 1 + (2.0 / 10);
         //重新设置zoom缩放等级
         myMap.Zoom *= Math.Pow(scaleBase, scale);
    
        //如图第5、6中的未来中心点的屏幕坐标
         int NewCenterX = (pictureBox1.Width / 2) + ((pictureBox1.Width / 2) - e.X);
         int NewCenterY = (pictureBox1.Height / 2) + ((pictureBox1.Height / 2) - e.Y);
         //修改鼠标缩放后的地图中心点空间坐标
         myMap.Center = Transform.MapToWorld(new System.Drawing.Point(NewCenterX, NewCenterY), myMap);
         pictureBox1.Image = myMap.GetMap();
    }

    3.总结

            本节主要讲了一下地图的平移和缩放的实现,展示地图操作的最基础的操作功能,相信大家可以通过简单的代码理解到GIS最核心的展示功能,下一节主要讲一下shape文件中的.dbf属性文件的读取以及鼠标点击查询,敬请期待。

    本节代码上传github,生成一个release,大家可以参考调试一下项目源码。

    image

    github项目地址:https://github.com/HuHongYong/ATtuingMap

    作者:ATtuing

    出处:http://www.cnblogs.com/ATtuing

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

  • 相关阅读:
    POJ 1251 换成字母编号的最小生成树
    POJ 2421 有一条连通下的最小生成树
    最小生成树-Prim算法和Kruskal算法
    POJ 3083 相对位置的DFS的变形和BFS
    POJ 3278 抓牛简单广搜
    POJ 2488 DFS 模拟 马的跳动
    POJ 1572 字符串替换
    POJ 3984 迷宫问题 BFS+记录路径
    解救人质 BFS模板(迷宫问题)
    解救人质 DFS简单模板
  • 原文地址:https://www.cnblogs.com/ATtuing/p/10830130.html
Copyright © 2020-2023  润新知