地图下载工具初步完成后,有网友提出需要加入经纬网络,看了文档,没有找到相关内容。那就自己动手,丰衣足食吧。最终效果如下图所示:

具体思路是,根据地图界面显示的经纬网络范围,确定一个合理的参数,结合地图层级,将经纬网络分别生成并显示出来,同时在周围显示具体数据,当鼠标拖动地图、地图放大缩小时,自动计算和更新经纬网络。比如,第3层,经度范围-180到180,可以平均为8份制定经线,纬度范围-90至90(实则为85°),可以平分为6份。
经过测算,不同层级内,经纬度平分参数如下:
代码为:

 public static int[] lngsplit = { 2,6,8,12,24,60,120,240,360,720,1440,2160,4320,9600,21600,43200,64800,129600,259200,648000,1296000};public static int[] latsplit = { 2,4,6,10,15,45,90,180,270,540,1080,2160,3600,7200,21600,43200,64800,129600,324000,648000,1296000};

具体实现步骤为,新建一个类LngLatGrid,构造函数传入参数GMapControl control,同时,动态添加一个层,用来放置经纬线和刻度值文本。具体代码如下

  public LngLatGrid(GMapControl control){this.control = control;InitOverlay();InitEvent();}
/// <summary>/// 初始化经纬网层/// </summary>private void InitOverlay(){bool haslnglatgrid = false;foreach (GMapOverlay overlay in control.Overlays){if (overlay.Id.Equals("lnglatgrid")){haslnglatgrid = true;this.gridOverlay = overlay;continue;}}if (!haslnglatgrid){gridOverlay = new GMapOverlay("lnglatgrid");control.Overlays.Add(gridOverlay);}}/// <summary>/// 初始化事件/// </summary>private void InitEvent(){control.MouseDown += control_MouseDown;control.MouseUp += control_MouseUp;control.MouseMove += control_MouseMove;control.OnMapZoomChanged += control_OnMapZoomChanged;}void control_OnMapZoomChanged(){UpdateLngLat();}void control_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e){if (isDrag){UpdateLngLat();}}void control_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e){isDrag = false; UpdateLngLat();}void control_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e){isDrag = true;}internal void ClearLngLat(){gridOverlay.Clear();}

经纬网计算函数为:
这里要强调一下,过细的拆分可能出现浮点数而变得不准确,需要先将范围扩大,所以我们可以把经度×3600,相当于把度换算成秒,这样平均计算时就不会有太大误差。

        public void UpdateLngLat(){if (GlobalConfig.isshowLnglatGird){int zoom = (int)control.Zoom;if (zoom > GlobalConfig.lngsplit.Length)return;gridOverlay.Clear();Rectangle m = control.ClientRectangle;PointLatLng p1 = control.FromLocalToLatLng(m.X, m.Y);PointLatLng p2 = control.FromLocalToLatLng(m.Width, m.Height);double latn = p1.Lat < 90 ? p1.Lat : 90;double lats = p2.Lat > -90 ? p2.Lat : -90;double lnge = p2.Lng < 180 ? p2.Lng : 180;double lngw = p1.Lng > -180 ? p1.Lng : -180;double lngsplit = 360d * 3600 / GlobalConfig.lngsplit[zoom - 1] ;double latsplit = 180d * 3600 / GlobalConfig.latsplit[zoom - 1] ;double mx = Convert.ToInt32(lngw * 3600 / lngsplit) * lngsplit;double nx = Convert.ToInt32(lats * 3600 / latsplit) * latsplit;for (double i = mx; i < lnge*3600; ){double cdeg = i / 3600;GMapPolygon p = new GMapPolygon(new List<PointLatLng>(){new PointLatLng(lats,cdeg),new PointLatLng(latn,cdeg)}, "lng" + cdeg.ToString().PadLeft(3, '0'));i += lngsplit;p.Stroke = new Pen(new SolidBrush(Color.Black), 2);gridOverlay.Polygons.Add(p);GMapMarker markern = new LabelMarker(new PointLatLng(latn, cdeg), Tools.ToDegreeStr(cdeg,"lng"), Color.Black);gridOverlay.Markers.Add(markern);GPoint slatp = control.FromLatLngToLocal(new PointLatLng(lats, cdeg));PointLatLng slat = control.FromLocalToLatLng((int)slatp.X, (int)(slatp.Y - 40));GMapMarker markerw = new LabelMarker(slat, Tools.ToDegreeStr(cdeg, "lng"), Color.Black);gridOverlay.Markers.Add(markerw);}for (double i = nx; i <= latn * 3600; ){double cdeg = i / 3600;GMapPolygon p = new GMapPolygon(new List<PointLatLng>(){new PointLatLng(cdeg,lngw),new PointLatLng(cdeg,lnge)}, "lat" + cdeg.ToString().PadLeft(3, '0'));i += latsplit;p.Stroke = new Pen(new SolidBrush(Color.Red), 2);gridOverlay.Polygons.Add(p);GPoint elngp = control.FromLatLngToLocal(new PointLatLng(cdeg, lnge));PointLatLng elng = control.FromLocalToLatLng((int)elngp.X - 140, (int)(elngp.Y));GMapMarker markere = new LabelMarker(elng, Tools.ToDegreeStr(cdeg,"lat"), Color.Red);gridOverlay.Markers.Add(markere);GMapMarker markerw = new LabelMarker(new PointLatLng(cdeg, lngw), Tools.ToDegreeStr(cdeg, "lat"), Color.Red);gridOverlay.Markers.Add(markerw);}control.Invalidate();}else{gridOverlay.Clear();}}

因为GMap.net中并未提供直接标注文字的功能,所以我们要改造一个marker,用Graphics进行文本绘制,

using GMap.NET.WindowsForms;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;namespace Mapmerger.Utils
{class LabelMarker:GMapMarker{private string text;public string Text{get { return text; }set { text = value; }}private Color defaultColor;public LabelMarker(GMap.NET.PointLatLng p, string text,Color color): base(p){this.text = text;this.defaultColor = color;}public override void OnRender(Graphics g){RectangleF rect = new RectangleF(LocalPosition.X, LocalPosition.Y, Size.Width, Size.Height);Font font = new Font("宋体", 18);StringFormat format = StringFormat.GenericTypographic;float dpi = g.DpiY;using (GraphicsPath path = GetStringPath(text, dpi, rect, font, format)){g.SmoothingMode = SmoothingMode.AntiAlias;//设置字体质量g.DrawPath(Pens.White, path);//绘制轮廓(描边)g.FillPath(new SolidBrush(defaultColor), path);//填充轮廓(填充)}}GraphicsPath GetStringPath(string s, float dpi, RectangleF rect, Font font, StringFormat format){GraphicsPath path = new GraphicsPath();float emSize = dpi * font.SizeInPoints / 72;path.AddString(s, font.FontFamily, (int)font.Style, emSize, rect, format);return path;}public override void Dispose(){base.Dispose();}}}

相关功能测试效果较好,效率也很好,因为动态更新且经纬网和注记数量较少,运行速度很快。完工。

打造地图拼接利器(六)GMap.net内动态显示和更新经纬网络相关推荐

  1. 打造地图拼接利器(二)软件框架

    我们采用Visual studio2013作为开发环境,GMap.net作为地图环境,实现相关功能. 一.GMap.net GMap.NET 是一个免费.开源的.NET控件,有Windows Form ...

  2. Winform下的地图开发控件(GMap.NET)使用心得之二

    在上篇<Winform下的地图开发控件(GMap.NET)使用心得>中简单介绍了GMap.NET的控件基本情况,本篇开始介绍一下相关的代码操作. 其实目前GMap.NET提供的功能还不是很 ...

  3. JSP的“三指六动九内”

    JavaWeb--JSP的"三指六动九内" JSP的基本使用 1. JSP模板元素 网页的静态内容.如html标签 JSP脚本 2. JSP的脚本 2.1.小脚本<% Jav ...

  4. 如何利用自己的数据制作社交地图?只显示可视区域内的标注

    地址:http://www.cnblogs.com/milkmap/archive/2012/02/02/2335989.html [百度地图API]如何利用自己的数据制作社交地图?只显示可视区域内的 ...

  5. 【百度地图API】如何利用自己的数据制作社交地图?只显示可视区域内的标注...

    原文:[百度地图API]如何利用自己的数据制作社交地图?只显示可视区域内的标注 摘要:如果你自己的数据已经超过1万个,如何进行合理的显示?除了聚合marker外,还有一个办法.那就是,只显示可视区域内 ...

  6. 【百度地图API】如何利用自己的数据制作社交地图?只显示可视区域内的标注

    [百度地图API]如何利用自己的数据制作社交地图?只显示可视区域内的标注 摘要:如果你自己的数据已经超过1万个,如何进行合理的显示?除了聚合marker外,还有一个办法.那就是,只显示可视区域内的标注 ...

  7. python用cartopy包画地图_python绘制地图的利器Cartopy使用说明

    python绘制地图一般使用Basemap绘图包,但该包配置相对较繁琐,自定义性不强,这里介绍一个绘制地图的利器Cartopy,个人认为该工具方便.快捷,附上一些自己写的程序. 准备工作,工欲善其事, ...

  8. java模仿微信QQ群聊头像拼接,根据群聊内的用户头像拼接群聊头像,九宫格

    java模仿微信QQ群聊头像拼接,根据群聊内的用户头像拼接群聊头像,九宫格 效果图,这里只放了几张,1-9张图片都可以的,如果图片路径是从数据库查出来的相对路径,记得加上绝对路径否则会报找不到读取文件 ...

  9. HTML+CSS3(六)——行内元素和块级元素

    目录: HTML+CSS3(一)--认识浏览器 HTML+CSS3(二)--HTML 初识 HTML+CSS3(三)--HTML基本标签 HTML+CSS3(四)--表单pattern正则属性 HTM ...

最新文章

  1. matlab怎么重复一个数字,有 1、2、3、4 个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?用matlab编程怎么编...
  2. 零基础入门学习python
  3. ZOJ 1049 2^x mod n = 1
  4. Linux下CMake简明教程(七)对库进行链接
  5. Java虚拟机详解05----垃圾收集器及GC参数
  6. 新瓶装旧酒,贴着区块链标签的QunQun社交平台真能讲个好故事?
  7. Java 动态代理实现
  8. Matlab调制库函数fskmod参数及源代码详解
  9. isdigit()、isalpha()、isalnum() 三个函数的区别和注意点
  10. 怎么做软件安全性测试
  11. JS中showModalDialog (模态窗口)详细使用
  12. 资深java面试题及答案整理(一)
  13. 嵌入式开发——物联网
  14. javaScript学习手册:JS对象
  15. c++字符串中元音字母转置
  16. Django分布式路由
  17. 2020年如何写一个现代的JavaScript库
  18. 有序的map LinkedHashMap
  19. 抖音头条小程序常见的问题
  20. style 标签属性 scoped 的作用和原理

热门文章

  1. 解决 FileNotFoundError: [WinError 2] 系统找不到指定的文件
  2. 虚拟DOM中的key
  3. inc si指令的作用_8086指令
  4. windows设置有线访问内网,无线访问外网
  5. LM2596-5.0开关电源电感的选取
  6. Latex报错 ! Misplaced alignment tab character
  7. 光学计算机PPT,光学课件
  8. LSTM 长短期记忆循环神经网络(学习笔记)
  9. 碾压Dota2世界冠军的AI,被一小撮人持续干翻了
  10. PAC(Probably Approximately Correct,概率近似正确)