一步一步手写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框架.一直没有时间去补充相应的文档,现在正好抽时间去整理下.通过思路历程和代码注释,一方面重温下知识,另 ...
随机推荐
- SDN上机第四次作业
1. 解压安装OpenDayLight控制器(本次实验统一使用Beryllium版本) 安装ODL后安装插件 2.3用Python脚本搭建如下拓扑,连接OpenDayLight控制器 拓扑如图: Py ...
- mybatis or的用法
@Test public void test3(){ CaseSmallListExample caseSmallListExample = new CaseSmallListExample(); c ...
- spring-JDBC模板
Spring的JDBC的模板 Spring是EE开发的一站式的框架,有EE开发的每层的解决方案. Spring对持久层也提供了解决方案:ORM模块和JDBC的模板. Spring提供了很多的模板用于简 ...
- .Net Core NOPI操作word(一)
NOPI使用方式 1.安装nuget包 即可使用 Install-Package NPOI 一.创建word文档 //创建生成word文档 string path = "D:\\test.d ...
- Web.Config配置文件中customErrors元素的使用方法
在Web.Config配置文件中,customErrors元素提供有关ASP.NET 应用程序自定义错误消息的信息. 先看一下配置结构的示例: <configuration> < ...
- nmon报告分析
nmon结果说明及分析 2018年09月29日 16:12:10 Jio_2018 阅读数 2334 使用nmon analyser生成的结果文件包含了N多个sheet页,下面只是结合个人经验对几 ...
- C#中 ??、 ?、 ?: 、?.、?[ ] 问号
1. 可空类型修饰符(?) 引用类型可以使用空引用表示一个不存在的值,而值类型通常不能表示为空.例如:string str=null; 是正确的,int i=null; 编译器就会报错.为了使值类型也 ...
- Composer 国内加速:可用镜像列表大全
查看地址1:https://learnku.com/composer/wikis/30594 查看地址2:https://learnku.com/articles/30258
- IFC文件介绍
IFC是一个数据交换标准, 用于不同系统交换和共享数据. IFC是采用EXPRESS语言定义的实体关系模型,由几百个实体对象组成.实体对象包括建筑要素如IfcWall,几何元素如IfcExtruded ...
- 删除Win10自动下载的更新安装包
当我们禁止了系统的自动更新后,会感觉还有什么东西没做,没错,你还没有删除系统自动下载好的安装包,如果不删除的话会白白浪费磁盘空间!那么系统自动下载的安装包在哪里呢? C盘Windows—Softwar ...