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