【问题标题】:Updating GMap.NET Marker Image in C#在 C# 中更新 GMap.NET 标记图像
【发布时间】:2017-02-18 16:06:24
【问题描述】:

我可以改变我的标记位置

markers.Markers[2].Position = new PointLatLng(30.0000, 30.00000);

但是我如何通过设置上面的变量来更改标记图标? 我将积分声明为

GMap.NET.WindowsForms.GMapMarker marker3 =
                new GMap.NET.WindowsForms.Markers.GMarkerGoogle(
                    new GMap.NET.PointLatLng(30.0000, 30.00000),
                    new Bitmap("images/2.png"));

谢谢...

【问题讨论】:

  • 当我像上面那样声明一个变量时,我可以像marker3[index] = new Bitmap("images/2.png");一样再次到达一个标记变量吗???
  • 否,因为您不能将图像分配给标记,因为图像是标记的属性。

标签: c# winforms google-maps google-maps-api-3 gmap.net


【解决方案1】:

为了解决这个问题,我联系了图书馆的创建者:radioman。 他提到了一些名为“GMarkerArrow”的代码。代码如下:

namespace Demo.WindowsForms.CustomMarkers
{
    using System;
    using System.Drawing;
    using System.Runtime.Serialization;
    using GMap.NET;
    using GMap.NET.WindowsForms;

    [Serializable]
    public class GMarkerArrow : GMapMarker, ISerializable
    {
        [NonSerialized]
        public Brush Fill = new SolidBrush(Color.FromArgb(155, Color.Blue));

        //[NonSerialized]
        //public Pen Pen = new Pen(Brushes.Blue, 5);

        static readonly Point[] Arrow = new Point[] { new Point(-7, 7), new Point(0, -22), new Point(7, 7), new Point(0, 2) };

        public float Bearing = 0;
        private float scale = 1;

        public float Scale
        {
            get
            {
                return scale;
            }
            set
            {
                scale = value;

                Size = new System.Drawing.Size((int)(14 * scale), (int)(14 * scale));
                Offset = new System.Drawing.Point(-Size.Width / 2, (int)(-Size.Height / 1.4));
            }
        }

        public GMarkerArrow(PointLatLng p)
           : base(p)
        {
            Scale = (float)1.4;
        }

        public override void OnRender(Graphics g)
        {
            //g.DrawRectangle(Pen, new System.Drawing.Rectangle(LocalPosition.X, LocalPosition.Y, Size.Width, Size.Height));
            {
                g.TranslateTransform(ToolTipPosition.X, ToolTipPosition.Y);
                var c = g.BeginContainer();
                {
                    g.RotateTransform(Bearing - Overlay.Control.Bearing);
                    g.ScaleTransform(Scale, Scale);

                    g.FillPolygon(Fill, Arrow);
                }
                g.EndContainer(c);
                g.TranslateTransform(-ToolTipPosition.X, -ToolTipPosition.Y);
            }
        }

        public override void Dispose()
        {
            //if(Pen != null)
            //{
            //   Pen.Dispose();
            //   Pen = null;
            //}

            if (Fill != null)
            {
                Fill.Dispose();
                Fill = null;
            }

            base.Dispose();
        }

        #region ISerializable Members

        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            base.GetObjectData(info, context);
        }

        protected GMarkerArrow(SerializationInfo info, StreamingContext context)
           : base(info, context)
        {
        }

        #endregion
    }
}

将其保存为 GMarkerArrow.cs 并将其添加到您的项目中。 将此添加到您的 Form1 代码中:

using Demo.WindowsForms.CustomMarkers;

现在您可以通过以下方式使用新标记:

GMarkerArrow marker1 = new GMarkerArrow(new PointLatLng(-30, -40));
            marker1.ToolTipText = "blablabla";
            marker1.ToolTip.Fill = Brushes.Black;
            marker1.ToolTip.Foreground = Brushes.White;
            marker1.ToolTip.Stroke = Pens.Black;
            marker1.Bearing = 30; // Rotation angle
            marker1.Fill = new SolidBrush(Color.FromArgb(155, Color.Blue)); // Arrow color
            markers.Markers.Add(marker1);
            gMapControl1.Overlays.Add(markers);

我还要感谢@rdoubleui,谢谢先生。 我希望这对每个人都有帮助。

【讨论】:

    【解决方案2】:

    更新该标记的图像的问题是 Image 属性不可公开访问,因此您不能以这种方式更新图像。

    有两种可能性:第一种是用新的标记参考替换标记参考,让您有机会设置新图像并复制当前标记的位置。但是,这不是干净的方式,因为您不必要地创建一大堆引用,只是为了根据用例立即处理它们。如果是一次性更新,那么这种方法就可以了。

    最好的方法是从GMapMarker 派生,就像 Google 标记所做的那样(您可以将其用作模板,而忽略整个 google 特定的图标逻辑)。你熟悉推导的概念吗?这将需要更多的努力,但值得,可以对此有所帮助。

    您的主要参考可能是project's github page

    编辑

    using System.Drawing;
    
    public class GImageMarker : GMapMarker
    {
        public Bitmap Bitmap { get; set; }
    
        public GImageMarker(PointLatLng p, Bitmap Bitmap)
            : base(p)
        {
            this.Bitmap = Bitmap;
            Size = new System.Drawing.Size(Bitmap.Width, Bitmap.Height);
            Offset = new Point(-Size.Width / 2, -Size.Height);
        }
    
        public override void OnRender(Graphics g)
        {
             g.DrawImage(Bitmap, LocalPosition.X, LocalPosition.Y, Size.Width, Size.Height);
        }
    }
    

    【讨论】:

    • 我再次用新图像声明标记,但我不喜欢这种方式。我不太了解 c#,所以我不想弄乱 GMap.NET 库:D
    • 没关系,你不会搞砸任何事情 :) 通过派生你可以扩展标记的功能。该扩展程序只会存在于您的代码中,一旦我回到电脑前,我可以提供一个示例。
    • 添加了一个包含图像的派生标记的最小示例,请将此类添加到您的项目中并尝试是否适合您。
    • 这对您有帮助吗?
    • 嗨@rdoubleui。对不起,迟到的评论。我太忙了。我尝试了您的代码,但您使用了您未提及的“DrawImageUnscaled”。我将其注释掉,但是当我到达我的标记为“markers.Markers[2]”时。没有“GImageMarker”这样的东西。我很抱歉这可能是我的坏事。我将为此努力。谢谢你的回答:)
    【解决方案3】:

    GMapOverlay 标记Overlay;

        private void AddOrUpdateMarker(string tag, double lat, double lng, Image NewImage)
        {
    
            Bitmap bmpmarker = (Bitmap)NewImage;
    
            var marker = markersOverlay.Markers.FirstOrDefault(m => m.Tag == tag);
    
            if(marker!=null)
            {
                markersOverlay.Markers.Remove(marker);
                gMapControl1.Refresh();
                marker = new GMarkerGoogle(new PointLatLng(lat, lng), bmpmarker);
                marker.Tag = tag;
                markersOverlay.Markers.Add(marker);
                gMapControl1.Refresh();
            }
            else
            {
                marker = new GMarkerGoogle(new PointLatLng(lat, lng), bmpmarker);
                marker.Tag = tag;
                markersOverlay.Markers.Add(marker);
                gMapControl1.Refresh();
            }
    
    
        }
    

    【讨论】:

    • 什么是标记覆盖你没有描述它是什么
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多