一步一步手写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鼠标移动-平移过程对上一步的地图图片进行切割,以模拟地图拖放效果。如图:

/// <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地图缩放不变,只需重新定位地图中心点,对地图进行重新绘制。

/// <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 / + (_mousedrag.X - e.Location.X),
pictureBox1.Height / + (_mousedrag.Y - e.Location.Y));
//修改鼠标拖动后的地图中心空间坐标点
myMap.Center = Transform.MapToWorld(pnt, myMap);
pictureBox1.Image = myMap.GetMap();
//取消鼠标拖动
_mousedragging = false;
}
2.地图缩放
地图缩放比较难理解,这里我们以下图的例子为例,黑色边框为地图可视区域,红色矩形代表的地图上的一个矢量图形,这时候鼠标在左上角或者任意一点,如图1、2,
     
滚动鼠标滚轮对地图进行放大,这是展示不同鼠标点放大后的地图如图3、4
    
我们知道地图的两个核心要素为zoom和新的地图中心点坐标,zoom=zoom*缩放倍数,新的地图中心点坐标怎么算呢?我们可以通过第5、6图进行简单的转化便可以算出。
首先通过把地图中心点定位到鼠标点,鼠标点的空间坐标已经知道,可以从六张图中看出,鼠标点到未来中心点的紫色线是恒定的,那我们知道了未来中心点的屏幕坐标,便可以求出他的未来中心点的空间坐标。实现代码如下:
    
/// <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 = + (2.0 / );
//重新设置zoom缩放等级
myMap.Zoom *= Math.Pow(scaleBase, scale); //如图第5、6中的未来中心点的屏幕坐标
int NewCenterX = (pictureBox1.Width / ) + ((pictureBox1.Width / ) - e.X);
int NewCenterY = (pictureBox1.Height / ) + ((pictureBox1.Height / ) - e.Y);
//修改鼠标缩放后的地图中心点空间坐标
myMap.Center = Transform.MapToWorld(new System.Drawing.Point(NewCenterX, NewCenterY), myMap);
pictureBox1.Image = myMap.GetMap();
}
3.总结
本节主要讲了一下地图的平移和缩放的实现,展示地图操作的最基础的操作功能,相信大家可以通过简单的代码理解到GIS最核心的展示功能,下一节主要讲一下shape文件中的.dbf属性文件的读取以及鼠标点击查询,敬请期待。
本节代码上传github,生成一个release,大家可以参考调试一下项目源码。

github项目地址:https://github.com/HuHongYong/ATtuingMap
作者:ATtuing
出处:http://www.cnblogs.com/ATtuing
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
一步一步手写GIS开源项目-(2)地图平移缩放实现的更多相关文章
- 一步一步手写GIS开源项目-(1)500行代码实现基础GIS展示功能
		
1.开篇 大学毕业工作已经两年了,上学那会就很想研读一份开源GIS的源码,苦于自己知识和理解有限,而市面上也没有什么由浅入深讲解开源gis原理的书籍,大多都是开源项目简介以及项目的简单应用.对于初级程 ...
 - pytorch 手写数字识别项目  增量式训练
		
dataset.py ''' 准备数据集 ''' import torch from torch.utils.data import DataLoader from torchvision.datas ...
 - js手写图片查看器(图片的缩放、旋转、拖拽)
		
在做一次代码编辑任务中,要查看图片器.在时间允许的条件下,放弃了已经封装好的图片jq插件,现在自己手写js实现图片的缩放.旋转.推拽功能! 具体代码如下: <!DOCTYPE html> ...
 - 深度学习之PyTorch实战(3)——实战手写数字识别
		
上一节,我们已经学会了基于PyTorch深度学习框架高效,快捷的搭建一个神经网络,并对模型进行训练和对参数进行优化的方法,接下来让我们牛刀小试,基于PyTorch框架使用神经网络来解决一个关于手写数字 ...
 - 如何把开源项目发布到Jcenter
		
转载自:https://www.jianshu.com/p/f66972f0607a 首先我们应该注册一个JFrog Bintray的账号 Jfrog Bintray官网 这里我们可以注意到那个绿色的 ...
 - 个人开源项目如何上传maven中央仓库
		
最近在写一些开源项目,想把自己写的东西放到maven中央仓库,提供给更多的人使用.所以写这一篇文章,记录一下自研开源项目jar包上传同步maven中央仓库成功的整个过程,这其中还是有不少的坑的. 目录 ...
 - C#.NET开源项目、机器学习、商务智能
		
所以原谅我,不能把所有的都发上来,太杂了,反而不好. 1..NET时间周期处理组件 这个组件很小,主要是对时间日期,特别是处理时间间隔以及时间范围非常方便.虽然.NET自带了时间日期的部分功能,但可能 ...
 - .NET跨平台:在Mac上跟着错误信息一步一步手写ASP.NET 5程序
		
今天坐高铁时尝试了一种学习ASP.NET 5的笨方法,从空文件夹开始,根据运行dnx . kestrel命令的错误信息,一步一步写代码,直至将一个最简单的ASP.NET程序运行起来. 尝试的具体步骤如 ...
 - 手写开源ORM框架介绍
		
手写开源ORM框架介绍 简介 前段时间利用空闲时间,参照mybatis的基本思路手写了一个ORM框架.一直没有时间去补充相应的文档,现在正好抽时间去整理下.通过思路历程和代码注释,一方面重温下知识,另 ...
 
随机推荐
- C博客作业00——我的第一篇博客
			
1.你对网络专业或计算机专业了解是怎样? 初看字眼,便觉得是理工性很强的专业,所以需要较强的开拓思维,创新精神,探索未知事物的勇气,才能掌握并且熟练应用相关知识.计算机类专业都需要学习计算机语言,而计 ...
 - C博客作业02——循环结构
			
0.展示PTA总分 单循环题目集 嵌套循环题目集 1.本章学习总结 1.1学习内容总结 (a)while语句 while(表达式) { 循环体语句: } 执行流程:当表达式的值为"真&quo ...
 - shell 杀死80端口的所有进程
			
netstat -lnp|grep |grep -v grep |awk
 - nRF52832 串口仅支持偶检验
			
通常在使用串口时,我们习惯是不进行奇偶检验(even/odd parity),让应用层的软件自己检验即可.如果非要硬件校验时,以下是关于NRF52832的奇偶检验配置: // 52832 仅支持 ev ...
 - 因在缓存对象中增加字段,而导致Redis中取出缓存转化成Java对象时出现反序列化失败的问题
			
背景描述 因为业务需求的需要,我们需要在原来项目中的一个DTO类中新增两个字段(我们项目使用的是dubbo架构,这个DTO在A项目/服务的domain包中,会被其他的项目如B.C.D引用到).但是这个 ...
 - linux 的 两种磁盘扩容
			
当LVM分区空间不足的时候,可以进行扩容.主要的扩容方法有两种: 通过空余的磁盘进行扩容,这个方法比较简单,不会对原有数据有影响.将其他LVM分区空间取出一部分给需要扩容的LVM分区.下面就分别具体介 ...
 - 《你必须知道的javascript(上)》- 1.作用域和闭包
			
1 作用域是什么 1.1 编译原理 分词/词法分析(Tokenizing/Lexing) 将由字符组成的字符串分解成(对编程语言来说)有意义的代码块,这些代码块被称为词法单元(token). 解析/语 ...
 - c的指针和php中的引用的区别
			
https://blog.csdn.net/yangfanzn/article/details/44731391 1-php和c中的变量名都会被解析成内存地址,变量名所代表的内存的地址中内容即代表变量 ...
 - 用浏览器控制台抓取shodan、搜索引擎、zone-h的结果
			
0x00 前言 大部分内容来自参考连接的内容,只是一种爬取内容的思路. 在很久以前自己会有爬取zone-h做目标测试的需求,但是总是有各种反爬限制.而且个别网址还有前端自动生成内容的功能,使用Java ...
 - CentOS 7.5二进制部署Kubernetes1.12(加密通信)(五)
			
一.安装方式介绍 1.yum 安装 目前CentOS官方已经把Kubernetes源放入到自己的默认 extras 仓库里面,使用 yum 安装,好处是简单,坏处也很明显,需要官方更新 yum 源才能 ...