如何为GMap.Net.WinForm路线描边自定义虚线样式并实现箭头路径?
在GMap.Net.WinForm中自定义路线并绘制箭头
首先明确:Custom DashStyle无法实现箭头绘制。DashStyle.Custom仅能通过DashPattern定义线条的虚实间隔(比如短划线、空白的循环序列),本质还是线性样式,无法生成箭头这类带有几何夹角的图形。
要在两点间绘制箭头,需要通过重写GMapRoute的绘制逻辑来实现,具体步骤如下:
1. 自定义带箭头的路线类
继承GMapRoute并重写OnRender方法,在基础路线绘制完成后,额外添加箭头的绘制逻辑:
using System.Collections.Generic; using System.Drawing; using System.Math; using GMap.NET.WindowsForms; public class ArrowRoute : GMapRoute { // 可调整箭头大小 public float ArrowSize { get; set; } = 10f; public ArrowRoute(List<PointLatLng> points, string name) : base(points, name) { } protected override void OnRender(Graphics g) { // 先绘制原始路线 base.OnRender(g); // 至少需要两个点才能绘制路径段 if (Points.Count < 2) return; // 遍历每一段路径,绘制箭头 for (int i = 0; i < Points.Count - 1; i++) { // 将经纬度转换为地图控件内的本地坐标 Point start = LocalPositionOf(Points[i]); Point end = LocalPositionOf(Points[i + 1]); // 计算路径的方向角度 float directionAngle = (float)Atan2(end.Y - start.Y, end.X - start.X); // 选择箭头位置(这里选路径中间,也可以改成end点) PointF arrowCenter = new PointF( start.X + (end.X - start.X) * 0.5f, start.Y + (end.Y - start.Y) * 0.5f ); // 计算箭头的两个分支端点 PointF arrowBranch1 = new PointF( arrowCenter.X - ArrowSize * (float)Cos(directionAngle - PI / 6), arrowCenter.Y - ArrowSize * (float)Sin(directionAngle - PI / 6) ); PointF arrowBranch2 = new PointF( arrowCenter.X - ArrowSize * (float)Cos(directionAngle + PI / 6), arrowCenter.Y - ArrowSize * (float)Sin(directionAngle + PI / 6) ); // 绘制箭头(使用与路线相同的画笔样式) using (Pen arrowPen = new Pen(Stroke.Color, Stroke.Width)) { g.DrawLine(arrowPen, arrowCenter, arrowBranch1); g.DrawLine(arrowPen, arrowCenter, arrowBranch2); } } } }
2. 在项目中使用自定义路线
替换原有的GMapRoute实例,使用ArrowRoute来创建带箭头的路线:
// 准备路线的经纬度点列表 List<PointLatLng> routePoints = new List<PointLatLng> { new PointLatLng(39.9042, 116.4074), // 示例点:北京 new PointLatLng(31.2304, 121.4737) // 示例点:上海 }; // 创建带箭头的路线 var arrowRoute = new ArrowRoute(routePoints, "Arrow Route"); arrowRoute.Stroke = new Pen(Color.Red, 3); arrowRoute.ArrowSize = 12f; // 根据需求调整箭头大小 // 将路线添加到地图控件 gMapControl1.Markers.Add(arrowRoute);
额外说明
- 你可以修改箭头的位置逻辑(比如把箭头放在路径末端而不是中间),只需要调整
arrowCenter的计算方式即可。 - 如果需要更复杂的箭头样式(比如填充实心箭头),可以使用
Graphics.FillPolygon方法替换DrawLine,绘制三角形填充区域。
内容的提问来源于stack exchange,提问作者Javad-M
相关产品推荐
相关产品推荐

