zoukankan      html  css  js  c++  java
  • 一步一步手写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

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

  • 相关阅读:
    解析CIDR表示的IP段表示的范围
    [Python] 使用乘号复制变量引起的问题
    [Python] 字典dict添加二级键值的问题
    [Java] [刷题] 连续自然数和
    [Java] [刷题] 多个整数连接为最大整数问题
    [CentOS] 编译安装Python3后pip3安装的库如何在命令行调用
    [CentOS] 宝塔面板与Python3的恩怨情仇
    [易语言] 两种字节序的直观比较
    [Java] [刷题] Excel地址转换
    [Java] 运算精度
  • 原文地址:https://www.cnblogs.com/ATtuing/p/10830130.html
Copyright © 2011-2022 走看看