谷歌地图控件,通过扩展实现GMAP的自定义绘图系统-程序员宅基地

技术标签: 数据结构与算法  

  这两天搞网络规划和优化系统,需要开发一套地图,并在地图上放置自定义图标,和放置复杂贴图,或画矩形多边形等随着地图移动和放缩。这件事情一开始搞得很痛苦,通过GMAP.NET开发,并使用了CodeProject上面的drawtools工具(有兴趣可以自行搜索,博客园也有相关的文章讨论),但就是没法实现随地图移动而移动,仿佛是浮在地图上的。最后这种方法只能放弃。

      看了几个博客上面讨论的GMAP,其他方面都有讨论,就是没有如何在地图上实现自定义绘图。后来反复研究了GMAP.NET的整个类的结构,以及例程,终于发现了方法。

  首先说下图层,要显示图标和图形,就必须有图层的概念,仿佛一层一层贴在地图上的。可以从下到上,表示为如下四个图层:

    地理信息图层——复杂贴图图层——地标图层——用户数据操作图层

    简单地说,就是地图显示在“地理信息图层”,“复杂贴图图层”来贴图,可实现放缩和位移,“地标图层”可放置自定义图标,“用户操作图层”可定义其他一些特殊功能。

    (一)实现自定义图标的GMAPMARKER

  我们知道,GMAP中有一个Gmapmarker类,可以实现在地图上放置图标,可移动但不可放缩,可气的是,只有一个气球,很丑,怎么才能设计自定义的图标呢?派生这个类就可以了。GMapMarkerBS是我建立的一个基站(BS)类。可以在地图上绘制一个基站。

  public class GMapMarkerBS : GMapMarker
   {
       Bitmap myBitmap;  //存储要保存的图标信息
       public int ID;    //标记当前的类
     
     

      public GMapMarkerBS(PointLatLng p,int thisID)
         : base(p)
      {
          myBitmap= (Bitmap)Bitmap.FromFile(Application.StartupPath + "\\Cursor\\BS_Large.png");
          ID = thisID;
          ToolTipText = "测试基站" + ID.ToString();
          ToolTipMode = MarkerTooltipMode.OnMouseOver;
      
          Size = myBitmap.Size;
          Offset = new System.Drawing.Point(-Size.Width / 2, -Size.Height / 2);
      
   
  
      }
      public GMapMarkerBS(PointLatLng p, Bitmap thisBitmap, int thisID)
          : base(p)
      {
          ID = thisID;
          ToolTipText = "测试基站" + ID.ToString();
          ToolTipMode = MarkerTooltipMode.OnMouseOver;
          myBitmap = thisBitmap;
         
          Size = myBitmap.Size;
          Offset = new System.Drawing.Point(-Size.Width / 2, -Size.Height / 2);
       

      }

      public override void OnRender(Graphics g)
      {
          g.DrawImage(myBitmap, new System.Drawing.Rectangle(LocalPosition.X, LocalPosition.Y, 80, 100));
         
      }
   }

     两个构造函数,可以实现默认图标,和自定义图标,关键在于重载Onrender()函数,大伙一看就能看懂。

     Size和Offset都是在基类Gmapmarker中定义的,其意义是当前图标的大小和偏移量。Size不设置,都可以在地图上绘图,但你却无法让它触发“点击”事件!这个要注意,它设置了在地图上有效的操作范围,而不是绘图大小。所谓偏移,应该是点击时与图标左上角之间的偏移。

      如何在地图上绘制这个图标呢?

         GMapMarkerBS tempMarker = new GMapMarkerBS(thisPosition, BSIDCounter);
        GISObjectOverlay.Markers.Add(tempMarker);

      GISObjectOverlay是我建立的所谓图层,

      GISObjectOverlay = new GMapOverlay(myGMapControl, "GISOverlay");

      这样,就能在地图上绘制自定义图标的图形了。

 (二)实现绘制多边形

     实现多边形,并在地图上填充,还要实现缩放和移动,如果不继承GMAP内置的类,那么会累死的,好在GMAP提供了支持。

     实现思路是这样的,用户选择多边形绘图工具后,先在临时绘图图层GISTempOverlay上画临时点,用自带的十字图标表示,然后双击完成一次完整的多边形绘图操作,把当前存储的临时点LIST表传给GMAP类。

        private void MainMap_MouseDown(object sender, MouseEventArgs e)
        {

    case GISObjectType.Polygon:  

                        GISTempPoint.Add(MainMap.FromLocalToLatLng(e.X, e.Y));
                        GISTempOverlay.Markers.Add(tempMarker);
                        break;

}

上面代码实现了左键单击后,在地图上绘制临时点;

 private void MainMap_MouseDoubleClick(object sender, MouseEventArgs e)
        {

  case GISObjectType.Polygon:
                    if (GISTempPoint.Count < 3)
                    {
                        MessageBox.Show("未绘制包围图形");
                        break;
                    }
                    else
                    {
                        myGISObject.AddRouteObject(GISTempPoint, "Polygon");
                        GISTempOverlay.Markers.Clear();
                        GISTempPoint.Clear();
                    }
                    break;

AddRouteObject()函数是我自己写的一个路径类函数,代码如下:

 public void AddRouteObject(List<PointLatLng> myPositionList,string name)
        {
            GISRouteObjectList.Add(new RouteObject(myPositionList,name,RouteIDCounter));
            GMap.NET.WindowsForms.GMapPolygon tempPolygon = new GMap.NET.WindowsForms.GMapPolygon(myPositionList, name);
            GISObjectOverlay.Polygons.Add(tempPolygon);
                  }

这样,就实现了多边形绘制。

(三)设计复杂贴图

     图标是不能跟着地图放缩而放缩的,如果贴了一张图上去,岂不是没法放缩了?可以的。

     可以把图片生成PNG,这样就有了透明度,新建一个图层GISPictOverlay专门存储贴图类型,重载gmapmarker得到GMapMarkerPict,添加变量zoom,

   在OnRender()函数中这么写:

   g.DrawImage(myBitmap, new System.Drawing.Rectangle(LocalPosition.X, LocalPosition.Y, myBitmap.Width*zoom, myBitmap.Height*zoom));

   在类外部,当地图缩放等级改变时,修改本类的静态变量zoom。注意!这种方法,只能让你的图片随着地图的放缩而改变,但不是死死贴上去的...因为,地图的放缩等级每改变一个等级,貌似地图尺寸变化是2次方关系,但此处是线性的。具体怎么设置,我还得再研究一下,貌似在GMAP工程文件中提供了这个关系的说明。

      当然,我们还要存储当前的所有地图上的数据,比如多边形,图标,贴图等等,可以自己设定数据结构,我在这方面懂得比较少,不敢拿来说了。 第一次在博客园写文章,加之本人是.NET菜鸟,看到网上没有GMAP绘图的问题,就拿自己开发的案例过来讨论一下,大侠们轻拍。还想弱弱问个问题,为什么GMAP这么大的开源工程,连像样的开发文档都没有,都让大家来摸索?欢迎讨论!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34161032/article/details/85487718

智能推荐

Ubuntu 系统 安装完Nginx和php后 能打开html .php提示下载或者connect() failed (111: Connection refused) while connectin_unix:/run/php/php8.3-fpm.sock failed (111: unknown-程序员宅基地

文章浏览阅读175次。php 版本为7.11.vim www.conf保存退出 重启php2.配置Nginx服务器vim /etc/nginx/nginx.conf在http{}中末尾添加或者在引用服务器域名配置的文件夹下新建一个文件也行我不知道为什么用fastcgi_pass unix:/var/run/php/php7.1-fpm.sock这个不行 但是fastcgi_pass 127.0.0..._unix:/run/php/php8.3-fpm.sock failed (111: unknown error) while connecti

k8s-高可用部署-calico插件_calico-3.9.2.yaml-程序员宅基地

文章浏览阅读2.6k次。kubernetes高可用部署参考:Creating Highly Available Clusters with kubeadm | KubernetesGitHub - kubernetes-sigs/kubespray: Deploy a Production Ready Kubernetes ClusterGitHub - wise2c-devops/breeze: Deploy a Production Ready Kubernetes Cluster with graphical interfa_calico-3.9.2.yaml

java 爬虫 抓取关键字_爬虫任务二:爬取(用到htmlunit和jsoup)通过百度搜索引擎关键字搜取到的新闻标题和url,并保存在本地文件中(主体借鉴了网上的资料)...-程序员宅基地

文章浏览阅读760次。packagecom.zhaowu.renwu2;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.net.MalformedURLException;importjava.net.URL;import..._爬虫java 无url通过文字抓取内容

SQL Server修改数据-程序员宅基地

文章浏览阅读1.6w次,点赞2次,收藏22次。SQL Server 修改数据的相关语句

前端工程与性能优化-程序员宅基地

文章浏览阅读881次。前端工程与性能优化 · Issue #3 · fouber/blog https://github.com/fouber/blog/issues/3

yolov5测试单张图片-程序员宅基地

文章浏览阅读4.1k次,点赞2次,收藏20次。yolov5测试单张图片,返回一个列表[类别,置信度,x,y,w,h]from numpy import randomimport torchfrom models.experimental import attempt_loadfrom utils.datasets import LoadStreams, LoadImagesfrom utils.general import ( check_img_size, non_max_suppression, apply_classifier_yolov5测试单张图片

随便推点

UNITY中判断两个点之间距离的方法_unity 判断两个距离-程序员宅基地

文章浏览阅读3.1k次,点赞3次,收藏4次。Vector3.SqrMagnitude与Vector3.Distance_unity 判断两个距离

Idea设置未使用的方法,变量的提示颜色_idea 更改未使用变量的颜色-程序员宅基地

文章浏览阅读2.8w次,点赞6次,收藏14次。修改未被调用的变量,方法的提示,方便观赏代码_idea 更改未使用变量的颜色

在Linux系统下C语言编译过程的四个步骤_linux下编写一个c程序的基本过程分为几部分?-程序员宅基地

文章浏览阅读2.7k次,点赞7次,收藏23次。1. 简介C语言程序从源代码到可执行文件(二进制文件)都经历了那些过程?本文以Linux下C语言的编译过程为例,讲解C语言程序的编译过程。以hello.c文件为例:#include <stdio.h>int main(){ printf("hello world!\n");}在linux下编译C程序:$ gcc hello.c -o hello # 编译$ ./hello # 执行hello world! # 输出文本2. 编译的步骤gcc命令编译C语言的过程中_linux下编写一个c程序的基本过程分为几部分?

pyqt5界面开发-制作程序集合桌面-基本的框架_用pyqt做程序集合的界面-程序员宅基地

文章浏览阅读340次。pyqt5界面开发-制作多个小程序-基本的框架和思路最近现在无事,看到了电脑桌面,又想到了最近入门的pyqt5,再看看以往的程序,想到了可不可以做一个集成的UI桌面_用pyqt做程序集合的界面

对网站商城源码的研究分析 分享大量源码下载_chengren 电影-程序员宅基地

文章浏览阅读2k次。第一部分(1-6):前端纯静态网页模板无后台+大量网站设计素材 1:PC模板: 9900套响应式html5+css3网页模板【页面齐,二级,三级页均有,含中文模板】 2:PSD模板:3000套PSD模板+600套Flash酷站源文件+千套矢量ICO图标 3:手机模板:2000套各行业中文手机..._chengren 电影

ORA-39143: 转储文件 "F:\ora10G_expdp\ic_price_fromlufang.dmp" 可能是原始的导出转 储文件...-程序员宅基地

文章浏览阅读441次。连接到: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - ProductionWith the Partitioning, OLAP and Data Mining optionsORA-39001: 参数值无效ORA-39000: 转储文件说明错误ORA-39143: 转储文件 "F:\ora10G_expdp\ic_pri..._ora39143