我有一个自定义的GMapMarker类绘制一个简单的图像来映射...如何使该图像在500毫秒的间隔内改变其属性(假设闪烁)?
使用GMapControl.Invalidate()将重绘我的标记和整个地图!这将导致不受管制的闪烁,因为每次更改map属性时都会调用OnRedraw()方法! (当地图处于空闲状态时,不会调用此方法!)
我的解决方案需要在我的示例中使用内部Timer,但不知道如何从Timer经过时间的功能中重绘我的图像。
namespace GMap.NET.WindowsForms.Markers {
public class GMarkerNode : GMapMarker {
public Image Image { get; set; }
private Timer Timer;
public GMarkerNode(PointLatLng p) : base(p)
{
Timer = new Timer()
{
AutoReset = true,
Interval = 500
};
Timer.Elapsed += Timer_Elapsed;
Timer.Start();
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
// How to triger OnRender or invalidate marker graphics?
}
public override void OnRender(Graphics g)
{
g.DrawImage(Image, LocalPosition);
}
public override void Dispose()
{
base.Dispose();
}
}
}
答案 0 :(得分:0)
您不需要在Marker类中直接使用计时器,因为它处理GDI,它在每次地图交互时从OnRender方法渲染标记图像。
因此,您可以从Marker类中删除计时器,并从放置GMapControl的Main表单中设置标记的image属性。
我为您创建了一个演示项目,演示了我的答案: 注意:使用的图像是我从谷歌获得的,所以你可以使用任何图像,或者你可以使用2张图像(黑色,白色)并在它们之间交换以产生闪烁效果。
您可以从以下链接免费下载演示项目:
<强> Download Demo Project 强>
<强> GMarkerNode.vb:强>
Imports GMap.NET
Imports GMap.NET.WindowsForms
Public Class GMarkerNode
Inherits GMapMarker
Public Property Image() As Image
Public Sub New(ByVal p As PointLatLng, ByVal image1 As Image)
MyBase.New(p)
Me.Image=image1
End Sub
Public Overrides Sub OnRender(ByVal g As Graphics)
if me.Image IsNot Nothing Then
g.DrawImage(me.Image, LocalPosition)
End If
End Sub
Public Overrides Sub Dispose()
MyBase.Dispose()
End Sub
End Class
<强> Form1.vb的:强>
Imports System.IO
Imports GMap.NET
Imports GMap.NET.MapProviders
Imports GMap.NET.WindowsForms
Public Class Form1
Private m_Index As Integer=1
Private m_ImagePath As String=""
Private m_ActiveMarker As GMarkerNode
Private m_ActiveImage As Image
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
with GMapControl1
.Manager.Mode = AccessMode.ServerAndCache
.CacheLocation = Path.Combine(Application.StartupPath,"cache")
.MapProvider = GMapProviders.OpenStreetMap
.Position = new PointLatLng(30.050578, 31.223027)
.Zoom = 15
.Overlays.Add(new GMapOverlay("markersOverlay"))
.Overlays(0).Markers.Add(new GMarkerNode(.Position,Pic.Image))
End With
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Timer1.Enabled=Not Timer1.Enabled
Timer1.Interval= Math.Abs(CInt(IIf(IsNumeric(txtInterval.Text), txtInterval.Text,500)))
If Timer1.Enabled Then
Button1.Text="Stop"
else
Button1.Text="Start"
End If
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
m_ImagePath = Path.Combine(Application.StartupPath,"images",String.Format("black{0:D2}.png",m_Index))
if File.Exists(m_ImagePath) Then
m_ActiveImage = Image.FromFile(m_ImagePath)
Pic.Image =m_ActiveImage
' Update the marker image
m_ActiveMarker = GMapControl1.Overlays(0).Markers(0)
m_ActiveMarker.Image = Pic.Image
' Update the marker in the overlay
GMapControl1.Overlays(0).Markers(0) = m_ActiveMarker
End If
If m_Index<100 Then
m_Index += 1
Else
m_Index = 1
End If
End Sub
End Class
<强> Form1.Designer.vb:强>
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
Inherits System.Windows.Forms.Form
'Form overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container()
Me.GMapControl1 = New GMap.NET.WindowsForms.GMapControl()
Me.SplitContainer1 = New System.Windows.Forms.SplitContainer()
Me.Label2 = New System.Windows.Forms.Label()
Me.Pic = New System.Windows.Forms.PictureBox()
Me.Label1 = New System.Windows.Forms.Label()
Me.txtInterval = New System.Windows.Forms.TextBox()
Me.Button1 = New System.Windows.Forms.Button()
Me.Timer1 = New System.Windows.Forms.Timer(Me.components)
CType(Me.SplitContainer1,System.ComponentModel.ISupportInitialize).BeginInit
Me.SplitContainer1.Panel1.SuspendLayout
Me.SplitContainer1.Panel2.SuspendLayout
Me.SplitContainer1.SuspendLayout
CType(Me.Pic,System.ComponentModel.ISupportInitialize).BeginInit
Me.SuspendLayout
'
'GMapControl1
'
Me.GMapControl1.Bearing = 0!
Me.GMapControl1.CanDragMap = true
Me.GMapControl1.Dock = System.Windows.Forms.DockStyle.Fill
Me.GMapControl1.EmptyTileColor = System.Drawing.Color.Navy
Me.GMapControl1.GrayScaleMode = false
Me.GMapControl1.HelperLineOption = GMap.NET.WindowsForms.HelperLineOptions.DontShow
Me.GMapControl1.LevelsKeepInMemmory = 5
Me.GMapControl1.Location = New System.Drawing.Point(0, 0)
Me.GMapControl1.MarkersEnabled = true
Me.GMapControl1.MaxZoom = 20
Me.GMapControl1.MinZoom = 2
Me.GMapControl1.MouseWheelZoomEnabled = true
Me.GMapControl1.MouseWheelZoomType = GMap.NET.MouseWheelZoomType.MousePositionAndCenter
Me.GMapControl1.Name = "GMapControl1"
Me.GMapControl1.NegativeMode = false
Me.GMapControl1.PolygonsEnabled = true
Me.GMapControl1.RetryLoadTile = 0
Me.GMapControl1.RoutesEnabled = true
Me.GMapControl1.ScaleMode = GMap.NET.WindowsForms.ScaleModes.[Integer]
Me.GMapControl1.SelectedAreaFillColor = System.Drawing.Color.FromArgb(CType(CType(33,Byte),Integer), CType(CType(65,Byte),Integer), CType(CType(105,Byte),Integer), CType(CType(225,Byte),Integer))
Me.GMapControl1.ShowTileGridLines = false
Me.GMapControl1.Size = New System.Drawing.Size(639, 556)
Me.GMapControl1.TabIndex = 0
Me.GMapControl1.Zoom = 0R
'
'SplitContainer1
'
Me.SplitContainer1.Dock = System.Windows.Forms.DockStyle.Fill
Me.SplitContainer1.Location = New System.Drawing.Point(0, 0)
Me.SplitContainer1.Name = "SplitContainer1"
'
'SplitContainer1.Panel1
'
Me.SplitContainer1.Panel1.Controls.Add(Me.Label2)
Me.SplitContainer1.Panel1.Controls.Add(Me.Pic)
Me.SplitContainer1.Panel1.Controls.Add(Me.Label1)
Me.SplitContainer1.Panel1.Controls.Add(Me.txtInterval)
Me.SplitContainer1.Panel1.Controls.Add(Me.Button1)
'
'SplitContainer1.Panel2
'
Me.SplitContainer1.Panel2.Controls.Add(Me.GMapControl1)
Me.SplitContainer1.Size = New System.Drawing.Size(816, 556)
Me.SplitContainer1.SplitterDistance = 173
Me.SplitContainer1.TabIndex = 1
'
'Label2
'
Me.Label2.AutoSize = true
Me.Label2.Location = New System.Drawing.Point(54, 31)
Me.Label2.Name = "Label2"
Me.Label2.Size = New System.Drawing.Size(70, 13)
Me.Label2.TabIndex = 4
Me.Label2.Text = "Active Image"
'
'Pic
'
Me.Pic.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
Me.Pic.Location = New System.Drawing.Point(52, 54)
Me.Pic.Name = "Pic"
Me.Pic.Size = New System.Drawing.Size(72, 65)
Me.Pic.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage
Me.Pic.TabIndex = 3
Me.Pic.TabStop = false
'
'Label1
'
Me.Label1.AutoSize = true
Me.Label1.Location = New System.Drawing.Point(21, 154)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(134, 13)
Me.Label1.TabIndex = 2
Me.Label1.Text = "Time Interval (miliseconds)"
'
'txtInterval
'
Me.txtInterval.Location = New System.Drawing.Point(45, 172)
Me.txtInterval.Name = "txtInterval"
Me.txtInterval.Size = New System.Drawing.Size(83, 20)
Me.txtInterval.TabIndex = 1
Me.txtInterval.Text = "500"
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(33, 211)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(107, 29)
Me.Button1.TabIndex = 0
Me.Button1.Text = "Start"
Me.Button1.UseVisualStyleBackColor = true
'
'Timer1
'
Me.Timer1.Interval = 1000
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6!, 13!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(816, 556)
Me.Controls.Add(Me.SplitContainer1)
Me.Name = "Form1"
Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
Me.Text = "Form1"
Me.SplitContainer1.Panel1.ResumeLayout(false)
Me.SplitContainer1.Panel1.PerformLayout
Me.SplitContainer1.Panel2.ResumeLayout(false)
CType(Me.SplitContainer1,System.ComponentModel.ISupportInitialize).EndInit
Me.SplitContainer1.ResumeLayout(false)
CType(Me.Pic,System.ComponentModel.ISupportInitialize).EndInit
Me.ResumeLayout(false)
End Sub
Friend WithEvents GMapControl1 As GMap.NET.WindowsForms.GMapControl
Friend WithEvents SplitContainer1 As SplitContainer
Friend WithEvents Label2 As Label
Friend WithEvents Pic As PictureBox
Friend WithEvents Label1 As Label
Friend WithEvents txtInterval As TextBox
Friend WithEvents Button1 As Button
Friend WithEvents Timer1 As Timer
End Class