GMap 自定义Marker以及规则图形的绘制

    xiaoxiao2024-03-29  6

    前言

    之前写了GMap GMapOverlay类的简单使用,主要介绍了Markers,Routes和Polygons,关于Route和Polygon不再做过多赘述,这里介绍一下,怎样自定义Marker

    新建工程

    新建winform工程,添加Gmap的引用(不会的请自行百度),在Form1的构造函数中添加对GMap对象的初始化代码:

    this.gMapControl1.CacheLocation = System.Windows.Forms.Application.StartupPath; this.gMapControl1.MapProvider = GMapProviders.BingHybridMap; this.gMapControl1.Manager.Mode = AccessMode.ServerAndCache; this.gMapControl1.MinZoom = 1;//最小比例 this.gMapControl1.MaxZoom = 23; //最大比例 this.gMapControl1.Zoom = 15; //当前比例 this.gMapControl1.ShowCenter = false;//不显示中心十字点 this.gMapControl1.DragButton = System.Windows.Forms.MouseButtons.Left; //左键拖拽地图 this.gMapControl1.Position = new PointLatLng(23, 113); this.gMapControl1.Overlays.Add(overlay); this.gMapControl1.MouseClick += gMapControl1_MouseClick;

    这里笔者新建的工程名为:RulesOfTheGraphics

    自定义Marker

    在上一篇博客中我写过怎么使用Marker但是仅仅只介绍了怎么使用GMap自带的Marker图标,这里介绍一下怎么自定义Marker图标。

    我们在鼠标点击事件的触发函数中首先需要获取位置信息,然后我们开始自定义绘制Marker图标,我在上一节介绍Marker的使用时,使用的是GMarker的子类GMarkerGoogle创建的Marker对象,细心的童鞋就会发现GMarkerGoogle有一个带两个参数的构造函数,第一个PointLatLng类型的参数毫无疑问的是用来表明Marker在地图上的位置,第二个参数是一个Bitmap类型的对象,这里很明显就可以使用这个Bitmap参数来构造自定义的Marker了,所以我们首先需要提供一个用来表示Marker图标的Bitmap对象。笔者比较懒,所以就做一个黑色的长宽为50的矩形(至于Bitmap上怎么绘制图形,请百度)。然后构造Marker对象,添加到我们的overlay图层中去。

    PointLatLng p= gMapControl1.FromLocalToLatLng(e.X, e.Y); Bitmap bitmap = new Bitmap(50,50); Graphics g = Graphics.FromImage(bitmap); g.Clear(Color.Black); GMapMarker marker = new GMarkerGoogle(p, bitmap); this.overlay.Markers.Add(marker);

    点击地图我们可以看到会在鼠标点击的地方创建黑色的矩形。地图上的点对应到矩形最下边界的中点。

    规则图形

    上一次介绍过GMapOverlay之后,一直想在地图上,实现类似画板的可以使用鼠标实现规则图形的绘制。这里笔者描述绘制鼠标拖动绘制矩形的圆的方法。

    首先我们要捕获GMap的鼠标按下事件,鼠标移动事件以及鼠标抬起事件。这样我们在鼠标按下时开始绘制,鼠标移动时指定绘制区域,鼠标抬起时结束绘制。所以我们先声明一个布尔类型来区分鼠标是否按下,按下时为true,抬起时为false,并在鼠标按下时记录鼠标按下的位置。需要注意的是在鼠标移动事件中计算几何图形的边界点时,如果此时是可以鼠标拖拽地图的话,那么在我们鼠标按下之后地图会跟着我们的鼠标开始移动,所以我们在鼠标移动事件中永远得到的就是我们按下时的经纬度坐标点,所以我们在绘制规则图形时,需要禁止鼠标拖拽地图。

    bool mousepressflag = false;

    绘制矩形

    如果我们要绘制矩形,那么就在鼠标移动事件中结合鼠标按下位置通过数学分析将矩形的四个角的经纬度坐标,换算出来四个角的坐标之后利用GMapOverlay的Polygons进行坐标点的绘制。

    void DrawRectangleCenter() { overlay.Polygons.Clear(); list.Clear(); if (nowpoint.Lat < presspoint.Lat){ if (nowpoint.Lng < presspoint.Lng){ double lat = presspoint.Lat - nowpoint.Lat; double lng = presspoint.Lng - nowpoint.Lng; list.Add(new PointLatLng(presspoint.Lat+lat, nowpoint.Lng)); list.Add(new PointLatLng(presspoint.Lat+lat,presspoint.Lng+lng)); list.Add(new PointLatLng(nowpoint.Lat, presspoint.Lng+lng)); list.Add(nowpoint); } else{ double lat = presspoint.Lat - nowpoint.Lat; double lng = -1*presspoint.Lng + nowpoint.Lng; list.Add(new PointLatLng(presspoint.Lat+lat,presspoint.Lng-lng)); list.Add(new PointLatLng(presspoint.Lat+lat, nowpoint.Lng)); list.Add(nowpoint); list.Add(new PointLatLng(nowpoint.Lat, presspoint.Lng-lng)); } }else{ if (nowpoint.Lng < presspoint.Lng){ double lat = -1*presspoint.Lat + nowpoint.Lat; double lng = presspoint.Lng - nowpoint.Lng; list.Add(nowpoint); list.Add(new PointLatLng(nowpoint.Lat, presspoint.Lng+lng)); list.Add(new PointLatLng(presspoint.Lat-lat,presspoint.Lng+lng)); list.Add(new PointLatLng(presspoint.Lat-lat, nowpoint.Lng)); }else { double lat = -1* presspoint.Lat + nowpoint.Lat; double lng = -1*presspoint.Lng + nowpoint.Lng; list.Add(new PointLatLng(nowpoint.Lat, presspoint.Lng-lng)); list.Add(nowpoint); list.Add(new PointLatLng(presspoint.Lat-lat, nowpoint.Lng)); list.Add(new PointLatLng(presspoint.Lat-lat,presspoint.Lng-lng)); } } GMapPolygon polygon = new GMapPolygon(list, "多边形"); polygon.Fill = new SolidBrush(Color.FromArgb(50, Color.Red)); polygon.Stroke = new Pen(Color.Blue, 2); polygon.IsHitTestVisible = true; overlay.Polygons.Add(polygon); }

    上述的代码笔者采用的是比较笨的做法,但是我们可以通过这种方式使用鼠标拖动绘制矩形了,这里是以鼠标按下点作为矩形中心点,移动点作为四个角中的某一点进行绘制。

    绘制椭圆形

    圆形不同于矩形的绘制,矩形是具有固定顶点数量的,而圆形的顶点,我们如果通过微分的方式来做的话,会很麻烦,那么这里使用Marker来进行圆形的绘制。Marker的绘制其实是使原本自定义的Bitmap背景透明然后在Bitmap上绘制椭圆形。

    void DrawCircleRadius() { this.overlay.Markers.Clear(); GPoint pnow = this.gMapControl1.FromLatLngToLocal(nowpoint); GPoint ppress = this.gMapControl1.FromLatLngToLocal(presspoint); double width = Math.Abs(pnow.X - ppress.X); double height = Math.Abs(pnow.Y - ppress.Y); if (width < 10 || height < 10) return; Bitmap BitmapMarker = new Bitmap((int)width, (int)height); Graphics GraphicsMarker = Graphics.FromImage(BitmapMarker); GraphicsMarker.Clear(Color.Transparent); GraphicsMarker.DrawEllipse(new Pen(Color.Red,2), new Rectangle(0, 0, BitmapMarker.Width-1, BitmapMarker.Height-1)); PointLatLng p = this.gMapControl1.FromLocalToLatLng((int)(pnow.X + ppress.X) / 2, (int)(pnow.Y>ppress.Y ? pnow.Y:ppress.Y)); GMapMarker marker = new GMarkerGoogle(p, BitmapMarker); this.overlay.Markers.Add(marker); }

    需要注意的地方是使用FromLatLngToLocal将经纬度坐标转换为像素点坐标,创建对应长宽的Bitmap对象,绘制效果如下:

    最后附上代码http://download.csdn.net/detail/yuanquanzheng/9601719

    转载请注明原文地址: https://ju.6miu.com/read-1287438.html
    最新回复(0)