GMap.NET开发技巧(三)-如何拖拽地图图元和图标
2012年10月7日
分类: GPS系统
GMap.NET上的地标图元的拖拽其实很简单,思路和正常的WInform控件拖拽是一样的,无非是在鼠标事件当中,记录下操作的状态,通过mapcontrol的Invalidate刷新重绘整个画布,造成一种拖拽的效果。
以下代码,以拖拽一个多边形Polygon图元为例。
增加一个变量IsMouseOverPolygon,表示鼠标经过多边形。
PointLatLng lastDragPolygon = PointLatLng.Empty; // 保存上一次鼠标的坐标位置。
Cursor cursorDragBefore = Cursors.Default; //上一次鼠标的位置.
List<GMapPolygon> movingPolygons = new List<GMapPolygon>();
GMap.NET.WindowsForms.GMapControl.OnMouseDown:
protected override void OnMouseDown(MouseEventArgs e)
{
if(!IsMouseOverMarker && (!CanDragPolygon || !IsMouseOverPolygon))//如果不能拖拽图元,就拖拽整个地图,这样不会因为拖拽图元影响拖拽地图的操作。
{
#if !PocketPC
if(e.Button == DragButton && CanDragMap)
#else
if (CanDragMap)
#endif
{
#if !PocketPC
Core.mouseDown = ApplyRotationInversion(e.X, e.Y);
#else
Core.mouseDown = new GPoint(e.X, e.Y);
#endif
this.Invalidate();
}
else if(!isSelected && !DisableSelectArea)
{
isSelected = true;
SelectedArea = RectLatLng.Empty;
selectionEnd = PointLatLng.Empty;
selectionStart = FromLocalToLatLng(e.X, e.Y);
}
}
else if ( CanDragPolygon && IsMouseOverPolygon )//确定可以拖拽的条件
{
lastDragPolygon = FromLocalToLatLng(e.X, e.Y);//标记开始拖拽的起始点
cursorDragBefore = this.Cursor;//保存光标位置
this.Cursor = Cursors.SizeAll;//改变形状
}
base.OnMouseDown(e);
}
GMap.NET.WindowsForms.GMapControl.OnMouseUp:
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if(isSelected)
{
isSelected = false;
}
//clans every polygon used variable to maintain normal behaviour
if ( !lastDragPolygon.IsEmpty )
{
lastDragPolygon = PointLatLng.Empty;
this.Cursor = cursorDragBefore;
movingPolygons.Clear();
}
if(Core.IsDragging)
{
if(isDragging)
{
isDragging = false;
Debug.WriteLine("IsDragging = " + isDragging);
#if !PocketPC
this.Cursor = cursorBefore;
cursorBefore = null;
#endif
}
Core.EndDrag();
if(BoundsOfMap.HasValue && !BoundsOfMap.Value.Contains(Position))
{
if(Core.LastLocationInBounds.HasValue)
{
Position = Core.LastLocationInBounds.Value;
}
}
}
else
{
#if !PocketPC
if(e.Button == DragButton)
{
Core.mouseDown = GPoint.Empty;
}
if(!selectionEnd.IsEmpty && !selectionStart.IsEmpty)
{
if(!SelectedArea.IsEmpty && Form.ModifierKeys == Keys.Shift)
{
SetZoomToFitRect(SelectedArea);
}
}
else
{
Invalidate();
}
#endif
}
}
GMap.NET.WindowsForms.GMapControl.OnMouseMove:
protected override void OnMouseMove(MouseEventArgs e)
{
if(!Core.IsDragging && !Core.mouseDown.IsEmpty && lastDragPolygon.IsEmpty) //let drag the map if the lastPolygon wasn't set
{
GPoint p = new GPoint(e.X, e.Y);
if(Math.Abs(p.X - Core.mouseDown.X) * 2 >= DragSize.Width || Math.Abs(p.Y - Core.mouseDown.Y) * 2 >= DragSize.Height)
{
Core.BeginDrag(Core.mouseDown);
}
}
else if ( !lastDragPolygon.IsEmpty )
{
//就开始添加鼠标经过的多边形
if(movingPolygons.Count == 0)
{
//
foreach (GMapOverlay layer in Overlays)
{
//and through the polygons
foreach ( GMapPolygon poly in layer.Polygons )
{
if ( poly.IsMouseOver )
{
movingPolygons.Add( poly );
}
}
}
}
//
PointLatLng mouse = FromLocalToLatLng( e.X, e.Y );
List<PointLatLng> points;
//循环要移动的多边形
foreach ( GMapPolygon poly in movingPolygons )
{
//保存多边形的坐标点
points = new List<PointLatLng>( poly.Points );
//clears the original, so we can put new values to them
poly.Points.Clear();
//and chage every point
foreach (PointLatLng point in points)
{
//移动图元到当前的位置
point.Offset( -(mouse.Lat - lastDragPolygon.Lat), mouse.Lng - lastDragPolygon.Lng );
poly.Points.Add( point );
}
//更新多边形的位置
this.UpdatePolygonLocalPosition( poly );
}
lastDragPolygon = mouse;
base.Invalidate();
}
if(Core.IsDragging)
{
if(!isDragging)
{
isDragging = true;
Debug.WriteLine("IsDragging = " + isDragging);
#if !PocketPC
cursorBefore = this.Cursor;
this.Cursor = Cursors.SizeAll;
#endif
}
if(BoundsOfMap.HasValue && !BoundsOfMap.Value.Contains(Position))
{
// ...
}
else
{
#if !PocketPC
Core.mouseCurrent = ApplyRotationInversion(e.X, e.Y);
#else
Core.mouseCurrent = new GPoint(e.X, e.Y);
#endif
Core.Drag(Core.mouseCurrent);
#if !PocketPC
if(MobileMode)
{
ForceUpdateOverlays();
}
#else
ForceUpdateOverlays();
#endif
base.Invalidate();
}
}
else
{
#if !PocketPC
if(isSelected && !selectionStart.IsEmpty && (Form.ModifierKeys == Keys.Alt || Form.ModifierKeys == Keys.Shift || DisableAltForSelection))
{
selectionEnd = FromLocalToLatLng(e.X, e.Y);
{
GMap.NET.PointLatLng p1 = selectionStart;
GMap.NET.PointLatLng p2 = selectionEnd;
double x1 = Math.Min(p1.Lng, p2.Lng);
double y1 = Math.Max(p1.Lat, p2.Lat);
double x2 = Math.Max(p1.Lng, p2.Lng);
double y2 = Math.Min(p1.Lat, p2.Lat);
SelectedArea = new RectLatLng(y1, x1, x2 - x1, y1 - y2);
}
}
else
#endif
if(Core.mouseDown.IsEmpty)
{
for(int i = Overlays.Count - 1; i >= 0; i--)
{
GMapOverlay o = Overlays[i];
if(o != null && o.IsVisibile)
{
foreach(GMapMarker m in o.Markers)
{
if(m.IsVisible && m.IsHitTestVisible)
{
#region -- check --
#if !PocketPC
if((MobileMode && m.LocalArea.Contains(e.X, e.Y)) || (!MobileMode && m.LocalAreaInControlSpace.Contains(e.X, e.Y)))
#else
if (m.LocalArea.Contains(e.X, e.Y))
#endif
{
if(!m.IsMouseOver)
{
#if !PocketPC
cursorBefore = this.Cursor;
this.Cursor = Cursors.Hand;
#endif
m.IsMouseOver = true;
if(OnMarkerEnter != null)
{
OnMarkerEnter(m);
}
Invalidate();
}
}
else if(m.IsMouseOver)
{
#if !PocketPC
this.Cursor = this.cursorBefore;
cursorBefore = null;
#endif
m.IsMouseOver = false;
if(OnMarkerLeave != null)
{
OnMarkerLeave(m);
}
Invalidate();
}
#endregion
}
}
#if !PocketPC
foreach(GMapRoute m in o.Routes)
{
if(m.IsVisible && m.IsHitTestVisible)
{
#region -- check --
GPoint rp = new GPoint(e.X, e.Y);
#if !PocketPC
if(!MobileMode)
{
rp.OffsetNegative(Core.renderOffset);
}
#endif
if(m.IsInside((int)rp.X, (int)rp.Y))
{
if(!m.IsMouseOver)
{
#if !PocketPC
cursorBefore = this.Cursor;
this.Cursor = Cursors.Hand;
#endif
m.IsMouseOver = true;
if(OnRouteEnter != null)
{
OnRouteEnter(m);
}
Invalidate();
}
}
else
{
if(m.IsMouseOver)
{
#if !PocketPC
this.Cursor = this.cursorBefore;
cursorBefore = null;
#endif
m.IsMouseOver = false;
if(OnRouteLeave != null)
{
OnRouteLeave(m);
}
Invalidate();
}
}
#endregion
}
}
#endif
//移除踪迹
IsMouseOverPolygon = false;
foreach(GMapPolygon m in o.Polygons)
{
if(m.IsVisible && (m.IsHitTestVisible || CanDragPolygon)) //check when I can drag the polygon too
{
#region -- check --
if(m.IsInside(FromLocalToLatLng(e.X, e.Y)))
{
//keep the value that there are polygons under mouse pointer
IsMouseOverPolygon = true;
if(!m.IsMouseOver)
{
m.IsMouseOver = true;
if ( m.IsHitTestVisible ) //only fires event if it IsHitTestVisible
{
#if !PocketPC
cursorBefore = this.Cursor;
this.Cursor = Cursors.Hand;
#endif
if ( OnPolygonEnter != null )
{
OnPolygonEnter( m );
}
}
Invalidate();
}
}
else
{
if(m.IsMouseOver)
{
m.IsMouseOver = false;
if ( m.IsHitTestVisible ) //触发点击事件
{
#if !PocketPC
this.Cursor = this.cursorBefore;
cursorBefore = null;
#endif
if ( OnPolygonLeave != null )
{
OnPolygonLeave( m );
}
}
Invalidate();
}
}
#endregion
}
}
}
}
}
}
base.OnMouseMove(e);
}
(23169)

最近在做一个GPS监控程序,但是发现用了Gmap.net 控件后,出现了位置偏移,不知道怎么解决啊!拜托了,给个解决方案!!
你使用的GPS设备的发送的坐标,需要对坐标通过算法做纠偏,最近正在做一个纠偏插件,过两天就在网站上发布出来。
谢了,你的那套算法是不是还要调用google服务器啊?
调用google的API啊,因为我是个C/s架构的程序,不能上外网啊
不能上外网?那你怎么接收GPS数据?
how can I login in ? I need to load the source code .Thanks!
这张图是我的项目中的,呵呵!
我是同行,不过现在技术上做的少,事务上多了。看了你的网站,相当专业,相当有帮助,当时要是认识你,一起交流,开发就轻松多了。我当时搞服务器端和客户端也是从没搞过,从0开始的,后来全搞通了费了不少精力!