首页 > 其他分享 >关于Gmap.Net在WPF中的运用笔记(二)地图标注及几种图形的绘制

关于Gmap.Net在WPF中的运用笔记(二)地图标注及几种图形的绘制

时间:2024-10-16 15:34:25浏览次数:9  
标签:PointLatLng Gmap public Lat new Net WPF Math 标注

通过第一篇,我们已经成功的加载了高德地图:https://www.cnblogs.com/zhouxiao123/p/18469933
现在,我们来往地图上加点东西。
Gmap.Net中,提供了标注类GmapMarker,通过创建标注,在将其添加到地图上,可以实现在地图上标点的功能。
准备一张地图标注图,推荐去阿里矢量图库选取,有不少免费的可用。
这里我用的图如下:image

现在我们新建一个标注
GMapMarker marker = new GMapMarker(new PointLatLng(lat,lng));
设置一下标注的属性,比如tag
marker.Tag = "Point";
和shape
这里我们新建一个方法用来调整标注图片

点击查看代码
public static Image CreatePinImage(GMapMarker marker)
{
    Image img = new Image();
    img.Tag = marker;
    img.Width = 32;
    img.Height = 32;

    if (_pinSrcImage == null)
    {
        //多个标注共用一个图像源,节省内存。
        _pinSrcImage = new BitmapImage(new Uri("pack://application:,,,/Images/Marker2.png"));
        _pinSrcImage.Freeze();
    }
    img.Source = _pinSrcImage;
    //鼠标热点位置
    marker.Offset = new Point(-img.Width / 2, -img.Height/10*9);
    return img;
}
需要说明的是,当我们不去设置鼠标热点位置时,图片的最中心点才是我们的坐标位置,只有设置了鼠标热点位置,才能准确的表示出标注指示的位置点。 标注现在创建好了,将其添加到地图即可 `mapControl.Markers.Add(marker);` 现在运行应该就可以看到标注了(推荐添加一个按钮,通过点击实现添加标注) GMapMarker的shape属性类型是UIElement,所以,如果我们需要自定义Marker,只需要针对shape属性进行开发即可,具体这里就不详细说明了 接下来是一些常用的图形的绘制方法

线

Gmap.Net提供的GMapRoute类来实现地图上画线的功能
GMapRoute route = new GMapRoute(LineOrPolygon);
LineOrPolygon是一个经纬度坐标的List,同样,可以用过修改GMapRoute的Shape属性来修改线条的样式
添加到地图上
mapControl.Markers.Add(marker);

多边形

Gmap.Net提供的GMapPolygon类来实现地图上画多边形的功能
GMapPolygon mapPolygon = new GMapPolygon(LineOrPolygon);
一样的添加到地图上即可

矩形

Gmap.Net没有提供现成的矩形类,但是矩形其实就是特殊的多边形,所以我们可以直接使用GMapPolygon来实现,当然,最好封装一下。

点击查看代码
public class GMapMarkerRectangle : GMapPolygon
{
    public PointLatLng StartLatLng;
    public PointLatLng EndLatLng;
    public GMapMarkerRectangle(PointLatLng StartLatLng, PointLatLng EndLatLng) : base(GetRectanglePoints(StartLatLng, EndLatLng))
    {
        Tag = "Rectangle";
    }

    private static List<PointLatLng> GetRectanglePoints(PointLatLng StartLatLng, PointLatLng EndLatLng)
    {
        List<PointLatLng> points = new List<PointLatLng>();
        // 确定左上角点和右下角点
        PointLatLng topLeft = new PointLatLng(Math.Min(StartLatLng.Lat, EndLatLng.Lat), Math.Min(StartLatLng.Lng, EndLatLng.Lng));
        PointLatLng bottomRight = new PointLatLng(Math.Max(StartLatLng.Lat, EndLatLng.Lat), Math.Max(StartLatLng.Lng, EndLatLng.Lng));
        points.Add(StartLatLng);
        points.Add(topLeft);
        points.Add(EndLatLng);
        points.Add(bottomRight);
        return points;
    }
}
上面实现了一个Gmap地图矩形类,方法就是通过传入一对对角的坐标,推算出四个点的坐标,再将其顺序放入List中,再生成一个多边形。至于为啥传的是对角坐标,主要是配合鼠标事件实现鼠标拖动画矩形。 以此类推,只有能确定图形的顶点坐标位置,就可以通过GMapPolygon画出来,这就考验大家的数学知识储备了。 #圆 对于圆形的绘制,有几种差异很大方法,这里还是举例用继承GMapPolygon的方法。 实现圆形类
点击查看代码
 public class GmapCirclePolygon : GMapPolygon
 {
     private const int PointsCount = 100; // 圆周上点的数量

     public System.Windows.Media.Color StrokeColor { get; set; }
     public float StrokeWidth { get; set; }

     public GmapCirclePolygon(PointLatLng center, PointLatLng edgePoint, System.Windows.Media.Color strokeColor, float strokeWidth)
         : base(CreateCirclePoints(center, edgePoint))
     {
         StrokeColor = strokeColor;
         StrokeWidth = strokeWidth;
         Tag = "Circle";
         Initialize();
     }

     private void Initialize()
     {
         // 设置线条颜色和宽度
         this.StrokeColor = StrokeColor;
         this.StrokeWidth = StrokeWidth;
     }

     private static List<PointLatLng> CreateCirclePoints(PointLatLng center, PointLatLng edgePoint)
     {
         // 计算圆的半径(单位:米)
         double radius = CalculateDistance(center, edgePoint);

         List<PointLatLng> points = new List<PointLatLng>();
         for (int i = 0; i < PointsCount; i++)
         {
             double angle = 2 * Math.PI * i / PointsCount;
             double latitude = center.Lat + (radius / 111320) * Math.Cos(angle);
             double longitude = center.Lng + (radius / (111320 * Math.Cos(center.Lat * Math.PI / 180))) * Math.Sin(angle);
             points.Add(new PointLatLng(latitude, longitude));
         }

         return points;
     }

     private static double CalculateDistance(PointLatLng point1, PointLatLng point2)
     {
         // 使用 Haversine 公式计算两点之间的距离(单位:米)
         var R = 6371000; // 地球半径(米)
         var lat1 = point1.Lat * Math.PI / 180;
         var lat2 = point2.Lat * Math.PI / 180;
         var deltaLat = (point2.Lat - point1.Lat) * Math.PI / 180;
         var deltaLon = (point2.Lng - point1.Lng) * Math.PI / 180;

         var a = Math.Sin(deltaLat / 2) * Math.Sin(deltaLat / 2) +
                 Math.Cos(lat1) * Math.Cos(lat2) *
                 Math.Sin(deltaLon / 2) * Math.Sin(deltaLon / 2);
         var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));

         return R * c; // 返回距离(米)
     }
}
构造函数参数解释如下 圆形点center 圆上任意一点edgePoint 圆的颜色和线条粗细。 实现原理,就是确定圆心和圆上一点后,通过公式计算得到半径,再通过公式,根据需要的数量获取圆上均匀弧度的点,最后得到一组坐标点,生成的多边形近似于圆,理论上点越多,越接近圆。这样的好处是,画出的圆可以跟随地图缩放而缩放,不用再额外考虑缩放问题。 好了,关于标注和图形相关的就简单说到这里,下一篇介绍地图导航,轨迹动画,标注闪烁等实现

标签:PointLatLng,Gmap,public,Lat,new,Net,WPF,Math,标注
From: https://www.cnblogs.com/zhouxiao123/p/18470087

相关文章

  • 使用宝塔面板一键部署.NET Core
    都2024年了,搜了一下网上关于在宝塔上部署.netCore项目的,基本还是五六年前那一套: supervisor守护进程启动项目+ 新增静态站点+手动配置反向代理全套下来也挺麻烦的........前几天在一台闲置主机上安装了个宝塔面板版本是:9.0  发现网站选项里多了很多选项,万恶的是居......
  • 关于Gmap.Net在WPF中的运用笔记(一)初步加载高德地图
    一、前言最近公司需要开发一个车辆在途轨迹追踪的软件,结合现有系统和技术体系,最终敲定使用WPF+Gmap.Net来实现,这里将一些坑踩一下,做个笔记记录一下。二、项目搭建本项目基于.Net6.0+Gmap.Net.Core+Gmap.Net.WinPresentation,前面是用到的框架版本,后面则是需要用到的地图包,可通......
  • 我被 .NET8 JIT 的一个BUG反复折磨了半年之久
    很久很久没有写过博客了,正好最近园子又挣得一线生机,必须得凑个热闹水一篇.事情是这样的,在今年的早些时候,把公司的一部分api服务器的.net版本从6升级到了8,毕竟6马上就是EOL了(.NET6TLS到2024年11月12日).没成想在升级完的3个月后竟然触发了一个.NET8runtimeJIT的B......
  • (系列七).net8 Aop切面编程
    说明  该文章是属于OverallAuth2.0系列文章,每周更新一篇该系列文章(从0到1完成系统开发)。   该系统文章,我会尽量说的非常详细,做到不管新手、老手都能看懂。   说明:OverallAuth2.0是一个简单、易懂、功能强大的权限+可视化流程管理系统。友情提醒:本篇文章是属于系......
  • Netflow配置开启
    router:ipflow-exportsourcelo1ipflow-exportversion5ipflow-exportdestination172.29.8.569996interfaceg0/0/0ipflowingressipflowegressinterfaceg0/0/1ipflowingressipflowegressASA:flow-exportdestinationDMZ172.29.12.1209996access-list......
  • 神经网络之卷积篇:详解残差网络为什么有用?(Why ResNets work?)
    详解残差网络为什么有用?为什么ResNets能有如此好的表现,来看个例子,它解释了其中的原因,至少可以说明,如何构建更深层次的ResNets网络的同时还不降低它们在训练集上的效率。通常来讲,网络在训练集上表现好,才能在Hold-Out交叉验证集或dev集和测试集上有好的表现,所以至少在训练集上训练......
  • R语言使用caret包构建神经网络模型(Neural Network )构建回归模型实战、通过method参数
    R语言使用caret包构建神经网络模型(NeuralNetwork )构建回归模型实战、通过method参数指定算法名称目录R语言使用caret包构建神经网络模型(NeuralNetwork )构建回归模型、通过method参数指定算法名称 #导入包和库#仿真数据#R语言使用caret包构建随机森林模型(randomfore......
  • 【K8s】专题十四(2):Kubernetes 安全机制之 Security Context
    本文内容均来自个人笔记并重新梳理,如有错误欢迎指正!如果对您有帮助,烦请点赞、关注、转发、订阅专栏!专栏订阅入口| 精选文章 | Kubernetes |Docker |Linux |羊毛资源 | 工具推荐 |往期精彩文章【Docker】(全网首发)KylinV10下MySQL容器内存占用异常的解决......
  • 界面组件DevExpress WPF v24.1亮点 - 支持全新的字体图标图像
    DevExpressWPF拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpressWPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。DevExpressWPF控件日前正式发布了今年一个重大版......
  • 吴恩达深度学习笔记:卷积神经网络(Foundations of Convolutional Neural Networks)3.5-3.
    目录第四门课卷积神经网络(ConvolutionalNeuralNetworks)第三周目标检测(Objectdetection)3.5BoundingBox预测(Boundingboxpredictions)3.6交并比(Intersectionoverunion)第四门课卷积神经网络(ConvolutionalNeuralNetworks)第三周目标检测(Objectdetection......