一、从GMap的鼠标移动、拖动开始说起
一个项目用到了地图控件
我们知道Winform的窗体一般都有MouseClick、MouseUp、MouseDown还有MouseMove等的事件
因为我这个是一个地图控件,控件里有自己加好的标注图层
所以又多了OnMarkerClick 、OnMarkerEnter、OnMarkerLeave事件
我做的功能是:有两个RadioButton(即只能选一种情况:编辑模式和测距模式)
编辑模式:可以移动(MouseDrag)还有添加Marker
测距模式: 此时关闭编辑状态,因为怕点击就会误触Marker,点击前后两点,计算距离(Click)
我自己的想法是:在两个RadioButton的CheckChanged的时候,定义了两个全局bool变量
IsEditable和IsCalDistance,赋相应的值就行了;
然后编辑模式需要考虑点击“MarkerClick”当前的点属于哪个图层,“拖动”到新位置:MarkerLeave,新位置“MarkerEnter”新点;
测距模式就需要考虑“两次”点击:—-这块可能有问题—待解决
第一次点击,此时StartPoint和EndPoint都为null,给StartPoint赋值
第二次点击时,给EndPoint赋值,顺便计算
第三次点击时,EndPoint作为了StartPoint,EndPoint为null
继续重复二
可能这一部分程序思路有问题
1.OnMarkerClick事件—-是指在鼠标点击地图控件引发此事件
2.OnMarkerEnter事件—-
3.OnMarkerLeave事件—-
控件的MouseDown首先记录位置,事件,还有记录鼠标已经按下
timemousedown是指落下时间,就在
private void gmap_MouseDown(object sender, MouseEventArgs e)
{
timemousedown = DateTime.Now;
mousepress_x = e.X;
mousepress_y = e.Y;
isMouseDown = true;
}
int isSetPoint = 0;//设置起止点,1为起点,2为终点
PointLatLng startPoint = PointLatLng.Empty;
PointLatLng endPoint = PointLatLng.Empty;
PointLatLng clickPos = PointLatLng.Empty;
private void gmap_MouseClick(object sender, MouseEventArgs e)
{
clickPos = this.gmap.FromLocalToLatLng(e.X, e.Y);
SetTxtLatLng(clickPos);
if (clickMarker != null && clickMarker.Position != clickPos)
{
((GMarkerGoogleExt)clickMarker).AddRect = false;
}
if (isMarkerEditable)//编辑模式下可以移动和添加标注
{
if (timemousedown.AddMilliseconds(timemillSecond) > DateTime.Now)
{
isMouseDrag = false;
}
else
{
isMouseDrag = true;
}
int x_dis = (mousepress_x > e.X) ? mousepress_x - e.X : e.X - mousepress_x;
int y_dis = (mousepress_y > e.Y) ? mousepress_y - e.Y : e.Y - mousepress_y;
if (mousedistance < System.Math.Sqrt(x_dis * x_dis + y_dis * x_dis))
{
isMouseDrag = true;//拖拽
}
if (!isMouseDrag)
{
PointLatLng p = gmap.FromLocalToLatLng(e.X, e.Y);
GMapMarker marker = new GMarkerGoogle(p, GMarkerGoogleType.blue_dot);
marker.IsVisible = true;
marker.ToolTipText = string.Format("经度{0},纬度:{1}", marker.Position.Lng, marker.Position.Lat);
mouseOverlay.Markers.Add(marker);
}
}
if (isCalDistanceMode)//测距模式下不能移动和添加标注
{
if (timemousedown.AddMilliseconds(timemillSecond) > DateTime.Now)
{
//isMouseDrag = false;
isMouseDrag = true;
}
else
{
//isMouseDrag = true;
isMouseDrag = false;
}
int x_dis = (mousepress_x > e.X) ? mousepress_x - e.X : e.X - mousepress_x;
int y_dis = (mousepress_y > e.Y) ? mousepress_y - e.Y : e.Y - mousepress_y;
if (mousedistance < System.Math.Sqrt(x_dis * x_dis + y_dis * x_dis))
{
isMouseDrag = true;//拖拽
}
if (!isMouseDrag)
{
PointLatLng point = this.gmap.FromLocalToLatLng(e.X, e.Y);
if (isSetPoint == 0)
{
isSetPoint = 1;//设置起始点
}
else if (isSetPoint == 1)
{
isSetPoint = 2;
}
else if (isSetPoint == 2)
{
isSetPoint = 1;
}
switch (isSetPoint)
{
case 1:
//起点
if (clickMarker != null)
{ startPoint = clickMarker.Position; }
else
{ startPoint = point; }
clickMarker = null;
txtStatic.Caption = "当前为起始点";
//纬度,经度
txt_Coordinate.EditValue = string.Format("{0},{1}", startPoint.Lat.ToString(), startPoint.Lng.ToString());
break;
case 2:
//终点
if (clickMarker != null)
{
endPoint = clickMarker.Position;
}
else
{
endPoint = point;
}
clickMarker = null;
txtStatic.Caption = "当前为结束点";
txtLatLng.EditValue = string.Format("{0},{1}", endPoint.Lat.ToString(), endPoint.Lng.ToString());
txtLatLng.AutoFillWidthInMenu = DevExpress.Utils.DefaultBoolean.True;
break;
default:
break;
}
if (startPoint != PointLatLng.Empty && endPoint != PointLatLng.Empty)
{
txtLength.Caption = string.Format("测距距离:{0}", GetDistance(startPoint, endPoint).ToString());
}
if (clickRoute != null)
{
txtStatic.Caption = "当前为轨道片";
txtLatLng.EditValue = string.Format("GMap距离{0},自己算的距离{1}", clickRoute.Distance, clickRoute.Tag);
txtLatLng.AutoFillWidthInMenu = DevExpress.Utils.DefaultBoolean.True;
}
}
}
}
private void gmap_OnMarkerEnter(GMapMarker item)//设置选中的Marker
{
isMarkerEnter = true;
currentMarker = item;
}
private void gmap_OnMarkerLeave(GMapMarker item)//取消选中的Marker
{
isMarkerEnter = false;
}
private void gmap_MouseMove(object sender, MouseEventArgs e)//鼠标移动事件
{
PointLatLng p = gmap.FromLocalToLatLng(e.X, e.Y);
if (isMarkerEditable)//可编辑的情况下可以移动
{
if (isMarkerEnter && isMouseDown)//如果按下且是Marker
{
isMarkerDrag = true;
}
if (!isMouseDown)//鼠标未按下
{
isMarkerDrag = false;//则图标不可移动
}
if (isMarkerDrag)//如果可移动
{
currentMarker.Position = p;//则位置随着鼠标移动
string txt = currentMarker.ToolTipText;
txt = string.Format("{0}:经度{1},纬度{2}", txt.Substring(0, txt.LastIndexOf(":")), p.Lng, p.Lat);
}
}
txtMousePos.Caption = string.Format("鼠标位置:{0},{1}", p.Lat, p.Lng);
}
private void gmap_MouseUp(object sender, MouseEventArgs e)
{
isMouseDown = false;//鼠标未按下
}
bool isCalDistanceMode = false;//是否是测距模式
bool isMarkerEditable = false;//点是否可以编辑
//private GMapMarker clickMarker = null;
private GMarkerGoogleExt clickMarker = null;
private void gmap_OnMarkerClick(GMapMarker item, MouseEventArgs e)
{
SetPerfectPos(true, false, item.Overlay);
SetCurrentCustomAttribute(item.Overlay.Id);
var overlayname = item.Overlay.Id;
var attribute = customAttributes.Find(a => a.LineName == overlayname);
if (item is GMarkerGoogleExt)
{
clickMarker = item as GMarkerGoogleExt;
clickMarker.AddRect = !clickMarker.AddRect;
SetTxtLatLng(clickMarker.Position);
}
gmap.Refresh();
}
private void chkbtnCalDisMode_CheckedChanged(object sender, EventArgs e)
{
isCalDistanceMode = chkbtnCalDisMode.Checked;
}
private void chkEditMode_CheckedChanged(object sender, EventArgs e)
{
isMarkerEditable = chkEditMode.Checked;
}